@ -22,6 +22,49 @@
using namespace osgManipulator ;
namespace
{
//------------------------------------------------------------------------------
osg : : Geometry * createDiskGeometry ( float radius , float offset , float z , unsigned int numSegments
)
{
const float angleDelta = 2.0f * osg : : PI / float ( numSegments ) ;
const unsigned int numPoints = ( numSegments + 1 ) * 2 ;
float angle = 0.0f ;
osg : : Vec3Array * vertexArray = new osg : : Vec3Array ( numPoints ) ;
osg : : Vec3Array * normalArray = new osg : : Vec3Array ( numPoints ) ;
unsigned int p = 0 ;
for ( unsigned int i = 0 ; i < numSegments ; + + i , angle + = angleDelta )
{
float c = cosf ( angle ) ;
float s = sinf ( angle ) ;
// Outer point
( * vertexArray ) [ p ] . set ( radius * c , radius * s , z ) ;
( * normalArray ) [ p ] . set ( 0.0 , 0.0 , - 1.0 ) ;
+ + p ;
// Inner point
( * vertexArray ) [ p ] . set ( ( radius - offset ) * c , ( radius - offset ) * s , z ) ;
( * normalArray ) [ p ] . set ( 0.0 , 0.0 , - 1.0 ) ;
+ + p ;
}
// do last points by hand to ensure no round off errors.
( * vertexArray ) [ p ] = ( * vertexArray ) [ 0 ] ;
( * normalArray ) [ p ] = ( * normalArray ) [ 0 ] ;
+ + p ;
( * vertexArray ) [ p ] = ( * vertexArray ) [ 1 ] ;
( * normalArray ) [ p ] = ( * normalArray ) [ 1 ] ;
osg : : Geometry * geometry = new osg : : Geometry ;
geometry - > setVertexArray ( vertexArray ) ;
geometry - > setNormalArray ( normalArray ) ;
geometry - > setNormalBinding ( osg : : Geometry : : BIND_PER_VERTEX ) ;
geometry - > addPrimitiveSet ( new osg : : DrawArrays ( osg : : PrimitiveSet : : TRIANGLE_STRIP , 0 , vertexArray - > size ( ) ) ) ;
return geometry ;
}
}
RotateCylinderDragger : : RotateCylinderDragger ( )
{
_projector = new CylinderPlaneProjector ( ) ;
@ -73,7 +116,6 @@ bool RotateCylinderDragger::handle(const PointerInfo& pointer, const osgGA::GUIE
_prevWorldProjPt = projectedPoint * _projector - > getLocalToWorld ( ) ;
_prevRotation = osg : : Quat ( ) ;
_prevPtOnCylinder = _projector - > isProjectionOnCylinder ( ) ;
aa . requestRedraw ( ) ;
}
@ -91,8 +133,8 @@ bool RotateCylinderDragger::handle(const PointerInfo& pointer, const osgGA::GUIE
if ( _projector - > project ( pointer , projectedPoint ) )
{
osg : : Vec3d prevProjectedPoint = _prevWorldProjPt * _projector - > getWorldToLocal ( ) ;
osg : : Quat deltaRotation = _projector - > getRotation ( prevProjectedPoint , _prevPtOnCylinder ,
projectedPoint , _projector - > isProjectionOnCylinder ( ) );
osg : : Quat deltaRotation = _projector - > getRotation ( prevProjectedPoint ,
projectedPoint );
osg : : Quat rotation = deltaRotation * _prevRotation ;
// Generate the motion command.
@ -106,7 +148,6 @@ bool RotateCylinderDragger::handle(const PointerInfo& pointer, const osgGA::GUIE
_prevWorldProjPt = projectedPoint * _projector - > getLocalToWorld ( ) ;
_prevRotation = rotation ;
_prevPtOnCylinder = _projector - > isProjectionOnCylinder ( ) ;
aa . requestRedraw ( ) ;
}
return true ;
@ -138,6 +179,34 @@ bool RotateCylinderDragger::handle(const PointerInfo& pointer, const osgGA::GUIE
void RotateCylinderDragger : : setupDefaultGeometry ( )
{
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( new osg : : ShapeDrawable ( const_cast < osg : : Cylinder * > ( _projector - > getCylinder ( ) ) ) ) ;
{
osg : : TessellationHints * hints = new osg : : TessellationHints ;
hints - > setCreateTop ( false ) ;
hints - > setCreateBottom ( false ) ;
hints - > setCreateBackFace ( false ) ;
float radius = 1.0f ;
float height = 0.1f ;
float thickness = 0.1f ;
// outer cylinder
osg : : Cylinder * cylinder = new osg : : Cylinder ;
cylinder - > setHeight ( height ) ;
cylinder - > setRadius ( radius ) ;
osg : : ShapeDrawable * cylinderDrawable = new osg : : ShapeDrawable ( cylinder , hints ) ;
geode - > addDrawable ( cylinderDrawable ) ;
// inner cylinder
osg : : Cylinder * cylinder1 = const_cast < osg : : Cylinder * > ( _projector - > getCylinder ( ) ) ;
cylinder1 - > setHeight ( height ) ;
cylinder1 - > setRadius ( radius - thickness ) ;
osg : : ShapeDrawable * cylinderDrawable1 = new osg : : ShapeDrawable ( cylinder1 , hints ) ;
geode - > addDrawable ( cylinderDrawable1 ) ;
// top
geode - > addDrawable ( createDiskGeometry ( radius , thickness , height / 2 , 100 ) ) ;
// bottom
geode - > addDrawable ( createDiskGeometry ( radius , thickness , - height / 2 , 100 ) ) ;
}
addChild ( geode ) ;
}