소스 검색

Merge pull request #2095 from Areloch/SetForwardVector

Enables setting the forward vector of a Scene Object
Areloch 8 년 전
부모
커밋
95053c6038
2개의 변경된 파일69개의 추가작업 그리고 0개의 파일을 삭제
  1. 66 0
      Engine/source/scene/sceneObject.cpp
  2. 3 0
      Engine/source/scene/sceneObject.h

+ 66 - 0
Engine/source/scene/sceneObject.cpp

@@ -433,6 +433,64 @@ void SceneObject::setScale( const VectorF &scale )
    setMaskBits( ScaleMask );
 }
 
+void SceneObject::setForwardVector(VectorF newForward, VectorF upVector)
+{
+   MatrixF mat = getTransform();
+
+   VectorF up(0.0f, 0.0f, 1.0f);
+   VectorF axisX;
+   VectorF axisY = newForward;
+   VectorF axisZ;
+
+   if (upVector != VectorF::Zero)
+      up = upVector;
+
+   // 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);
+
+   setTransform(mat);
+}
+
 //-----------------------------------------------------------------------------
 
 void SceneObject::resetWorldBox()
@@ -1458,3 +1516,11 @@ DefineEngineMethod( SceneObject, isGlobalBounds, bool, (),,
 {
    return object->isGlobalBounds();
 }
+
+DefineConsoleMethod(SceneObject, setForwardVector, void, (VectorF newForward, VectorF upVector), (VectorF(0, 0, 0), VectorF(0, 0, 1)),
+   "Sets the forward vector of a scene object, making it face Y+ along the new vector.\n"
+   "@param The new forward vector to set.\n"
+   "@param (Optional) The up vector to use to help orient the rotation.")
+{
+   object->setForwardVector(newForward, upVector);
+}

+ 3 - 0
Engine/source/scene/sceneObject.h

@@ -504,6 +504,9 @@ class SceneObject : public NetObject, private SceneContainer::Link, public Proce
       /// @param   scale   Scaling values
       virtual void setScale( const VectorF &scale );
 
+      /// Sets the forward vector of the object
+      void setForwardVector(VectorF newForward, VectorF upVector = VectorF(0, 0, 1));
+
       /// This sets the render transform for this object
       /// @param   mat   New render transform
       virtual void setRenderTransform(const MatrixF &mat);