diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2012-05-29 01:36:29 +0400 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2012-05-29 01:36:29 +0400 |
commit | dfc19a1ff7968e547c33ef3304849f69ddf76f4f (patch) | |
tree | 62764fb4d5ebf37785a1d34dcda7e01d4392bc18 /source/gameengine/Ketsji | |
parent | 4e0492e3bc59a4adca8ea5075a96bc78cd6bb67a (diff) |
BGE patch #28476: Character object physics type
===============================================
This patch adds a new "Character" BGE physics type which uses Bullet's btKinematicCharacter for simulation instead of full-blown dynamics. It is appropiate for (player-controlled) characters, for which the other physics types often result unexpected results (bouncing off walls, sliding etc.) and for which simple kinematics offers much more precision.
"Character" can be chosen like any other physics type in the "Physics" section of the properties window. Current settings for tweaking are "Step Height" (to make the object automatically climb small steps if it collides with them), "Fall Speed" (the maximum speed that the object can have when falling) and "Jump Speed", which is currently not used.
See http://projects.blender.org/tracker/?func=detail&atid=127&aid=28476&group_id=9
for sample blends and a discussion on the patch: how to use it and what influences the behavior of the character object.
Known problem: there is a crash if the "compound" option is set in the physics panel of the Character object.
Diffstat (limited to 'source/gameengine/Ketsji')
7 files changed, 31 insertions, 9 deletions
diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp index f5926818e7d..abc2460a5ba 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.cpp @@ -20,8 +20,8 @@ #include "BulletSoftBody/btSoftBody.h" -KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound) -: KX_IPhysicsController(dyna,sensor,compound,(PHY_IPhysicsController*)this), +KX_BulletPhysicsController::KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool character, bool compound) +: KX_IPhysicsController(dyna,sensor,character,compound,(PHY_IPhysicsController*)this), CcdPhysicsController(ci), m_savedCollisionFlags(0), m_savedCollisionFilterGroup(0), @@ -472,7 +472,7 @@ SG_Controller* KX_BulletPhysicsController::GetReplica(class SG_Node* destnode) void KX_BulletPhysicsController::SetSumoTransform(bool nondynaonly) { - if (!m_bDyna && !m_bSensor) + if (!m_bDyna && !m_bSensor && !m_bCharacter) { btCollisionObject* object = GetRigidBody(); object->setActivationState(ACTIVE_TAG); diff --git a/source/gameengine/Ketsji/KX_BulletPhysicsController.h b/source/gameengine/Ketsji/KX_BulletPhysicsController.h index d2f56bccaa0..4ced21aa2d8 100644 --- a/source/gameengine/Ketsji/KX_BulletPhysicsController.h +++ b/source/gameengine/Ketsji/KX_BulletPhysicsController.h @@ -26,7 +26,7 @@ private: public: #ifdef USE_BULLET - KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool compound); + KX_BulletPhysicsController (const CcdConstructionInfo& ci, bool dyna, bool sensor, bool character, bool compound); virtual ~KX_BulletPhysicsController (); #endif /////////////////////////////////// diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h index f1f58d7da9a..0f1ce403881 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObject.h @@ -72,6 +72,7 @@ struct KX_ObjectProperties class KX_GameObject* m_dynamic_parent; bool m_isactor; bool m_sensor; + bool m_character; bool m_concave; bool m_isdeformable; bool m_disableSleeping; diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index e0e8e2d9b3f..227ca39281f 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -100,6 +100,7 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, bool isbulletdyna = false; bool isbulletsensor = false; + bool isbulletchar = false; bool useGimpact = false; CcdConstructionInfo ci; class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode()); @@ -122,9 +123,13 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, ci.m_clamp_vel_min = shapeprops->m_clamp_vel_min; ci.m_clamp_vel_max = shapeprops->m_clamp_vel_max; ci.m_margin = objprop->m_margin; + ci.m_stepHeight = objprop->m_character ? shapeprops->m_step_height : 0.f; + ci.m_jumpSpeed = objprop->m_character ? shapeprops->m_jump_speed : 0.f; + ci.m_fallSpeed = objprop->m_character ? shapeprops->m_fall_speed : 0.f; shapeInfo->m_radius = objprop->m_radius; isbulletdyna = objprop->m_dyna; isbulletsensor = objprop->m_sensor; + isbulletchar = objprop->m_character; useGimpact = ((isbulletdyna || isbulletsensor) && !objprop->m_softbody); ci.m_localInertiaTensor = btVector3(ci.m_mass/3.f,ci.m_mass/3.f,ci.m_mass/3.f); @@ -400,21 +405,24 @@ void KX_ConvertBulletObject( class KX_GameObject* gameobj, //////////////////// ci.m_collisionFilterGroup = (isbulletsensor) ? short(CcdConstructionInfo::SensorFilter) : - (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : + (isbulletdyna) ? short(CcdConstructionInfo::DefaultFilter) : + (isbulletchar) ? short(CcdConstructionInfo::CharacterFilter) : short(CcdConstructionInfo::StaticFilter); ci.m_collisionFilterMask = (isbulletsensor) ? short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::SensorFilter) : (isbulletdyna) ? short(CcdConstructionInfo::AllFilter) : + (isbulletchar) ? short(CcdConstructionInfo::AllFilter) : short(CcdConstructionInfo::AllFilter ^ CcdConstructionInfo::StaticFilter); ci.m_bRigid = objprop->m_dyna && objprop->m_angular_rigidbody; ci.m_contactProcessingThreshold = objprop->m_contactProcessingThreshold;//todo: expose this in advanced settings, just like margin, default to 10000 or so ci.m_bSoft = objprop->m_softbody; ci.m_bSensor = isbulletsensor; + ci.m_bCharacter = isbulletchar; ci.m_bGimpact = useGimpact; MT_Vector3 scaling = gameobj->NodeGetWorldScaling(); ci.m_scaling.setValue(scaling[0], scaling[1], scaling[2]); - KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,objprop->m_hasCompoundChildren); + KX_BulletPhysicsController* physicscontroller = new KX_BulletPhysicsController(ci,isbulletdyna,isbulletsensor,isbulletchar,objprop->m_hasCompoundChildren); // shapeInfo is reference counted, decrement now as we don't use it anymore if (shapeInfo) shapeInfo->Release(); diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.cpp b/source/gameengine/Ketsji/KX_IPhysicsController.cpp index bd75246a97f..f0e57ceac02 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.cpp +++ b/source/gameengine/Ketsji/KX_IPhysicsController.cpp @@ -33,10 +33,11 @@ #include "PHY_DynamicTypes.h" -KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool sensor, bool compound, void* userdata) +KX_IPhysicsController::KX_IPhysicsController(bool dyna, bool sensor, bool character, bool compound, void* userdata) : m_bDyna(dyna), m_bSensor(sensor), + m_bCharacter(character), m_bCompound(compound), m_suspendDynamics(false), m_userdata(userdata) diff --git a/source/gameengine/Ketsji/KX_IPhysicsController.h b/source/gameengine/Ketsji/KX_IPhysicsController.h index 68577f09414..528bf00d574 100644 --- a/source/gameengine/Ketsji/KX_IPhysicsController.h +++ b/source/gameengine/Ketsji/KX_IPhysicsController.h @@ -53,11 +53,12 @@ class KX_IPhysicsController : public SG_Controller protected: bool m_bDyna; bool m_bSensor; + bool m_bCharacter; bool m_bCompound; bool m_suspendDynamics; void* m_userdata; public: - KX_IPhysicsController(bool dyna,bool sensor,bool compound, void* userdata); + KX_IPhysicsController(bool dyna,bool sensor,bool character,bool compound, void* userdata); virtual ~KX_IPhysicsController(); @@ -109,6 +110,10 @@ public: m_bSensor = isSensor; } + void SetCharacter(bool isCharacter) { + m_bCharacter = isCharacter; + } + bool IsDyna(void) { return m_bDyna; } @@ -117,6 +122,10 @@ public: return m_bSensor; } + bool IsCharacter(void) { + return m_bCharacter; + } + bool IsCompound(void) { return m_bCompound; } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 503c16fae9c..4f0ae4261c9 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -2267,7 +2267,10 @@ KX_PYMETHODDEF_DOC(KX_Scene, addObject, !ConvertPythonToGameObject(pyother, &other, false, "scene.addObject(object, other, time): KX_Scene (second argument)") ) return NULL; - + if (!m_inactivelist->SearchValue(ob)) { + PyErr_Format(PyExc_ValueError, "scene.addObject(object, other, time): KX_Scene (second argument): object does not belong to scene"); + return NULL; + } SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time); // release here because AddReplicaObject AddRef's |