forked from bartvdbraak/blender
386122ada6
This commit extends the technique of dynamic linked list to the logic system to eliminate as much as possible temporaries, map lookup or full scan. The logic engine is now free of memory allocation, which is an important stability factor. The overhead of the logic system is reduced by a factor between 3 and 6 depending on the logic setup. This is the speed-up you can expect on a logic setup using simple bricks. Heavy bricks like python controllers and ray sensors will still take about the same time to execute so the speed up will be less important. The core of the logic engine has been much reworked but the functionality is still the same except for one thing: the priority system on the execution of controllers. The exact same remark applies to actuators but I'll explain for controllers only: Previously, it was possible, with the "executePriority" attribute to set a controller to run before any other controllers in the game. Other than that, the sequential execution of controllers, as defined in Blender was guaranteed by default. With the new system, the sequential execution of controllers is still guaranteed but only within the controllers of one object. the user can no longer set a controller to run before any other controllers in the game. The "executePriority" attribute controls the execution of controllers within one object. The priority is a small number starting from 0 for the first controller and incrementing for each controller. If this missing feature is a must, a special method can be implemented to set a controller to run before all other controllers. Other improvements: - Systematic use of reference in parameter passing to avoid unnecessary data copy - Use pre increment in iterator instead of post increment to avoid temporary allocation - Use const char* instead of STR_String whenever possible to avoid temporary allocation - Fix reference counting bugs (memory leak) - Fix a crash in certain cases of state switching and object deletion - Minor speed up in property sensor - Removal of objects during the game is a lot faster
654 lines
16 KiB
C++
654 lines
16 KiB
C++
//
|
|
// Replace the mesh for this actuator's parent
|
|
//
|
|
// $Id$
|
|
//
|
|
// ***** BEGIN GPL 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.
|
|
//
|
|
// 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 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"
|
|
|
|
#include "PyObjectPlus.h"
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* 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;
|
|
m_parentobj = 0;
|
|
|
|
if (m_object)
|
|
m_object->RegisterActuator(this);
|
|
|
|
if (gameobj->isA(&KX_GameObject::Type))
|
|
{
|
|
// if the object is vertex parented, don't check parent orientation as the link is broken
|
|
if (!((KX_GameObject*)gameobj)->IsVertexParent()){
|
|
m_parentobj = ((KX_GameObject*)gameobj)->GetParent(); // check if the object is parented
|
|
if (m_parentobj) {
|
|
// if so, store the initial local rotation
|
|
// this is needed to revert the effect of the parent inverse node (TBC)
|
|
m_parentlocalmat = m_parentobj->GetSGNode()->GetLocalOrientation();
|
|
// use registration mechanism rather than AddRef, it creates zombie objects
|
|
m_parentobj->RegisterActuator(this);
|
|
// GetParent did AddRef, undo here
|
|
m_parentobj->Release();
|
|
}
|
|
}
|
|
}
|
|
|
|
} /* 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 Mat3ToEulOld(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;
|
|
|
|
/* angular difference of 360 degrees */
|
|
|
|
dx= eul[0] - oldrot[0];
|
|
dy= eul[1] - oldrot[1];
|
|
dz= eul[2] - oldrot[2];
|
|
|
|
if( fabs(dx) > MT_PI) {
|
|
if(dx > 0.0) eul[0] -= MT_2_PI; else eul[0]+= MT_2_PI;
|
|
}
|
|
if( fabs(dy) > MT_PI) {
|
|
if(dy > 0.0) eul[1] -= MT_2_PI; else eul[1]+= MT_2_PI;
|
|
}
|
|
if( fabs(dz) > MT_PI ) {
|
|
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];
|
|
|
|
Mat3ToEulOld(oldmat, oldeul);
|
|
Mat3ToEulOld(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()
|
|
{
|
|
if (m_object)
|
|
m_object->UnregisterActuator(this);
|
|
if (m_parentobj)
|
|
m_parentobj->UnregisterActuator(this);
|
|
} /* end of destructor */
|
|
|
|
void KX_TrackToActuator::ProcessReplica()
|
|
{
|
|
// the replica is tracking the same object => register it
|
|
if (m_object)
|
|
m_object->RegisterActuator(this);
|
|
if (m_parentobj)
|
|
m_parentobj->RegisterActuator(this);
|
|
SCA_IActuator::ProcessReplica();
|
|
}
|
|
|
|
|
|
bool KX_TrackToActuator::UnlinkObject(SCA_IObject* clientobj)
|
|
{
|
|
if (clientobj == m_object)
|
|
{
|
|
// this object is being deleted, we cannot continue to track it.
|
|
m_object = NULL;
|
|
return true;
|
|
}
|
|
if (clientobj == m_parentobj)
|
|
{
|
|
m_parentobj = NULL;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void KX_TrackToActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
|
|
{
|
|
void **h_obj = (*obj_map)[m_object];
|
|
if (h_obj) {
|
|
if (m_object)
|
|
m_object->UnregisterActuator(this);
|
|
m_object = (SCA_IObject*)(*h_obj);
|
|
m_object->RegisterActuator(this);
|
|
}
|
|
|
|
void **h_parobj = (*obj_map)[m_parentobj];
|
|
if (h_parobj) {
|
|
if (m_parentobj)
|
|
m_parentobj->UnregisterActuator(this);
|
|
m_parentobj= (KX_GameObject*)(*h_parobj);
|
|
m_parentobj->RegisterActuator(this);
|
|
}
|
|
}
|
|
|
|
|
|
bool KX_TrackToActuator::Update(double curtime, bool frame)
|
|
{
|
|
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();
|
|
if (dir.length2())
|
|
dir.normalize();
|
|
MT_Vector3 up(0,0,1);
|
|
|
|
|
|
#ifdef DSADSA
|
|
switch (m_upflag)
|
|
{
|
|
case 0:
|
|
{
|
|
up.setValue(1.0,0,0);
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
up.setValue(0,1.0,0);
|
|
break;
|
|
}
|
|
case 2:
|
|
default:
|
|
{
|
|
up.setValue(0,0,1.0);
|
|
}
|
|
}
|
|
#endif
|
|
if (m_allow3D)
|
|
{
|
|
up = (up - up.dot(dir) * dir).safe_normalized();
|
|
|
|
}
|
|
else
|
|
{
|
|
dir = (dir - up.dot(dir)*up).safe_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.safe_normalized();
|
|
dir = (left.cross(up)).safe_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)).safe_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.safe_normalized();
|
|
up = dir.safe_normalized();
|
|
dir = left;
|
|
left = (dir.cross(up)).safe_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.safe_normalized();
|
|
dir = -(left.cross(up)).safe_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)).safe_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.safe_normalized();
|
|
up = -dir.safe_normalized();
|
|
dir = left;
|
|
left = (dir.cross(up)).safe_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.safe_normalized();
|
|
dir = -(left.cross(up)).safe_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);
|
|
|
|
|
|
if(m_parentobj){ // check if the model is parented and calculate the child transform
|
|
|
|
MT_Point3 localpos;
|
|
localpos = curobj->GetSGNode()->GetLocalPosition();
|
|
// Get the inverse of the parent matrix
|
|
MT_Matrix3x3 parentmatinv;
|
|
parentmatinv = m_parentobj->NodeGetWorldOrientation ().inverse ();
|
|
// transform the local coordinate system into the parents system
|
|
mat = parentmatinv * mat;
|
|
// append the initial parent local rotation matrix
|
|
mat = m_parentlocalmat * mat;
|
|
|
|
// set the models tranformation properties
|
|
curobj->NodeSetLocalOrientation(mat);
|
|
curobj->NodeSetLocalPosition(localpos);
|
|
//curobj->UpdateTransform();
|
|
}
|
|
else
|
|
{
|
|
curobj->NodeSetLocalOrientation(mat);
|
|
}
|
|
|
|
result = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------------------- */
|
|
/* Python functions */
|
|
/* ------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/* Integration hooks ------------------------------------------------------- */
|
|
PyTypeObject KX_TrackToActuator::Type = {
|
|
#if (PY_VERSION_HEX >= 0x02060000)
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
#else
|
|
/* python 2.5 and below */
|
|
PyObject_HEAD_INIT( NULL ) /* required py macro */
|
|
0, /* ob_size */
|
|
#endif
|
|
"KX_TrackToActuator",
|
|
sizeof(PyObjectPlus_Proxy),
|
|
0,
|
|
py_base_dealloc,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
py_base_repr,
|
|
0,0,0,0,0,0,
|
|
py_base_getattro,
|
|
py_base_setattro,
|
|
0,0,0,0,0,0,0,0,0,
|
|
Methods
|
|
};
|
|
|
|
|
|
|
|
PyParentObject KX_TrackToActuator::Parents[] = {
|
|
&KX_TrackToActuator::Type,
|
|
&SCA_IActuator::Type,
|
|
&SCA_ILogicBrick::Type,
|
|
&CValue::Type,
|
|
NULL
|
|
};
|
|
|
|
|
|
|
|
PyMethodDef KX_TrackToActuator::Methods[] = {
|
|
// ---> deprecated
|
|
{"setTime", (PyCFunction) KX_TrackToActuator::sPySetTime, METH_VARARGS, (PY_METHODCHAR)SetTime_doc},
|
|
{"getTime", (PyCFunction) KX_TrackToActuator::sPyGetTime, METH_NOARGS, (PY_METHODCHAR)GetTime_doc},
|
|
{"setUse3D", (PyCFunction) KX_TrackToActuator::sPySetUse3D, METH_VARARGS, (PY_METHODCHAR)SetUse3D_doc},
|
|
{"getUse3D", (PyCFunction) KX_TrackToActuator::sPyGetUse3D, METH_NOARGS, (PY_METHODCHAR)GetUse3D_doc},
|
|
{"setObject", (PyCFunction) KX_TrackToActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
|
|
{"getObject", (PyCFunction) KX_TrackToActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
|
|
|
|
{NULL,NULL} //Sentinel
|
|
};
|
|
|
|
PyAttributeDef KX_TrackToActuator::Attributes[] = {
|
|
KX_PYATTRIBUTE_INT_RW("time",0,1000,true,KX_TrackToActuator,m_time),
|
|
KX_PYATTRIBUTE_BOOL_RW("use3D",KX_TrackToActuator,m_allow3D),
|
|
KX_PYATTRIBUTE_RW_FUNCTION("object", KX_TrackToActuator, pyattr_get_object, pyattr_set_object),
|
|
|
|
{ NULL } //Sentinel
|
|
};
|
|
|
|
PyObject* KX_TrackToActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
|
|
{
|
|
KX_TrackToActuator* actuator = static_cast<KX_TrackToActuator*>(self);
|
|
if (!actuator->m_object)
|
|
Py_RETURN_NONE;
|
|
else
|
|
return actuator->m_object->GetProxy();
|
|
}
|
|
|
|
int KX_TrackToActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
|
|
{
|
|
KX_TrackToActuator* actuator = static_cast<KX_TrackToActuator*>(self);
|
|
KX_GameObject *gameobj;
|
|
|
|
if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_TrackToActuator"))
|
|
return 1; // ConvertPythonToGameObject sets the error
|
|
|
|
if (actuator->m_object != NULL)
|
|
actuator->m_object->UnregisterActuator(actuator);
|
|
|
|
actuator->m_object = (SCA_IObject*) gameobj;
|
|
|
|
if (actuator->m_object)
|
|
actuator->m_object->RegisterActuator(actuator);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
PyObject* KX_TrackToActuator::py_getattro(PyObject *attr)
|
|
{
|
|
py_getattro_up(SCA_IActuator);
|
|
}
|
|
|
|
PyObject* KX_TrackToActuator::py_getattro_dict() {
|
|
py_getattro_dict_up(SCA_IActuator);
|
|
}
|
|
|
|
int KX_TrackToActuator::py_setattro(PyObject *attr, PyObject* value)
|
|
{
|
|
py_setattro_up(SCA_IActuator);
|
|
}
|
|
|
|
/* 1. setObject */
|
|
const char KX_TrackToActuator::SetObject_doc[] =
|
|
"setObject(object)\n"
|
|
"\t- object: KX_GameObject, string or None\n"
|
|
"\tSet the object to track with the parent of this actuator.\n";
|
|
PyObject* KX_TrackToActuator::PySetObject(PyObject* value)
|
|
{
|
|
KX_GameObject *gameobj;
|
|
|
|
ShowDeprecationWarning("setObject()", "the object property");
|
|
|
|
if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.setObject(value): KX_TrackToActuator"))
|
|
return NULL; // ConvertPythonToGameObject sets the error
|
|
|
|
if (m_object != NULL)
|
|
m_object->UnregisterActuator(this);
|
|
|
|
m_object = (SCA_IObject*)gameobj;
|
|
if (m_object)
|
|
m_object->RegisterActuator(this);
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
|
|
/* 2. getObject */
|
|
const char KX_TrackToActuator::GetObject_doc[] =
|
|
"getObject(name_only = 1)\n"
|
|
"name_only - optional arg, when true will return the KX_GameObject rather then its name\n"
|
|
"\tReturns the object to track with the parent of this actuator\n";
|
|
PyObject* KX_TrackToActuator::PyGetObject(PyObject* args)
|
|
{
|
|
int ret_name_only = 1;
|
|
|
|
ShowDeprecationWarning("getObject()", "the object property");
|
|
|
|
if (!PyArg_ParseTuple(args, "|i:getObject", &ret_name_only))
|
|
return NULL;
|
|
|
|
if (!m_object)
|
|
Py_RETURN_NONE;
|
|
|
|
if (ret_name_only)
|
|
return PyString_FromString(m_object->GetName());
|
|
else
|
|
return m_object->GetProxy();
|
|
}
|
|
|
|
|
|
|
|
/* 3. setTime */
|
|
const 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* args)
|
|
{
|
|
ShowDeprecationWarning("setTime()", "the timer property");
|
|
int timeArg;
|
|
|
|
if (!PyArg_ParseTuple(args, "i:setTime", &timeArg))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
m_time= timeArg;
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
|
|
/* 4.getTime */
|
|
const 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()
|
|
{
|
|
ShowDeprecationWarning("getTime()", "the timer property");
|
|
return PyInt_FromLong(m_time);
|
|
}
|
|
|
|
|
|
|
|
/* 5. getUse3D */
|
|
const 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()
|
|
{
|
|
ShowDeprecationWarning("setTime()", "the use3D property");
|
|
return PyInt_FromLong(!(m_allow3D == 0));
|
|
}
|
|
|
|
|
|
|
|
/* 6. setUse3D */
|
|
const 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* args)
|
|
{
|
|
ShowDeprecationWarning("setTime()", "the use3D property");
|
|
int boolArg;
|
|
|
|
if (!PyArg_ParseTuple(args, "i:setUse3D", &boolArg)) {
|
|
return NULL;
|
|
}
|
|
|
|
m_allow3D = !(boolArg == 0);
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
/* eof */
|