[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