Patch #11000 approved: [new function] KX_GameObject::alignAxisToVect() Align an objec...
authorBenoit Bolsee <benoit.bolsee@online.be>
Mon, 2 Jun 2008 17:31:05 +0000 (17:31 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Mon, 2 Jun 2008 17:31:05 +0000 (17:31 +0000)
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/PyDoc/KX_GameObject.py

index dada47e2fa46a54185cc151e2a6c0123373b21e5..c192cd012614a59425e06b0540eacac1dbd2ddd3 100644 (file)
@@ -580,7 +580,68 @@ void KX_GameObject::SetObjectColor(const MT_Vector4& rgbavec)
        m_objectColor = rgbavec;
 }
 
+void KX_GameObject::AlignAxisToVect(const MT_Vector3& dir, int axis)
+{
+       MT_Matrix3x3 orimat;
+       MT_Vector3 vect,ori,z,x,y;
+       MT_Scalar len;
 
+       vect = dir;
+       len = vect.length();
+       if (MT_fuzzyZero(len))
+       {
+               cout << "alignAxisToVect() Error: Null vector!\n";
+               return;
+       }
+       // normalize
+       vect /= len;
+       orimat = GetSGNode()->GetWorldOrientation();
+       switch (axis)
+       {       
+               case 0: //x axis
+                       ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]); //pivot axis
+                       if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON) //is the vector paralell to the pivot?
+                               ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]); //change the pivot!
+                       x = vect; 
+                       y = ori.cross(x);
+                       z = x.cross(y);
+                       break;
+               case 1: //y axis
+                       ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]);
+                       if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON)
+                               ori = MT_Vector3(orimat[0][2], orimat[1][2], orimat[2][2]);
+                       y = vect;
+                       z = ori.cross(y);
+                       x = y.cross(z);
+                       break;
+               case 2: //z axis
+                       ori = MT_Vector3(orimat[0][1], orimat[1][1], orimat[2][1]);
+                       if (MT_abs(vect.dot(ori)) > 1.0-3.0*MT_EPSILON)
+                               ori = MT_Vector3(orimat[0][0], orimat[1][0], orimat[2][0]);
+                       z = vect;
+                       x = ori.cross(z);
+                       y = z.cross(x);
+                       break;
+               default: //wrong input?
+                       cout << "alignAxisToVect(): Wrong axis '" << axis <<"'\n";
+                       return;
+       }
+       x.normalize(); //normalize the vectors
+       y.normalize();
+       z.normalize();
+       orimat = MT_Matrix3x3(  x[0],y[0],z[0],
+                                                       x[1],y[1],z[1],
+                                                       x[2],y[2],z[2]);
+       if (GetSGNode()->GetSGParent() != NULL)
+       {
+               // the object is a child, adapt its local orientation so that 
+               // the global orientation is aligned as we want.
+               MT_Matrix3x3 invori = GetSGNode()->GetSGParent()->GetWorldOrientation().inverse();
+               NodeSetLocalOrientation(invori*orimat);
+       }
+       else
+               NodeSetLocalOrientation(orimat);
+}
 
 MT_Vector3 KX_GameObject::GetLinearVelocity(bool local)
 {
@@ -723,6 +784,7 @@ void KX_GameObject::Suspend(void)
 
 PyMethodDef KX_GameObject::Methods[] = {
        {"setVisible",(PyCFunction) KX_GameObject::sPySetVisible, METH_VARARGS},  
+       {"alignAxisToVect",(PyCFunction) KX_GameObject::sPyAlignAxisToVect, METH_VARARGS},
        {"setPosition", (PyCFunction) KX_GameObject::sPySetPosition, METH_VARARGS},
        {"getPosition", (PyCFunction) KX_GameObject::sPyGetPosition, METH_VARARGS},
        {"getOrientation", (PyCFunction) KX_GameObject::sPyGetOrientation, METH_VARARGS},
@@ -1255,7 +1317,24 @@ PyObject* KX_GameObject::PySetOrientation(PyObject* self,
        return NULL;
 }
 
-
+PyObject* KX_GameObject::PyAlignAxisToVect(PyObject* self, 
+                                                                                 PyObject* args, 
+                                                                                 PyObject* kwds)
+{
+       PyObject* pyvect;
+       int axis = 2; //z axis is the default
+       
+       if (PyArg_ParseTuple(args,"O|i",&pyvect,&axis))
+       {
+               MT_Vector3 vect;
+               if (PyVecTo(pyvect, vect))
+               {
+                       AlignAxisToVect(vect,axis);                             
+                       Py_Return;
+               }
+       }
+       return NULL;
+}
 
 PyObject* KX_GameObject::PySetPosition(PyObject* self, 
                                                                           PyObject* args, 
index 3758651f53dee8f50609a6f93635b718f50e1f5d..56b9f3f6375f528064cf89828133fc483f605ae4 100644 (file)
@@ -258,6 +258,15 @@ public:
                bool local=false
        );
 
+       /** 
+        * Align the object to a given normal.
+        */
+               void 
+       AlignAxisToVect(
+               const MT_Vector3& vect,
+               int axis = 2 
+       );
+
        /** 
         * Quick'n'dirty obcolor ipo stuff
         */
@@ -662,6 +671,7 @@ public:
        KX_PYMETHOD(KX_GameObject,GetOrientation);
        KX_PYMETHOD(KX_GameObject,SetOrientation);
        KX_PYMETHOD(KX_GameObject,SetVisible);
+       KX_PYMETHOD(KX_GameObject,AlignAxisToVect);
        KX_PYMETHOD(KX_GameObject,SuspendDynamics);
        KX_PYMETHOD(KX_GameObject,RestoreDynamics);
        KX_PYMETHOD(KX_GameObject,EnableRigidBody);
index fbd896a55d13996faff54546bd901c0a1d0c897a..8d29a70438084f82a1fa14f4ff416686dba1f31c 100644 (file)
@@ -51,6 +51,18 @@ class KX_GameObject:
                @type orn: 3x3 rotation matrix, or Quaternion.
                @param orn: a rotation matrix specifying the new rotation.
                """
+       def alignAxisToVect(vect, axis):
+               """
+               Aligns any of the game object's axis along the given vector.
+               
+               @type vect: 3d vector.
+               @param vect: a vector to align the axis.
+               @type axis: integer.
+               @param axis:The axis you want to align
+                                       - 0: X axis
+                                       - 1: Y axis
+                                       - 2: Z axis (default) 
+               """
        def getOrientation():
                """
                Gets the game object's orientation.
@@ -213,4 +225,5 @@ class KX_GameObject:
                @rtype: 3-tuple (L{KX_GameObject}, 3-tuple (x,y,z), 3-tuple (nx,ny,nz))
                @return: (object,hitpoint,hitnormal) or (None,None,None)
                """
-       
\ No newline at end of file
+
+