Point an object at another object
by James Greenhalgh · in Torque Game Engine · 01/19/2009 (1:13 am) · 9 replies
I'm trying to expand the functionality of the fsShapeReplicator to point at another object, but I'm not getting the exact results I'd like, am I missing a necessary rotation or is createOrientFromDir not proper?
Relevant Code:
Figure 1:

Say I have a circular pit, I want all the trees along the cliff in a circle to point towards an invisible object I've placed in the center of the pit a little higher. (Image A)
Instead of getting the results I want (Image C), the object's rotation is oriented to the same vector that is calculated. (Image B) I can kind of cheat this and get the result I want by placing the object lower, but this will never allow for all the functionality I desire. (Image D) Anyone point me to what steps I need to do or if this is even possible?
Relevant Code:
SceneObject* SceneObj = dynamic_cast<SceneObject*>(Sim::findObject(mFieldData.mAimAtObject));
if (SceneObj)
{
Point3F aimObjPos;
aimObjPos = SceneObj->getPosition();
VectorF los = aimObjPos - ShapePosition;
los.normalize();
XForm = MathUtils::createOrientFromDir(los);
}
}
// Set Position.
XForm.setColumn(3, ShapePosition);
// Set Shape Position / Rotation.
fxStatic->setTransform(XForm);Figure 1:

Say I have a circular pit, I want all the trees along the cliff in a circle to point towards an invisible object I've placed in the center of the pit a little higher. (Image A)
Instead of getting the results I want (Image C), the object's rotation is oriented to the same vector that is calculated. (Image B) I can kind of cheat this and get the result I want by placing the object lower, but this will never allow for all the functionality I desire. (Image D) Anyone point me to what steps I need to do or if this is even possible?
#2
01/19/2009 (4:11 am)
Change line 271 fromt2dMatrix xForm( -angle );to
t2dMatrix xForm( angle );in T2D/activeTiles/t2dGunTurret.cc.
#3
Thanks for the tips, however I guess I wasn't clear, and owe you an apology for your time. This is for TGE 1.5.2 (probably work fine on TGEA as well), I just drew my diagram in 2d. I don't have a license to T2D though now I'm doubting your pointers will help any way. I did go take a look at the Turret resource and I'm hoping that'll point me in the right direction.
Thanks,
James
01/19/2009 (5:26 am)
Hi Stefan,Thanks for the tips, however I guess I wasn't clear, and owe you an apology for your time. This is for TGE 1.5.2 (probably work fine on TGEA as well), I just drew my diagram in 2d. I don't have a license to T2D though now I'm doubting your pointers will help any way. I did go take a look at the Turret resource and I'm hoping that'll point me in the right direction.
Thanks,
James
#4
01/19/2009 (7:05 am)
My fault, sorry. I thought you were posting in the TGB private forums :)
#5
I seemed to get the exact result I want simply by rotating on the X axis. I'm not sure if it can be done better or if it will cause problems in other areas, but all tests are appearing correct.
Here is the final code:
01/19/2009 (7:40 am)
No worries Stefan,I seemed to get the exact result I want simply by rotating on the X axis. I'm not sure if it can be done better or if it will cause problems in other areas, but all tests are appearing correct.
Here is the final code:
bool aimObjFound = false;
if (mFieldData.mAimAtObject != ST_NULLSTRING)
{
SceneObject* SceneObj = dynamic_cast<SceneObject*>(Sim::findObject(mFieldData.mAimAtObject));
if (SceneObj)
{
Point3F aimObjPos;
aimObjPos = SceneObj->getPosition();
VectorF los = aimObjPos - ShapePosition;
los.normalize();
// Orient our shape's transform to the same vector as the direction
// between the RayCast ground transform and the object's position
XForm = MathUtils::createOrientFromDir(los);
aimObjFound = true;
}
}
if (!aimObjFound)
{
// Set Quaternion Rotation.
QRotation.set(ShapeRotation);
// Set Transform Rotation.
QRotation.setMatrix(&XForm);
}
// Set Position.
XForm.setColumn(3, ShapePosition);
// Set Shape Position / Rotation.
fxStatic->setTransform(XForm);
// If we're aiming at an object we need to rotate 90 degrees along the X
if (aimObjFound)
{
EulerF rot(mDegToRad(90.f),0.f,0.f);
fxStatic->RotateObj(rot);
}
#6
sounds like you've already got a solution,
but i wrote a method a while you might still find useful, or at least informative:
sceneObject::setForwardVector()
01/20/2009 (5:19 pm)
james,sounds like you've already got a solution,
but i wrote a method a while you might still find useful, or at least informative:
sceneObject::setForwardVector()
#7
In other words, this method call will always orient the object's local +Y (i.e. it's forward vector) along the specified direction vector. Indeed, looking at figure B in the original diagrams of the problem, this does appear to be exactly what it was doing: the trees were orienting their forward faces to point at the target object, as if it were a camera and they were billboard objects.
Based on this, your solution of rotating 90 degrees in the X is perfectly legit. Since you know the first move leaves +Y facing the target, following up with a 90 degree X rotation finishes the job. Just for the heck of it, though, here's an alternate approach that seemed to work in the rudimentary testing I was able to do without knowing your full code plans. The following listing represents a new function is intended to be a variation on createOrientFromDir, which does the same thing except that it points the object's local +Z along the direction vector (which, if I understand correctly, is what you're trying to do...)
Note that this is basically the same as createOrientFromDir, except for a reversal of the order of the 2nd cross product's operands and a reversal of some matrix column assignments at the end, so its pretty much exactly the same efficiency, but with a modified result to match what you're trying to do.
01/21/2009 (12:24 pm)
Rotating around the X axis sounds like it will work. The problem you were encountering originally was that MathUtils::createOrientFromDir appears to be designed to orient things like particles and billboards to always face a particular direction (indeed, the only references to it that I found in code deal with particles). In other words, this method call will always orient the object's local +Y (i.e. it's forward vector) along the specified direction vector. Indeed, looking at figure B in the original diagrams of the problem, this does appear to be exactly what it was doing: the trees were orienting their forward faces to point at the target object, as if it were a camera and they were billboard objects.
Based on this, your solution of rotating 90 degrees in the X is perfectly legit. Since you know the first move leaves +Y facing the target, following up with a 90 degree X rotation finishes the job. Just for the heck of it, though, here's an alternate approach that seemed to work in the rudimentary testing I was able to do without knowing your full code plans. The following listing represents a new function is intended to be a variation on createOrientFromDir, which does the same thing except that it points the object's local +Z along the direction vector (which, if I understand correctly, is what you're trying to do...)
MatrixF orientTopAtDirection( Point3F &direction )
{
Point3F j = direction;
Point3F k(0.0f, 0.0f, 1.0f);
Point3F i;
mCross( j, k, &i );
if( i.magnitudeSafe() == 0.0f )
{
i.set( 0.0f, -1.0f, 0.0f );
}
i.normalizeSafe();
mCross( j, i, &k );
MatrixF mat( true );
mat.setColumn( 0, i );
mat.setColumn( 1, k );
mat.setColumn( 2, j );
return mat;
}Note that this is basically the same as createOrientFromDir, except for a reversal of the order of the 2nd cross product's operands and a reversal of some matrix column assignments at the end, so its pretty much exactly the same efficiency, but with a modified result to match what you're trying to do.
#8
As for my full code plans, it was just a slight variation I added to fxShapeReplicator to make formations out of replicated shapes. Think like a log teepee or a cave entrance surrounded in stalagmites that look like teeth. Here's a gigantic pit we have in game that I've aligned with trees to show the result, (using your code btw), everything looks to be right.
01/21/2009 (12:46 pm)
Thanks for that Charles, it does make things a little cleaner and lets me just set the transform the right way to begin with. I also understand what's going on much clearer now.As for my full code plans, it was just a slight variation I added to fxShapeReplicator to make formations out of replicated shapes. Think like a log teepee or a cave entrance surrounded in stalagmites that look like teeth. Here's a gigantic pit we have in game that I've aligned with trees to show the result, (using your code btw), everything looks to be right.
#9
OK, now that you describe it some more I can see what you were working toward. Sounds like it would be handy in a flight game for making rings of jagged spikes for players to crash into as they pass through narrow tunnels, or making basically conical (yet naturally randomized) constructs without a lot of tedious manual placements. Nice.
01/21/2009 (3:18 pm)
Excellent! Glad to hear it worked in the bigger picture. Demo screenshot looks cool, too.OK, now that you describe it some more I can see what you were working toward. Sounds like it would be handy in a flight game for making rings of jagged spikes for players to crash into as they pass through narrow tunnels, or making basically conical (yet naturally randomized) constructs without a lot of tedious manual placements. Nice.
Torque Owner Shaderman
and you'd have to remove that minus sign to have it rotate properly.