From 3fcba1bc511b263d2a1ba7ae77bdd72128cb8c04 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 16 Dec 2007 17:57:19 +0000 Subject: [PATCH] From Jean-Sebastien Guay, "Some clients at my new job noticed that picking did not work with the osg::Capsule subclass of osg::Shape in an osg::ShapeDrawable. Other shapes worked fine. So I have fixed this. Code attached. My modification is in the PrimitiveShapeVisitor, and is based on the DrawShapeVisitor - I added methods called createCylinderBody and createHalfSphere, and used them in apply(Cylinder&) and apply(Capsule&). In my testing they work fine, tested even with transforms and moving around the scene. " --- src/osg/ShapeDrawable.cpp | 210 +++++++++++++++++++++++++++++--------- 1 file changed, 160 insertions(+), 50 deletions(-) diff --git a/src/osg/ShapeDrawable.cpp b/src/osg/ShapeDrawable.cpp index ebee928c3..f676bbed4 100644 --- a/src/osg/ShapeDrawable.cpp +++ b/src/osg/ShapeDrawable.cpp @@ -1320,10 +1320,113 @@ class PrimitiveShapeVisitor : public ConstShapeVisitor PrimitiveFunctor& _functor; const TessellationHints* _hints; + + private: + // helpers for apply( Cylinder | Sphere | Capsule ) + void createCylinderBody(unsigned int numSegments, float radius, float height, const osg::Matrix& matrix); + void createHalfSphere(unsigned int numSegments, unsigned int numRows, float radius, int which, float zOffset, const osg::Matrix& matrix); }; +void PrimitiveShapeVisitor::createCylinderBody(unsigned int numSegments, float radius, float height, const osg::Matrix& matrix) +{ + const float angleDelta = 2.0f*osg::PI/(float)numSegments; + + const float r = radius; + const float h = height; + + float basez = -h*0.5f; + float topz = h*0.5f; + + float angle = 0.0f; + + _functor.begin(GL_QUAD_STRIP); + + for(unsigned int bodyi=0; + bodyigetDetailRatio() : 1.0f); + if (ratio > 0.0f && ratio != 1.0f) { + numRows = (unsigned int) (numRows * ratio); + if (numRows < MIN_NUM_ROWS) + numRows = MIN_NUM_ROWS; + numSegments = (unsigned int) (numSegments * ratio); + if (numSegments < MIN_NUM_SEGMENTS) + numSegments = MIN_NUM_SEGMENTS; + } float r = cone.getRadius(); float h = cone.getHeight(); @@ -1498,8 +1604,6 @@ void PrimitiveShapeVisitor::apply(const Cone& cone) normalz *= normalRatio; float angleDelta = 2.0f*osg::PI/(float)numSegments; - float texCoordHorzDelta = 1.0/(float)numSegments; - float texCoordRowDelta = 1.0/(float)numRows; float hDelta = cone.getHeight()/(float)numRows; float rDelta = cone.getRadius()/(float)numRows; @@ -1508,13 +1612,11 @@ void PrimitiveShapeVisitor::apply(const Cone& cone) float topv=1.0f; float basez=topz-hDelta; float baser=rDelta; - float basev=topv-texCoordRowDelta; float angle; - float texCoord; for(unsigned int rowi=0; rowigetDetailRatio() : 1.0f); + if (ratio > 0.0f && ratio != 1.0f) { + numSegments = (unsigned int) (numSegments * ratio); + if (numSegments < MIN_NUM_SEGMENTS) + numSegments = MIN_NUM_SEGMENTS; + } float angleDelta = 2.0f*osg::PI/(float)numSegments; - float texCoordDelta = 1.0/(float)numSegments; - float r = cylinder.getRadius(); float h = cylinder.getHeight(); float basez = -h*0.5f; float topz = h*0.5f; + float angle; // cylinder body - _functor.begin(GL_QUAD_STRIP); - - float angle = 0.0f; - float texCoord = 0.0f; - for(unsigned int bodyi=0; - bodyigetDetailRatio() : 1.0f); + if (ratio > 0.0f && ratio != 1.0f) { + numRows = (unsigned int) (numRows * ratio); + if (numRows < MIN_NUM_ROWS) + numRows = MIN_NUM_ROWS; + numSegments = (unsigned int) (numSegments * ratio); + if (numSegments < MIN_NUM_SEGMENTS) + numSegments = MIN_NUM_SEGMENTS; + } + + float angleDelta = 2.0f*osg::PI/(float)numSegments; + + float r = capsule.getRadius(); + float h = capsule.getHeight(); + + float basez = -h*0.5f; + float topz = h*0.5f; + + // capsule body + createCylinderBody(numSegments, capsule.getRadius(), capsule.getHeight(), matrix); + + // capsule top cap + 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); + } void PrimitiveShapeVisitor::apply(const InfinitePlane&)