From Jean-Sebastien Guay, "When creating a cylinder without a bottom or a top (in the traits, createBottom=false and createTop=false), the cylinder could still be picked by picking its (non-existent) bottom or top. This is because the PrimitiveShapeFunctor does not consider the traits when returning the cylinder's geometry for the picking test, and always returns geometry for the whole cylinder, with bottom, top and body.
I have attached a fixed file where the traits are checked in the PrimitiveShapeFunctor where appropriate. They are checked for Box, Cone Capsule and Cylinder. These just mirror the checks that were already done in the DrawShapeVisitor.
(another instance where if the ShapeDrawable had just been osg::Geometry, there wouldn't have been a problem... :-) )
I also fixed a small typo in the file in two places ("implementated" --> "implemented")."
This commit is contained in:
@@ -833,7 +833,7 @@ void DrawShapeVisitor::apply(const Capsule& capsule)
|
||||
|
||||
void DrawShapeVisitor::apply(const InfinitePlane&)
|
||||
{
|
||||
notify(NOTICE)<<"Warning: DrawShapeVisitor::apply(const InfinitePlane& plane) not yet implementated. "<<std::endl;
|
||||
notify(NOTICE)<<"Warning: DrawShapeVisitor::apply(const InfinitePlane& plane) not yet implemented. "<<std::endl;
|
||||
}
|
||||
|
||||
void DrawShapeVisitor::apply(const TriangleMesh& mesh)
|
||||
@@ -1511,6 +1511,11 @@ void PrimitiveShapeVisitor::apply(const Sphere& sphere)
|
||||
|
||||
void PrimitiveShapeVisitor::apply(const Box& box)
|
||||
{
|
||||
// evaluate hints
|
||||
bool createBody = (_hints ? _hints->getCreateBody() : true);
|
||||
bool createTop = (_hints ? _hints->getCreateTop() : true);
|
||||
bool createBottom = (_hints ? _hints->getCreateBottom() : true);
|
||||
|
||||
float x = box.getHalfLengths().x();
|
||||
float y = box.getHalfLengths().y();
|
||||
float z = box.getHalfLengths().z();
|
||||
@@ -1554,36 +1559,44 @@ void PrimitiveShapeVisitor::apply(const Box& box)
|
||||
}
|
||||
|
||||
_functor.begin(GL_QUADS);
|
||||
|
||||
_functor.vertex(top_1);
|
||||
_functor.vertex(base_1);
|
||||
_functor.vertex(base_2);
|
||||
_functor.vertex(top_2);
|
||||
if (createBody)
|
||||
{
|
||||
_functor.vertex(top_1);
|
||||
_functor.vertex(base_1);
|
||||
_functor.vertex(base_2);
|
||||
_functor.vertex(top_2);
|
||||
|
||||
_functor.vertex(top_2);
|
||||
_functor.vertex(base_2);
|
||||
_functor.vertex(base_3);
|
||||
_functor.vertex(top_3);
|
||||
_functor.vertex(top_2);
|
||||
_functor.vertex(base_2);
|
||||
_functor.vertex(base_3);
|
||||
_functor.vertex(top_3);
|
||||
|
||||
_functor.vertex(top_3);
|
||||
_functor.vertex(base_3);
|
||||
_functor.vertex(base_4);
|
||||
_functor.vertex(top_4);
|
||||
_functor.vertex(top_3);
|
||||
_functor.vertex(base_3);
|
||||
_functor.vertex(base_4);
|
||||
_functor.vertex(top_4);
|
||||
|
||||
_functor.vertex(top_4);
|
||||
_functor.vertex(base_4);
|
||||
_functor.vertex(base_1);
|
||||
_functor.vertex(top_1);
|
||||
_functor.vertex(top_4);
|
||||
_functor.vertex(base_4);
|
||||
_functor.vertex(base_1);
|
||||
_functor.vertex(top_1);
|
||||
}
|
||||
|
||||
_functor.vertex(top_4);
|
||||
_functor.vertex(top_1);
|
||||
_functor.vertex(top_2);
|
||||
_functor.vertex(top_3);
|
||||
if (createTop)
|
||||
{
|
||||
_functor.vertex(top_4);
|
||||
_functor.vertex(top_1);
|
||||
_functor.vertex(top_2);
|
||||
_functor.vertex(top_3);
|
||||
}
|
||||
|
||||
_functor.vertex(base_4);
|
||||
_functor.vertex(base_3);
|
||||
_functor.vertex(base_2);
|
||||
_functor.vertex(base_1);
|
||||
if (createBottom)
|
||||
{
|
||||
_functor.vertex(base_4);
|
||||
_functor.vertex(base_3);
|
||||
_functor.vertex(base_2);
|
||||
_functor.vertex(base_1);
|
||||
}
|
||||
|
||||
_functor.end();
|
||||
|
||||
@@ -1591,6 +1604,10 @@ void PrimitiveShapeVisitor::apply(const Box& box)
|
||||
|
||||
void PrimitiveShapeVisitor::apply(const Cone& cone)
|
||||
{
|
||||
// evaluate hints
|
||||
bool createBody = (_hints ? _hints->getCreateBody() : true);
|
||||
bool createBottom = (_hints ? _hints->getCreateBottom() : true);
|
||||
|
||||
Matrix matrix = cone.computeRotationMatrix();
|
||||
matrix.setTrans(cone.getCenter());
|
||||
|
||||
@@ -1623,66 +1640,77 @@ void PrimitiveShapeVisitor::apply(const Cone& cone)
|
||||
float baser=rDelta;
|
||||
float angle;
|
||||
|
||||
for(unsigned int rowi=0;
|
||||
rowi<numRows;
|
||||
++rowi,topz=basez, basez-=hDelta, topr=baser, baser+=rDelta)
|
||||
if (createBody)
|
||||
{
|
||||
for(unsigned int rowi=0;
|
||||
rowi<numRows;
|
||||
++rowi,topz=basez, basez-=hDelta, topr=baser, baser+=rDelta)
|
||||
{
|
||||
// we can't use a fan for the cone top
|
||||
// since we need different normals at the top
|
||||
// for each face..
|
||||
_functor.begin(GL_QUAD_STRIP);
|
||||
|
||||
angle = 0.0f;
|
||||
for(unsigned int topi=0;
|
||||
topi<numSegments;
|
||||
++topi,angle+=angleDelta)
|
||||
{
|
||||
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
_functor.vertex(Vec3(c*topr,s*topr,topz)*matrix);
|
||||
_functor.vertex(Vec3(c*baser,s*baser,basez)*matrix);
|
||||
|
||||
}
|
||||
|
||||
// do last point by hand to ensure no round off errors.
|
||||
_functor.vertex(Vec3(topr,0.0f,topz)*matrix);
|
||||
_functor.vertex(Vec3(baser,0.0f,basez)*matrix);
|
||||
|
||||
_functor.end();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (createBottom)
|
||||
{
|
||||
// we can't use a fan for the cone top
|
||||
// since we need different normals at the top
|
||||
// for each face..
|
||||
_functor.begin(GL_QUAD_STRIP);
|
||||
_functor.begin(GL_TRIANGLE_FAN);
|
||||
|
||||
angle = 0.0f;
|
||||
for(unsigned int topi=0;
|
||||
topi<numSegments;
|
||||
++topi,angle+=angleDelta)
|
||||
{
|
||||
angle = osg::PI*2.0f;
|
||||
basez = cone.getBaseOffset();
|
||||
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
_functor.vertex(Vec3(0.0f,0.0f,basez)*matrix);
|
||||
|
||||
_functor.vertex(Vec3(c*topr,s*topr,topz)*matrix);
|
||||
_functor.vertex(Vec3(c*baser,s*baser,basez)*matrix);
|
||||
for(unsigned int bottomi=0;
|
||||
bottomi<numSegments;
|
||||
++bottomi,angle-=angleDelta)
|
||||
{
|
||||
|
||||
}
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
// do last point by hand to ensure no round off errors.
|
||||
_functor.vertex(Vec3(topr,0.0f,topz)*matrix);
|
||||
_functor.vertex(Vec3(baser,0.0f,basez)*matrix);
|
||||
_functor.vertex(Vec3(c*r,s*r,basez)*matrix);
|
||||
|
||||
}
|
||||
|
||||
_functor.vertex(Vec3(r,0.0f,basez)*matrix);
|
||||
|
||||
_functor.end();
|
||||
|
||||
}
|
||||
|
||||
// we can't use a fan for the cone top
|
||||
// since we need different normals at the top
|
||||
// for each face..
|
||||
_functor.begin(GL_TRIANGLE_FAN);
|
||||
|
||||
angle = osg::PI*2.0f;
|
||||
basez = cone.getBaseOffset();
|
||||
|
||||
_functor.vertex(Vec3(0.0f,0.0f,basez)*matrix);
|
||||
|
||||
for(unsigned int bottomi=0;
|
||||
bottomi<numSegments;
|
||||
++bottomi,angle-=angleDelta)
|
||||
{
|
||||
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
_functor.vertex(Vec3(c*r,s*r,basez)*matrix);
|
||||
|
||||
}
|
||||
|
||||
_functor.vertex(Vec3(r,0.0f,basez)*matrix);
|
||||
|
||||
_functor.end();
|
||||
}
|
||||
|
||||
void PrimitiveShapeVisitor::apply(const Cylinder& cylinder)
|
||||
{
|
||||
// evaluate hints
|
||||
bool createBody = (_hints ? _hints->getCreateBody() : true);
|
||||
bool createTop = (_hints ? _hints->getCreateTop() : true);
|
||||
bool createBottom = (_hints ? _hints->getCreateBottom() : true);
|
||||
|
||||
Matrix matrix = cylinder.computeRotationMatrix();
|
||||
matrix.setTrans(cylinder.getCenter());
|
||||
|
||||
@@ -1704,55 +1732,67 @@ void PrimitiveShapeVisitor::apply(const Cylinder& cylinder)
|
||||
float angle;
|
||||
|
||||
// cylinder body
|
||||
createCylinderBody(numSegments, cylinder.getRadius(), cylinder.getHeight(), matrix);
|
||||
if (createBody)
|
||||
createCylinderBody(numSegments, cylinder.getRadius(), cylinder.getHeight(), matrix);
|
||||
|
||||
// cylinder top
|
||||
_functor.begin(GL_TRIANGLE_FAN);
|
||||
if (createTop)
|
||||
{
|
||||
_functor.begin(GL_TRIANGLE_FAN);
|
||||
|
||||
_functor.vertex(Vec3(0.0f,0.0f,topz)*matrix);
|
||||
_functor.vertex(Vec3(0.0f,0.0f,topz)*matrix);
|
||||
|
||||
angle = 0.0f;
|
||||
for(unsigned int topi=0;
|
||||
topi<numSegments;
|
||||
++topi,angle+=angleDelta)
|
||||
{
|
||||
angle = 0.0f;
|
||||
for(unsigned int topi=0;
|
||||
topi<numSegments;
|
||||
++topi,angle+=angleDelta)
|
||||
{
|
||||
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
_functor.vertex(Vec3(c*r,s*r,topz)*matrix);
|
||||
_functor.vertex(Vec3(c*r,s*r,topz)*matrix);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_functor.vertex(Vec3(r,0.0f,topz)*matrix);
|
||||
_functor.vertex(Vec3(r,0.0f,topz)*matrix);
|
||||
|
||||
_functor.end();
|
||||
_functor.end();
|
||||
}
|
||||
|
||||
// cylinder bottom
|
||||
_functor.begin(GL_TRIANGLE_FAN);
|
||||
if (createBottom)
|
||||
{
|
||||
_functor.begin(GL_TRIANGLE_FAN);
|
||||
|
||||
_functor.vertex(Vec3(0.0f,0.0f,basez)*matrix);
|
||||
_functor.vertex(Vec3(0.0f,0.0f,basez)*matrix);
|
||||
|
||||
angle = osg::PI*2.0f;
|
||||
for(unsigned int bottomi=0;
|
||||
bottomi<numSegments;
|
||||
++bottomi,angle-=angleDelta)
|
||||
{
|
||||
angle = osg::PI*2.0f;
|
||||
for(unsigned int bottomi=0;
|
||||
bottomi<numSegments;
|
||||
++bottomi,angle-=angleDelta)
|
||||
{
|
||||
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
float s = sinf(angle);
|
||||
|
||||
_functor.vertex(Vec3(c*r,s*r,basez)*matrix);
|
||||
_functor.vertex(Vec3(c*r,s*r,basez)*matrix);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_functor.vertex(Vec3(r,0.0f,basez)*matrix);
|
||||
_functor.vertex(Vec3(r,0.0f,basez)*matrix);
|
||||
|
||||
_functor.end();
|
||||
_functor.end();
|
||||
}
|
||||
}
|
||||
|
||||
void PrimitiveShapeVisitor::apply(const Capsule& capsule)
|
||||
{
|
||||
// evaluate hints
|
||||
bool createBody = (_hints ? _hints->getCreateBody() : true);
|
||||
bool createTop = (_hints ? _hints->getCreateTop() : true);
|
||||
bool createBottom = (_hints ? _hints->getCreateBottom() : true);
|
||||
|
||||
Matrix matrix = capsule.computeRotationMatrix();
|
||||
matrix.setTrans(capsule.getCenter());
|
||||
|
||||
@@ -1769,19 +1809,22 @@ void PrimitiveShapeVisitor::apply(const Capsule& capsule)
|
||||
}
|
||||
|
||||
// capsule body
|
||||
createCylinderBody(numSegments, capsule.getRadius(), capsule.getHeight(), matrix);
|
||||
if (createBody)
|
||||
createCylinderBody(numSegments, capsule.getRadius(), capsule.getHeight(), matrix);
|
||||
|
||||
// capsule top cap
|
||||
createHalfSphere(numSegments, numRows, capsule.getRadius(), 0, capsule.getHeight()/2.0f, matrix);
|
||||
if (createTop)
|
||||
createHalfSphere(numSegments, numRows, capsule.getRadius(), 0, capsule.getHeight()/2.0f, matrix);
|
||||
|
||||
// capsule bottom cap
|
||||
createHalfSphere(numSegments, numRows, capsule.getRadius(), 1, -capsule.getHeight()/2.0f, matrix);
|
||||
if (createBottom)
|
||||
createHalfSphere(numSegments, numRows, capsule.getRadius(), 1, -capsule.getHeight()/2.0f, matrix);
|
||||
|
||||
}
|
||||
|
||||
void PrimitiveShapeVisitor::apply(const InfinitePlane&)
|
||||
{
|
||||
notify(NOTICE)<<"Warning: PrimitiveShapeVisitor::apply(const InfinitePlane& plane) not yet implementated. "<<std::endl;
|
||||
notify(NOTICE)<<"Warning: PrimitiveShapeVisitor::apply(const InfinitePlane& plane) not yet implemented. "<<std::endl;
|
||||
}
|
||||
|
||||
void PrimitiveShapeVisitor::apply(const TriangleMesh& mesh)
|
||||
|
||||
Reference in New Issue
Block a user