Making an object rotate along with a mountsystem?
by Christopher Gu · in Torque Game Builder · 11/28/2005 (12:44 pm) · 10 replies
Hey again,
Wow...I'm full of all sorts of questions lately...
Anywho, I have an object in my game that pops up at the bottom of the screen and travels in an arc. I've implemented this using a mountsystem similar to the one found in the shooter demo. My problem is that my object does not rotate along with the mount system, i.e. it always faces the same direction while it travels in an arc. Is there a way to make it rotate along with the mount system?
Here is an excerpt from the code that gets called when the object is created:
Hopefully that snippet will give you guys a better idea of what I'm doing with this object...maybe it'll also help others who are trying to do something similar, who knows.
Wow...I'm full of all sorts of questions lately...
Anywho, I have an object in my game that pops up at the bottom of the screen and travels in an arc. I've implemented this using a mountsystem similar to the one found in the shooter demo. My problem is that my object does not rotate along with the mount system, i.e. it always faces the same direction while it travels in an arc. Is there a way to make it rotate along with the mount system?
Here is an excerpt from the code that gets called when the object is created:
%mountSystem = new fxSceneObject2D() { scenegraph = t2dSceneGraph; };
%mountSystem.setSize( "37 37");
%mountSystem.setAutoMountRotation( -80 );
%mountPoint = new fxSceneObject2D() { scenegraph = t2dSceneGraph; };
%mountPoint.setPosition(%xCoord SPC "40");
%mountSystem.mount( %mountPoint, "0 0" );
%mountPosition = (mCos(mDegToRad(120 * 1))) SPC (mSin(mDegToRad(120 * 1)));
%enemy.mount( %mountSystem, %mountPosition );Hopefully that snippet will give you guys a better idea of what I'm doing with this object...maybe it'll also help others who are trying to do something similar, who knows.
#2
11/28/2005 (1:01 pm)
Hmmm, switching between true and false doesnt seem to make a differance :( Isn't it set to true by default anyways?
#3
11/28/2005 (1:36 pm)
Oh, I think I know what's wrong. None of these objects are actually rotating. You use setAutoMountRotation. The rotation of mountSystem stays zero. Try this:%mountSystem = new fxSceneObject2D() { scenegraph = t2dSceneGraph; };
%mountSystem.setSize( "37 37");
// %mountSystem.setAutoMountRotation( -80 ); commented out
%mountPoint = new fxSceneObject2D() { scenegraph = t2dSceneGraph; };
%mountPoint.setPosition(%xCoord SPC "40");
%mountSystem.mount( %mountPoint, "0 0" );
[b]%mountPoint.setAutoMountRotation(-80);[/b]
%mountPosition = (mCos(mDegToRad(120 * 1))) SPC (mSin(mDegToRad(120 * 1)));
%enemy.mount( %mountSystem, %mountPosition );
#4
11/29/2005 (12:16 pm)
Hmmm...thats not really the problem. The object mounts just fine onto my mountSystem, and it moves along with it. The problem is that the object's orientation doesnt change. It moves in a circle, as desired, but it just points in the same direction the whole time.
#5
The problem is setAutoMountRotation does not manipulate the mounted object's rotation in any way. I just manipulates the mounted object's position.
If you tell a object to track the rotation of the object it should be mounted to, this object only calculates its own rotation relative to the value the getRotation()-method of the object mounted to returns. If you say %mountPoint.setAutoMountRotation(-80); the getRotation()-return value of %mountPoint does not change (as the object does NOT rotate itself, which is the purpose of setAutoMountRotation). You get what I mean?
Here is the solution: %mountSystem must actually rotate. Then %enemy can read getRotation() of %mountSystem and set its own rotation accordingly.
This code is tested and works. %mountPoint is not actually necessary.
EDIT:
Optionally, if you want to keep the %mountPoint, delete the line
-Michael
11/29/2005 (4:20 pm)
Ok, now I really know what the problem is (I have tested it).The problem is setAutoMountRotation does not manipulate the mounted object's rotation in any way. I just manipulates the mounted object's position.
If you tell a object to track the rotation of the object it should be mounted to, this object only calculates its own rotation relative to the value the getRotation()-method of the object mounted to returns. If you say %mountPoint.setAutoMountRotation(-80); the getRotation()-return value of %mountPoint does not change (as the object does NOT rotate itself, which is the purpose of setAutoMountRotation). You get what I mean?
Here is the solution: %mountSystem must actually rotate. Then %enemy can read getRotation() of %mountSystem and set its own rotation accordingly.
This code is tested and works. %mountPoint is not actually necessary.
// you'll have to convert names to 1.0.2 versions
%mountSystem = new t2dSceneObject() { scenegraph = t2dScene; };
%mountSystem.setSize("37 37");
%mountSystem.setPosition("0 0"); // or what ever position you want
%mountPosition = (mCos(mDegToRad(120 * 1))) SPC (mSin(mDegToRad(120 * 1)));
%enemy.mount( %mountSystem, %mountPosition );EDIT:
Optionally, if you want to keep the %mountPoint, delete the line
%mountSystem.setAutoMountRotation( -80 );and put a
%mountPoint.setAngularVelocity( -80 );somewhere in after creating %mountPoint. However, if you don't plan to mount other objects directly to %mountPoint then it is really redundant.
-Michael
#6
11/30/2005 (11:03 am)
OK, everything works now. Thanks for taking the time to help out!
#7
The code that deals with this is relatively simple; it's in "t2dSceneObject.cc" (line 3759 of the alpha#1). Adding "mpMountTo->getMountRotation()" into the equation would work as desired above.
This comes down to a single line of code if it was required that the mount-systems rotation needed to be added into this but I'm kinda' wondering if this would be behaviour that is required by all or just a few or perhaps just an option. The "mount()" command is getting awfully full of options so I don't want to add many more than is absolutely necessary.
Thoughts?
12/04/2005 (4:33 am)
Interesting thread. Yes, the "tracked rotation" is now a composite of the objects original rotation plus the current rotation of the "mounted to" object only.The code that deals with this is relatively simple; it's in "t2dSceneObject.cc" (line 3759 of the alpha#1). Adding "mpMountTo->getMountRotation()" into the equation would work as desired above.
This comes down to a single line of code if it was required that the mount-systems rotation needed to be added into this but I'm kinda' wondering if this would be behaviour that is required by all or just a few or perhaps just an option. The "mount()" command is getting awfully full of options so I don't want to add many more than is absolutely necessary.
Thoughts?
#8
As it is now, there's always the work around of inserting such a mountsystem to get the desired behavior. You can do it if you have to. However this gives you the overhead of one additional sceneobject, which may make absolutly no difference if this plus 1,2,..,10 objects in total but would make quite a difference if every entity needed this an there are lots of them. Chances are this won't happen too often.
I had a similar problem: as mentioned in some other thread, I created an ExtendedSprite class derived from t2dSceneObject. The purpose of this class is that it can play ExtendedAnimationDatablocks which are derived from t2dAnimationDatablock and introduce an additional offset and size ratio for the animation. This way, an ExtendedSprite can say a 64x64 idle animation followed by a 80x64 attacking animation, without resizing it (in which case I would have to recalculate the collisionpoly and things like that).
ExtendedSprite accomplishes this by creating and mounting a t2dAnimatedSprite to itself on creation. (Tried to completly redo the t2dAnimatedSprite plus extension but the method calculateSpatials() was not virtual. Because of this, there were clipping problems if the resized animation was bigger than the t2dSceneObjects mWorldClipBoundarys)
So here it is again, the overhead of a full t2dSceneObject were just some functionality of it is needed. I don't think, the memory overhead is something to worry about but I am not sure how much cpu time this consumes. Not too much I suppose, if you turn off physics and collision for the mounted object.
Hm, I think somewhere on my way I must have forgotten what I actually wanted to say...
Have a nice Sunday,
Michael
12/04/2005 (5:13 am)
@Christopher: No problem.As it is now, there's always the work around of inserting such a mountsystem to get the desired behavior. You can do it if you have to. However this gives you the overhead of one additional sceneobject, which may make absolutly no difference if this plus 1,2,..,10 objects in total but would make quite a difference if every entity needed this an there are lots of them. Chances are this won't happen too often.
I had a similar problem: as mentioned in some other thread, I created an ExtendedSprite class derived from t2dSceneObject. The purpose of this class is that it can play ExtendedAnimationDatablocks which are derived from t2dAnimationDatablock and introduce an additional offset and size ratio for the animation. This way, an ExtendedSprite can say a 64x64 idle animation followed by a 80x64 attacking animation, without resizing it (in which case I would have to recalculate the collisionpoly and things like that).
ExtendedSprite accomplishes this by creating and mounting a t2dAnimatedSprite to itself on creation. (Tried to completly redo the t2dAnimatedSprite plus extension but the method calculateSpatials() was not virtual. Because of this, there were clipping problems if the resized animation was bigger than the t2dSceneObjects mWorldClipBoundarys)
So here it is again, the overhead of a full t2dSceneObject were just some functionality of it is needed. I don't think, the memory overhead is something to worry about but I am not sure how much cpu time this consumes. Not too much I suppose, if you turn off physics and collision for the mounted object.
Hm, I think somewhere on my way I must have forgotten what I actually wanted to say...
Have a nice Sunday,
Michael
#9
I have another object in my game which requires objects to orbit it with a fixed orientation (guns orbiting an enemy), so there are definately more ways than one to use mount(). I really have no problem with it staying the way it is as long as workarounds like the one devised in this thread are possible.
12/05/2005 (11:24 am)
Melv-I have another object in my game which requires objects to orbit it with a fixed orientation (guns orbiting an enemy), so there are definately more ways than one to use mount(). I really have no problem with it staying the way it is as long as workarounds like the one devised in this thread are possible.
#10
This didn't make it into the alpha#2 but it will be in the alpha#3. In-case you want this feature now, replace the code in "t2dSceneObject.cc" (approx line 3769 in alpha#2) with the following:
You can test this using the following script (uncomment the appropriate lines) that can rotate either the parent-sprite or the parent-sprites mount-rotation:
The system uses both the parent-objects rotation and the parents mount-rotation meaning that you can use both simultaneously allowing for effects such as the object rotating one way but the mount-system rotating the other way.
Please note that this also fixes a bug with the existing rotation of an object being applied in the wrong angular direction.
Hope this helps,
- Melv.
12/27/2005 (8:48 am)
Okay,This didn't make it into the alpha#2 but it will be in the alpha#3. In-case you want this feature now, replace the code in "t2dSceneObject.cc" (approx line 3769 in alpha#2) with the following:
// Track rotation ( if selected ).
if ( mMountTrackRotation )
{
// Calculate Mount Rotation.
// NOTE:- We're using the parents mount-rotation, rotation and this objects pre-rotation value.
const F32 mountRotation = mpMountedTo->getMountRotation() + mpMountedTo->getRotation() + mMountPreRotation;
// Are we at the target mount rotation?
if ( mNotEqual(mountRotation, getRotation()) )
{
// No, so set rotation.
setRotation( mountRotation);
}
}You can test this using the following script (uncomment the appropriate lines) that can rotate either the parent-sprite or the parent-sprites mount-rotation:
// Begin Scene Addition. t2dBeginScene( t2dScene ); // Create parent sprite. %sprite1 = new t2dStaticSprite(); %sprite1.setImageMap( ggLogoImageMap ); // Create child sprite. %sprite2 = new t2dStaticSprite(); %sprite2.setImageMap( shipImageMap ); %sprite2.setRotation( 90 ); %sprite2.mount( %sprite1, "3 0", 0, true ); // Uncomment *ONE* of the following to test! //%sprite1.setAutoRotation( 90 ); //%sprite1.setAutoMountRotation( 180 ); // End Scene Addition. t2dEndScene();
The system uses both the parent-objects rotation and the parents mount-rotation meaning that you can use both simultaneously allowing for effects such as the object rotating one way but the mount-system rotating the other way.
Please note that this also fixes a bug with the existing rotation of an object being applied in the wrong angular direction.
Hope this helps,
- Melv.
Torque Owner Michael Woerister
The last parameter tells the mounted objects to track the rotation of the object it is mounted to.
-Michael