Updates to DOFTransform so that its overrides the traverse() and compute*() methods
rather than depending upon callbacks for animating and compute matrices. Merged the put/inverseput code between Sasa's and Ferndinand's DOF code. From Bora Utka, Added support to osg::Sequence/OpenFlight AnimNode to the flt plugin.
This commit is contained in:
parent
d43b00ac4e
commit
29490a8c1c
@ -40,26 +40,28 @@ class SG_EXPORT DOFTransform : public Transform
|
||||
|
||||
META_Node(osg, DOFTransform);
|
||||
|
||||
void loadMinHPR(const Vec3& hpr) {_minHPR = hpr;}
|
||||
void loadMaxHPR(const Vec3& hpr) {_maxHPR = hpr;}
|
||||
void loadCurrentHPR(const Vec3& hpr) {_currentHPR = hpr;}
|
||||
void loadIncrementHPR(const Vec3& hpr) {_incrementHPR = hpr;}
|
||||
virtual void traverse(NodeVisitor& nv);
|
||||
|
||||
void setCurrentHPR(const Vec3& hpr);
|
||||
void setMinHPR(const Vec3& hpr) {_minHPR = hpr;}
|
||||
void setMaxHPR(const Vec3& hpr) {_maxHPR = hpr;}
|
||||
void setCurrentHPR(const Vec3& hpr) {_currentHPR = hpr;}
|
||||
void setIncrementHPR(const Vec3& hpr) {_incrementHPR = hpr;}
|
||||
|
||||
void loadMinTranslate(const Vec3& translate) {_minTranslate = translate;}
|
||||
void loadMaxTranslate(const Vec3& translate) {_maxTranslate = translate;}
|
||||
void loadCurrentTranslate(const Vec3& translate){_currentTranslate = translate;}
|
||||
void loadIncrementTranslate(const Vec3& translate) {_incrementTranslate = translate;}
|
||||
void updateCurrentHPR(const Vec3& hpr);
|
||||
|
||||
void setCurrentTranslate(const Vec3& translate);
|
||||
void setMinTranslate(const Vec3& translate) {_minTranslate = translate;}
|
||||
void setMaxTranslate(const Vec3& translate) {_maxTranslate = translate;}
|
||||
void setCurrentTranslate(const Vec3& translate){_currentTranslate = translate;}
|
||||
void setIncrementTranslate(const Vec3& translate) {_incrementTranslate = translate;}
|
||||
|
||||
void loadMinScale(const Vec3& scale) {_minScale = scale;}
|
||||
void loadMaxScale(const Vec3& scale) {_maxScale = scale;}
|
||||
void loadCurrentScale(const Vec3& scale) {_currentScale = scale;}
|
||||
void loadIncrementScale(const Vec3& scale) {_incrementScale = scale;}
|
||||
void updateCurrentTranslate(const Vec3& translate);
|
||||
|
||||
void setCurrentScale(const Vec3& scale);
|
||||
void setMinScale(const Vec3& scale) {_minScale = scale;}
|
||||
void setMaxScale(const Vec3& scale) {_maxScale = scale;}
|
||||
void setCurrentScale(const Vec3& scale) {_currentScale = scale;}
|
||||
void setIncrementScale(const Vec3& scale) {_incrementScale = scale;}
|
||||
|
||||
void updateCurrentScale(const Vec3& scale);
|
||||
|
||||
void setPutMatrix(const Matrix& put) {_Put = put;}
|
||||
void setInversePutMatrix(const Matrix& inversePut) {_inversePut = inversePut;}
|
||||
@ -78,10 +80,12 @@ class SG_EXPORT DOFTransform : public Transform
|
||||
inline void setAnimationOn(bool do_animate) {_animationOn = do_animate;}
|
||||
inline const bool animationOn() const {return _animationOn;}
|
||||
|
||||
// inline const bool increasing() const {return _increasing;}
|
||||
|
||||
void animate();
|
||||
|
||||
virtual const bool computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor* nv) const;
|
||||
|
||||
virtual const bool computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor* nv) const;
|
||||
|
||||
protected:
|
||||
virtual ~DOFTransform() {}
|
||||
|
||||
|
@ -2,120 +2,96 @@
|
||||
|
||||
using namespace osg;
|
||||
|
||||
struct DOFCullCallback : public Transform::ComputeTransformCallback
|
||||
{
|
||||
/**/
|
||||
virtual const bool computeLocalToWorldMatrix(Matrix& matrix, const Transform* trans, NodeVisitor* nv) const
|
||||
{
|
||||
const DOFTransform* dof = dynamic_cast<const DOFTransform*>(trans);
|
||||
if(dof)
|
||||
{
|
||||
//here we are:
|
||||
//put the PUT matrix first:
|
||||
Matrix l2w(dof->getPutMatrix());
|
||||
|
||||
//now the current matrix:
|
||||
Matrix current;
|
||||
current.makeTranslate(dof->getCurrentTranslate());
|
||||
|
||||
//now create the local rotation:
|
||||
current.preMult(Matrix::rotate(dof->getCurrentHPR()[1], 1.0, 0.0, 0.0));//pitch
|
||||
current.preMult(Matrix::rotate(dof->getCurrentHPR()[2], 0.0, 1.0, 0.0));//roll
|
||||
current.preMult(Matrix::rotate(dof->getCurrentHPR()[0], 0.0, 0.0, 1.0));//heading
|
||||
|
||||
//and scale:
|
||||
current.preMult(Matrix::scale(dof->getCurrentScale()));
|
||||
|
||||
l2w.postMult(current);
|
||||
|
||||
//and impose inverse put:
|
||||
l2w.postMult(dof->getInversePutMatrix());
|
||||
|
||||
//finally:
|
||||
matrix.preMult(l2w);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**/
|
||||
virtual const bool computeWorldToLocalMatrix(Matrix& matrix, const Transform* trans, NodeVisitor* nv) const
|
||||
{
|
||||
const DOFTransform* dof = dynamic_cast<const DOFTransform*>(trans);
|
||||
if(dof)
|
||||
{
|
||||
//here we are:
|
||||
//put the PUT matrix first:
|
||||
Matrix w2l(dof->getInversePutMatrix());
|
||||
|
||||
//now the current matrix:
|
||||
Matrix current;
|
||||
current.makeTranslate(-dof->getCurrentTranslate());
|
||||
|
||||
//now create the local rotation:
|
||||
|
||||
|
||||
current.postMult(Matrix::rotate(-dof->getCurrentHPR()[0], 0.0, 0.0, 1.0));//heading
|
||||
current.postMult(Matrix::rotate(-dof->getCurrentHPR()[2], 0.0, 1.0, 0.0));//roll
|
||||
current.postMult(Matrix::rotate(-dof->getCurrentHPR()[1], 1.0, 0.0, 0.0));//pitch
|
||||
|
||||
//and scale:
|
||||
current.postMult(Matrix::scale(1./dof->getCurrentScale()[0], 1./dof->getCurrentScale()[1], 1./dof->getCurrentScale()[2]));
|
||||
|
||||
w2l.postMult(current);
|
||||
|
||||
//and impose inverse put:
|
||||
w2l.postMult(dof->getPutMatrix());
|
||||
|
||||
//finally:
|
||||
matrix.postMult(w2l);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class DOFAnimationAppCallback : public osg::NodeCallback
|
||||
{
|
||||
/** Callback method call by the NodeVisitor when visiting a node.*/
|
||||
virtual void operator()(Node* node, NodeVisitor* nv)
|
||||
{
|
||||
if (nv && nv->getVisitorType()==NodeVisitor::APP_VISITOR)
|
||||
{
|
||||
|
||||
//this is aspp visitor, see if we have DOFTransform:
|
||||
DOFTransform* dof = dynamic_cast<DOFTransform*>(node);
|
||||
if(dof)
|
||||
{
|
||||
//see if it is ina animation mode:
|
||||
dof->animate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// note, callback is repsonsible for scenegraph traversal so
|
||||
// should always include call the traverse(node,nv) to ensure
|
||||
// that the rest of cullbacks and the scene graph are traversed.
|
||||
traverse(node,nv);
|
||||
}
|
||||
};
|
||||
|
||||
DOFTransform::DOFTransform():
|
||||
_limitationFlags(0),
|
||||
_animationOn(true),
|
||||
_increasingFlags(0xffff)
|
||||
{
|
||||
//default zero-ed Vec3-s are fine for all
|
||||
//default idenetiy inverse matrix is fine:
|
||||
|
||||
_computeTransformCallback = new DOFCullCallback;
|
||||
|
||||
DOFAnimationAppCallback* dof_animation = new DOFAnimationAppCallback;
|
||||
|
||||
setAppCallback(dof_animation);
|
||||
setNumChildrenRequiringAppTraversal(1);
|
||||
}
|
||||
|
||||
void DOFTransform::setCurrentHPR(const Vec3& hpr)
|
||||
void DOFTransform::traverse(NodeVisitor& nv)
|
||||
{
|
||||
if (nv.getVisitorType()==NodeVisitor::APP_VISITOR)
|
||||
{
|
||||
animate();
|
||||
}
|
||||
Transform::traverse(nv);
|
||||
}
|
||||
|
||||
const bool DOFTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const
|
||||
{
|
||||
//put the PUT matrix first:
|
||||
Matrix l2w(getPutMatrix());
|
||||
|
||||
//now the current matrix:
|
||||
Matrix current;
|
||||
current.makeTranslate(getCurrentTranslate());
|
||||
|
||||
//now create the local rotation:
|
||||
current.preMult(Matrix::rotate(getCurrentHPR()[1], 1.0, 0.0, 0.0));//pitch
|
||||
current.preMult(Matrix::rotate(getCurrentHPR()[2], 0.0, 1.0, 0.0));//roll
|
||||
current.preMult(Matrix::rotate(getCurrentHPR()[0], 0.0, 0.0, 1.0));//heading
|
||||
|
||||
//and scale:
|
||||
current.preMult(Matrix::scale(getCurrentScale()));
|
||||
|
||||
l2w.postMult(current);
|
||||
|
||||
//and impose inverse put:
|
||||
l2w.postMult(getInversePutMatrix());
|
||||
|
||||
// finally.
|
||||
if (_referenceFrame==RELATIVE_TO_PARENTS)
|
||||
{
|
||||
matrix.preMult(l2w);
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix = l2w;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const bool DOFTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const
|
||||
{
|
||||
//put the PUT matrix first:
|
||||
Matrix w2l(getInversePutMatrix());
|
||||
|
||||
//now the current matrix:
|
||||
Matrix current;
|
||||
current.makeTranslate(-getCurrentTranslate());
|
||||
|
||||
//now create the local rotation:
|
||||
|
||||
|
||||
current.postMult(Matrix::rotate(-getCurrentHPR()[0], 0.0, 0.0, 1.0));//heading
|
||||
current.postMult(Matrix::rotate(-getCurrentHPR()[2], 0.0, 1.0, 0.0));//roll
|
||||
current.postMult(Matrix::rotate(-getCurrentHPR()[1], 1.0, 0.0, 0.0));//pitch
|
||||
|
||||
//and scale:
|
||||
current.postMult(Matrix::scale(1./getCurrentScale()[0], 1./getCurrentScale()[1], 1./getCurrentScale()[2]));
|
||||
|
||||
w2l.postMult(current);
|
||||
|
||||
//and impose inverse put:
|
||||
w2l.postMult(getPutMatrix());
|
||||
|
||||
if (_referenceFrame==RELATIVE_TO_PARENTS)
|
||||
{
|
||||
//finally:
|
||||
matrix.postMult(w2l);
|
||||
}
|
||||
else // absolute
|
||||
{
|
||||
matrix = w2l;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DOFTransform::updateCurrentHPR(const Vec3& hpr)
|
||||
{
|
||||
//if there is no constrain on animation
|
||||
if(!(_limitationFlags & ((unsigned long)1<<26)))
|
||||
@ -183,9 +159,10 @@ void DOFTransform::setCurrentHPR(const Vec3& hpr)
|
||||
}
|
||||
}
|
||||
}
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
void DOFTransform::setCurrentTranslate(const Vec3& translate)
|
||||
void DOFTransform::updateCurrentTranslate(const Vec3& translate)
|
||||
{
|
||||
if(!(_limitationFlags & (unsigned long)1<<29))
|
||||
{
|
||||
@ -246,9 +223,10 @@ void DOFTransform::setCurrentTranslate(const Vec3& translate)
|
||||
}
|
||||
}
|
||||
}
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
void DOFTransform::setCurrentScale(const Vec3& scale)
|
||||
void DOFTransform::updateCurrentScale(const Vec3& scale)
|
||||
{
|
||||
|
||||
if(!(_limitationFlags & ((unsigned long)1<<23)))
|
||||
@ -310,6 +288,7 @@ void DOFTransform::setCurrentScale(const Vec3& scale)
|
||||
}
|
||||
}
|
||||
}
|
||||
dirtyBound();
|
||||
}
|
||||
|
||||
void DOFTransform::animate()
|
||||
@ -334,7 +313,7 @@ void DOFTransform::animate()
|
||||
else
|
||||
new_value[2] -= _incrementTranslate[2];
|
||||
|
||||
setCurrentTranslate(new_value);
|
||||
updateCurrentTranslate(new_value);
|
||||
|
||||
new_value = _currentHPR;
|
||||
|
||||
@ -353,7 +332,7 @@ void DOFTransform::animate()
|
||||
else
|
||||
new_value[0] -= _incrementHPR[0];
|
||||
|
||||
setCurrentHPR(new_value);
|
||||
updateCurrentHPR(new_value);
|
||||
|
||||
new_value = _currentScale;
|
||||
|
||||
@ -372,7 +351,6 @@ void DOFTransform::animate()
|
||||
else
|
||||
new_value[2] -= _incrementScale[2];
|
||||
|
||||
setCurrentScale(new_value);
|
||||
updateCurrentScale(new_value);
|
||||
|
||||
dirtyBound();
|
||||
}
|
||||
|
@ -36,6 +36,15 @@ struct SGroup
|
||||
class GroupRecord : public PrimNodeRecord
|
||||
{
|
||||
public:
|
||||
|
||||
enum FlagBit {
|
||||
FORWARD_ANIM = 0x40000000,
|
||||
SWING_ANIM = 0x20000000,
|
||||
BOUND_BOX_FOLLOW = 0x10000000,
|
||||
FREEZE_BOUND_BOX = 0x08000000,
|
||||
DEFAULT_PARENT = 0x04000000
|
||||
};
|
||||
|
||||
GroupRecord();
|
||||
|
||||
virtual Record* clone() const { return new GroupRecord(); }
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osg/DOFTransform>
|
||||
#include <osg/Sequence>
|
||||
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileNameUtils>
|
||||
@ -557,12 +558,38 @@ void ConvertFromFLT::visitNormalTextureVertex(osg::Group& , NormalTextureVertexR
|
||||
|
||||
osg::Group* ConvertFromFLT::visitGroup(osg::Group& osgParent, GroupRecord* rec)
|
||||
{
|
||||
osg::Group* group = new osg::Group;
|
||||
|
||||
group->setName(rec->getData()->szIdent);
|
||||
visitAncillary(osgParent, *group, rec)->addChild( group );
|
||||
visitPrimaryNode(*group, rec);
|
||||
return group;
|
||||
SGroup* currentGroup = (SGroup*) rec->getData();
|
||||
bool forwardAnim , swingAnim;
|
||||
|
||||
// OpenFlight 15.7 has two animation flags, forward and swing
|
||||
if ( (currentGroup->dwFlags & GroupRecord::FORWARD_ANIM)== GroupRecord::FORWARD_ANIM) forwardAnim = true; else forwardAnim = false;
|
||||
if ( (currentGroup->dwFlags & GroupRecord::SWING_ANIM) == GroupRecord::SWING_ANIM) swingAnim = true; else swingAnim = false;
|
||||
|
||||
if( forwardAnim || swingAnim )
|
||||
{
|
||||
osg::Sequence* animSeq = new osg::Sequence;
|
||||
|
||||
if ( forwardAnim )
|
||||
animSeq->setInterval(osg::Sequence::LOOP, 0, -1);
|
||||
else
|
||||
animSeq->setInterval(osg::Sequence::SWING, 0, -1);
|
||||
|
||||
animSeq->setName(rec->getData()->szIdent);
|
||||
|
||||
visitAncillary(osgParent, *animSeq, rec)->addChild( animSeq );
|
||||
visitPrimaryNode(*animSeq, rec);
|
||||
return animSeq;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
osg::Group* group = new osg::Group;
|
||||
group->setName(rec->getData()->szIdent);
|
||||
visitAncillary(osgParent, *group, rec)->addChild( group );
|
||||
visitPrimaryNode(*group, rec);
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Group* ConvertFromFLT::visitRoadConstruction(osg::Group& osgParent, GroupRecord* rec)
|
||||
@ -622,7 +649,9 @@ osg::Group* ConvertFromFLT::visitOldLOD(osg::Group& osgParent, OldLodRecord* rec
|
||||
// Converted DOF to use transform - jtracy@ist.ucf.edu
|
||||
osg::Group* ConvertFromFLT::visitDOF(osg::Group& osgParent, DofRecord* rec)
|
||||
{
|
||||
#if 1
|
||||
#define USE_DOFTransform
|
||||
|
||||
#if defined(USE_DOFTransform)
|
||||
|
||||
osg::DOFTransform* transform = new osg::DOFTransform;
|
||||
transform->setName(rec->getData()->szIdent);
|
||||
@ -635,119 +664,96 @@ osg::Group* ConvertFromFLT::visitDOF(osg::Group& osgParent, DofRecord* rec)
|
||||
//now fill up members:
|
||||
|
||||
//tranlsations:
|
||||
transform->loadMinTranslate(osg::Vec3(_unitScale*p_data->dfX._dfMin,
|
||||
transform->setMinTranslate(osg::Vec3(_unitScale*p_data->dfX._dfMin,
|
||||
_unitScale*p_data->dfY._dfMin,
|
||||
_unitScale*p_data->dfZ._dfMin));
|
||||
|
||||
transform->loadMaxTranslate(osg::Vec3(_unitScale*p_data->dfX._dfMax,
|
||||
transform->setMaxTranslate(osg::Vec3(_unitScale*p_data->dfX._dfMax,
|
||||
_unitScale*p_data->dfY._dfMax,
|
||||
_unitScale*p_data->dfZ._dfMax));
|
||||
|
||||
transform->loadCurrentTranslate(osg::Vec3(_unitScale*p_data->dfX._dfCurrent,
|
||||
transform->setCurrentTranslate(osg::Vec3(_unitScale*p_data->dfX._dfCurrent,
|
||||
_unitScale*p_data->dfY._dfCurrent,
|
||||
_unitScale*p_data->dfZ._dfCurrent));
|
||||
|
||||
transform->loadIncrementTranslate(osg::Vec3(_unitScale*p_data->dfX._dfIncrement,
|
||||
transform->setIncrementTranslate(osg::Vec3(_unitScale*p_data->dfX._dfIncrement,
|
||||
_unitScale*p_data->dfY._dfIncrement,
|
||||
_unitScale*p_data->dfZ._dfIncrement));
|
||||
|
||||
//rotations:
|
||||
transform->loadMinHPR(osg::Vec3(osg::inDegrees(p_data->dfYaw._dfMin),
|
||||
transform->setMinHPR(osg::Vec3(osg::inDegrees(p_data->dfYaw._dfMin),
|
||||
osg::inDegrees(p_data->dfPitch._dfMin),
|
||||
osg::inDegrees(p_data->dfRoll._dfMin)));
|
||||
|
||||
transform->loadMaxHPR(osg::Vec3(osg::inDegrees(p_data->dfYaw._dfMax),
|
||||
transform->setMaxHPR(osg::Vec3(osg::inDegrees(p_data->dfYaw._dfMax),
|
||||
osg::inDegrees(p_data->dfPitch._dfMax),
|
||||
osg::inDegrees(p_data->dfRoll._dfMax)));
|
||||
|
||||
transform->loadCurrentHPR(osg::Vec3(osg::inDegrees(p_data->dfYaw._dfCurrent),
|
||||
transform->setCurrentHPR(osg::Vec3(osg::inDegrees(p_data->dfYaw._dfCurrent),
|
||||
osg::inDegrees(p_data->dfPitch._dfCurrent),
|
||||
osg::inDegrees(p_data->dfRoll._dfCurrent)));
|
||||
|
||||
transform->loadIncrementHPR(osg::Vec3(osg::inDegrees(p_data->dfYaw._dfIncrement),
|
||||
transform->setIncrementHPR(osg::Vec3(osg::inDegrees(p_data->dfYaw._dfIncrement),
|
||||
osg::inDegrees(p_data->dfPitch._dfIncrement),
|
||||
osg::inDegrees(p_data->dfRoll._dfIncrement)));
|
||||
|
||||
//scales:
|
||||
transform->loadMinScale(osg::Vec3(p_data->dfXscale._dfMin,
|
||||
transform->setMinScale(osg::Vec3(p_data->dfXscale._dfMin,
|
||||
p_data->dfYscale._dfMin,
|
||||
p_data->dfZscale._dfMin));
|
||||
|
||||
transform->loadMaxScale(osg::Vec3(p_data->dfXscale._dfMax,
|
||||
transform->setMaxScale(osg::Vec3(p_data->dfXscale._dfMax,
|
||||
p_data->dfYscale._dfMax,
|
||||
p_data->dfZscale._dfMax));
|
||||
|
||||
transform->loadCurrentScale(osg::Vec3(p_data->dfXscale._dfCurrent,
|
||||
transform->setCurrentScale(osg::Vec3(p_data->dfXscale._dfCurrent,
|
||||
p_data->dfYscale._dfCurrent,
|
||||
p_data->dfZscale._dfCurrent));
|
||||
|
||||
transform->loadIncrementScale(osg::Vec3(p_data->dfXscale._dfIncrement,
|
||||
transform->setIncrementScale(osg::Vec3(p_data->dfXscale._dfIncrement,
|
||||
p_data->dfYscale._dfIncrement,
|
||||
p_data->dfZscale._dfIncrement));
|
||||
|
||||
//now calculate put and inverse put matrix:
|
||||
//the translation matrix:
|
||||
osg::Matrix l2g_translation;
|
||||
// compute the put matrix.
|
||||
osg::Vec3 O ( p_data->OriginLocalDOF.x(),
|
||||
p_data->OriginLocalDOF.y(),
|
||||
p_data->OriginLocalDOF.z());
|
||||
|
||||
//translation vector
|
||||
osg::Vec3 origin_translation(p_data->OriginLocalDOF.x(), p_data->OriginLocalDOF.y(), p_data->OriginLocalDOF.z());
|
||||
origin_translation *= _unitScale;//of course, has to be scaled to units used
|
||||
|
||||
//so we make translation matrix
|
||||
l2g_translation.makeTranslate(origin_translation);
|
||||
|
||||
//now we need to construct rotation matrix that describes how is local coordinate system
|
||||
//rotatoed in global:
|
||||
osg::Matrix l2g_rotation;
|
||||
|
||||
//we make two normalized osg::Vec3s so we can cross-multiply them ....
|
||||
|
||||
//first we have "point on x axis", i.e. what the DOF local looks like in global
|
||||
osg::Vec3 point_on_x_axis(p_data->PointOnXaxis.x(), p_data->PointOnXaxis.y(), p_data->PointOnXaxis.z());
|
||||
point_on_x_axis *= _unitScale;
|
||||
point_on_x_axis -= origin_translation;//we need to offset it for the origin
|
||||
|
||||
//second, we have "point in xy plane", so x ^ y gives us local z vector
|
||||
osg::Vec3 point_in_xy_plane(p_data->PointInXYplane.x(), p_data->PointInXYplane.y(), p_data->PointInXYplane.z());
|
||||
point_in_xy_plane *= _unitScale;
|
||||
point_in_xy_plane -= origin_translation;//also offset it
|
||||
|
||||
//just in case, normalize them:
|
||||
point_on_x_axis.normalize();
|
||||
|
||||
//now, local x in global is [1 0 0 1] * rotation_matrix, so we can directly write down first row
|
||||
l2g_rotation.ptr()[0] = point_on_x_axis.x(); //that is mat[0][0]
|
||||
l2g_rotation.ptr()[1] = point_on_x_axis.y(); //that is mat[0][1]
|
||||
l2g_rotation.ptr()[2] = point_on_x_axis.z(); //that is mat[0][2]
|
||||
osg::Vec3 xAxis ( p_data->PointOnXaxis.x(),
|
||||
p_data->PointOnXaxis.y(),
|
||||
p_data->PointOnXaxis.z());
|
||||
xAxis = xAxis - O;
|
||||
xAxis.normalize();
|
||||
|
||||
osg::Vec3 xyPlane ( p_data->PointInXYplane.x(),
|
||||
p_data->PointInXYplane.y(),
|
||||
p_data->PointInXYplane.z());
|
||||
xyPlane = xyPlane - O;
|
||||
xyPlane.normalize();
|
||||
|
||||
//the cross product of x ^point_in_local_xy_plane gives local z
|
||||
osg::Vec3 z_transformed = point_on_x_axis ^ point_in_xy_plane;
|
||||
z_transformed.normalize();//we have to normalize it, and than we can directly writ it down to rotation matrix
|
||||
//we can write it down to matrix directly:
|
||||
l2g_rotation.ptr()[8] = z_transformed.x(); //that is mat[2][0]
|
||||
l2g_rotation.ptr()[9] = z_transformed.y(); //that is mat[2][1]
|
||||
l2g_rotation.ptr()[10] = z_transformed.z(); //that is mat[2][2]
|
||||
osg::Vec3 normalz = xAxis ^ xyPlane;
|
||||
normalz.normalize();
|
||||
|
||||
//now that we have x and z, we can get y = z ^ x
|
||||
osg::Vec3 y_transformed = z_transformed ^ point_on_x_axis;
|
||||
//and just in case, we can normalize it:
|
||||
// y_transformed.normalize();
|
||||
|
||||
//this goes to rotation matrix:
|
||||
l2g_rotation.ptr()[4] = y_transformed.x(); //that is mat[1][0]
|
||||
l2g_rotation.ptr()[5] = y_transformed.y(); //that is mat[1][0]
|
||||
l2g_rotation.ptr()[6] = y_transformed.z(); //that is mat[1][0]
|
||||
// get X, Y, Z axis of the DOF in terms of global coordinates
|
||||
osg::Vec3 Rz = normalz;
|
||||
if (Rz == osg::Vec3(0,0,0)) Rz[2] = 1;
|
||||
osg::Vec3 Rx = xAxis;
|
||||
if (Rx == osg::Vec3(0,0,0)) Rx[0] = 1;
|
||||
osg::Vec3 Ry = Rz ^ Rx;
|
||||
|
||||
|
||||
//now we have actually the second "PUT" transformation, and the first is inverse
|
||||
osg::Matrix second_put = l2g_rotation * l2g_translation;
|
||||
O *= _unitScale;
|
||||
|
||||
// create the putmatrix
|
||||
osg::Matrix inv_putmat( Rx.x(), Rx.y(), Rx.z(), 0,
|
||||
Ry.x(), Ry.y(), Ry.z(), 0,
|
||||
Rz.x(), Rz.y(), Rz.z(), 0,
|
||||
O.x(), O.y(), O.z(), 1);
|
||||
|
||||
transform->setInversePutMatrix(inv_putmat);
|
||||
transform->setPutMatrix(osg::Matrix::inverse(inv_putmat));
|
||||
|
||||
//and we take invers of it since it has to be done at the end, see FLT spec
|
||||
osg::Matrix the_first = osg::Matrix::inverse(second_put);
|
||||
|
||||
transform->setPutMatrix(the_first);
|
||||
transform->setInversePutMatrix(second_put);
|
||||
/*
|
||||
//and now do a little ENDIAN to put flags in ordewr as described in OpenFlight spec
|
||||
unsigned long flags = p_data->dwFlags;
|
||||
@ -780,16 +786,16 @@ osg::Group* ConvertFromFLT::visitDOF(osg::Group& osgParent, DofRecord* rec)
|
||||
p_data->PointOnXaxis.y(),
|
||||
p_data->PointOnXaxis.z());
|
||||
xAxis = xAxis - O;
|
||||
xAxis.normalize();
|
||||
xAxis.normalize();
|
||||
|
||||
osg::Vec3 xyPlane ( p_data->PointInXYplane.x(),
|
||||
p_data->PointInXYplane.y(),
|
||||
p_data->PointInXYplane.z());
|
||||
xyPlane = xyPlane - O;
|
||||
xyPlane.normalize();
|
||||
xyPlane.normalize();
|
||||
|
||||
osg::Vec3 normalz = xAxis ^ xyPlane;
|
||||
normalz.normalize();
|
||||
normalz.normalize();
|
||||
|
||||
// get X, Y, Z axis of the DOF in terms of global coordinates
|
||||
osg::Vec3 Rz = normalz;
|
||||
@ -817,20 +823,22 @@ osg::Group* ConvertFromFLT::visitDOF(osg::Group& osgParent, DofRecord* rec)
|
||||
float sy = rec->getData()->dfYscale.current();
|
||||
float sz = rec->getData()->dfZscale.current();
|
||||
|
||||
// this is the local DOF transformation
|
||||
osg::Matrix dof_matrix = osg::Matrix::scale(sx, sy, sz)*
|
||||
// this is the local DOF transformation
|
||||
osg::Matrix dof_matrix = osg::Matrix::scale(sx, sy, sz)*
|
||||
osg::Matrix::rotate(yaw_rad, 0.0f,0.0f,1.0f)*
|
||||
osg::Matrix::rotate(roll_rad, 0.0f,1.0f,0.0f)*
|
||||
osg::Matrix::rotate(pitch_rad, 1.0f,0.0f,0.0f)*
|
||||
osg::Matrix::translate(trans);
|
||||
|
||||
// transforming local into global
|
||||
dof_matrix.preMult(osg::Matrix::inverse(putmat));
|
||||
// transforming local into global
|
||||
dof_matrix.preMult(osg::Matrix::inverse(putmat));
|
||||
|
||||
// transforming global into local
|
||||
dof_matrix.postMult(putmat);
|
||||
cout << "putmat "<< putmat<<endl;
|
||||
|
||||
transform->setMatrix(dof_matrix);
|
||||
// transforming global into local
|
||||
dof_matrix.postMult(putmat);
|
||||
|
||||
transform->setMatrix(dof_matrix);
|
||||
return transform;
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user