Game Development Community

Get node transform

by Clint S. Brewer · in Torque Game Engine · 12/22/2004 (12:00 am) · 44 replies

Anyone know how to get the position of a specific node from script?

I want to access a named node in my model and create an explosion at that position.

lets just say mount0 for now, but eventually any named node.

thanks
Page «Previous 1 2 3 Last »
#1
12/22/2004 (12:45 am)
Ok, found this post that helped:
http://www.garagegames.com/mg/forums/result.thread.php?qt=23321


I basically did the same thing, but in shapebase, so I can access it from Player as well.

I'm not positive it's animating exactly correct, but it looks ok for what I'm doing right now.

in shapebase.cc after the getSlotTransform ConsoleMethod

ConsoleMethod(ShapeBase, getNodePosition, const char*, 3, 3, 
			  "point getNodePosition(string nodeName)")
{
   Point3F nodePoint;
   MatrixF shapeTransform;
   nodePoint = object->getNodePoint(argv[2]);
   shapeTransform = object->getTransform();
   shapeTransform.mulP(nodePoint);
   char* buff = Con::getReturnBuffer(100);
   dSprintf(buff, 100, "%g %g %g", nodePoint.x, nodePoint.y, nodePoint.z);
   return buff;
}

Point3F ShapeBase::getNodePoint(const char* nodeName) {
   Point3F nodePoint;
   MatrixF nodeMat;
   S32 ni = mDataBlock->shape->findNode(nodeName);
   if(ni)
   {
	nodeMat = mShapeInstance->mNodeTransforms[ni];
	nodeMat.getColumn(3, &nodePoint);
   }
   else
   {
	  Con::errorf("Error: searching for unknown node %s",  nodeName);

   }
   return nodePoint;
}

in ShapeBase.h also after getSlotTransform

add
/// Get the transform of a named node
   /// @param nodeName the name of the node such as "mount0"
   virtual Point3F getNodePoint(const char* nodeName);


I don't see exactly how this will get the proper transform within a given playing animation, but I haven't really looked into all that code yet.
#2
12/23/2004 (7:24 pm)
MShapeInstance->mNodeTransforms stores the latest node transforms, so as long as you're calling animate() on a regular basis you'll get good data in there. (For very fine situations you might have to pay close attention to the order of calls, most of the time not a big deal.)
#3
12/23/2004 (11:26 pm)
Ah great, thanks for the reply Ben, arent' you supposed to be on break :)

-c
#4
10/16/2005 (4:24 pm)
Well that's all fine and dandy... but the title of the thread is getting node transform. I want that. This does just position... Anyone know how to use this to return the transform of the node and not just the Position?

Seems like the GetnodePoint function returns a transform..... but my weak C++ skills can't decipher it. Anyone wanna lend a hand?
#5
10/16/2005 (5:44 pm)
Ok, i got a working solution if anyone else is interested in the code. I'll post it here later.
#6
11/24/2005 (8:04 pm)
Finally got around to posting this code for those interested.


add this in at the bottom of shapebase.cc

//Ramen Added//
void ShapeBase::getNodeTransform(const char* nodeName,MatrixF* mat)
{
   // Returns mount point to world space transform
   S32 ni = mDataBlock->shape->findNode(nodeName);
      if (ni != -1) {
         MatrixF nodeTransform = mShapeInstance->mNodeTransforms[ni];
         const Point3F& scale = getScale();

         // The position of the mount point needs to be scaled.
         Point3F position = nodeTransform.getPosition();
         position.convolve( scale );
         nodeTransform.setPosition( position );

         // Also we would like the object to be scaled to the model.
         mat->mul(mObjToWorld, nodeTransform);
         return;
   }
   *mat = mObjToWorld;
}


ConsoleMethod( ShapeBase, getNodeTransform, const char*, 3, 3, "NodeName")
{
   MatrixF xf(true);

//Check to see if this object is a server objec
	if (object->isServerObject()){
		
		//Obtain a local connection, i have no idea if this will work in a network play
		GameConnection * LocalCon = GameConnection::getLocalClientConnection();
		
		//Should be an index of the object
		S32 gIndex = LocalCon->getGhostIndex(object);
		
		//Obtain connection to server
		GameConnection* con = GameConnection::getConnectionToServer();

		
		//Make a null netobject, point it to the object in the ghost index
		NetObject* nObject = NULL;
		nObject = con->resolveGhost( gIndex );
		
		ShapeBase* shape = dynamic_cast<ShapeBase*>(nObject); 

	   // ok, we are left with local object, so we should be able to get all the transforms properly
		shape->getNodeTransform(argv[2],&xf);
        
   }
   else
	   object->getNodeTransform(argv[2],&xf);  // Used if object is local object to begin with

   Point3F pos;
   xf.getColumn(3,&pos);
   AngAxisF aa(xf);
   char* buff = Con::getReturnBuffer(200);
   dSprintf(buff,200,"%g %g %g %g %g %g %g",
            pos.x,pos.y,pos.z,aa.axis.x,aa.axis.y,aa.axis.z,aa.angle);
   return buff;
}

//Ramen Added//


and in shapebase.h

add this in under:

/// Gets the transform of a mounted image in world space
/// @param imageSlot Image slot
/// @param mat Transform (out)
virtual void getImageTransform(U32 imageSlot,MatrixF* mat);


virtual void getNodeTransform(const char* nodeName,MatrixF* mat);
#7
11/24/2005 (8:47 pm)
Slick, thanks Ramen.
#8
01/19/2006 (12:02 am)
Hi,

I have a DTS model (just a simple cube) with an animation sequence that moves it across the terrain.
I added the getNodeTransform functions to obtain the node point/transform of the model during the animation sequence.

Problem is while I can see my cube moving around the terrain, the values returned from getNodeTransform doesn't change; the values are the same as initially loaded ( like in the mission file).

I started to think if "ground transforms" maybe the problem, but it doesn't seem appear so as
- "ground transform" was enabled in the DTS exporter.
- I can see the node values changing in ShowTool.

Anyone? Thanks.
#9
01/19/2006 (4:40 pm)
Hmm well in my experience, i noticed that node positions may not change when animated. I had similar issues when animating Objects. I had to insert a animate() command at the top of updatethread in shapebase.cc to get it to update.
#10
06/16/2006 (6:30 pm)
Hi ramen & all,

i inserted said animate() in the processTick and my nodetransforms are unchanged. i notice if i move my object in the world, i get an updated transform, but i do not get the transform of an obviously moving node while the object is not, yet animating in place.

any ideas? just where is this node data actually live and accessable?

thanks!
j
#11
06/16/2006 (7:19 pm)
Here's what i dont understand. well there are a lot of things, but this in particular

inside tsAnimate, animateNodes() i can plop this debugging code down at the bottom:

//KLIMA DEBUGGING
Point3F pos;   
mNodeTransforms[3].getColumn(3,&pos);   
AngAxisF aa(mNodeTransforms[3]);   
char* buff = Con::getReturnBuffer(200);   
dSprintf(buff,200,"%g %g %g %g %g %g %g",            
    pos.x,pos.y,pos.z,aa.axis.x,aa.axis.y,aa.axis.z,aa.angle);   

Con::printf("And here is node 3 transform %s /n", buff);

and watch my node transforms do their transforming thing. so there it is, mNodeTransforms, as far as i can tell the same mNodeTransforms as is accessible from your getNodeTransform above. but by the time i call getNodeTransform the values have been magically reset to what i guess are the initial node positions of an un-animated model.

so short of stuffing these values in a buffer for later access (ie chewing up more ram) how can i get at them WHILE they are being animated?

i may simply make the buffer and be done with it, but this cant be right, and i hate it when i do something i know is wrong ;)

thanks!
j
#12
06/16/2006 (7:23 pm)
Hmmm i just peeked at my code

void ShapeBase::updateThread(Thread& st)
{
   //ramen fix for nodes
	if (mShapeInstance)
         mShapeInstance->animate();
//ramen fix for nodes


here's where i have my animate(), it seems like my previous mention of processtick was not correct :)

Sorry bout the time wasted.
#13
06/16/2006 (7:27 pm)
img88.imageshack.us/img88/584/nodes9ls.jpgHeres a hard to see image.

if you notice on the tips of the icicles, there's a green apostrophe.

I placed them there to make sure it was animated my nodes right.

So i know they're animated properly.

I have no idea if this is some performance hit or anything though :)
#14
06/16/2006 (8:12 pm)
Heya, actually processTick works too - i could have sworn that node was called "leftWrist" - so thanks. but i still dont understand what is happening to those transforms. why are they reset? is this the best way you have found to deal with it?

yes i worry about the hit, i suppose it can't be great processing the animation threads twice. WHY MUST WE???

hehe okay thanks again

j
#15
06/16/2006 (8:14 pm)
I dunno. this is one of the bugs that no one seems to care about.
I haven't really looked into a better fix. i just know this works. :)
#16
03/11/2007 (9:59 am)
I've also run into this problem. Inside tsShapeInstance::render(...), I display the node positions based on their corresponding transformation information in mNodeTransforms. I then rotate the head of the character (by altering mHead.x, mHead.z) and the node positions are updated and displayed perfectly on screen (as you would expect).

But if I query the same node transforms at any time from elsewhere (e.g. my own function in player.cc), mNodeTransforms gives me back the original (reset) transforms of the nodes and not the actual current ones. It seems like mNodeTransforms is constantly in the 'reset' state, apart from at display time when the correct values are actually there (recalculated it seems). Very strange!

Anyway, for me, adding in the animate() function in the tsShapeInstance::processTick() did the job (as suggested above). I guess it's interesting to look at how the default code handles this issue: in Player::getEyeTransform, they only use the position from mNodeTransforms and they reconstruct the rotation from the mHead.x and mHead.z variables.
#17
05/10/2007 (7:54 am)
I just want to say thanks for the info on fixing the updates in the animations. That bug has been torturing me for many weeks. This has been a really helpful thread!
#18
05/10/2007 (2:39 pm)
I do wonder what negative effects it creates by calling animate, but yeah, it worked so i didn't really care to investigate further.
#19
02/14/2008 (11:14 am)
Sorry to bump this old topic, but I can't seem to get this working in 1.5.2

I can get the transform of any node in my dts model, but the number does not change during an animation.

I'm trying to emulate animation-based movement. So as the AiPlayer moves, I can get the transformation of the node and set the position of the entire model to that node upon animation completion.

thank you
#20
02/14/2008 (11:22 am)
Hi David, if you are doing this on the server, then by default the skeleton doesn't animate there. it only does the detailed animation on the client.

it should be pretty easy to find the spot where it does this and let it happen on the server too but will slow things down a bit.

thats all if my memory serves me right, been a while since I looked at this.
Page «Previous 1 2 3 Last »