BGE patch #28476: Character object physics type
authorBenoit Bolsee <benoit.bolsee@online.be>
Mon, 28 May 2012 21:36:29 +0000 (21:36 +0000)
committerBenoit Bolsee <benoit.bolsee@online.be>
Mon, 28 May 2012 21:36:29 +0000 (21:36 +0000)
===============================================
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.

21 files changed:
extern/bullet2/CMakeLists.txt
extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
extern/bullet2/src/SConscript
release/scripts/startup/bl_ui/properties_game.py
source/blender/blenkernel/intern/object.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/rna_object.c
source/blender/python/generic/py_capi_utils.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.h
source/gameengine/Ketsji/KX_ConvertPhysicsObject.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_IPhysicsController.cpp
source/gameengine/Ketsji/KX_IPhysicsController.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/common/PHY_Pro.h

index 51b295e897f9dba9cbae43b35c5614f8a1a4af2f..ae7d282ca55ae0508843d05ccefe69596aded54e 100644 (file)
@@ -118,6 +118,7 @@ set(SRC
        src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
        src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
        src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
        src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
        src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
        src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
+       src/BulletDynamics/Character/btKinematicCharacterController.cpp
        src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
        src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
@@ -154,7 +155,6 @@ set(SRC
        # src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp
        # src/BulletCollision/CollisionShapes/btBox2dShape.cpp
        # src/BulletCollision/CollisionShapes/btConvex2dShape.cpp
        # src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp
        # src/BulletCollision/CollisionShapes/btBox2dShape.cpp
        # src/BulletCollision/CollisionShapes/btConvex2dShape.cpp
-       # src/BulletDynamics/Character/btKinematicCharacterController.cpp
        # src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp
        # src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp
 
        # src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp
        # src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp
 
@@ -274,6 +274,7 @@ set(SRC
        src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h
        src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
        src/BulletDynamics/Character/btCharacterControllerInterface.h
        src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h
        src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
        src/BulletDynamics/Character/btCharacterControllerInterface.h
+       src/BulletDynamics/Character/btKinematicCharacterController.h
        src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
        src/BulletDynamics/ConstraintSolver/btConstraintSolver.h
        src/BulletDynamics/ConstraintSolver/btContactConstraint.h
        src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
        src/BulletDynamics/ConstraintSolver/btConstraintSolver.h
        src/BulletDynamics/ConstraintSolver/btContactConstraint.h
@@ -343,7 +344,6 @@ set(SRC
        # src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h
        # src/BulletCollision/CollisionShapes/btBox2dShape.h
        # src/BulletCollision/CollisionShapes/btConvex2dShape.h
        # src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h
        # src/BulletCollision/CollisionShapes/btBox2dShape.h
        # src/BulletCollision/CollisionShapes/btConvex2dShape.h
-       # src/BulletDynamics/Character/btKinematicCharacterController.h
        # src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h
        # src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
 )
        # src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h
        # src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
 )
index 51b27afe6866612359e52c844eb036540ca26697..9e247d125f588386b4c139c1394762d126de63e3 100644 (file)
@@ -339,7 +339,7 @@ public:
 
        
        ///***************************************** expert/internal use only *************************
 
        
        ///***************************************** expert/internal use only *************************
-       void    setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0));
+       void    setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.5));
        QuantizedNodeArray&     getLeafNodeArray() {                    return  m_quantizedLeafNodes;   }
        ///buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialized
        void    buildInternal();
        QuantizedNodeArray&     getLeafNodeArray() {                    return  m_quantizedLeafNodes;   }
        ///buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialized
        void    buildInternal();
index 9732553130d15adc834cfe8415ffbfa61449757e..f733dc0cd226fd3474beb6dd32f7ce8dd4775b9a 100644 (file)
@@ -84,7 +84,7 @@ public:
                } else
                {
                        ///need to transform normal into worldspace
                } else
                {
                        ///need to transform normal into worldspace
-                       hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
+                       hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
                }
 
                btScalar dotUp = m_up.dot(hitNormalWorld);
                }
 
                btScalar dotUp = m_up.dot(hitNormalWorld);
index f59bcba9fa61e4980435523eddd91f0d61004291..cd94df257eca19cda84354a799bbddd014f6a0c8 100644 (file)
@@ -23,7 +23,7 @@ elif sys.platform=='darwin':
 
 linearmath_src = env.Glob("LinearMath/*.cpp")
 
 
 linearmath_src = env.Glob("LinearMath/*.cpp")
 
-bulletdyn_src = env.Glob("BulletDynamics/Vehicle/*.cpp") + env.Glob("BulletDynamics/ConstraintSolver/*.cpp") + env.Glob("BulletDynamics/Dynamics/*.cpp")
+bulletdyn_src = env.Glob("BulletDynamics/Vehicle/*.cpp") + env.Glob("BulletDynamics/ConstraintSolver/*.cpp") + env.Glob("BulletDynamics/Dynamics/*.cpp") + env.Glob("BulletDynamics/Character/*.cpp")
 
 collision_broadphase_src = env.Glob("BulletCollision/BroadphaseCollision/*.cpp")
 collision_dispatch_src = env.Glob("BulletCollision/CollisionDispatch/*.cpp")
 
 collision_broadphase_src = env.Glob("BulletCollision/BroadphaseCollision/*.cpp")
 collision_dispatch_src = env.Glob("BulletCollision/CollisionDispatch/*.cpp")
index 2aff07bd98eaaf3d4f8e10a9c2310eeda9340f2d..857afbd9f0981689ceab14c94fa9f94f821a1b0f 100644 (file)
@@ -49,7 +49,12 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel):
 
         physics_type = game.physics_type
 
 
         physics_type = game.physics_type
 
-        if physics_type in {'DYNAMIC', 'RIGID_BODY'}:
+        if physics_type == 'CHARACTER':
+            layout.prop(game, "step_height", slider=True)
+            layout.prop(game, "jump_speed")
+            layout.prop(game, "fall_speed")
+
+        elif physics_type in {'DYNAMIC', 'RIGID_BODY'}:
             split = layout.split()
 
             col = split.column()
             split = layout.split()
 
             col = split.column()
@@ -192,7 +197,7 @@ class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel):
     def poll(cls, context):
         game = context.object.game
         rd = context.scene.render
     def poll(cls, context):
         game = context.object.game
         rd = context.scene.render
-        return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC'}) and (rd.engine in cls.COMPAT_ENGINES)
+        return (game.physics_type in {'DYNAMIC', 'RIGID_BODY', 'SENSOR', 'SOFT_BODY', 'STATIC', 'CHARACTER'}) and (rd.engine in cls.COMPAT_ENGINES)
 
     def draw_header(self, context):
         game = context.active_object.game
 
     def draw_header(self, context):
         game = context.active_object.game
index 098d702a7e26d78df417c3a78cb83e5f61003421..04631729d7a718c4fb016af9843c9118e3d8e187 100644 (file)
@@ -835,6 +835,9 @@ Object *BKE_object_add_only_object(int type, const char *name)
        /* ob->pad3 == Contact Processing Threshold */
        ob->m_contactProcessingThreshold = 1.0f;
        ob->obstacleRad = 1.0f;
        /* ob->pad3 == Contact Processing Threshold */
        ob->m_contactProcessingThreshold = 1.0f;
        ob->obstacleRad = 1.0f;
+       ob->step_height = 0.15f;
+       ob->jump_speed = 10.0f;
+       ob->fall_speed = 55.0f;
        
        /* NT fluid sim defaults */
        ob->fluidsimSettings = NULL;
        
        /* NT fluid sim defaults */
        ob->fluidsimSettings = NULL;
index 1ea50ec9c1a2c7b988728fbbb7e35cd04768e9e8..11ca1f1fa8ecc55068b07459448a93dd4a1c28cf 100644 (file)
@@ -204,6 +204,12 @@ typedef struct Object {
        float min_vel; /* clamp the maximum velocity 0.0 is disabled */
        float m_contactProcessingThreshold;
        float obstacleRad;
        float min_vel; /* clamp the maximum velocity 0.0 is disabled */
        float m_contactProcessingThreshold;
        float obstacleRad;
+       
+       /* "Character" physics properties */
+       float step_height;
+       float jump_speed;
+       float fall_speed;
+       char pad1[4];
 
        short rotmode;          /* rotation mode - uses defines set out in DNA_action_types.h for PoseChannel rotations... */
 
 
        short rotmode;          /* rotation mode - uses defines set out in DNA_action_types.h for PoseChannel rotations... */
 
@@ -483,6 +489,7 @@ typedef struct DupliObject {
 #define OB_SENSOR              0x80000
 #define OB_NAVMESH             0x100000
 #define OB_HASOBSTACLE 0x200000
 #define OB_SENSOR              0x80000
 #define OB_NAVMESH             0x100000
 #define OB_HASOBSTACLE 0x200000
+#define OB_CHARACTER           0x400000
 
 /* ob->gameflag2 */
 #define OB_NEVER_DO_ACTIVITY_CULLING   1
 
 /* ob->gameflag2 */
 #define OB_NEVER_DO_ACTIVITY_CULLING   1
@@ -504,6 +511,7 @@ typedef struct DupliObject {
 #define OB_BODY_TYPE_OCCLUDER          5
 #define OB_BODY_TYPE_SENSOR                    6
 #define OB_BODY_TYPE_NAVMESH           7
 #define OB_BODY_TYPE_OCCLUDER          5
 #define OB_BODY_TYPE_SENSOR                    6
 #define OB_BODY_TYPE_NAVMESH           7
+#define OB_BODY_TYPE_CHARACTER                 8
 
 /* ob->scavisflag */
 #define OB_VIS_SENS            1
 
 /* ob->scavisflag */
 #define OB_VIS_SENS            1
index 21c9187cbb84939709a58188649e8407e15027fd..7e3b368aa64cbd2bf3e3099d5c89a2cc7ecd7619 100644 (file)
@@ -891,6 +891,9 @@ static int rna_GameObjectSettings_physics_type_get(PointerRNA *ptr)
                        ob->body_type = OB_BODY_TYPE_NO_COLLISION;
                }
        }
                        ob->body_type = OB_BODY_TYPE_NO_COLLISION;
                }
        }
+       else if (ob->gameflag & OB_CHARACTER) {
+               ob->body_type = OB_BODY_TYPE_CHARACTER;
+       }
        else if (ob->gameflag & OB_SENSOR) {
                ob->body_type = OB_BODY_TYPE_SENSOR;
        }
        else if (ob->gameflag & OB_SENSOR) {
                ob->body_type = OB_BODY_TYPE_SENSOR;
        }
@@ -922,16 +925,16 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value)
        switch (ob->body_type) {
                case OB_BODY_TYPE_SENSOR:
                        ob->gameflag |= OB_SENSOR | OB_COLLISION | OB_GHOST;
        switch (ob->body_type) {
                case OB_BODY_TYPE_SENSOR:
                        ob->gameflag |= OB_SENSOR | OB_COLLISION | OB_GHOST;
-                       ob->gameflag &= ~(OB_OCCLUDER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
+                       ob->gameflag &= ~(OB_OCCLUDER | OB_CHARACTER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR |
                                          OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
                        break;
                case OB_BODY_TYPE_OCCLUDER:
                        ob->gameflag |= OB_OCCLUDER;
                                          OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
                        break;
                case OB_BODY_TYPE_OCCLUDER:
                        ob->gameflag |= OB_OCCLUDER;
-                       ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_DYNAMIC | OB_NAVMESH);
+                       ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_DYNAMIC | OB_NAVMESH);
                        break;
                case OB_BODY_TYPE_NAVMESH:
                        ob->gameflag |= OB_NAVMESH;
                        break;
                case OB_BODY_TYPE_NAVMESH:
                        ob->gameflag |= OB_NAVMESH;
-                       ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_DYNAMIC | OB_OCCLUDER);
+                       ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_DYNAMIC | OB_OCCLUDER);
 
                        if (ob->type == OB_MESH) {
                                /* could be moved into mesh UI but for now ensure mesh data layer */
 
                        if (ob->type == OB_MESH) {
                                /* could be moved into mesh UI but for now ensure mesh data layer */
@@ -940,24 +943,29 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value)
 
                        break;
                case OB_BODY_TYPE_NO_COLLISION:
 
                        break;
                case OB_BODY_TYPE_NO_COLLISION:
-                       ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH);
+                       ob->gameflag &= ~(OB_SENSOR | OB_RIGID_BODY | OB_SOFT_BODY | OB_COLLISION | OB_CHARACTER | OB_OCCLUDER | OB_DYNAMIC | OB_NAVMESH);
                        break;
                        break;
+               case OB_BODY_TYPE_CHARACTER:
+                       ob->gameflag |= OB_COLLISION | OB_GHOST | OB_CHARACTER;
+                       ob->gameflag &= ~(OB_SENSOR | OB_OCCLUDER | OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_ACTOR
+                                    | OB_ANISOTROPIC_FRICTION | OB_DO_FH | OB_ROT_FH | OB_COLLISION_RESPONSE | OB_NAVMESH);
+               break;
                case OB_BODY_TYPE_STATIC:
                        ob->gameflag |= OB_COLLISION;
                case OB_BODY_TYPE_STATIC:
                        ob->gameflag |= OB_COLLISION;
-                       ob->gameflag &= ~(OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_SENSOR | OB_NAVMESH);
+                       ob->gameflag &= ~(OB_DYNAMIC | OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH);
                        break;
                case OB_BODY_TYPE_DYNAMIC:
                        ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_ACTOR;
                        break;
                case OB_BODY_TYPE_DYNAMIC:
                        ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_ACTOR;
-                       ob->gameflag &= ~(OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_SENSOR | OB_NAVMESH);
+                       ob->gameflag &= ~(OB_RIGID_BODY | OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH);
                        break;
                case OB_BODY_TYPE_RIGID:
                        ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_RIGID_BODY | OB_ACTOR;
                        break;
                case OB_BODY_TYPE_RIGID:
                        ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_RIGID_BODY | OB_ACTOR;
-                       ob->gameflag &= ~(OB_SOFT_BODY | OB_OCCLUDER | OB_SENSOR | OB_NAVMESH);
+                       ob->gameflag &= ~(OB_SOFT_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH);
                        break;
                default:
                case OB_BODY_TYPE_SOFT:
                        ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_SOFT_BODY | OB_ACTOR;
                        break;
                default:
                case OB_BODY_TYPE_SOFT:
                        ob->gameflag |= OB_COLLISION | OB_DYNAMIC | OB_SOFT_BODY | OB_ACTOR;
-                       ob->gameflag &= ~(OB_RIGID_BODY | OB_OCCLUDER | OB_SENSOR | OB_NAVMESH);
+                       ob->gameflag &= ~(OB_RIGID_BODY | OB_OCCLUDER | OB_CHARACTER | OB_SENSOR | OB_NAVMESH);
 
                        /* assume triangle mesh, if no bounds chosen for soft body */
                        if ((ob->gameflag & OB_BOUNDS) && (ob->boundtype < OB_BOUND_TRIANGLE_MESH)) {
 
                        /* assume triangle mesh, if no bounds chosen for soft body */
                        if ((ob->gameflag & OB_BOUNDS) && (ob->boundtype < OB_BOUND_TRIANGLE_MESH)) {
@@ -1436,6 +1444,7 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
                                      "Collision Sensor, detects static and dynamic objects but not the other "
                                      "collision sensor objects"},
                {OB_BODY_TYPE_NAVMESH, "NAVMESH", 0, "Navigation Mesh", "Navigation mesh"},
                                      "Collision Sensor, detects static and dynamic objects but not the other "
                                      "collision sensor objects"},
                {OB_BODY_TYPE_NAVMESH, "NAVMESH", 0, "Navigation Mesh", "Navigation mesh"},
+               {OB_BODY_TYPE_CHARACTER, "CHARACTER", 0, "Character", "Simple kinematic physics appropiate for game characters"},
                {0, NULL, 0, NULL, NULL}
        };
 
                {0, NULL, 0, NULL, NULL}
        };
 
@@ -1529,6 +1538,22 @@ static void rna_def_object_game_settings(BlenderRNA *brna)
        RNA_def_property_float_sdna(prop, NULL, "max_vel");
        RNA_def_property_range(prop, 0.0, 1000.0);
        RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed");
        RNA_def_property_float_sdna(prop, NULL, "max_vel");
        RNA_def_property_range(prop, 0.0, 1000.0);
        RNA_def_property_ui_text(prop, "Velocity Max", "Clamp velocity to this maximum speed");
+       
+       prop= RNA_def_property(srna, "step_height", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "step_height");
+       RNA_def_property_range(prop, 0.0, 1.0);
+       RNA_def_property_ui_text(prop, "Step Height", "Maximum height of steps the character can run over");
+
+       prop= RNA_def_property(srna, "jump_speed", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "jump_speed");
+       RNA_def_property_range(prop, 0.0, 1000.0);
+       RNA_def_property_ui_text(prop, "Jump Force", "Upward velocity applied to the character when jumping (with the Motion actuator)");
+
+       prop= RNA_def_property(srna, "fall_speed", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "fall_speed");
+       RNA_def_property_range(prop, 0.0, 1000.0);
+       RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall");
+
 
        /* lock position */
        prop = RNA_def_property(srna, "lock_location_x", PROP_BOOLEAN, PROP_NONE);
 
        /* lock position */
        prop = RNA_def_property(srna, "lock_location_x", PROP_BOOLEAN, PROP_NONE);
index 3a405575926aae59924928cf49dabd9c98e8307e..fd12f7f483dc651afa2be1abb7e42fa732ae8df3 100644 (file)
@@ -489,7 +489,7 @@ void PyC_SetHomePath(const char *py_path_bundle)
        /* cmake/MSVC debug build crashes without this, why only
         * in this case is unknown.. */
        {
        /* cmake/MSVC debug build crashes without this, why only
         * in this case is unknown.. */
        {
-               BLI_setenv("PYTHONPATH", py_path_bundle);
+               /*BLI_setenv("PYTHONPATH", py_path_bundle)*/;
        }
 #endif
 #endif
        }
 #endif
 #endif
index 196f032e584eb1a4521f3cf6cea923d94d5136b1..3d73ca66c92794b6b25991fda2bebebfde58aeb6 100644 (file)
@@ -1346,6 +1346,11 @@ static PHY_ShapeProps *CreateShapePropsFromBlenderObject(struct Object* blendero
        shapeProps->m_clamp_vel_min = blenderobject->min_vel;
        shapeProps->m_clamp_vel_max = blenderobject->max_vel;
        
        shapeProps->m_clamp_vel_min = blenderobject->min_vel;
        shapeProps->m_clamp_vel_max = blenderobject->max_vel;
        
+//  Character physics properties
+       shapeProps->m_step_height = blenderobject->step_height;
+       shapeProps->m_jump_speed = blenderobject->jump_speed;
+       shapeProps->m_fall_speed = blenderobject->fall_speed;
+       
        return shapeProps;
 }
 
        return shapeProps;
 }
 
@@ -1638,6 +1643,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
        objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
        objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
        objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
        objprop.m_dyna = (blenderobject->gameflag & OB_DYNAMIC) != 0;
        objprop.m_softbody = (blenderobject->gameflag & OB_SOFT_BODY) != 0;
        objprop.m_angular_rigidbody = (blenderobject->gameflag & OB_RIGID_BODY) != 0;
+       objprop.m_character = (blenderobject->gameflag & OB_CHARACTER) != 0;
        
        ///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
        if (objprop.m_angular_rigidbody || !objprop.m_dyna )
        
        ///contact processing threshold is only for rigid bodies and static geometry, not 'dynamic'
        if (objprop.m_angular_rigidbody || !objprop.m_dyna )
@@ -1754,6 +1760,11 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj,
                objprop.m_boundclass = KX_BOUNDMESH;
        }
 
                objprop.m_boundclass = KX_BOUNDMESH;
        }
 
+       if ((blenderobject->gameflag & OB_CHARACTER) && !(blenderobject->gameflag & OB_BOUNDS))
+       {
+               objprop.m_boundclass = KX_BOUNDSPHERE;
+       }
+
        KX_BoxBounds bb;
        DerivedMesh* dm = NULL;
        if (gameobj->GetDeformer())
        KX_BoxBounds bb;
        DerivedMesh* dm = NULL;
        if (gameobj->GetDeformer())
index f5926818e7d478971c312e287e8e8a0efb72055c..abc2460a5ba564f1196f031b94a54b2b95fdd21f 100644 (file)
@@ -20,8 +20,8 @@
 #include "BulletSoftBody/btSoftBody.h"
 
 
 #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),
 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)
 {
 
 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);
        {
                btCollisionObject* object = GetRigidBody();
                object->setActivationState(ACTIVE_TAG);
index d2f56bccaa0106b83e429ff67be1294b9517d283..4ced21aa2d81968f912ec2307645c2a96a5fd9db 100644 (file)
@@ -26,7 +26,7 @@ private:
 
 public:
 #ifdef USE_BULLET
 
 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
        ///////////////////////////////////
        virtual ~KX_BulletPhysicsController ();
 #endif
        ///////////////////////////////////
index f1f58d7da9ac55607a3df586920eeb85f9ba5653..0f1ce4038813dc770c798736dc801890ea2cf749 100644 (file)
@@ -72,6 +72,7 @@ struct KX_ObjectProperties
        class KX_GameObject*    m_dynamic_parent;
        bool    m_isactor;
        bool    m_sensor;
        class KX_GameObject*    m_dynamic_parent;
        bool    m_isactor;
        bool    m_sensor;
+       bool    m_character;
        bool    m_concave;
        bool    m_isdeformable;
        bool    m_disableSleeping;
        bool    m_concave;
        bool    m_isdeformable;
        bool    m_disableSleeping;
index e0e8e2d9b3f729c1d144e328c6572e23e155970d..227ca39281f6672c09f174a4065900ab83521aa1 100644 (file)
@@ -100,6 +100,7 @@ void        KX_ConvertBulletObject( class   KX_GameObject* gameobj,
 
        bool isbulletdyna = false;
        bool isbulletsensor = false;
 
        bool isbulletdyna = false;
        bool isbulletsensor = false;
+       bool isbulletchar = false;
        bool useGimpact = false;
        CcdConstructionInfo ci;
        class PHY_IMotionState* motionstate = new KX_MotionState(gameobj->GetSGNode());
        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_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;
        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);
        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) :
        ////////////////////
        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) : 
                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;
                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]);
        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();
        // shapeInfo is reference counted, decrement now as we don't use it anymore
        if (shapeInfo)
                shapeInfo->Release();
index bd75246a97f631adc3ff0a29aeed1b38f5cd007c..f0e57ceac02e6226df8f51c99d8ac35cd4ff4503 100644 (file)
 
 #include "PHY_DynamicTypes.h"
 
 
 #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_bDyna(dyna),
        m_bSensor(sensor),
+       m_bCharacter(character),
        m_bCompound(compound),
        m_suspendDynamics(false),
        m_userdata(userdata)
        m_bCompound(compound),
        m_suspendDynamics(false),
        m_userdata(userdata)
index 68577f09414cb403cc637c37d4809a206c9a51ca..528bf00d574ef734660ae20e09960a89288f68c8 100644 (file)
@@ -53,11 +53,12 @@ class KX_IPhysicsController : public SG_Controller
 protected:
        bool            m_bDyna;
        bool            m_bSensor;
 protected:
        bool            m_bDyna;
        bool            m_bSensor;
+       bool            m_bCharacter;
        bool            m_bCompound;
        bool            m_suspendDynamics;
        void*           m_userdata;
 public:
        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();
 
 
        virtual ~KX_IPhysicsController();
 
 
@@ -109,6 +110,10 @@ public:
                m_bSensor = isSensor;
        }
 
                m_bSensor = isSensor;
        }
 
+       void    SetCharacter(bool isCharacter) {
+               m_bCharacter = isCharacter;
+       }
+
        bool    IsDyna(void) {
                return m_bDyna;
        }
        bool    IsDyna(void) {
                return m_bDyna;
        }
@@ -117,6 +122,10 @@ public:
                return m_bSensor;
        }
 
                return m_bSensor;
        }
 
+       bool    IsCharacter(void) {
+               return m_bCharacter;
+       }
+
        bool    IsCompound(void) {
                return m_bCompound;
        }
        bool    IsCompound(void) {
                return m_bCompound;
        }
index 503c16fae9cada5beff8e0de00aa889fdca92102..4f0ae4261c9214f357a2084ecf99fc7578f36ef0 100644 (file)
@@ -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;
 
                        !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
        SCA_IObject* replica = AddReplicaObject((SCA_IObject*)ob, other, time);
        
        // release here because AddReplicaObject AddRef's
index 6c1e2998bdb719f2bca7f21d46cd2b18e278ec18..92a9b405b7c8a1d22d1383820ffe0cc0587827e7 100644 (file)
@@ -22,6 +22,7 @@ subject to the following restrictions:
 
 #include "CcdPhysicsController.h"
 #include "btBulletDynamicsCommon.h"
 
 #include "CcdPhysicsController.h"
 #include "btBulletDynamicsCommon.h"
+#include "BulletCollision/CollisionDispatch/btGhostObject.h"
 #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
 
 #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
 #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
 
 #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
@@ -88,7 +89,7 @@ CcdPhysicsController::CcdPhysicsController (const CcdConstructionInfo& ci)
                m_shapeInfo->AddRef();
        
        m_bulletMotionState = 0;
                m_shapeInfo->AddRef();
        
        m_bulletMotionState = 0;
-       
+       m_characterController = 0;
        
        CreateRigidbody();
        
        
        CreateRigidbody();
        
@@ -151,6 +152,24 @@ public:
 
 };
 
 
 };
 
+class BlenderBulletCharacterController : public btKinematicCharacterController
+{
+private:
+       btMotionState* m_motionState;
+
+public:
+       BlenderBulletCharacterController(btMotionState *motionState, btPairCachingGhostObject *ghost, btConvexShape* shape, float stepHeight)
+               : btKinematicCharacterController(ghost,shape,stepHeight,2),
+                 m_motionState(motionState)
+       {
+       }
+
+       virtual void updateAction(btCollisionWorld *collisionWorld, btScalar dt)
+       {
+               btKinematicCharacterController::updateAction(collisionWorld,dt);
+               m_motionState->setWorldTransform(getGhostObject()->getWorldTransform());
+       }
+};
 
 btRigidBody* CcdPhysicsController::GetRigidBody()
 {
 
 btRigidBody* CcdPhysicsController::GetRigidBody()
 {
@@ -164,6 +183,10 @@ btSoftBody* CcdPhysicsController::GetSoftBody()
 {
        return btSoftBody::upcast(m_object);
 }
 {
        return btSoftBody::upcast(m_object);
 }
+btKinematicCharacterController* CcdPhysicsController::GetCharacterController()
+{
+       return m_characterController;
+}
 
 #include "BulletSoftBody/btSoftBodyHelpers.h"
 
 
 #include "BulletSoftBody/btSoftBodyHelpers.h"
 
@@ -425,6 +448,29 @@ bool CcdPhysicsController::CreateSoftbody()
        return true;
 }
 
        return true;
 }
 
+bool CcdPhysicsController::CreateCharacterController()
+{
+       if (!m_cci.m_bCharacter)
+               return false;
+       m_object = new btPairCachingGhostObject();
+       m_object->setCollisionShape(m_collisionShape);
+       m_object->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
+
+       btTransform trans;
+       m_bulletMotionState->getWorldTransform(trans);
+       m_object->setWorldTransform(trans);
+
+       m_characterController = new BlenderBulletCharacterController(m_bulletMotionState,(btPairCachingGhostObject*)m_object,(btConvexShape*)m_collisionShape,m_cci.m_stepHeight);
+
+       PHY__Vector3 gravity;
+       m_cci.m_physicsEnv->getGravity(gravity);
+       m_characterController->setGravity(-gravity.m_vec[2]); // need positive gravity
+       m_characterController->setJumpSpeed(m_cci.m_jumpSpeed);
+       m_characterController->setFallSpeed(m_cci.m_fallSpeed);
+
+       return true;
+}
 
 void CcdPhysicsController::CreateRigidbody()
 {
 
 void CcdPhysicsController::CreateRigidbody()
 {
@@ -433,7 +479,7 @@ void CcdPhysicsController::CreateRigidbody()
        m_bulletMotionState = new BlenderBulletMotionState(m_MotionState);
 
        ///either create a btCollisionObject, btRigidBody or btSoftBody
        m_bulletMotionState = new BlenderBulletMotionState(m_MotionState);
 
        ///either create a btCollisionObject, btRigidBody or btSoftBody
-       if (CreateSoftbody())
+       if (CreateSoftbody() || CreateCharacterController())
                // soft body created, done
                return;
 
                // soft body created, done
                return;
 
index 2228b6511ce89b1525d00e1ba342530d331e0ca5..63c267443aa6a6d4ba952b1cf330eb4392e2742c 100644 (file)
@@ -29,6 +29,7 @@ subject to the following restrictions:
 ///    PHY_IPhysicsController is the abstract simplified Interface to a physical object.
 ///    It contains the IMotionState and IDeformableMesh Interfaces.
 #include "btBulletDynamicsCommon.h"
 ///    PHY_IPhysicsController is the abstract simplified Interface to a physical object.
 ///    It contains the IMotionState and IDeformableMesh Interfaces.
 #include "btBulletDynamicsCommon.h"
+#include "BulletDynamics/Character/btKinematicCharacterController.h"
 #include "LinearMath/btTransform.h"
 
 #include "PHY_IMotionState.h"
 #include "LinearMath/btTransform.h"
 
 #include "PHY_IMotionState.h"
@@ -221,7 +222,8 @@ struct CcdConstructionInfo
                KinematicFilter = 4,
                DebrisFilter = 8,
                SensorFilter = 16,
                KinematicFilter = 4,
                DebrisFilter = 8,
                SensorFilter = 16,
-               AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorFilter,
+               CharacterFilter = 32,
+               AllFilter = DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorFilter | CharacterFilter,
        };
 
 
        };
 
 
@@ -301,6 +303,10 @@ struct CcdConstructionInfo
        btScalar        m_margin;
 
        ////////////////////
        btScalar        m_margin;
 
        ////////////////////
+       float   m_stepHeight;
+       float   m_jumpSpeed;
+       float   m_fallSpeed;
+       
        int             m_gamesoftFlag;
        float   m_soft_linStiff;                        /* linear stiffness 0..1 */
        float   m_soft_angStiff;                /* angular stiffness 0..1 */
        int             m_gamesoftFlag;
        float   m_soft_linStiff;                        /* linear stiffness 0..1 */
        float   m_soft_angStiff;                /* angular stiffness 0..1 */
@@ -343,6 +349,7 @@ struct CcdConstructionInfo
        bool            m_bRigid;
        bool            m_bSoft;
        bool            m_bSensor;
        bool            m_bRigid;
        bool            m_bSoft;
        bool            m_bSensor;
+       bool            m_bCharacter;
        bool            m_bGimpact;                     // use Gimpact for mesh body
 
        ///optional use of collision group/mask:
        bool            m_bGimpact;                     // use Gimpact for mesh body
 
        ///optional use of collision group/mask:
@@ -391,6 +398,7 @@ class CcdPhysicsController : public PHY_IPhysicsController
 {
 protected:
        btCollisionObject* m_object;
 {
 protected:
        btCollisionObject* m_object;
+       btKinematicCharacterController* m_characterController;
        
 
        class PHY_IMotionState*         m_MotionState;
        
 
        class PHY_IMotionState*         m_MotionState;
@@ -417,6 +425,7 @@ protected:
 
        void CreateRigidbody();
        bool CreateSoftbody();
 
        void CreateRigidbody();
        bool CreateSoftbody();
+       bool CreateCharacterController();
 
        bool Register() { 
                return (m_registerCount++ == 0) ? true : false;
 
        bool Register() { 
                return (m_registerCount++ == 0) ? true : false;
@@ -453,6 +462,7 @@ protected:
                btRigidBody* GetRigidBody();
                btCollisionObject*      GetCollisionObject();
                btSoftBody* GetSoftBody();
                btRigidBody* GetRigidBody();
                btCollisionObject*      GetCollisionObject();
                btSoftBody* GetSoftBody();
+               btKinematicCharacterController* GetCharacterController();
 
                CcdShapeConstructionInfo* GetShapeInfo() { return m_shapeInfo; }
 
 
                CcdShapeConstructionInfo* GetShapeInfo() { return m_shapeInfo; }
 
index ba0d3f18b1dc054ab68e050409f97e6b0022301b..767d99583b86a41c76d783ab5ddd5f29e487bd23 100644 (file)
@@ -26,6 +26,7 @@ subject to the following restrictions:
 #include <algorithm>
 #include "btBulletDynamicsCommon.h"
 #include "LinearMath/btIDebugDraw.h"
 #include <algorithm>
 #include "btBulletDynamicsCommon.h"
 #include "LinearMath/btIDebugDraw.h"
+#include "BulletCollision/CollisionDispatch/btGhostObject.h"
 #include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
 #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
 #include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
 #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
@@ -369,6 +370,7 @@ m_scalingPropagated(false)
 
        m_filterCallback = new CcdOverlapFilterCallBack(this);
        m_broadphase->getOverlappingPairCache()->setOverlapFilterCallback(m_filterCallback);
 
        m_filterCallback = new CcdOverlapFilterCallBack(this);
        m_broadphase->getOverlappingPairCache()->setOverlapFilterCallback(m_filterCallback);
+       m_broadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
 
        setSolverType(1);//issues with quickstep and memory allocations
 //     m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
 
        setSolverType(1);//issues with quickstep and memory allocations
 //     m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
@@ -406,7 +408,11 @@ void       CcdPhysicsEnvironment::addCcdPhysicsController(CcdPhysicsController* ctrl)
                {
                        if (obj->getCollisionShape())
                        {
                {
                        if (obj->getCollisionShape())
                        {
-                               m_dynamicsWorld->addCollisionObject(obj,ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
+                               m_dynamicsWorld->addCollisionObject(obj, ctrl->GetCollisionFilterGroup(), ctrl->GetCollisionFilterMask());
+                       }
+                       if (ctrl->GetCharacterController())
+                       {
+                               m_dynamicsWorld->addAction(ctrl->GetCharacterController());
                        }
                }
        }
                        }
                }
        }
index 110d4731cdc012ef5136387387e50d2449ae6082..b930177d3a8b0c28cc20a76e826e1e3f03c52b42 100644 (file)
@@ -46,6 +46,9 @@ struct PHY_ShapeProps {
        bool       m_do_anisotropic;        // Should I do anisotropic friction? 
        bool       m_do_fh;                 // Should the object have a linear Fh spring?
        bool       m_do_rot_fh;             // Should the object have an angular Fh spring?
        bool       m_do_anisotropic;        // Should I do anisotropic friction? 
        bool       m_do_fh;                 // Should the object have a linear Fh spring?
        bool       m_do_rot_fh;             // Should the object have an angular Fh spring?
+       MT_Scalar  m_step_height;                       // Max height of climbable steps (Character)
+       MT_Scalar  m_jump_speed;                        // Velocity of jumps (Character)
+       MT_Scalar  m_fall_speed;                        // Max velocity of falling (Character)
 };
 
 
 };