Node Transforms are not updating when manually modifying node locations
by Jack Stone · in Torque 3D Professional · 10/14/2013 (11:01 am) · 10 replies
This is a difficult one to explain, but I am creating a turret class based on the existing T3D turret class. I have added the ability to manually rotate and elevate the turret from script, by using a "heading" and a "pitch" node. Rotating these causes the turret shape to rotate visibly in the world.
I now want to fire a projectile from the muzzle point of the turret, however, the transform of the muzzle point (or, seemingly, any other node) does not change when I rotate the node, even though the position does update visually. I have no idea why this is happening.
I am calling "setMaskBits(TurretUpdateMask);" as well as "mShapeInstance->animateNodeSubtrees(true);" and "mShapeInstance->animate();".
I have tried mounting an object to the muzzlepoint of the turret, and, bizarrely, this also update visually in the world, but returns the wrong transform as well!
I am setting the transforms using the "updatenode" function in the existing turret code, and I am getting the transforms like this:
Is this a client/server issue? Or is there some kind of updating or syncing function I need to call to force an update of the transforms?
I now want to fire a projectile from the muzzle point of the turret, however, the transform of the muzzle point (or, seemingly, any other node) does not change when I rotate the node, even though the position does update visually. I have no idea why this is happening.
I am calling "setMaskBits(TurretUpdateMask);" as well as "mShapeInstance->animateNodeSubtrees(true);" and "mShapeInstance->animate();".
I have tried mounting an object to the muzzlepoint of the turret, and, bizarrely, this also update visually in the world, but returns the wrong transform as well!
I am setting the transforms using the "updatenode" function in the existing turret code, and I am getting the transforms like this:
S32 node = mShapeInstance->getShape()->findNode("muzzlepoint");
MatrixF mat;
mShapeInstance->setNodeAnimationState(node, mShapeInstance->MaskNodeAll);
mShapeInstance->getShape()->getNodeWorldTransform(node,&mat);
pos = mat.getPosition();
Point3F rot = Point3F(0,0,0);
rot = mat.getForwardVector();
Con::printf("TEST: %f %f %f %f %f %f" , pos.x,pos.y,pos.z,rot.x,rot.y,rot.z);Is this a client/server issue? Or is there some kind of updating or syncing function I need to call to force an update of the transforms?
#2
10/14/2013 (6:18 pm)
Is it reporting local transform or world transform data? In order to use the muzzle point you might need to convert to world transform. I'm just guessing, but hey - I'm lucky that way....
#3
10/14/2013 (8:24 pm)
It seems to be reporting world transform data, it's just not updating? I am calling the "get world transform" function in Shapebase at least...
#4
if(isServerObject()
{
S32 nodeIdx = mShapeInstance->getShape()->findNode(nodeName);
if(bool(mShapeInstance->getNodeAnimationState(nodeIdx)))
mShapeInstance->animate();
}
If you are not using animation, just call setPosition() or setTransform() in processTick() for both client and server and this should work out of the box.
btw there are several resources with setNodePosition() and setNodeTransform()
10/15/2013 (12:42 am)
animate() is used to advance an animation if it exists:if(isServerObject()
{
S32 nodeIdx = mShapeInstance->getShape()->findNode(nodeName);
if(bool(mShapeInstance->getNodeAnimationState(nodeIdx)))
mShapeInstance->animate();
}
If you are not using animation, just call setPosition() or setTransform() in processTick() for both client and server and this should work out of the box.
btw there are several resources with setNodePosition() and setNodeTransform()
#5
10/15/2013 (6:39 am)
Huh. Sweet tip - thanks Ivan!
#6
I have tried quite a few resources for "setNodeTransform()" but I Can't seem to get the positions updated, only the visible mesh...
10/15/2013 (9:25 am)
Thanks for your response Ivan, I tried adding "setTransform()" in a few places, but it just made the object invisible?I have tried quite a few resources for "setNodeTransform()" but I Can't seem to get the positions updated, only the visible mesh...
#7
This solution now works on both client and server, however, I have another issue. The node rotations are only visible on the server, the object does not move on the client!
I have made sure that I am sending all of the relevant data in pack/unpack update, and, as I said, the transforms are changing on the client, but the nodes aren't moving.
Does anyone have any ideas on this?
10/16/2013 (5:42 pm)
Ok, I managed to get this working server side by just storing the transform and vector of the node in a variable, and accessing it. The getTransform() functions didn't work, but for some reason setting the variable from UpdateNodes() did.This solution now works on both client and server, however, I have another issue. The node rotations are only visible on the server, the object does not move on the client!
I have made sure that I am sending all of the relevant data in pack/unpack update, and, as I said, the transforms are changing on the client, but the nodes aren't moving.
Does anyone have any ideas on this?
#8
The client usually use interpolation (render transforms). Locate and debug functions as interpolateTick(), advanceTime(), ...
10/17/2013 (4:09 am)
There are 2 types of transforms in T3D - usual transforms (updated per tick) and render transforms (updated per frame using interpolation between ticks).The client usually use interpolation (render transforms). Locate and debug functions as interpolateTick(), advanceTime(), ...
#9
Thanks Ivan, I'm sure that the cause of the issue is somewhere in interpolateTick. I am doing something that might be slightly odd, I am allowing the player to set a rotation from script, and the inerpolateTick() function is then rotating the turret object to face that rotation.
However, I think that I have skipped a vital step somewhere, by tying my code into the interpolate tick function, which is stopping it from working over the network.
At the moment, I am getting around this issue by sending a commandtoclient to every connected client with the ID of the turret, and calling my rotate function on the clients that way. This does work, but obviously, it's a nasty hack!
10/17/2013 (7:59 pm)
Thanks Ivan, I'm sure that the cause of the issue is somewhere in interpolateTick. I am doing something that might be slightly odd, I am allowing the player to set a rotation from script, and the inerpolateTick() function is then rotating the turret object to face that rotation.
However, I think that I have skipped a vital step somewhere, by tying my code into the interpolate tick function, which is stopping it from working over the network.
At the moment, I am getting around this issue by sending a commandtoclient to every connected client with the ID of the turret, and calling my rotate function on the clients that way. This does work, but obviously, it's a nasty hack!
#10
10/19/2013 (2:22 pm)
Usually the way you send data to clients is using the un/packUpdate methods of an object. Did you add anything there?
Torque 3D Owner Jack Stone
The node transform values *do* seem to update in the shape editor, just not when I call the function from script. So obviously the shape editor is updating something?