Game Development Community

dev|Pro Game Development Curriculum

setForwardVector()

by Orion Elenzil · 08/01/2008 (10:26 am) · 3 comments

this resource adds the ConsoleMethod SceneObject::setForwardVector(, []).

this will set the orientation of an object so that it's local Y-vector is pointing in the direction given.
optionally, you can specify an Up vector. if the vectors are invalid (eg zero length or fwd is parallel to up), defaults will be chosen. (up defaults to <0 0 1>, fwd defaults to <0 1 0>, and if fwd is parallel to up the results are undefined but hopefully reasonable.)

sceneObject.cc
after the getForwardVector() consoleMethod, add:
ConsoleMethod( SceneObject, setForwardVector, void, 3, 4, "(vector forward dir, [vector up]) Change the object's rotation so that its local Y vector is aligned to the input.")
{
   MatrixF mat = object->getTransform();

   VectorF up(0.0f, 0.0f, 1.0f);
   VectorF axisX;
   VectorF axisY;
   VectorF axisZ;

   dSscanf(   argv[2], "%f %f %f", &axisY.x, &axisY.y, &axisY.z);

   if (argc > 3)
      dSscanf(argv[3], "%f %f %f", &up   .x, &up   .y, &up   .z);


   // Validate and normalize input:
   F32 lenSq;
   lenSq = axisY.lenSquared();
   if (lenSq < 0.000001f)
   {
      axisY.set(0.0f, 1.0f, 0.0f);
      Con::errorf("SceneObject::setForwardVector() - degenerate forward vector");
   }
   else
   {
      axisY /= mSqrt(lenSq);
   }


   lenSq = up.lenSquared();
   if (lenSq < 0.000001f)
   {
      up.set(0.0f, 0.0f, 1.0f);
      Con::errorf("SceneObject::setForwardVector() - degenerate up vector - too small");
   }
   else
   {
      up /= mSqrt(lenSq);
   }

   if (fabsf(mDot(up, axisY)) > 0.9999f)
   {
      Con::errorf("SceneObject::setForwardVector() - degenerate up vector - same as forward");
      // i haven't really tested this, but i think it generates something which should be not parallel to the previous vector:
      F32 tmp = up.x;
      up.x = -up.y;
      up.y =  up.z;
      up.z =  tmp;
   }

   // construct the remaining axes:

   mCross(axisY, up   , &axisX);
   mCross(axisX, axisY, &axisZ);

   mat.setColumn(0, axisX);
   mat.setColumn(1, axisY);
   mat.setColumn(2, axisZ);

   object->setTransform(mat);
}

#1
08/01/2008 (7:16 pm)
Nice, I was just about to hunt through the search function for something like this. Great timing!
#2
08/07/2008 (4:48 am)
I think... it can really be of some great use for me...
#3
01/04/2009 (7:51 pm)
Very useful, this belongs in torque.