Hi there

Don't use the ShapeDrawable class, these are pretty slow and inefficient. 
Instead, draw the geometry yourself. 

Here - this function will create a cone with different top/bottom radius, and a 
length. Variables needed by the function include 

startRadius (float)
endRadius (float)
length (float)

and colour (Vec4)

Then I suggest you look at the Sphere shape to see how they calculate their 
vertices to append to the bottom of your cone (to get the rounded bottom). 
Finally you will need to add the Geometry object to a Geode and run the 
Smoothing Visitor over the node in order to create normals. 

Cheers,
Andrew

//////////////////////////////////

osg::Geometry * CCone::CreateConeGeometry()
{
        // Here's our cone/cylinder implementation. We will create the 
top/bottom
        // by triangle fans and the body will connect the two as a quad strip 
        // 
        // Y             Z   
        // ^            /
        // |      ---
        // |    --   --
        // |   -  Top  -
        // |   |--   --|
        // |   |  ---  |
        // |   |       |
        // |   |  Body |
        // |   |       |
        // |   |       |
        // |   |  ...  |
        // |   |..   ..|
        // |   | Bottom|
        // |    --   --
        // |      ---
        // o---------------> X
        //              

        float angle = 0.0f;
        float angleDelta = 2.0f * osg::PI/(float)numberSegments;

        // Create arrays to hold the X & Y coeffiecients that we will re-use
        // throughout the creation of vertices
        float * xTop = nullptr;
        float * yTop = nullptr;
        float * xBottom = nullptr;
        float * yBottom = nullptr;

        try
        {
                xTop = new float[numberSegments+1];
                yTop = new float[numberSegments+1];
                xBottom = new float[numberSegments+1];
                yBottom = new float[numberSegments+1];

                for (int i = 0; i < numberSegments; i++,angle -= angleDelta)
                {
                        // Compute the cos/sin of the current angle as we 
rotate around the cylinder
                        float cosAngle = cosf(angle);
                        float sinAngle = sinf(angle);

                        // Compute the top/bottom locations
                        xTop[i] = cosAngle * endRadius;
                        yTop[i] = sinAngle * endRadius;

                        xBottom[i] = cosAngle * startRadius;
                        yBottom[i] = sinAngle * startRadius;
                }               

                // Put the last point equal to the first point so the cylinder
                // is complete
                xTop[numberSegments] = xTop[0];
                yTop[numberSegments] = yTop[0];
                xBottom[numberSegments] = xBottom[0];
                yBottom[numberSegments] = yBottom[0];

                // Compute the number of vertices required for the top and 
bottom
                int numTopBottomVertices = numberSegments + 2;

                // Compute the number of vertices required for the body
                int numBodyVertices = (numberSegments + 1) * 2;

                // Create an array to hold the cylinder vertices
                osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array();
                vertices->reserve(2 * numTopBottomVertices);                    
        
                
                int j = 0;

                // Create three primitive sets for the top, bottom and body of 
the cone
                osg::ref_ptr<osg::DrawElementsUByte> topPrimitive = new 
osg::DrawElementsUByte(osg::PrimitiveSet::TRIANGLE_FAN);
                osg::ref_ptr<osg::DrawElementsUByte> bottomPrimitive = new 
osg::DrawElementsUByte(osg::PrimitiveSet::TRIANGLE_FAN);
                osg::ref_ptr<osg::DrawElementsUByte> bodyPrimitive = new 
osg::DrawElementsUByte(osg::PrimitiveSet::QUAD_STRIP);
        
                // Allocate sufficient memory for the top/bottom and body
                topPrimitive->reserve(numTopBottomVertices);
                bottomPrimitive->reserve(numTopBottomVertices);
                bodyPrimitive->reserve(numBodyVertices);

                //
                // Create the vertices and indices for the bottom
                //
                
                // Create the centre vertex in the trianglestrip that will form 
the bottom
                vertices->push_back(osg::Vec3f(0.0f, 0.0f, 0.0f));              
        
                bottomPrimitive->push_back(j++);

                // Create the surrounding vertices for the bottom
                for (int i = 0; i <= numberSegments; i++)
                {
                        // Set the vertex location
                        vertices->push_back(osg::Vec3f(xBottom[i], yBottom[i], 
0.0f));

                        // Set the index to the vertex in the bottom primitive
                        bottomPrimitive->push_back(j++);
                }

                //
                // Create the vertices and indices for the top
                //

                // Create the centre vertex in the trianglestrip that will form 
the top
                vertices->push_back(osg::Vec3f(0.0f, 0.0f, length));
                topPrimitive->push_back(j++);

                // Create surrounding vertices for the top in reverse order, so 
the normals
                // point the other way
                for (int i = numberSegments; i >=0; i--)
                {
                        // Set the vertex location
                        vertices->push_back(osg::Vec3f(xTop[i], yTop[i], 
length));

                        // Set the index to the vertex in the bottom primitive
                        topPrimitive->push_back(j++);
                }

                //
                // Finally create the indices for the body vertices
                //
                
                // To do this we will take one vertex from top and bottom 
alternately as the body
                // is constructed using a quad strip. So we take two variables, 
k and l, K starts at the bottom
                // and L at the top (remember top vertices are in reverse order 
due to normals) and work inwards
                for (int k = 1, l = vertices->size() - 1; k < 
numTopBottomVertices; k++, l--)
                {
                        bodyPrimitive->push_back(k);
                        bodyPrimitive->push_back(l);
                }

                // Note no memory management for coneBodyGeometry as this is 
returned from the function
                osg::Geometry * coneBodyGeometry = new osg::Geometry();
                
                // Set the vertices on the cone
                coneBodyGeometry->setVertexArray(vertices);                     

                // Set the PrimitiveSets on the geometry object
                coneBodyGeometry->addPrimitiveSet(topPrimitive);
                coneBodyGeometry->addPrimitiveSet(bottomPrimitive);
                coneBodyGeometry->addPrimitiveSet(bodyPrimitive);

                // Set the Colour to the entire object
                osg::ref_ptr<osg::Vec4Array> colourArray = new osg::Vec4Array();
                colourArray->push_back(osg::Vec4(*colour));
                coneBodyGeometry->setColorArray(colourArray.get());             
        
                coneBodyGeometry->setColorBinding(osg::Geometry::BIND_OVERALL); 
                
                return coneBodyGeometry;
        }
        finally
        {
                delete [] xTop;
                delete [] yTop);
                delete [] xBottom;
                delete [] yBottom;
        }
}
//////////////////////////////////

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=15667#15667





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to