Game Development Community

Node Transform

by Howard Dortch · in Torque 3D Professional · 04/28/2011 (1:41 pm) · 6 replies

I have an object with some mountpoints. I would like to get the transform of one of the nodes in the object but the dump() doesn't show a getNodeTransform() any help?

#1
04/28/2011 (3:10 pm)
From the chaps at MaxGaming ...
//change static shape to anything else eg player
void StaticShape::getNodeTransform(const char* nodeName, MatrixF* mat)
{

   S32 node = getShape()->findNode(nodeName);

   MatrixF pmat;
   pmat.identity();
   
   F32 *dp = pmat;
   
   if (node != -1)
   {
	   F32* sp;
       sp = mShapeInstance->mNodeTransforms[node];
	   const Point3F& scale = getScale();
	   dp[3] = sp[3] * scale.x;
	   dp[7] = sp[7] * scale.y;
	   dp[11] = sp[11] * scale.z;
   }

   mat->mul(getTransform(), pmat);
   
}

ConsoleMethod( StaticShape, getNodePosition, const char*, 3, 3, "(slotname) returns the nodes position")
{
   MatrixF mat;
   object->getNodeTransform(argv[2], &mat);
   Point3F pos(0,0,0);
   mat.getColumn(3,&pos);
   char* buff = Con::getReturnBuffer(100);
   dSprintf(buff, 100,"%g %g %g",pos.x,pos.y,pos.z);
   return buff;
}

//in .h after a public:

void getNodeTransform(const char* nodeName, MatrixF* mat);
#2
04/29/2011 (12:07 am)
It's always baffled my that this isn't in stock code.
#3
04/29/2011 (5:01 am)
This code does not support animated transforms as well.
#4
04/29/2011 (7:07 am)
@Steve thanks mucho. I thought it was stock code as well just couldn't find it.
#5
04/29/2011 (11:12 am)
I use the following to get the node position for ShapeBase derived objects. It can be used for any node in the object, not just mount points.

Point3F ShapeBase::getNodePosition(const String &nodeName) const
{
   S32 nodeIdx = mShapeInstance->getShape()->findNode(nodeName);

   return getNodePosition(nodeIdx);
}

Point3F ShapeBase::getNodePosition(const S32 nodeIdx) const
{
   Point3F nodeObjPos, nodeWorldPos;

   if(nodeIdx == -1)
      nodeObjPos.set(0.0f, 0.0f, 0.0f);
   else
   {
      if (isServerObject() && mShapeInstance)
         mShapeInstance->animateNodeSubtrees(true);
   
      mShapeInstance->mNodeTransforms[nodeIdx].getColumn(3, &nodeObjPos);
   }

   const Point3F& scale = getScale();
   nodeObjPos.convolve( scale );
   getTransform().mulP(nodeObjPos, &nodeWorldPos);

   return nodeWorldPos;
}


ConsoleMethod( ShapeBase, getNodePosition, const char*, 3, 3, "(string nodeName)"
              "returns the world space position of the named node")
{
   char *returnBuffer = Con::getReturnBuffer(256);
   Point3F nodePos = object->getNodePosition(argv[2]);
   dSprintf(returnBuffer, 256, "%g %g %g", nodePos.x, nodePos.y, nodePos.z);
   return returnBuffer;
}

It could be expanded pretty easily to return the full transform.
#6
04/29/2011 (12:48 pm)
@Guy

The correct way is to animate only when an animation exists.
if(isServerObject()
  if(bool(mShapeInstance->getNodeAnimationState(nodeIdx))) 
	mShapeInstance->animate();