Game Development Community

Rotating A StaticShape to Orient Towards Another

by Michael Greene · in Torque 3D Beginner · 12/28/2012 (5:58 pm) · 14 replies

For a project I'm working on, I'm trying to get an "energy cable" static shape to correctly orient itself between two other objects. Getting it to be the correct length is of no consequence and is just a matter of scaling it by the distance. Getting it to point in the correct direction on the other hand is another matter entirely and is something I've been beating my head against the wall with for a while now. This is largely because I just don't have the knowledge of the math involved.

I have seen the following before (see reply #3) http://www.garagegames.com/community/forums/viewthread/129813

Unfortunately, when I've tried pointToPos(%posOne,%posTwo), the effect has been rather.. lackluster. Since in my searches, I've seen this several times, perhaps I just need to hook this in in a different way than I am?

The following is my current implementation:

// Spawn Energy Cable
   %start = %reactor.position;
   %end = %obj.position;
   %rot = pointToPos(%start,%end);
   %cable = new StaticShape() {
      canSaveDynamicFields = "1";
      Enabled = "1";
      position = %reactor.position;
      rotation = %rot;
      scale = "1.0" SPC VectorDist(%start,%end) SPC "1.0";
      doDistanceFade = "0";
      startFadeDistance = "10";
      endFadeDistance = "500";
      teamIndex = %reactor.Owner.teamIndex;
      dataBlock = "EnergyCable";
      receiveSunLight = "1";
      receiveLMLighting = "0";
      useCustomAmbientLighting = "0";
      customAmbientLighting = "0 0 0 1";
      usePolysoup = "1";
      polysoupDL = "0";
   };

Instead of orienting between the two objects, the cable is instead parallel with the y-axis of the world. Ideas for why this may be/suggestions for a fix?

About the author

CS Student at Purdue University

Recent Threads


#1
12/29/2012 (7:26 am)
Doing a quick search of the engine and scripts I don't see a definition for "pointToPos()" anywhere so I'm guessing that someone created a quick script function and posted it in an example somewhere.

So, add a script function like so:
function pointToPos(%startPos, %targetPos)
{
   return VectorSub(%targetPos, %startPos);
}

That'll get you a vector to the other object - and I think passing that in as your object's rotation should aim it at the target object. Give it a shot, and watch your game's console.log file for error messages - it helps.
#2
12/29/2012 (9:25 am)
pointToPos is a function given at the aforementioned location: reply 3 of http://www.garagegames.com/community/forums/viewthread/129813

And merely setting the rotation to the vector (normalized or not) didn't in my experience result in anything useful but rather an orientation that was always incorrect. The cable was always correct in one plane but completely wrong in another.
#3
12/30/2012 (10:40 am)
// And this lil function generates the rotation required for an object at posOne  
// to point at PosTwo for X, Y And Z axis.  
function pointToPos(%posOne, %posTwo)  
{  
   // sub the two positions so we get a vector pointing from the origin in the  
   // direction we want our object to face  
   %vec = VectorSub(%posTwo, %posOne);  
  
   // pull the values out of the vector  
   %x = firstWord(%vec);  
   %y = getWord(%vec, 1);  
   %z = getWord(%vec, 2);  
  
   // this finds the distance from origin to our point  
   %len = vectorLen(%vec);  
  
   //---------X-----------------  
   // given the rise and length of our vector this will give us the angle in radians  
   %rotAngleX = mATan(%z, %len);  
  
   //---------Z-----------------  
   // get the angle for the z axis  
   %rotAngleZ = mATan(%x, %y);  
  
   // create 2 matrices, one for the z rotation, the other for the x rotation  
   %matrix = MatrixCreateFromEuler("0 0" SPC %rotAngleZ * -1);  
   %matrix2 = MatrixCreateFromEuler(%rotAngleX SPC "0 0");  
  
   // now multiply them together so we end up with the rotation we want  
   %finalMat = MatrixMultiply(%matrix, %matrix2);  
  
   // we're done, send the proper numbers back  
   return getWords(%finalMat, 3, 6);  
}

Not sure why that's not working. Indeed seems to do nothing
#4
12/31/2012 (9:53 am)
Just to note, returning the numbers from that pointToPos() helper method doesn't actually make object A look at object B, you still have to use them in a call to setTransform() for the action to take place.
#5
12/31/2012 (10:09 am)
He is defining the rotation numbers from his function in the object creation however.
#6
12/31/2012 (10:41 am)
Ah - see, that's where I was sort of curious. I knew that would get the vector but I wasn't sure if setTransform() takes a vector or if it expects a full rotation transform - obviously it's the second case reading the results.

That's what I get for posting without testing first.... lol

I suppose the better thing would be to create the object and immediately call setTransform() rather than trying to directly set the value. I've noticed that with some objects (or perhaps under certain circumstances) setting the parameters in the "constructor" fails to perform as expected, but setting them immediately following the object's creation works.
#7
12/31/2012 (4:52 pm)
%p2p = pointToPos(%start,%end);
%pos = getWords(%cable.getTransform(), 0, 2);  
%cable.setTransform(%pos SPC %p2p);

That worked , thanks a bunch : )
#8
12/31/2012 (11:55 pm)
Quote:I've noticed that with some objects (or perhaps under certain circumstances) setting the parameters in the "constructor" fails to perform as expected, but setting them immediately following the object's creation works.
Sounds like bug report material! Though in initPersistFields, SceneObject's rotation member is defined as a TypeMatrixRotation. Does is mean it expects a full matrix? One way to check would be to echo someObj.rotation in the console and see what sort of data type you get back.
#9
01/01/2013 (9:51 am)
I see Matt already posted, but anyways, thanks again guys.
#10
01/01/2013 (12:22 pm)
Actually it works well if objects are with 10 or 15 meters or so within the same plane. As soon as the second object is way above the first . the beam misses under and when the second object is way below the first, the beam missed above. Anyone know what this is about ?
#11
01/31/2013 (3:37 pm)
I have been trying with the problem mentioned in my last post and cant really figure out how to test this math to fix it. I also verified the pivot point for the bounds and other objects are in the correct place on the 'beams' anyone have any insight as to why this might happen ? this math is so beyond me.

Thanks,
Matt
#12
01/31/2013 (3:50 pm)
This last issue probably has to do with the center of the object.
#13
01/31/2013 (3:58 pm)
I have all the pivot points of the objects/bounds at one end direct center of two X planes. The idea being that it would scale and aim from that point , is that what you mean ?
#14
01/31/2013 (9:11 pm)
That is sort of what I was thinking. Is it aiming for the pivot point? Is that what causes it to miss? Or does it look like some sort of distance error?

Also, if that is what is causing the problem you could add half the height of the object to the position to make it aim more at the center of the bounding box.

Maybe a picture or movie showing the problem would help.