Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Ketsji/KX_TrackToActuator.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_TrackToActuator.cpp487
1 files changed, 487 insertions, 0 deletions
diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.cpp b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
new file mode 100644
index 00000000000..647ffb447aa
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_TrackToActuator.cpp
@@ -0,0 +1,487 @@
+//
+// Replace the mesh for this actuator's parent
+//
+// $Id$
+//
+// ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version. The Blender
+// Foundation also sells licenses for use in proprietary software under
+// the Blender License. See http://www.blender.org/BL/ for information
+// about this.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+// All rights reserved.
+//
+// The Original Code is: all of this file.
+//
+// Contributor(s): none yet.
+//
+// ***** END GPL/BL DUAL LICENSE BLOCK *****
+
+// todo: not all trackflags / upflags are implemented/tested !
+// m_trackflag is used to determine the forward tracking direction
+// m_upflag for the up direction
+// normal situation is +y for forward, +z for up
+
+#include "MT_Scalar.h"
+#include "SCA_IActuator.h"
+#include "KX_TrackToActuator.h"
+#include "SCA_IScene.h"
+#include "SCA_LogicManager.h"
+#include <math.h>
+#include <iostream>
+#include "KX_GameObject.h"
+
+
+/* ------------------------------------------------------------------------- */
+/* Native functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+KX_TrackToActuator::KX_TrackToActuator(SCA_IObject *gameobj,
+ SCA_IObject *ob,
+ int time,
+ bool allow3D,
+ int trackflag,
+ int upflag,
+ PyTypeObject* T)
+ :
+ SCA_IActuator(gameobj, T)
+{
+ m_time = time;
+ m_allow3D = allow3D;
+ m_object = ob;
+ m_trackflag = trackflag;
+ m_upflag = upflag;
+} /* End of constructor */
+
+
+
+/* old function from Blender */
+MT_Matrix3x3 EulToMat3(float *eul)
+{
+ MT_Matrix3x3 mat;
+ float ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
+
+ ci = cos(eul[0]);
+ cj = cos(eul[1]);
+ ch = cos(eul[2]);
+ si = sin(eul[0]);
+ sj = sin(eul[1]);
+ sh = sin(eul[2]);
+ cc = ci*ch;
+ cs = ci*sh;
+ sc = si*ch;
+ ss = si*sh;
+
+ mat[0][0] = cj*ch;
+ mat[1][0] = sj*sc-cs;
+ mat[2][0] = sj*cc+ss;
+ mat[0][1] = cj*sh;
+ mat[1][1] = sj*ss+cc;
+ mat[2][1] = sj*cs-sc;
+ mat[0][2] = -sj;
+ mat[1][2] = cj*si;
+ mat[2][2] = cj*ci;
+
+ return mat;
+}
+
+
+
+/* old function from Blender */
+void Mat3ToEul(MT_Matrix3x3 mat, float *eul)
+{
+ MT_Scalar cy;
+
+ cy = sqrt(mat[0][0]*mat[0][0] + mat[0][1]*mat[0][1]);
+
+ if (cy > 16.0*FLT_EPSILON) {
+ eul[0] = atan2(mat[1][2], mat[2][2]);
+ eul[1] = atan2(-mat[0][2], cy);
+ eul[2] = atan2(mat[0][1], mat[0][0]);
+ } else {
+ eul[0] = atan2(-mat[2][1], mat[1][1]);
+ eul[1] = atan2(-mat[0][2], cy);
+ eul[2] = 0.0;
+ }
+}
+
+
+
+/* old function from Blender */
+void compatible_eulFast(float *eul, float *oldrot)
+{
+ float dx, dy, dz;
+
+ /* verschillen van ong 360 graden corrigeren */
+
+ dx= eul[0] - oldrot[0];
+ dy= eul[1] - oldrot[1];
+ dz= eul[2] - oldrot[2];
+
+ if( fabs(dx) > 5.1) {
+ if(dx > 0.0) eul[0] -= MT_2_PI; else eul[0]+= MT_2_PI;
+ }
+ if( fabs(dy) > 5.1) {
+ if(dy > 0.0) eul[1] -= MT_2_PI; else eul[1]+= MT_2_PI;
+ }
+ if( fabs(dz) > 5.1 ) {
+ if(dz > 0.0) eul[2] -= MT_2_PI; else eul[2]+= MT_2_PI;
+ }
+}
+
+
+
+MT_Matrix3x3 matrix3x3_interpol(MT_Matrix3x3 oldmat, MT_Matrix3x3 mat, int m_time)
+{
+ float eul[3], oldeul[3];
+
+ Mat3ToEul(oldmat, oldeul);
+ Mat3ToEul(mat, eul);
+ compatible_eulFast(eul, oldeul);
+
+ eul[0]= (m_time*oldeul[0] + eul[0])/(1.0+m_time);
+ eul[1]= (m_time*oldeul[1] + eul[1])/(1.0+m_time);
+ eul[2]= (m_time*oldeul[2] + eul[2])/(1.0+m_time);
+
+ return EulToMat3(eul);
+}
+
+
+
+KX_TrackToActuator::~KX_TrackToActuator()
+{
+ // there's nothing to be done here, really....
+} /* end of destructor */
+
+
+
+bool KX_TrackToActuator::Update(double curtime,double deltatime)
+{
+ bool result = false;
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ {
+ // do nothing on negative events
+ }
+ else if (m_object)
+ {
+ KX_GameObject* curobj = (KX_GameObject*) GetParent();
+ MT_Vector3 dir = ((KX_GameObject*)m_object)->NodeGetWorldPosition() - curobj->NodeGetWorldPosition();
+ dir.normalize();
+ MT_Vector3 up(0,0,1);
+
+
+#ifdef DSADSA
+ switch (m_upflag)
+ {
+ case 0:
+ {
+ up = MT_Vector3(1.0,0,0);
+ break;
+ }
+ case 1:
+ {
+ up = MT_Vector3(0,1.0,0);
+ break;
+ }
+ case 2:
+ default:
+ {
+ up = MT_Vector3(0,0,1.0);
+ }
+ }
+#endif
+ if (m_allow3D)
+ {
+ up = (up - up.dot(dir) * dir).normalized();
+
+ }
+ else
+ {
+ dir = (dir - up.dot(dir)*up).normalized();
+ }
+
+ MT_Vector3 left;
+ MT_Matrix3x3 mat;
+
+ switch (m_trackflag)
+ {
+ case 0: // TRACK X
+ {
+ // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = dir.normalized();
+ dir = (left.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+
+ break;
+ };
+ case 1: // TRACK Y
+ {
+ // (0.0 , 1.0 , 0.0 ) y direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = (dir.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+
+ break;
+ }
+
+ case 2: // track Z
+ {
+ left = up.normalized();
+ up = dir.normalized();
+ dir = left;
+ left = (dir.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+ break;
+ }
+
+ case 3: // TRACK -X
+ {
+ // (1.0 , 0.0 , 0.0 ) x direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = -dir.normalized();
+ dir = -(left.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+
+ break;
+ };
+ case 4: // TRACK -Y
+ {
+ // (0.0 , -1.0 , 0.0 ) -y direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = (-dir.cross(up)).normalized();
+ mat.setValue (
+ left[0], -dir[0],up[0],
+ left[1], -dir[1],up[1],
+ left[2], -dir[2],up[2]
+ );
+ break;
+ }
+ case 5: // track -Z
+ {
+ left = up.normalized();
+ up = -dir.normalized();
+ dir = left;
+ left = (dir.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+
+ break;
+ }
+
+ default:
+ {
+ // (1.0 , 0.0 , 0.0 ) -x direction is forward, z (0.0 , 0.0 , 1.0 ) up
+ left = -dir.normalized();
+ dir = -(left.cross(up)).normalized();
+ mat.setValue (
+ left[0], dir[0],up[0],
+ left[1], dir[1],up[1],
+ left[2], dir[2],up[2]
+ );
+ }
+ }
+
+ MT_Matrix3x3 oldmat;
+ oldmat= curobj->NodeGetWorldOrientation();
+
+ /* erwin should rewrite this! */
+ mat= matrix3x3_interpol(oldmat, mat, m_time);
+
+ curobj->NodeSetLocalOrientation(mat);
+
+ //cout << "\n TrackTo!";
+ result = true;
+ }
+
+ return result;
+}
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_TrackToActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_TrackToActuator",
+ sizeof(KX_TrackToActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+
+
+PyParentObject KX_TrackToActuator::Parents[] = {
+ &KX_TrackToActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+PyMethodDef KX_TrackToActuator::Methods[] = {
+ {"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_VARARGS, SetObject_doc},
+ {"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, GetObject_doc},
+ {"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, SetTime_doc},
+ {"getTime", (PyCFunction) KX_TrackToActuator::sPyGetTime, METH_VARARGS, GetTime_doc},
+ {"setUse3D", (PyCFunction) KX_TrackToActuator::sPySetUse3D, METH_VARARGS, SetUse3D_doc},
+ {"getUse3D", (PyCFunction) KX_TrackToActuator::sPyGetUse3D, METH_VARARGS, GetUse3D_doc},
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* KX_TrackToActuator::_getattr(char* attr)
+{
+ _getattr_up(SCA_IActuator);
+}
+
+
+
+/* 1. setObject */
+char KX_TrackToActuator::SetObject_doc[] =
+"setObject(object)\n"
+"\t- object: string\n"
+"\tSet the object to track with the parent of this actuator.\n";
+PyObject* KX_TrackToActuator::PySetObject(PyObject* self, PyObject* args, PyObject* kwds) {
+ char* nameArg;
+
+ if (!PyArg_ParseTuple(args, "s", &nameArg)) {
+ return NULL;
+ }
+ CValue* gameobj = SCA_ILogicBrick::m_sCurrentLogicManager->GetGameObjectByName(STR_String(nameArg));
+
+ m_object= (SCA_IObject*)gameobj;
+
+ Py_Return;
+}
+
+
+
+/* 2. getObject */
+char KX_TrackToActuator::GetObject_doc[] =
+"getObject()\n"
+"\tReturns the object to track with the parent of this actuator.\n";
+PyObject* KX_TrackToActuator::PyGetObject(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyString_FromString(m_object->GetName());
+}
+
+
+
+/* 3. setTime */
+char KX_TrackToActuator::SetTime_doc[] =
+"setTime(time)\n"
+"\t- time: integer\n"
+"\tSet the time in frames with which to delay the tracking motion.\n";
+PyObject* KX_TrackToActuator::PySetTime(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int timeArg;
+
+ if (!PyArg_ParseTuple(args, "i", &timeArg))
+ {
+ return NULL;
+ }
+
+ m_time= timeArg;
+
+ Py_Return;
+}
+
+
+
+/* 4.getTime */
+char KX_TrackToActuator::GetTime_doc[] =
+"getTime()\n"
+"\t- time: integer\n"
+"\tReturn the time in frames with which the tracking motion is delayed.\n";
+PyObject* KX_TrackToActuator::PyGetTime(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(m_time);
+}
+
+
+
+/* 5. getUse3D */
+char KX_TrackToActuator::GetUse3D_doc[] =
+"getUse3D()\n"
+"\tReturns 1 if the motion is allowed to extend in the z-direction.\n";
+PyObject* KX_TrackToActuator::PyGetUse3D(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ return PyInt_FromLong(!(m_allow3D == 0));
+}
+
+
+
+/* 6. setUse3D */
+char KX_TrackToActuator::SetUse3D_doc[] =
+"setUse3D(value)\n"
+"\t- value: 0 or 1\n"
+"\tSet to 1 to allow the tracking motion to extend in the z-direction,\n"
+"\tset to 0 to lock the tracking motion to the x-y plane.\n";
+PyObject* KX_TrackToActuator::PySetUse3D(PyObject* self, PyObject* args, PyObject* kwds)
+{
+ int boolArg;
+
+ if (!PyArg_ParseTuple(args, "i", &boolArg)) {
+ return NULL;
+ }
+
+ m_allow3D = !(boolArg == 0);
+
+ Py_Return;
+}
+
+/* eof */