From 820ca419e098f1ac90b499180a3206dd44692ba8 Mon Sep 17 00:00:00 2001 From: David Vogel Date: Thu, 30 Jul 2020 18:35:34 +0200 Subject: Add compound shape for rigid body simulation This patch adds a new compound shape entry to the shape selection dropdown. It also corrects wrong inertia calculation for convex hulls, that resulted in strange behavior for small objects. The compound shape take the collision shapes from its object children and combines them. This makes it possible to create concave shapes from primitive shapes. Using this instead of the mesh collision shape is often many times faster. Reviewed By: Sergey, Sebastian Parborg Differential Revision: http://developer.blender.org/D5797 --- .../startup/bl_ui/properties_physics_rigidbody.py | 46 +++++++++++++++++++--- 1 file changed, 41 insertions(+), 5 deletions(-) (limited to 'release/scripts') diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index b03f80bd600..a55bd89ca18 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -23,10 +23,10 @@ from bpy.types import ( ) -def rigid_body_warning(layout): +def rigid_body_warning(layout, text): row = layout.row(align=True) row.alignment = 'RIGHT' - row.label(text="Object does not have a Rigid Body") + row.label(text=text, icon='ERROR') class PHYSICS_PT_rigidbody_panel: @@ -49,13 +49,24 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): layout.use_property_split = True ob = context.object + parent = ob.parent rbo = ob.rigid_body if rbo is None: - rigid_body_warning(layout) + rigid_body_warning(layout, "Object does not have a Rigid Body") return - layout.prop(rbo, "type", text="Type") + if parent is not None and parent.rigid_body is not None: + if parent.rigid_body.collision_shape == 'COMPOUND': + row = layout.row(align=True) + row.alignment = 'RIGHT' + row.label(text="This object is part of a compound shape", icon='INFO') + else: + rigid_body_warning(layout, "Rigid Body can't be child of a non compound Rigid Body") + return + + if parent is None or parent.rigid_body is None: + layout.prop(rbo, "type", text="Type") class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel): @@ -66,6 +77,8 @@ class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel): @classmethod def poll(cls, context): obj = context.object + if obj.parent is not None and obj.parent.rigid_body is not None: + return False return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): @@ -76,7 +89,7 @@ class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel): rbo = ob.rigid_body if rbo is None: - rigid_body_warning(layout) + rigid_body_warning(layout, "Object does not have a Rigid Body") return col = layout.column() @@ -96,17 +109,32 @@ class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): @classmethod def poll(cls, context): obj = context.object + if obj.parent is not None and obj.parent.rigid_body is not None and not obj.parent.rigid_body.collision_shape == 'COMPOUND': + return False return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): layout = self.layout ob = context.object + parent = ob.parent rbo = ob.rigid_body layout.use_property_split = True layout.prop(rbo, "collision_shape", text="Shape") + if rbo.collision_shape == 'COMPOUND': + if parent is not None and parent.rigid_body is not None and parent.rigid_body.collision_shape == 'COMPOUND': + rigid_body_warning(layout, "Sub compound shapes are not allowed") + else: + found = False + for child in ob.children: + if child.rigid_body is not None: + found = True + break + if not found: + rigid_body_warning(layout, "There are no child rigid bodies") + if rbo.collision_shape in {'MESH', 'CONVEX_HULL'}: layout.prop(rbo, "mesh_source", text="Source") @@ -123,6 +151,8 @@ class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel @classmethod def poll(cls, context): obj = context.object + if obj.parent is not None and obj.parent.rigid_body is not None: + return False return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): @@ -149,6 +179,8 @@ class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, P @classmethod def poll(cls, context): obj = context.object + if obj.parent is not None and obj.parent.rigid_body is not None and not obj.parent.rigid_body.collision_shape == 'COMPOUND': + return False return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): @@ -180,6 +212,8 @@ class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, P @classmethod def poll(cls, context): obj = context.object + if obj.parent is not None and obj.parent.rigid_body is not None: + return False return (obj and obj.rigid_body and (context.engine in cls.COMPAT_ENGINES)) def draw(self, context): @@ -200,6 +234,8 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): @classmethod def poll(cls, context): obj = context.object + if obj.parent is not None and obj.parent.rigid_body is not None: + return False return (obj and obj.rigid_body and obj.rigid_body.type == 'ACTIVE' and (context.engine in cls.COMPAT_ENGINES)) -- cgit v1.2.3