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_ConstraintActuator.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_ConstraintActuator.cpp629
1 files changed, 0 insertions, 629 deletions
diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp b/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
deleted file mode 100644
index a1ccd9f8bf8..00000000000
--- a/source/gameengine/Ketsji/KX_ConstraintActuator.cpp
+++ /dev/null
@@ -1,629 +0,0 @@
-/*
- * Apply a constraint to a position or rotation value
- *
- *
- * ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 *****
- */
-
-/** \file gameengine/Ketsji/KX_ConstraintActuator.cpp
- * \ingroup ketsji
- */
-
-
-#include "SCA_IActuator.h"
-#include "KX_ConstraintActuator.h"
-#include "SCA_IObject.h"
-#include "MT_Point3.h"
-#include "MT_Matrix3x3.h"
-#include "KX_GameObject.h"
-#include "KX_RayCast.h"
-#include "KX_PythonInit.h" // KX_GetActiveScene
-#include "RAS_MeshObject.h"
-
-#include <stdio.h>
-
-/* ------------------------------------------------------------------------- */
-/* Native functions */
-/* ------------------------------------------------------------------------- */
-
-KX_ConstraintActuator::KX_ConstraintActuator(SCA_IObject *gameobj,
- int posDampTime,
- int rotDampTime,
- float minBound,
- float maxBound,
- float refDir[3],
- int locrotxyz,
- int time,
- int option,
- char *property) :
- SCA_IActuator(gameobj, KX_ACT_CONSTRAINT),
- m_refDirVector(refDir),
- m_currentTime(0)
-{
- m_refDirection[0] = refDir[0];
- m_refDirection[1] = refDir[1];
- m_refDirection[2] = refDir[2];
- m_posDampTime = posDampTime;
- m_rotDampTime = rotDampTime;
- m_locrot = locrotxyz;
- m_option = option;
- m_activeTime = time;
- if (property) {
- m_property = property;
- } else {
- m_property = "";
- }
- /* The units of bounds are determined by the type of constraint. To */
- /* make the constraint application easier and more transparent later on, */
- /* I think converting the bounds to the applicable domain makes more */
- /* sense. */
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_ORIX:
- case KX_ACT_CONSTRAINT_ORIY:
- case KX_ACT_CONSTRAINT_ORIZ:
- {
- MT_Scalar len = m_refDirVector.length();
- if (MT_fuzzyZero(len)) {
- // missing a valid direction
- std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no valid reference direction!" << std::endl;
- m_locrot = KX_ACT_CONSTRAINT_NODEF;
- } else {
- m_refDirection[0] /= len;
- m_refDirection[1] /= len;
- m_refDirection[2] /= len;
- m_refDirVector /= len;
- }
- m_minimumBound = cosf(minBound);
- m_maximumBound = cosf(maxBound);
- m_minimumSine = sinf(minBound);
- m_maximumSine = sinf(maxBound);
- }
- break;
- default:
- m_minimumBound = minBound;
- m_maximumBound = maxBound;
- m_minimumSine = 0.f;
- m_maximumSine = 0.f;
- break;
- }
-
-} /* End of constructor */
-
-KX_ConstraintActuator::~KX_ConstraintActuator()
-{
- // there's nothing to be done here, really....
-} /* end of destructor */
-
-bool KX_ConstraintActuator::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, void *UNUSED(data))
-{
-
- m_hitObject = client->m_gameobject;
-
- bool bFound = false;
-
- if (m_property.IsEmpty())
- {
- bFound = true;
- }
- else
- {
- if (m_option & KX_ACT_CONSTRAINT_MATERIAL) {
- for (unsigned int i = 0; i < m_hitObject->GetMeshCount(); ++i) {
- RAS_MeshObject *meshObj = m_hitObject->GetMesh(i);
- for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) {
- bFound = strcmp(m_property.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0;
- if (bFound)
- break;
- }
- }
- }
- else {
- bFound = m_hitObject->GetProperty(m_property) != NULL;
- }
- }
- // update the hit status
- result->m_hitFound = bFound;
- // stop looking
- return true;
-}
-
-/* This function is used to pre-filter the object before casting the ray on them.
- * This is useful for "X-Ray" option when we want to see "through" unwanted object.
- */
-bool KX_ConstraintActuator::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data))
-{
- if (client->m_type > KX_ClientObjectInfo::ACTOR)
- {
- // Unknown type of object, skip it.
- // Should not occur as the sensor objects are filtered in RayTest()
- printf("Invalid client type %d found in ray casting\n", client->m_type);
- return false;
- }
- // no X-Ray function yet
- return true;
-}
-
-bool KX_ConstraintActuator::Update(double curtime, bool frame)
-{
-
- bool result = false;
- bool bNegativeEvent = IsNegativeEvent();
- RemoveAllEvents();
-
- if (!bNegativeEvent) {
- /* Constraint clamps the values to the specified range, with a sort of */
- /* low-pass filtered time response, if the damp time is unequal to 0. */
-
- /* Having to retrieve location/rotation and setting it afterwards may not */
- /* be efficient enough... Something to look at later. */
- KX_GameObject *obj = (KX_GameObject*) GetParent();
- MT_Point3 position = obj->NodeGetWorldPosition();
- MT_Point3 newposition;
- MT_Vector3 normal, direction, refDirection;
- MT_Matrix3x3 rotation = obj->NodeGetWorldOrientation();
- MT_Scalar filter, newdistance, cosangle;
- int axis, sign;
-
- if (m_posDampTime) {
- filter = m_posDampTime/(1.0f+m_posDampTime);
- } else {
- filter = 0.0f;
- }
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_ORIX:
- case KX_ACT_CONSTRAINT_ORIY:
- case KX_ACT_CONSTRAINT_ORIZ:
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_ORIX:
- direction[0] = rotation[0][0];
- direction[1] = rotation[1][0];
- direction[2] = rotation[2][0];
- axis = 0;
- break;
- case KX_ACT_CONSTRAINT_ORIY:
- direction[0] = rotation[0][1];
- direction[1] = rotation[1][1];
- direction[2] = rotation[2][1];
- axis = 1;
- break;
- default:
- direction[0] = rotation[0][2];
- direction[1] = rotation[1][2];
- direction[2] = rotation[2][2];
- axis = 2;
- break;
- }
- if ((m_maximumBound < (1.0f-FLT_EPSILON)) || (m_minimumBound < (1.0f-FLT_EPSILON))) {
- // reference direction needs to be evaluated
- // 1. get the cosine between current direction and target
- cosangle = direction.dot(m_refDirVector);
- if (cosangle >= (m_maximumBound-FLT_EPSILON) && cosangle <= (m_minimumBound+FLT_EPSILON)) {
- // no change to do
- result = true;
- goto CHECK_TIME;
- }
- // 2. define a new reference direction
- // compute local axis with reference direction as X and
- // Y in direction X refDirection plane
- MT_Vector3 zaxis = m_refDirVector.cross(direction);
- if (MT_fuzzyZero2(zaxis.length2())) {
- // direction and refDirection are identical,
- // choose any other direction to define plane
- if (direction[0] < 0.9999f)
- zaxis = m_refDirVector.cross(MT_Vector3(1.0f,0.0f,0.0f));
- else
- zaxis = m_refDirVector.cross(MT_Vector3(0.0f,1.0f,0.0f));
- }
- MT_Vector3 yaxis = zaxis.cross(m_refDirVector);
- yaxis.normalize();
- if (cosangle > m_minimumBound) {
- // angle is too close to reference direction,
- // choose a new reference that is exactly at minimum angle
- refDirection = m_minimumBound * m_refDirVector + m_minimumSine * yaxis;
- } else {
- // angle is too large, choose new reference direction at maximum angle
- refDirection = m_maximumBound * m_refDirVector + m_maximumSine * yaxis;
- }
- } else {
- refDirection = m_refDirVector;
- }
- // apply damping on the direction
- direction = filter*direction + (1.0f-filter)*refDirection;
- obj->AlignAxisToVect(direction, axis);
- result = true;
- goto CHECK_TIME;
- case KX_ACT_CONSTRAINT_DIRPX:
- case KX_ACT_CONSTRAINT_DIRPY:
- case KX_ACT_CONSTRAINT_DIRPZ:
- case KX_ACT_CONSTRAINT_DIRNX:
- case KX_ACT_CONSTRAINT_DIRNY:
- case KX_ACT_CONSTRAINT_DIRNZ:
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_DIRPX:
- normal[0] = rotation[0][0];
- normal[1] = rotation[1][0];
- normal[2] = rotation[2][0];
- axis = 0; // axis according to KX_GameObject::AlignAxisToVect()
- sign = 0; // X axis will be parrallel to direction of ray
- break;
- case KX_ACT_CONSTRAINT_DIRPY:
- normal[0] = rotation[0][1];
- normal[1] = rotation[1][1];
- normal[2] = rotation[2][1];
- axis = 1;
- sign = 0;
- break;
- case KX_ACT_CONSTRAINT_DIRPZ:
- normal[0] = rotation[0][2];
- normal[1] = rotation[1][2];
- normal[2] = rotation[2][2];
- axis = 2;
- sign = 0;
- break;
- case KX_ACT_CONSTRAINT_DIRNX:
- normal[0] = -rotation[0][0];
- normal[1] = -rotation[1][0];
- normal[2] = -rotation[2][0];
- axis = 0;
- sign = 1;
- break;
- case KX_ACT_CONSTRAINT_DIRNY:
- normal[0] = -rotation[0][1];
- normal[1] = -rotation[1][1];
- normal[2] = -rotation[2][1];
- axis = 1;
- sign = 1;
- break;
- case KX_ACT_CONSTRAINT_DIRNZ:
- normal[0] = -rotation[0][2];
- normal[1] = -rotation[1][2];
- normal[2] = -rotation[2][2];
- axis = 2;
- sign = 1;
- break;
- }
- normal.normalize();
- if (m_option & KX_ACT_CONSTRAINT_LOCAL) {
- // direction of the ray is along the local axis
- direction = normal;
- } else {
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_DIRPX:
- direction = MT_Vector3(1.0f,0.0f,0.0f);
- break;
- case KX_ACT_CONSTRAINT_DIRPY:
- direction = MT_Vector3(0.0f,1.0f,0.0f);
- break;
- case KX_ACT_CONSTRAINT_DIRPZ:
- direction = MT_Vector3(0.0f,0.0f,1.0f);
- break;
- case KX_ACT_CONSTRAINT_DIRNX:
- direction = MT_Vector3(-1.0f,0.0f,0.0f);
- break;
- case KX_ACT_CONSTRAINT_DIRNY:
- direction = MT_Vector3(0.0f,-1.0f,0.0f);
- break;
- case KX_ACT_CONSTRAINT_DIRNZ:
- direction = MT_Vector3(0.0f,0.0f,-1.0f);
- break;
- }
- }
- {
- MT_Point3 topoint = position + (m_maximumBound) * direction;
- PHY_IPhysicsEnvironment* pe = KX_GetActiveScene()->GetPhysicsEnvironment();
- PHY_IPhysicsController *spc = obj->GetPhysicsController();
-
- if (!pe) {
- std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no physics environment!" << std::endl;
- goto CHECK_TIME;
- }
- if (!spc) {
- // the object is not physical, we probably want to avoid hitting its own parent
- KX_GameObject *parent = obj->GetParent();
- if (parent) {
- spc = parent->GetPhysicsController();
- }
- }
- KX_RayCast::Callback<KX_ConstraintActuator, void> callback(this,dynamic_cast<PHY_IPhysicsController*>(spc));
- result = KX_RayCast::RayTest(pe, position, topoint, callback);
- if (result) {
- MT_Vector3 newnormal = callback.m_hitNormal;
- // compute new position & orientation
- if ((m_option & (KX_ACT_CONSTRAINT_NORMAL|KX_ACT_CONSTRAINT_DISTANCE)) == 0) {
- // if none option is set, the actuator does nothing but detect ray
- // (works like a sensor)
- goto CHECK_TIME;
- }
- if (m_option & KX_ACT_CONSTRAINT_NORMAL) {
- MT_Scalar rotFilter;
- // apply damping on the direction
- if (m_rotDampTime) {
- rotFilter = m_rotDampTime/(1.0f+m_rotDampTime);
- } else {
- rotFilter = filter;
- }
- newnormal = rotFilter*normal - (1.0f-rotFilter)*newnormal;
- obj->AlignAxisToVect((sign)?-newnormal:newnormal, axis);
- if (m_option & KX_ACT_CONSTRAINT_LOCAL) {
- direction = newnormal;
- direction.normalize();
- }
- }
- if (m_option & KX_ACT_CONSTRAINT_DISTANCE) {
- if (m_posDampTime) {
- newdistance = filter*(position-callback.m_hitPoint).length()+(1.0f-filter)*m_minimumBound;
- } else {
- newdistance = m_minimumBound;
- }
- // logically we should cancel the speed along the ray direction as we set the
- // position along that axis
- spc = obj->GetPhysicsController();
- if (spc && spc->IsDynamic()) {
- MT_Vector3 linV = spc->GetLinearVelocity();
- // cancel the projection along the ray direction
- MT_Scalar fallspeed = linV.dot(direction);
- if (!MT_fuzzyZero(fallspeed))
- spc->SetLinearVelocity(linV-fallspeed*direction,false);
- }
- } else {
- newdistance = (position-callback.m_hitPoint).length();
- }
- newposition = callback.m_hitPoint-newdistance*direction;
- } else if (m_option & KX_ACT_CONSTRAINT_PERMANENT) {
- // no contact but still keep running
- result = true;
- goto CHECK_TIME;
- }
- }
- break;
- case KX_ACT_CONSTRAINT_FHPX:
- case KX_ACT_CONSTRAINT_FHPY:
- case KX_ACT_CONSTRAINT_FHPZ:
- case KX_ACT_CONSTRAINT_FHNX:
- case KX_ACT_CONSTRAINT_FHNY:
- case KX_ACT_CONSTRAINT_FHNZ:
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_FHPX:
- normal[0] = -rotation[0][0];
- normal[1] = -rotation[1][0];
- normal[2] = -rotation[2][0];
- direction = MT_Vector3(1.0f,0.0f,0.0f);
- break;
- case KX_ACT_CONSTRAINT_FHPY:
- normal[0] = -rotation[0][1];
- normal[1] = -rotation[1][1];
- normal[2] = -rotation[2][1];
- direction = MT_Vector3(0.0f,1.0f,0.0f);
- break;
- case KX_ACT_CONSTRAINT_FHPZ:
- normal[0] = -rotation[0][2];
- normal[1] = -rotation[1][2];
- normal[2] = -rotation[2][2];
- direction = MT_Vector3(0.0f,0.0f,1.0f);
- break;
- case KX_ACT_CONSTRAINT_FHNX:
- normal[0] = rotation[0][0];
- normal[1] = rotation[1][0];
- normal[2] = rotation[2][0];
- direction = MT_Vector3(-1.0f,0.0f,0.0f);
- break;
- case KX_ACT_CONSTRAINT_FHNY:
- normal[0] = rotation[0][1];
- normal[1] = rotation[1][1];
- normal[2] = rotation[2][1];
- direction = MT_Vector3(0.0f,-1.0f,0.0f);
- break;
- case KX_ACT_CONSTRAINT_FHNZ:
- normal[0] = rotation[0][2];
- normal[1] = rotation[1][2];
- normal[2] = rotation[2][2];
- direction = MT_Vector3(0.0f,0.0f,-1.0f);
- break;
- }
- normal.normalize();
- {
- PHY_IPhysicsEnvironment* pe = KX_GetActiveScene()->GetPhysicsEnvironment();
- PHY_IPhysicsController *spc = obj->GetPhysicsController();
-
- if (!pe) {
- std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no physics environment!" << std::endl;
- goto CHECK_TIME;
- }
- if (!spc || !spc->IsDynamic()) {
- // the object is not dynamic, it won't support setting speed
- goto CHECK_TIME;
- }
- m_hitObject = NULL;
- // distance of Fh area is stored in m_minimum
- MT_Point3 topoint = position + (m_minimumBound+spc->GetRadius()) * direction;
- KX_RayCast::Callback<KX_ConstraintActuator, void> callback(this, spc);
- result = KX_RayCast::RayTest(pe, position, topoint, callback);
- // we expect a hit object
- if (!m_hitObject)
- result = false;
- if (result)
- {
- MT_Vector3 newnormal = callback.m_hitNormal;
- // compute new position & orientation
- MT_Scalar distance = (callback.m_hitPoint-position).length()-spc->GetRadius();
- // estimate the velocity of the hit point
- MT_Point3 relativeHitPoint;
- relativeHitPoint = (callback.m_hitPoint-m_hitObject->NodeGetWorldPosition());
- MT_Vector3 velocityHitPoint = m_hitObject->GetVelocity(relativeHitPoint);
- MT_Vector3 relativeVelocity = spc->GetLinearVelocity() - velocityHitPoint;
- MT_Scalar relativeVelocityRay = direction.dot(relativeVelocity);
- MT_Scalar springExtent = 1.0f - distance/m_minimumBound;
- // Fh force is stored in m_maximum
- MT_Scalar springForce = springExtent * m_maximumBound;
- // damping is stored in m_refDirection [0] = damping, [1] = rot damping
- MT_Scalar springDamp = relativeVelocityRay * m_refDirVector[0];
- MT_Vector3 newVelocity = spc->GetLinearVelocity()-(springForce+springDamp)*direction;
- if (m_option & KX_ACT_CONSTRAINT_NORMAL)
- {
- newVelocity+=(springForce+springDamp)*(newnormal-newnormal.dot(direction)*direction);
- }
- spc->SetLinearVelocity(newVelocity, false);
- if (m_option & KX_ACT_CONSTRAINT_DOROTFH)
- {
- MT_Vector3 angSpring = (normal.cross(newnormal))*m_maximumBound;
- MT_Vector3 angVelocity = spc->GetAngularVelocity();
- // remove component that is parallel to normal
- angVelocity -= angVelocity.dot(newnormal)*newnormal;
- MT_Vector3 angDamp = angVelocity * ((m_refDirVector[1]>MT_EPSILON)?m_refDirVector[1]:m_refDirVector[0]);
- spc->SetAngularVelocity(spc->GetAngularVelocity()+(angSpring-angDamp), false);
- }
- } else if (m_option & KX_ACT_CONSTRAINT_PERMANENT) {
- // no contact but still keep running
- result = true;
- }
- // don't set the position with this constraint
- goto CHECK_TIME;
- }
- break;
- case KX_ACT_CONSTRAINT_LOCX:
- case KX_ACT_CONSTRAINT_LOCY:
- case KX_ACT_CONSTRAINT_LOCZ:
- newposition = position = obj->GetSGNode()->GetLocalPosition();
- switch (m_locrot) {
- case KX_ACT_CONSTRAINT_LOCX:
- Clamp(newposition[0], m_minimumBound, m_maximumBound);
- break;
- case KX_ACT_CONSTRAINT_LOCY:
- Clamp(newposition[1], m_minimumBound, m_maximumBound);
- break;
- case KX_ACT_CONSTRAINT_LOCZ:
- Clamp(newposition[2], m_minimumBound, m_maximumBound);
- break;
- }
- result = true;
- if (m_posDampTime) {
- newposition = filter*position + (1.0f-filter)*newposition;
- }
- obj->NodeSetLocalPosition(newposition);
- goto CHECK_TIME;
- }
- if (result) {
- // set the new position but take into account parent if any
- obj->NodeSetWorldPosition(newposition);
- }
- CHECK_TIME:
- if (result && m_activeTime > 0 ) {
- if (++m_currentTime >= m_activeTime)
- result = false;
- }
- }
- if (!result) {
- m_currentTime = 0;
- }
- return result;
-} /* end of KX_ConstraintActuator::Update(double curtime,double deltatime) */
-
-void KX_ConstraintActuator::Clamp(MT_Scalar &var,
- float min,
- float max) {
- if (var < min) {
- var = min;
- } else if (var > max) {
- var = max;
- }
-}
-
-
-bool KX_ConstraintActuator::IsValidMode(KX_ConstraintActuator::KX_CONSTRAINTTYPE m)
-{
- bool res = false;
-
- if ( (m > KX_ACT_CONSTRAINT_NODEF) && (m < KX_ACT_CONSTRAINT_MAX)) {
- res = true;
- }
-
- return res;
-}
-
-#ifdef WITH_PYTHON
-
-/* ------------------------------------------------------------------------- */
-/* Python functions */
-/* ------------------------------------------------------------------------- */
-
-/* Integration hooks ------------------------------------------------------- */
-PyTypeObject KX_ConstraintActuator::Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "KX_ConstraintActuator",
- sizeof(PyObjectPlus_Proxy),
- 0,
- py_base_dealloc,
- 0,
- 0,
- 0,
- 0,
- py_base_repr,
- 0,0,0,0,0,0,0,0,0,
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- 0,0,0,0,0,0,0,
- Methods,
- 0,
- 0,
- &SCA_IActuator::Type,
- 0,0,0,0,0,0,
- py_base_new
-};
-
-PyMethodDef KX_ConstraintActuator::Methods[] = {
- {NULL,NULL} //Sentinel
-};
-
-PyAttributeDef KX_ConstraintActuator::Attributes[] = {
- KX_PYATTRIBUTE_INT_RW("damp",0,100,true,KX_ConstraintActuator,m_posDampTime),
- KX_PYATTRIBUTE_INT_RW("rotDamp",0,100,true,KX_ConstraintActuator,m_rotDampTime),
- KX_PYATTRIBUTE_FLOAT_ARRAY_RW_CHECK("direction",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_refDirection,3,pyattr_check_direction),
- KX_PYATTRIBUTE_INT_RW("option",0,0xFFFF,false,KX_ConstraintActuator,m_option),
- KX_PYATTRIBUTE_INT_RW("time",0,1000,true,KX_ConstraintActuator,m_activeTime),
- KX_PYATTRIBUTE_STRING_RW("propName",0,MAX_PROP_NAME,true,KX_ConstraintActuator,m_property),
- KX_PYATTRIBUTE_FLOAT_RW("min",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_minimumBound),
- KX_PYATTRIBUTE_FLOAT_RW("distance",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_minimumBound),
- KX_PYATTRIBUTE_FLOAT_RW("max",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_maximumBound),
- KX_PYATTRIBUTE_FLOAT_RW("rayLength",0,2000.f,KX_ConstraintActuator,m_maximumBound),
- KX_PYATTRIBUTE_INT_RW("limit",KX_ConstraintActuator::KX_ACT_CONSTRAINT_NODEF+1,KX_ConstraintActuator::KX_ACT_CONSTRAINT_MAX-1,false,KX_ConstraintActuator,m_locrot),
- { NULL } //Sentinel
-};
-
-int KX_ConstraintActuator::pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
-{
- KX_ConstraintActuator* act = static_cast<KX_ConstraintActuator*>(self);
- MT_Vector3 dir(act->m_refDirection);
- MT_Scalar len = dir.length();
- if (MT_fuzzyZero(len)) {
- PyErr_SetString(PyExc_ValueError, "actuator.direction = vec: KX_ConstraintActuator, invalid direction");
- return 1;
- }
- act->m_refDirVector = dir/len;
- return 0;
-}
-
-#endif
-
-/* eof */