Changeset View
Changeset View
Standalone View
Standalone View
source/gameengine/Ketsji/KX_SteeringActuator.cpp
| Show All 35 Lines | |||||
| #include "KX_PythonInit.h" | #include "KX_PythonInit.h" | ||||
| #include "KX_PyMath.h" | #include "KX_PyMath.h" | ||||
| #include "Recast.h" | #include "Recast.h" | ||||
| /* ------------------------------------------------------------------------- */ | /* ------------------------------------------------------------------------- */ | ||||
| /* Native functions */ | /* Native functions */ | ||||
| /* ------------------------------------------------------------------------- */ | /* ------------------------------------------------------------------------- */ | ||||
| KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj, | KX_SteeringActuator::KX_SteeringActuator(SCA_IObject *gameobj, | ||||
| int mode, | int mode, | ||||
| KX_GameObject *target, | KX_GameObject *target, | ||||
| KX_GameObject *navmesh, | KX_GameObject *navmesh, | ||||
| float distance, | float distance, | ||||
| float velocity, | float velocity, | ||||
| float acceleration, | float acceleration, | ||||
| float turnspeed, | float turnspeed, | ||||
| bool isSelfTerminated, | bool isSelfTerminated, | ||||
| int pathUpdatePeriod, | int pathUpdatePeriod, | ||||
| KX_ObstacleSimulation* simulation, | KX_ObstacleSimulation* simulation, | ||||
| short facingmode, | short facingmode, | ||||
| bool normalup, | bool normalup, | ||||
| bool enableVisualization) | bool enableVisualization, | ||||
| bool lockzvel) | |||||
| : SCA_IActuator(gameobj, KX_ACT_STEERING), | : SCA_IActuator(gameobj, KX_ACT_STEERING), | ||||
| m_target(target), | m_target(target), | ||||
| m_mode(mode), | m_mode(mode), | ||||
| m_distance(distance), | m_distance(distance), | ||||
| m_velocity(velocity), | m_velocity(velocity), | ||||
| m_acceleration(acceleration), | m_acceleration(acceleration), | ||||
| m_turnspeed(turnspeed), | m_turnspeed(turnspeed), | ||||
| m_simulation(simulation), | m_simulation(simulation), | ||||
| m_updateTime(0), | m_updateTime(0), | ||||
| m_obstacle(NULL), | m_obstacle(NULL), | ||||
| m_isActive(false), | m_isActive(false), | ||||
| m_isSelfTerminated(isSelfTerminated), | m_isSelfTerminated(isSelfTerminated), | ||||
| m_enableVisualization(enableVisualization), | m_enableVisualization(enableVisualization), | ||||
| m_facingMode(facingmode), | m_facingMode(facingmode), | ||||
| m_normalUp(normalup), | m_normalUp(normalup), | ||||
| m_pathLen(0), | m_pathLen(0), | ||||
| m_pathUpdatePeriod(pathUpdatePeriod), | m_pathUpdatePeriod(pathUpdatePeriod), | ||||
| m_lockzvel(lockzvel), | |||||
| m_wayPointIdx(-1), | m_wayPointIdx(-1), | ||||
| m_steerVec(MT_Vector3(0, 0, 0)) | m_steerVec(MT_Vector3(0, 0, 0)) | ||||
| { | { | ||||
| m_navmesh = static_cast<KX_NavMeshObject*>(navmesh); | m_navmesh = static_cast<KX_NavMeshObject*>(navmesh); | ||||
| if (m_navmesh) | if (m_navmesh) | ||||
| m_navmesh->RegisterActuator(this); | m_navmesh->RegisterActuator(this); | ||||
| if (m_target) | if (m_target) | ||||
| m_target->RegisterActuator(this); | m_target->RegisterActuator(this); | ||||
| ▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | switch (m_mode) { | ||||
| } | } | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| if (apply_steerforce) | if (apply_steerforce) | ||||
| { | { | ||||
| MT_Vector3 newvel; | |||||
| bool isdyna = obj->IsDynamic(); | bool isdyna = obj->IsDynamic(); | ||||
| if (isdyna) | if (isdyna) | ||||
| m_steerVec.z() = 0; | m_steerVec.z() = 0; | ||||
| if (!m_steerVec.fuzzyZero()) | if (!m_steerVec.fuzzyZero()) | ||||
| m_steerVec.normalize(); | m_steerVec.normalize(); | ||||
| MT_Vector3 newvel = m_velocity*m_steerVec; | |||||
| //adjust velocity to avoid obstacles | //adjust velocity to avoid obstacles | ||||
| if (m_simulation && m_obstacle /*&& !newvel.fuzzyZero()*/) | if (m_simulation && m_obstacle /*&& !newvel.fuzzyZero()*/) | ||||
| { | { | ||||
| if (m_enableVisualization) | if (m_enableVisualization) | ||||
| KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(1.0, 0.0, 0.0)); | KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(1.0, 0.0, 0.0)); | ||||
| m_simulation->AdjustObstacleVelocity(m_obstacle, m_mode!=KX_STEERING_PATHFOLLOWING ? m_navmesh : NULL, | m_simulation->AdjustObstacleVelocity(m_obstacle, m_mode!=KX_STEERING_PATHFOLLOWING ? m_navmesh : NULL, | ||||
| newvel, m_acceleration*delta, m_turnspeed/180.0f*M_PI*delta); | newvel, m_acceleration*delta, m_turnspeed/180.0f*M_PI*delta); | ||||
| if (m_enableVisualization) | if (m_enableVisualization) | ||||
| KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(0.0, 1.0, 0.0)); | KX_RasterizerDrawDebugLine(mypos, mypos + newvel, MT_Vector3(0.0, 1.0, 0.0)); | ||||
| } | } | ||||
| HandleActorFace(newvel); | HandleActorFace(newvel); | ||||
| if (isdyna) | if (isdyna) | ||||
| { | { | ||||
| //temporary solution: set 2D steering velocity directly to obj | //TODO: Take into account angular velocity on turns | ||||
| //correct way is to apply physical force | |||||
| MT_Vector3 curvel = obj->GetLinearVelocity(); | MT_Vector3 curvel = obj->GetLinearVelocity(); | ||||
| newvel = (curvel.length() * m_steerVec) + (m_acceleration * delta) * m_steerVec; | |||||
| if (newvel.length2() >= (m_velocity * m_velocity)) | |||||
| newvel = m_velocity * m_steerVec; | |||||
| if (m_lockzvel) | |||||
| newvel.z() = 0.0f; | |||||
| else | |||||
| newvel.z() = curvel.z(); | newvel.z() = curvel.z(); | ||||
| obj->setLinearVelocity(newvel, false); | obj->setLinearVelocity(newvel, false); | ||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| MT_Vector3 movement = delta*newvel; | MT_Vector3 movement = delta*newvel; | ||||
| obj->ApplyMovement(movement, false); | obj->ApplyMovement(movement, false); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 252 Lines • ▼ Show 20 Lines | PyAttributeDef KX_SteeringActuator::Attributes[] = { | ||||
| KX_PYATTRIBUTE_FLOAT_RW("velocity", 0.0f, 1000.0f, KX_SteeringActuator, m_velocity), | KX_PYATTRIBUTE_FLOAT_RW("velocity", 0.0f, 1000.0f, KX_SteeringActuator, m_velocity), | ||||
| KX_PYATTRIBUTE_FLOAT_RW("acceleration", 0.0f, 1000.0f, KX_SteeringActuator, m_acceleration), | KX_PYATTRIBUTE_FLOAT_RW("acceleration", 0.0f, 1000.0f, KX_SteeringActuator, m_acceleration), | ||||
| KX_PYATTRIBUTE_FLOAT_RW("turnspeed", 0.0f, 720.0f, KX_SteeringActuator, m_turnspeed), | KX_PYATTRIBUTE_FLOAT_RW("turnspeed", 0.0f, 720.0f, KX_SteeringActuator, m_turnspeed), | ||||
| KX_PYATTRIBUTE_BOOL_RW("selfterminated", KX_SteeringActuator, m_isSelfTerminated), | KX_PYATTRIBUTE_BOOL_RW("selfterminated", KX_SteeringActuator, m_isSelfTerminated), | ||||
| KX_PYATTRIBUTE_BOOL_RW("enableVisualization", KX_SteeringActuator, m_enableVisualization), | KX_PYATTRIBUTE_BOOL_RW("enableVisualization", KX_SteeringActuator, m_enableVisualization), | ||||
| KX_PYATTRIBUTE_RO_FUNCTION("steeringVec", KX_SteeringActuator, pyattr_get_steeringVec), | KX_PYATTRIBUTE_RO_FUNCTION("steeringVec", KX_SteeringActuator, pyattr_get_steeringVec), | ||||
| KX_PYATTRIBUTE_SHORT_RW("facingMode", 0, 6, true, KX_SteeringActuator, m_facingMode), | KX_PYATTRIBUTE_SHORT_RW("facingMode", 0, 6, true, KX_SteeringActuator, m_facingMode), | ||||
| KX_PYATTRIBUTE_INT_RW("pathUpdatePeriod", -1, 100000, true, KX_SteeringActuator, m_pathUpdatePeriod), | KX_PYATTRIBUTE_INT_RW("pathUpdatePeriod", -1, 100000, true, KX_SteeringActuator, m_pathUpdatePeriod), | ||||
| KX_PYATTRIBUTE_BOOL_RW("lockZVelocity", KX_SteeringActuator, m_lockzvel), | |||||
| { NULL } //Sentinel | { NULL } //Sentinel | ||||
| }; | }; | ||||
| PyObject *KX_SteeringActuator::pyattr_get_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) | PyObject *KX_SteeringActuator::pyattr_get_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef) | ||||
| { | { | ||||
| KX_SteeringActuator* actuator = static_cast<KX_SteeringActuator*>(self); | KX_SteeringActuator* actuator = static_cast<KX_SteeringActuator*>(self); | ||||
| if (!actuator->m_target) | if (!actuator->m_target) | ||||
| Py_RETURN_NONE; | Py_RETURN_NONE; | ||||
| ▲ Show 20 Lines • Show All 68 Lines • Show Last 20 Lines | |||||