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