[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [2123] contrib/py/scripts/addons/ game_engine_ragdolls_kit: Support added for BBone templates for rigid body creation as per Wraaah' s addition (many thanks :).

Marcus Jenkins funkywyrm at gmail.com
Sat Jul 16 20:31:29 CEST 2011


Revision: 2123
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=2123
Author:   funkywyrm
Date:     2011-07-16 18:31:29 +0000 (Sat, 16 Jul 2011)
Log Message:
-----------
Support added for BBone templates for rigid body creation as per Wraaah's addition (many thanks :).

In the operator display for the rigid body creation, there is now a dropdown box allowing selection between BBones, Envelopes and scalable values based on bone size. Default is BBones.

Modified Paths:
--------------
    contrib/py/scripts/addons/game_engine_ragdolls_kit/brik.py
    contrib/py/scripts/addons/game_engine_ragdolls_kit/brik_funcs.py

Modified: contrib/py/scripts/addons/game_engine_ragdolls_kit/brik.py
===================================================================
--- contrib/py/scripts/addons/game_engine_ragdolls_kit/brik.py	2011-07-15 14:20:07 UTC (rev 2122)
+++ contrib/py/scripts/addons/game_engine_ragdolls_kit/brik.py	2011-07-16 18:31:29 UTC (rev 2123)
@@ -83,7 +83,7 @@
     
     #Draws the brik panel in the tools pane
     def draw(self, context):
-
+        
         ob = bpy.context.object
 
         layout = self.layout
@@ -130,6 +130,329 @@
         else:
             col.label(text='Select an object')
 
+class brik_create_structure(bpy.types.Operator):
+    bl_label = 'brik create structure operator'
+    bl_idname = 'object.brik_create_structure'
+    bl_description = 'Create a rigid body structure based on an amature.'
+    bl_options = {'REGISTER', 'UNDO'}
+
+    #Properties that can be changed by the user
+
+    prefix = StringProperty(name='Prefix', \
+                            description='Prefix to be appended to the bone name that defines the rigid body object.',\
+                            default='RB_')
+    
+    driver_length = FloatProperty(name='Driver length',\
+                              description='Length of rigid body driver objects as proportion of bone length.',\
+                              min=0.05,\
+                              max=1.0,\
+                              step=0.05,\
+                              default=0.8)
+    
+    driver_width = FloatProperty(name = 'Driver width',\
+                                  description='Width of rigid body driver objects as proportion of bone length',\
+                                  min=0.05,\
+                                  max=1.0,\
+                                  step=0.05,\
+                                  default=0.2)
+    
+    add_to_group = BoolProperty(name='Add to group',\
+                                description='Add all created objects to a group',\
+                                default=True)
+                                
+    box_type = EnumProperty(name="Box type",
+        description="Shape that rigid body objects are created from.",
+        items=[ \
+          ('BONE', "Bone",
+              "Plain bone dimensions are used."),
+          ('ENVELOPE', "Envelope",
+              "Bone envelope dimensions are used."),
+          ('BBONE', "BBone",
+              "BBone dimensions are used. "\
+              "(BBones can be scaled using Ctrl+Alt+S in armature edit mode.)"),
+          ],
+        default='BBONE')
+    
+    #Create the rigid body boxes
+    def create_boxes(self, armature):
+        bones_dict = armature.pose.bones      #Dictionary of posebones
+        bones = bones_dict.values()
+        armature = bpy.context.object
+        
+        RB_dict = {}            #Dictionary of rigid body objects
+        
+        armature['brik_bone_driver_dict'] = {}
+        armature['brik_armature_locator_name'] = ''
+        
+        #All deforming bones have boxes created for them
+        for bone in bones:
+            if bone.bone.use_deform:
+                #print(self.box_type)
+                box = None
+                volume = 0.0
+                #Create boxes that do not exist
+                if self.box_type == 'BONE':
+                    box, volume = create_box(self.prefix, self.driver_length, self.driver_width, armature, bone)
+                elif self.box_type == 'BBONE':
+                    box, volume = create_box_bbone(self.prefix, armature, bone)
+                elif self.box_type == 'ENVELOPE':
+                    box, volume = create_box_envelope(self.prefix, armature, bone)
+                #box = create_box(self.prefix, self.driver_length, self.driver_width, armature, bone)
+                RB_dict[box.name] = box
+                armature['brik_bone_driver_dict'][bone.name] = box.name
+            
+                #Orientate and position the box
+                self.position_box(armature, bone, box)
+                box['brik_bone_name'] = bone.name
+    
+        return RB_dict
+    
+    def make_bone_constraints(self, armature, RB_dict):
+        bones_dict = armature.pose.bones
+        
+        for bone in bones_dict:
+            if not 'brik_copy_rot' in bone.constraints:
+                constraint = bone.constraints.new(type='COPY_ROTATION')
+                constraint.name = 'brik_copy_rot'
+                constraint.target = RB_dict[armature['brik_bone_driver_dict'][bone.name]]
+            if not 'brik_copy_loc' in bone.constraints:
+                if not bone.parent:
+                    #print(bone.head, bone.tail)
+                    if armature['brik_armature_locator_name'] == '':
+                        bpy.ops.object.add(type='EMPTY')
+                        locator = bpy.context.object
+                        locator.name = 'brik_'+armature.name+'_loc'
+                        locator.location = (0.0,-bone.length/2,0.0)
+                        locator.parent = RB_dict[armature['brik_bone_driver_dict'][bone.name]]
+                        armature['brik_armature_locator_name'] = locator.name
+                        bpy.ops.object.select_all(action='DESELECT')
+                        bpy.ops.object.select_name(name=armature.name, extend=False)
+                    else:
+                        locator = bpy.data.objects['brik_armature_locator_name']
+                        locator.location = (0.0,-bone.length/2,0.0)
+                        locator.parent = RB_dict[armature['brik_bone_driver_dict'][bone.name]]
+                    constraint = bone.constraints.new(type='COPY_LOCATION')
+                    constraint.name = 'brik_copy_loc'
+                    constraint.target = locator
+    
+    def reshape_boxes(self, armature):
+        '''
+        Reshape an existing box based on parameter changes.
+        I introduced this as an attempt to improve responsiveness. This should
+        eliminate the overhead from creating completely new meshes or objects on
+        each refresh.
+        '''
+        objects = bpy.context.scene.objects
+        
+        for bone_name in armature['brik_bone_driver_dict']:
+            bone = armature.bones[bone_name]
+            box = objects[armature['brik_bone_driver_dict'][bone_name]]
+        
+            height = bone.length
+            #gap = height * self.hit_box_length      #The distance between two boxes
+            box_length = bone.length*self.driver_length
+            width = bone.length * self.driver_width
+            
+            x = width/2
+            y = box_length/2
+            z = width/2
+            
+            verts = [[-x,y,-z],[-x,y,z],[x,y,z],[x,y,-z],\
+                     [x,-y,-z],[-x,-y,-z],[-x,-y,z],[x,-y,z]]
+            
+            #This could be a problem if custom object shapes are used...
+            count = 0
+            for vert in box.data.vertices:
+                vert.co = Vector(verts[count])
+                count += 1
+    
+    #Orient the box to the bone and set the box object centre to the bone location
+    def position_box(self, armature, bone, box):
+        scene = bpy.context.scene
+        
+        #Set the box to the bone orientation and location
+        box.matrix_world = bone.matrix
+        box.location = armature.location+bone.bone.head_local+(bone.bone.tail_local-bone.bone.head_local)/2
+    
+    #Set up the objects for rigid body physics and create rigid body joints.
+    def make_RB_constraints(self, armature, RB_dict):
+        bones_dict = armature.pose.bones
+        
+        for box in RB_dict:
+            bone = bones_dict[RB_dict[box]['brik_bone_name']]
+            
+            boxObj = RB_dict[box]
+            
+            #Make the radius half the length of the longest axis of the box
+            radius_driver_length = (bone.length*self.driver_length)/2
+            radius_driver_width = (bone.length*self.driver_width)/2
+            radius = radius_driver_length
+            if radius_driver_width > radius:
+                radius = radius_driver_width
+            
+            
+            #Set up game physics attributes
+            boxObj.game.use_actor = True
+            boxObj.game.use_ghost = False
+            boxObj.game.physics_type = 'RIGID_BODY'
+            boxObj.game.use_collision_bounds = True
+            boxObj.game.collision_bounds_type = 'BOX'
+            boxObj.game.radius = radius
+                
+            #Make the rigid body joints
+            if bone.parent:
+                #print(bone, bone.parent)
+                boxObj['brik_joint_target'] = armature['brik_bone_driver_dict'][bone.parent.name]
+                RB_joint = boxObj.constraints.new('RIGID_BODY_JOINT')
+                RB_joint.pivot_y = -bone.length/2
+                RB_joint.target = RB_dict[boxObj['brik_joint_target']]
+                RB_joint.use_linked_collision = True
+                RB_joint.pivot_type = ("GENERIC_6_DOF")
+                RB_joint.limit_angle_max_x = bone.ik_max_x
+                RB_joint.limit_angle_max_y = bone.ik_max_y
+                RB_joint.limit_angle_max_z = bone.ik_max_z
+                RB_joint.limit_angle_min_x = bone.ik_min_x
+                RB_joint.limit_angle_min_y = bone.ik_min_y
+                RB_joint.limit_angle_min_z = bone.ik_min_z
+                RB_joint.use_limit_x = True
+                RB_joint.use_limit_y = True
+                RB_joint.use_limit_z = True
+                RB_joint.use_angular_limit_x = True
+                RB_joint.use_angular_limit_y = True
+                RB_joint.use_angular_limit_z = True
+            else:
+                boxObj['brik_joint_target'] = 'None'
+    
+    def add_boxes_to_group(self, armature, RB_dict):
+        #print("Adding boxes to group")
+        group_name = self.prefix+armature.name+"_Group"
+        if not group_name in bpy.data.groups:
+            group = bpy.data.groups.new(group_name)
+        else:
+            group = bpy.data.groups[group_name]
+        #print(group)
+        #print(RB_dict)
+        for box in RB_dict:
+            if not box in group.objects:
+                group.objects.link(bpy.context.scene.objects[box])
+        
+        return
+    
+    #Armature and mesh need to be set to either no collision or ghost. No collision
+    #is much faster.
+    def set_armature_physics(self, armature):

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list