From 843b45cafa618cd6230a16ca13f24860b3301b39 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Wed, 8 Aug 2012 01:24:48 +0000 Subject: [PATCH] --- .../scripts/startup/bl_ui/properties_game.py | 12 +++- source/blender/blenkernel/intern/object.c | 2 + source/blender/blenloader/intern/readfile.c | 10 +++ source/blender/makesdna/DNA_object_types.h | 6 ++ source/blender/makesrna/intern/rna_object.c | 70 +++++++++++++++++++ source/gameengine/Ketsji/KX_GameObject.cpp | 13 ++++ source/gameengine/Ketsji/KX_GameObject.h | 11 +++ .../Physics/Bullet/CcdPhysicsEnvironment.cpp | 8 +++ 8 files changed, 130 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index 5ff49a7d369..f055ac61b72 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -189,8 +189,16 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel): layout.operator("mesh.navmesh_reset") layout.operator("mesh.navmesh_clear") - - + + if physics_type not in {'NO_COLLISION', 'OCCLUDE'}: + layout.separator() + split = layout.split() + + col = split.column() + col.prop(game, "collision_group") + col = split.column() + col.prop(game, "collision_mask") + class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel): bl_label = "Collision Bounds" COMPAT_ENGINES = {'BLENDER_GAME'} diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index baf216b95e9..f2b1dada791 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -844,6 +844,8 @@ Object *BKE_object_add_only_object(int type, const char *name) ob->step_height = 0.15f; ob->jump_speed = 10.0f; ob->fall_speed = 55.0f; + ob->col_group = 0x01; + ob->col_mask = 0xff; /* NT fluid sim defaults */ ob->fluidsimSettings = NULL; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 73494d118d4..4c5c796aec4 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7890,6 +7890,16 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ntreetype->foreach_nodetree(main, NULL, do_version_ntree_mask_264); } + { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + if (ob->col_group == 0) { + ob->col_group = 0x01; + ob->col_mask = 0xff; + } + } + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 3da6d0fc99d..cf28f36ef77 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -241,6 +241,9 @@ typedef struct Object { short recalc; /* dependency flag */ float anisotropicFriction[3]; + /** Collision mask settings */ + unsigned short col_group, col_mask, col_pad[2]; + ListBase constraints; /* object constraints */ ListBase nlastrips DNA_DEPRECATED; // XXX depreceated... old animation system ListBase hooks DNA_DEPRECATED; // XXX depreceated... old animation system @@ -472,6 +475,9 @@ typedef struct DupliObject { /* controller state */ #define OB_MAX_STATES 30 +/* collision masks */ +#define OB_MAX_COL_MASKS 8 + /* ob->gameflag */ #define OB_DYNAMIC 1 #define OB_CHILD 2 diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 7aedbf40eba..a95645e5d9f 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1077,6 +1077,62 @@ static void rna_GameObjectSettings_state_set(PointerRNA *ptr, const int *values) } } +static void rna_GameObjectSettings_col_group_get(PointerRNA *ptr, int *values) +{ + Object *ob = (Object*)ptr->data; + int i; + + for (i = 0; i < OB_MAX_COL_MASKS; i++) + values[i] = (ob->col_group & (1<data; + int i, tot = 0; + + /* ensure we always have some group selected */ + for (i = 0; i < OB_MAX_COL_MASKS; i++) + if(values[i]) + tot++; + + if (tot==0) + return; + + for (i = 0; i < OB_MAX_COL_MASKS; i++) { + if (values[i]) ob->col_group |= (1<col_group &= ~(1<data; + int i; + + for (i = 0; i < OB_MAX_COL_MASKS; i++) + values[i] = (ob->col_mask & (1<data; + int i, tot = 0; + + /* ensure we always have some mask selected */ + for (i = 0; i < OB_MAX_COL_MASKS; i++) + if(values[i]) + tot++; + + if (tot==0) + return; + + for (i = 0; i < OB_MAX_COL_MASKS; i++) { + if (values[i]) ob->col_mask |= (1<col_mask &= ~(1<data; @@ -1438,6 +1494,8 @@ static void rna_def_object_game_settings(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + int default_col_mask[8] = {1,0,0,0, 0,0,0,0}; + static EnumPropertyItem body_type_items[] = { {OB_BODY_TYPE_NO_COLLISION, "NO_COLLISION", 0, "No Collision", "Disable collision for this object"}, {OB_BODY_TYPE_STATIC, "STATIC", 0, "Static", "Stationary object"}, @@ -1561,6 +1619,18 @@ static void rna_def_object_game_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall"); + prop = RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER); + RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1); + RNA_def_property_array(prop, OB_MAX_COL_MASKS); + RNA_def_property_ui_text(prop, "Collision Group", "The collision group of the object"); + RNA_def_property_boolean_funcs(prop, "rna_GameObjectSettings_col_group_get", "rna_GameObjectSettings_col_group_set"); + + prop = RNA_def_property(srna, "collision_mask", PROP_BOOLEAN, PROP_LAYER_MEMBER); + RNA_def_property_boolean_sdna(prop, NULL, "col_mask", 1); + RNA_def_property_array(prop, OB_MAX_COL_MASKS); + RNA_def_property_ui_text(prop, "Collision Mask", "The groups this object can collide with"); + RNA_def_property_boolean_funcs(prop, "rna_GameObjectSettings_col_mask_get", "rna_GameObjectSettings_col_mask_set"); + /* lock position */ prop = RNA_def_property(srna, "lock_location_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gameflag2", OB_LOCK_RIGID_BODY_X_AXIS); diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 04a806dfd92..5b8d5fbfe1f 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -481,6 +481,19 @@ void KX_GameObject::ActivateGraphicController(bool recurse) } } +void KX_GameObject::SetUserCollisionGroup(short group) +{ + m_userCollisionGroup = group; +} +void KX_GameObject::SetUserCollisionMask(short mask) +{ + m_userCollisionMask = mask; +} + +bool KX_GameObject::CheckCollision(KX_GameObject* other) +{ + return this->m_userCollisionGroup & other->m_userCollisionMask; +} CValue* KX_GameObject::GetReplica() { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 2b0d13ff2f7..569a4a2b2a1 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -98,6 +98,10 @@ protected: bool m_bIsNegativeScaling; MT_Vector4 m_objectColor; + // Bit fields for user control over physics collisions + short m_userCollisionGroup; + short m_userCollisionMask; + // visible = user setting // culled = while rendering, depending on camera bool m_bVisible; @@ -464,6 +468,13 @@ public: * @add/remove the graphic controller to the physic system */ void ActivateGraphicController(bool recurse); + + void SetUserCollisionGroup(short filter); + void SetUserCollisionMask(short mask); + /** + * Extra broadphase check for user controllable collisions + */ + bool CheckCollision(KX_GameObject *other); /** * \section Coordinate system manipulation functions diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index 5d28bf47401..49652ef9544 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -2214,11 +2214,19 @@ void CcdPhysicsEnvironment::CallbackTriggers() bool CcdOverlapFilterCallBack::needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const { btCollisionObject *colObj0, *colObj1; + KX_GameObject *gameObj0 = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)((CcdPhysicsController*)((btCollisionObject*)proxy0->m_clientObject)->getUserPointer())->getNewClientInfo()); + KX_GameObject *gameObj1 = KX_GameObject::GetClientObject((KX_ClientObjectInfo*)((CcdPhysicsController*)((btCollisionObject*)proxy1->m_clientObject)->getUserPointer())->getNewClientInfo()); CcdPhysicsController *sensorCtrl, *objCtrl; + bool collides; // first check the filters collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + if (gameObj0 && gameObj1) + { + collides = collides && gameObj0->CheckCollision(gameObj1); + collides = collides && gameObj1->CheckCollision(gameObj0); + } if (!collides) return false;