Game Development Community

Modifying and animating mounted objects

by Amr Bekhit · in Torque Game Engine · 11/04/2006 (6:27 am) · 5 replies

Hi all,

Recently I've had the need to modify a mounted object's rotation. Specifically, I have a cannon mounted on a ship and would like the user to control the cannon's rotation. I've had a search on the forums but I couldn't find a solution - people said that this would need to be implemented into the source, which I might look at later. There is the turret resource as well, but I would like to implement something a lot simpler.

Another way I could do this is to create 2 animation frames for the cannon: one at each of its rotation limits, then depending on the angle I need, I would play a part of that animation. I notice that the Show Tool Pro does it using the animation slider on the bottom right of the screen. How can I play back only part of an animation in Torque?

Thanks

--Amr

#1
11/05/2006 (8:03 am)
Hello again,

I've been working on a way to do this myself in the source. After reading through this forum post, I found that I can retrieve the transform of a mount node using the getSlotTransform. I examined this function in the source and found that the node transforms are stored in the mShapeInstance->mNodeTransforms array. So I figured that I could modify the transform of a node by writing the correct information to that array.

I am confused as to how to pack rotation and position into a single matrix and then store that information in the array. Here is the code so far (both functions are in shapeBase.cc) - I've highlighted sections I'm not too sure about:

Here is the main functon:

void ShapeBase::setMountTransform(U32 mountPoint,MatrixF* matTransform)
{
	[b]//Before any of this will work, we need to relinquish control of the animation
	//from the engine. This is done by setting the shape's animation state to 'HandsOff'
	//The following snippet of code was taken from the forum post @
	//http://www.garagegames.com/mg/forums/result.thread.php?qt=33391 by John Kilma
	//NOTE: I'm not entirely sure if I need this or not - I was trying things out.
	//START CODE SNIPPET
	TSShape *shape=mShapeInstance->getShape();
	for (U32 i=0;i<shape->nodes.size();i++)
		mShapeInstance->setNodeAnimationState(i,mShapeInstance->MaskNodeHandsOff);
	//END CODE SNIPPET[/b]

	//Check that the required mountPoint is valid
	if (mountPoint < ShapeBaseData::NumMountPoints)
	{
		//Retrieve the ID of the mountPoint
		S32 nodeID = mDataBlock->mountPointNode[mountPoint];

		if (nodeID != -1)
		{
			//Set the transformation of this node to the one we passed to the function
			Point3F buf;
			for (int x=0;x<3;x++)
			{
				[b]//Here's the bit I'm not sure about
				//I'm taking the columns of the matrix and storing them in the array
				matTransform->getColumn(x,&buf);
				mShapeInstance->mNodeTransforms[nodeID].setColumn(x,buf);[/b]
			}
		}
	}
	return;
}

Here is the console method:

ConsoleMethod(ShapeBase,setSlotTransform,void,4,4,"setSlotTransform(slot,transform)")
{
	//argv[0] = function name
	//argv[1] = ShapeBase object ID
	//argv[2] = slot
	//argv[3] = transform
	int slot = dAtoi(argv[2]);

	//Matrix used to hold the transformation
	MatrixF matTransform;

	//Store the transform into the matrix
	Point3F pos;	//Holds the x,y,z position
	AngAxisF rot;	//Hold the quaternion rotation

	dSscanf(argv[3],"%g %g %g %g %g %g %g",&pos.x,&pos.y,&pos.z,&rot.axis.x,&rot.axis.y,&rot.axis.z,&rot.angle);

	[b]//I don't understand this part of the code - it is coped from the SceneObject setTransform method
	rot.setMatrix(&matTransform);
	matTransform.setColumn(3,pos);[/b]

	//Check that the slot is valid
	if (slot >= 0 && slot < ShapeBase::MaxMountedImages)
		object->setMountTransform(slot,&matTransform);
	return;
}

Am I on the right track with this code?

Thanks

--Amr
#2
11/06/2006 (11:37 am)
*Bump*
#3
11/06/2006 (12:05 pm)
Hmm..
Will this not modify the mount for each instance of that mesh?

I think handling this at the animation level would be best.

if you consult the playthread function and any surrounding it, I am sure you can specify or set the current frametime of the animation, this will allow you to use playthread stopthread and stuff.

Quote://I don't understand this part of the code - it is coped from the SceneObject setTransform method
rot.setMatrix(&matTransform);
matTransform.setColumn(3,pos);

here rot is a quaternion, and that quat is being used to initialize a matrix.
so that is now a rotation matrix.
setcolumn 3 will set the matrix transform with your new position.
#4
11/06/2006 (12:13 pm)
You can stop on a specified frame in an animation.

The node of the mounted object should not move other than relative to the new position of the cannon. IE it should all ways stay at the same rotation, or position.
#5
11/06/2006 (2:08 pm)
Ah OK thanks for the pointers. As I was looking at the Wheel animations for Wheeled Vehicle I did notice a setPos function, so I'll explore that further.

I'll let you know how I get on.

--Amr