Changeset View
Changeset View
Standalone View
Standalone View
source/gameengine/Ketsji/KX_ConstraintActuator.cpp
| Context not available. | |||||
| #include "SCA_IActuator.h" | #include "SCA_IActuator.h" | ||||
| #include "KX_ConstraintActuator.h" | #include "KX_ConstraintActuator.h" | ||||
| #include "SCA_IObject.h" | #include "SCA_IObject.h" | ||||
| #include "MT_Point3.h" | #include "MT_Vector3.h" | ||||
| #include "MT_Matrix3x3.h" | #include "MT_Matrix3x3.h" | ||||
| #include "KX_GameObject.h" | #include "KX_GameObject.h" | ||||
| #include "KX_RayCast.h" | #include "KX_RayCast.h" | ||||
| #include "KX_PythonInit.h" // KX_GetActiveScene | #include "KX_Globals.h" // KX_GetActiveScene | ||||
| #include "RAS_MeshObject.h" | #include "RAS_MeshObject.h" | ||||
| #include <stdio.h> | #include "CM_Message.h" | ||||
| /* ------------------------------------------------------------------------- */ | /* ------------------------------------------------------------------------- */ | ||||
| /* Native functions */ | /* Native functions */ | ||||
| Context not available. | |||||
| MT_Scalar len = m_refDirVector.length(); | MT_Scalar len = m_refDirVector.length(); | ||||
| if (MT_fuzzyZero(len)) { | if (MT_fuzzyZero(len)) { | ||||
| // missing a valid direction | // missing a valid direction | ||||
| std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no valid reference direction!" << std::endl; | CM_LogicBrickWarning(this, "there is no valid reference direction!"); | ||||
| m_locrot = KX_ACT_CONSTRAINT_NODEF; | m_locrot = KX_ACT_CONSTRAINT_NODEF; | ||||
| } else { | } else { | ||||
| m_refDirection[0] /= len; | m_refDirection[0] /= len; | ||||
| Context not available. | |||||
| bool bFound = false; | bool bFound = false; | ||||
| if (m_property.IsEmpty()) | if (m_property.empty()) | ||||
| { | { | ||||
| bFound = true; | bFound = true; | ||||
| } | } | ||||
| Context not available. | |||||
| for (unsigned int i = 0; i < m_hitObject->GetMeshCount(); ++i) { | for (unsigned int i = 0; i < m_hitObject->GetMeshCount(); ++i) { | ||||
| RAS_MeshObject *meshObj = m_hitObject->GetMesh(i); | RAS_MeshObject *meshObj = m_hitObject->GetMesh(i); | ||||
| for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) { | for (unsigned int j = 0; j < meshObj->NumMaterials(); ++j) { | ||||
| bFound = strcmp(m_property.ReadPtr(), meshObj->GetMaterialName(j).ReadPtr() + 2) == 0; | bFound = (m_property == std::string(meshObj->GetMaterialName(j), 2)); | ||||
| if (bFound) | if (bFound) | ||||
| break; | break; | ||||
| } | } | ||||
| Context not available. | |||||
| { | { | ||||
| // Unknown type of object, skip it. | // Unknown type of object, skip it. | ||||
| // Should not occur as the sensor objects are filtered in RayTest() | // Should not occur as the sensor objects are filtered in RayTest() | ||||
| printf("Invalid client type %d found in ray casting\n", client->m_type); | CM_LogicBrickError(this, "invalid client type " << client->m_type << " found in ray casting"); | ||||
| return false; | return false; | ||||
| } | } | ||||
| // no X-Ray function yet | // no X-Ray function yet | ||||
| Context not available. | |||||
| /* Having to retrieve location/rotation and setting it afterwards may not */ | /* Having to retrieve location/rotation and setting it afterwards may not */ | ||||
| /* be efficient enough... Something to look at later. */ | /* be efficient enough... Something to look at later. */ | ||||
| KX_GameObject *obj = (KX_GameObject*) GetParent(); | KX_GameObject *obj = (KX_GameObject*) GetParent(); | ||||
| MT_Point3 position = obj->NodeGetWorldPosition(); | MT_Vector3 position = obj->NodeGetWorldPosition(); | ||||
| MT_Point3 newposition; | MT_Vector3 newposition; | ||||
| MT_Vector3 normal, direction, refDirection; | MT_Vector3 normal, direction, refDirection; | ||||
| MT_Matrix3x3 rotation = obj->NodeGetWorldOrientation(); | MT_Matrix3x3 rotation = obj->NodeGetWorldOrientation(); | ||||
| MT_Scalar filter, newdistance, cosangle; | MT_Scalar filter, newdistance, cosangle; | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| { | { | ||||
| MT_Point3 topoint = position + (m_maximumBound) * direction; | MT_Vector3 topoint = position + (m_maximumBound) * direction; | ||||
| PHY_IPhysicsEnvironment* pe = KX_GetActiveScene()->GetPhysicsEnvironment(); | PHY_IPhysicsEnvironment* pe = KX_GetActiveScene()->GetPhysicsEnvironment(); | ||||
| PHY_IPhysicsController *spc = obj->GetPhysicsController(); | PHY_IPhysicsController *spc = obj->GetPhysicsController(); | ||||
| if (!pe) { | if (!pe) { | ||||
| std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no physics environment!" << std::endl; | CM_LogicBrickWarning(this, "there is no physics environment!"); | ||||
| goto CHECK_TIME; | goto CHECK_TIME; | ||||
| } | } | ||||
| if (!spc) { | if (!spc) { | ||||
| Context not available. | |||||
| PHY_IPhysicsController *spc = obj->GetPhysicsController(); | PHY_IPhysicsController *spc = obj->GetPhysicsController(); | ||||
| if (!pe) { | if (!pe) { | ||||
| std::cout << "WARNING: Constraint actuator " << GetName() << ": There is no physics environment!" << std::endl; | CM_LogicBrickWarning(this, "there is no physics environment!"); | ||||
| goto CHECK_TIME; | goto CHECK_TIME; | ||||
| } | } | ||||
| if (!spc || !spc->IsDynamic()) { | if (!spc || !spc->IsDynamic()) { | ||||
| Context not available. | |||||
| } | } | ||||
| m_hitObject = NULL; | m_hitObject = NULL; | ||||
| // distance of Fh area is stored in m_minimum | // distance of Fh area is stored in m_minimum | ||||
| MT_Point3 topoint = position + (m_minimumBound+spc->GetRadius()) * direction; | MT_Vector3 topoint = position + (m_minimumBound+spc->GetRadius()) * direction; | ||||
| KX_RayCast::Callback<KX_ConstraintActuator, void> callback(this, spc); | KX_RayCast::Callback<KX_ConstraintActuator, void> callback(this, spc); | ||||
| result = KX_RayCast::RayTest(pe, position, topoint, callback); | result = KX_RayCast::RayTest(pe, position, topoint, callback); | ||||
| // we expect a hit object | // we expect a hit object | ||||
| Context not available. | |||||
| // compute new position & orientation | // compute new position & orientation | ||||
| MT_Scalar distance = (callback.m_hitPoint-position).length()-spc->GetRadius(); | MT_Scalar distance = (callback.m_hitPoint-position).length()-spc->GetRadius(); | ||||
| // estimate the velocity of the hit point | // estimate the velocity of the hit point | ||||
| MT_Point3 relativeHitPoint; | MT_Vector3 relativeHitPoint; | ||||
| relativeHitPoint = (callback.m_hitPoint-m_hitObject->NodeGetWorldPosition()); | relativeHitPoint = (callback.m_hitPoint-m_hitObject->NodeGetWorldPosition()); | ||||
| MT_Vector3 velocityHitPoint = m_hitObject->GetVelocity(relativeHitPoint); | MT_Vector3 velocityHitPoint = m_hitObject->GetVelocity(relativeHitPoint); | ||||
| MT_Vector3 relativeVelocity = spc->GetLinearVelocity() - velocityHitPoint; | MT_Vector3 relativeVelocity = spc->GetLinearVelocity() - velocityHitPoint; | ||||
| Context not available. | |||||
| KX_PYATTRIBUTE_FLOAT_RW("max",-FLT_MAX,FLT_MAX,KX_ConstraintActuator,m_maximumBound), | 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_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), | 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 | KX_PYATTRIBUTE_NULL //Sentinel | ||||
| }; | }; | ||||
| int KX_ConstraintActuator::pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) | int KX_ConstraintActuator::pyattr_check_direction(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) | ||||
| Context not available. | |||||