def create(name, name_e='', scale=1, obj_name=None, armature=None, add_root_bone=False): scene = SceneOp(bpy.context) if obj_name is None: obj_name = name root = bpy.data.objects.new(name=obj_name, object_data=None) root.mmd_type = 'ROOT' root.mmd_root.name = name root.mmd_root.name_e = name_e root.empty_draw_size = scale / 0.2 scene.link_object(root) armObj = armature if armObj: m = armObj.matrix_world armObj.parent_type = 'OBJECT' armObj.parent = root #armObj.matrix_world = m root.matrix_world = m armObj.matrix_local.identity() else: arm = bpy.data.armatures.new(name=obj_name) #arm.draw_type = 'STICK' armObj = bpy.data.objects.new(name=obj_name + '_arm', object_data=arm) armObj.parent = root scene.link_object(armObj) armObj.lock_rotation = armObj.lock_location = armObj.lock_scale = [ True, True, True ] armObj.show_x_ray = True armObj.draw_type = 'WIRE' if add_root_bone: bone_name = u'全ての親' with bpyutils.edit_object(armObj) as data: bone = data.edit_bones.new(name=bone_name) bone.head = [0.0, 0.0, 0.0] bone.tail = [0.0, 0.0, root.empty_draw_size] armObj.pose.bones[bone_name].mmd_bone.name_j = bone_name armObj.pose.bones[bone_name].mmd_bone.name_e = 'Root' bpyutils.select_object(root) return Model(root)
def execute(self, context): obj = context.active_object root = mmd_model.Model.findRoot(obj) rig = mmd_model.Model(root) mmd_root = root.mmd_root meshObj = None for i in rig.meshes(): meshObj = i break if meshObj is None: self.report({ 'ERROR' }, "The model mesh can't be found") return { 'CANCELLED' } with bpyutils.select_object(meshObj) as data: if meshObj.data.shape_keys is None: bpy.ops.object.shape_key_add() data.shape_key_add(self.name_j) idx = len(meshObj.data.shape_keys.key_blocks)-1 meshObj.active_shape_key_index = idx vtx_morph = mmd_root.vertex_morphs.add() vtx_morph.name = self.name_j vtx_morph.name_e = self.name_e vtx_morph.category = self.category mmd_root.active_morph = len(mmd_root.vertex_morphs)-1 frame = mmd_root.display_item_frames[u'表情'] item = frame.items.add() item.name = vtx_morph.name item.type = 'MORPH' item.morph_category = self.category return { 'FINISHED' }
def execute(self, context): obj = context.active_object root = mmd_model.Model.findRoot(obj) rig = mmd_model.Model(root) mmd_root = root.mmd_root items_map = { "MATMORPH": "material_morphs", "BONEMORPH": "bone_morphs", "VTXMORPH": "vertex_morphs" } attr_name = items_map[mmd_root.active_morph_type] items = getattr(mmd_root, attr_name) if mmd_root.active_morph >= 0 and mmd_root.active_morph < len(items): active_morph = items[mmd_root.active_morph] if attr_name == "vertex_morphs": for meshObj in rig.meshes(): with bpyutils.select_object(meshObj) as m: if m.data.shape_keys is not None: i = m.data.shape_keys.key_blocks.find( active_morph.name) m.active_shape_key_index = i bpy.ops.object.shape_key_remove() facial_frame = mmd_root.display_item_frames[u'表情'] idx = facial_frame.items.find(active_morph.name) if facial_frame.active_item == idx: facial_frame.active_item -= 1 facial_frame.items.remove(idx) items.remove(mmd_root.active_morph) mmd_root.active_morph -= 1 return {'FINISHED'}
def execute(self, context): obj = context.active_object root = mmd_model.Model.findRoot(obj) rig = mmd_model.Model(root) mmd_root = root.mmd_root meshObj = None for i in rig.meshes(): meshObj = i break if meshObj is None: self.report({'ERROR'}, "The model mesh can't be found") return {'CANCELLED'} with bpyutils.select_object(meshObj) as data: if meshObj.data.shape_keys is None: bpy.ops.object.shape_key_add() data.shape_key_add(self.name_j) idx = len(meshObj.data.shape_keys.key_blocks) - 1 meshObj.active_shape_key_index = idx vtx_morph = mmd_root.vertex_morphs.add() vtx_morph.name = self.name_j vtx_morph.name_e = self.name_e vtx_morph.category = self.category mmd_root.active_morph = len(mmd_root.vertex_morphs) - 1 frame = mmd_root.display_item_frames[u'表情'] item = frame.items.add() item.name = vtx_morph.name item.type = 'MORPH' item.morph_category = self.category return {'FINISHED'}
def execute(self, context): obj = context.active_object root = mmd_model.Model.findRoot(obj) rig = mmd_model.Model(root) mmd_root = root.mmd_root items_map = {"MATMORPH":"material_morphs", "BONEMORPH":"bone_morphs", "VTXMORPH":"vertex_morphs"} attr_name = items_map[mmd_root.active_morph_type] items = getattr(mmd_root, attr_name) if mmd_root.active_morph >= 0 and mmd_root.active_morph < len(items): active_morph = items[mmd_root.active_morph] if attr_name == "vertex_morphs": for meshObj in rig.meshes(): with bpyutils.select_object(meshObj) as m: if m.data.shape_keys is not None: i = m.data.shape_keys.key_blocks.find(active_morph.name) m.active_shape_key_index = i bpy.ops.object.shape_key_remove() facial_frame = mmd_root.display_item_frames[u'表情'] idx = facial_frame.items.find(active_morph.name) if facial_frame.active_item == idx: facial_frame.active_item -= 1 facial_frame.items.remove(idx) items.remove(mmd_root.active_morph) mmd_root.active_morph -= 1 return { 'FINISHED' }
def get_selected_pose_bones(armature): if armature.mode == 'EDIT': with bpyutils.select_object(armature): # update selected bones bpy.ops.object.mode_set(mode='EDIT') # back to edit mode context_selected_bones = bpy.context.selected_pose_bones or bpy.context.selected_bones or [] bones = armature.pose.bones return (bones[b.name] for b in context_selected_bones if not bones[b.name].is_mmd_shadow_bone)
def apply_bone_groups(mmd_root, armature): arm_bone_groups = armature.pose.bone_groups if not hasattr(arm_bone_groups, 'remove'): #bpy.app.version < (2, 72, 0): from mmd_tools import bpyutils bpyutils.select_object(armature) bpy.ops.object.mode_set(mode='POSE') class arm_bone_groups: values = armature.pose.bone_groups.values get = armature.pose.bone_groups.get @staticmethod def new(name): bpy.ops.pose.group_add() group = armature.pose.bone_groups.active group.name = name return group @staticmethod def remove(group): armature.pose.bone_groups.active = group bpy.ops.pose.group_remove() pose_bones = armature.pose.bones used_groups = set() unassigned_bones = {b.name for b in pose_bones} for frame in mmd_root.display_item_frames: for item in frame.data: if item.type == 'BONE' and item.name in unassigned_bones: unassigned_bones.remove(item.name) group_name = frame.name used_groups.add(group_name) group = arm_bone_groups.get(group_name) if group is None: group = arm_bone_groups.new(name=group_name) pose_bones[item.name].bone_group = group for name in unassigned_bones: pose_bones[name].bone_group = None # remove unused bone groups for group in arm_bone_groups.values(): if group.name not in used_groups: arm_bone_groups.remove(group)
def __makeSpring(self, target, base_obj, spring_stiffness): with bpyutils.select_object(target): bpy.ops.object.duplicate() spring_target = SceneOp(bpy.context).active_object t = spring_target.constraints.get('mmd_tools_rigid_parent') if t is not None: spring_target.constraints.remove(t) spring_target.mmd_type = 'SPRING_GOAL' spring_target.rigid_body.kinematic = True spring_target.rigid_body.collision_groups = (False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True) spring_target.parent = base_obj spring_target.matrix_parent_inverse = mathutils.Matrix( base_obj.matrix_basis).inverted() spring_target.hide = True obj = bpy.data.objects.new('S.' + target.name, None) SceneOp(bpy.context).link_object(obj) obj.location = target.location obj.empty_draw_size = 0.1 obj.empty_draw_type = 'ARROWS' obj.hide_render = True obj.select = False obj.hide = True obj.mmd_type = 'SPRING_CONSTRAINT' obj.parent = self.temporaryGroupObject() with bpyutils.select_object(obj): bpy.ops.rigidbody.constraint_add(type='GENERIC_SPRING') rbc = obj.rigid_body_constraint rbc.object1 = target rbc.object2 = spring_target rbc.use_spring_x = True rbc.use_spring_y = True rbc.use_spring_z = True rbc.spring_stiffness_x = spring_stiffness[0] rbc.spring_stiffness_y = spring_stiffness[1] rbc.spring_stiffness_z = spring_stiffness[2]
def execute(self, context): obj = context.active_object root = mmd_model.Model.findRoot(obj) if root is None: self.report({'ERROR'}, 'Select a MMD model') return {'CANCELLED'} if root: bpy.ops.mmd_tools.clear_temp_materials() bpy.ops.mmd_tools.clear_uv_morph_view() # Find all the meshes in mmd_root rig = mmd_model.Model(root) meshes_list = sorted(rig.meshes(), key=lambda x: x.name) if not meshes_list: self.report({'ERROR'}, 'The model does not have any meshes') return {'CANCELLED'} active_mesh = meshes_list[0] from mmd_tools import bpyutils bpyutils.select_object(active_mesh, objects=meshes_list) # Store the current order of the materials for m in meshes_list[1:]: for mat in m.data.materials: if getattr(mat, 'name', None) not in active_mesh.data.materials[:]: active_mesh.data.materials.append(mat) # Join selected meshes bpy.ops.object.join() if self.sort_shape_keys: FnMorph.fixShapeKeyOrder(active_mesh, root.mmd_root.vertex_morphs.keys()) active_mesh.active_shape_key_index = 0 if len(root.mmd_root.material_morphs) > 0: for morph in root.mmd_root.material_morphs: mo = FnMorph(morph, rig) mo.update_mat_related_mesh(active_mesh) utils.clearUnusedMeshes() return {'FINISHED'}
def assign(self, obj): if obj is None: return if obj.type == 'ARMATURE': with bpyutils.select_object(obj): bpy.ops.object.mode_set(mode='POSE') self.__assignToArmature(obj) elif obj.type == 'MESH': self.__assignToMesh(obj) else: pass
def __makeSpring(self, target, base_obj, spring_stiffness): with bpyutils.select_object(target): bpy.ops.object.duplicate() spring_target = bpy.context.scene.objects.active t = spring_target.constraints.get('mmd_tools_rigid_parent') if t is not None: spring_target.constraints.remove(t) spring_target.mmd_type = 'SPRING_GOAL' spring_target.rigid_body.kinematic = True spring_target.rigid_body.collision_groups = (False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True) spring_target.parent = base_obj spring_target.matrix_parent_inverse = mathutils.Matrix(base_obj.matrix_basis).inverted() spring_target.hide = True obj = bpy.data.objects.new( 'S.' + target.name, None) bpy.context.scene.objects.link(obj) obj.location = target.location obj.empty_draw_size = 0.1 obj.empty_draw_type = 'ARROWS' obj.hide_render = True obj.select = False obj.hide = True obj.mmd_type = 'SPRING_CONSTRAINT' obj.parent = self.temporaryGroupObject() with bpyutils.select_object(obj): bpy.ops.rigidbody.constraint_add(type='GENERIC_SPRING') rbc = obj.rigid_body_constraint rbc.object1 = target rbc.object2 = spring_target rbc.use_spring_x = True rbc.use_spring_y = True rbc.use_spring_z = True rbc.spring_stiffness_x = spring_stiffness[0] rbc.spring_stiffness_y = spring_stiffness[1] rbc.spring_stiffness_z = spring_stiffness[2]
def __createNonCollisionConstraint(self, nonCollisionJointTable): total_len = len(nonCollisionJointTable) if total_len < 1: return start_time = time.time() logging.debug('-' * 60) logging.debug(' creating ncc, counts: %d', total_len) ncc_obj = bpy.data.objects.new('ncc', None) bpy.context.scene.collection.objects.link(ncc_obj) ncc_obj.location = [0, 0, 0] ncc_obj.empty_display_size = 0.5 ncc_obj.empty_display_type = 'ARROWS' ncc_obj.mmd_type = 'NON_COLLISION_CONSTRAINT' ncc_obj.hide_render = True ncc_obj.parent = self.temporaryGroupObject() with bpyutils.select_object(ncc_obj): bpy.ops.rigidbody.constraint_add(type='GENERIC') rb = ncc_obj.rigid_body_constraint rb.disable_collisions = True ncc_objs = [] last_selected = [ncc_obj] while len(ncc_objs) < total_len: bpy.ops.object.duplicate() ncc_objs.extend(bpy.context.selected_objects) remain = total_len - len(ncc_objs) - len( bpy.context.selected_objects) if remain < 0: last_selected = bpy.context.selected_objects for i in range(-remain): last_selected[i].select_set(False) else: for i in range(min(remain, len(last_selected))): last_selected[i].select_set(True) last_selected = bpy.context.selected_objects logging.debug(' created %d ncc.', len(ncc_objs)) for i in range(total_len): rb = ncc_objs[i].rigid_body_constraint rb.object1, rb.object2 = nonCollisionJointTable[i] logging.debug(' finish in %f seconds.', time.time() - start_time) logging.debug('-' * 60)
def __exportPoseLib(self, armObj, pose_type, filepath, use_pose_mode=False): if armObj is None: return None if armObj.pose_library is None: return None pose_bones = armObj.pose.bones converters = self.__getConverters(pose_bones) backup = { b: (b.matrix_basis.copy(), b.bone.select) for b in pose_bones } for b in pose_bones: b.bone.select = False matrix_basis_map = {} if use_pose_mode: matrix_basis_map = {b: bak[0] for b, bak in backup.items()} def __export_index(index, filepath): bpy.ops.poselib.apply_pose(pose_index=index) vpd_bones = self.__exportBones(armObj, converters, matrix_basis_map) self.__exportVPDFile(filepath, vpd_bones) try: pose_markers = armObj.pose_library.pose_markers with bpyutils.select_object(armObj): bpy.ops.object.mode_set(mode='POSE') if pose_type == 'ACTIVE': if 0 <= pose_markers.active_index < len(pose_markers): __export_index(pose_markers.active_index, filepath) else: folder = os.path.dirname(filepath) for i, m in enumerate(pose_markers): __export_index(i, os.path.join(folder, m.name + '.vpd')) finally: for b, bak in backup.items(): b.matrix_basis, b.bone.select = bak
def __createNonCollisionConstraint(self, nonCollisionJointTable): total_len = len(nonCollisionJointTable) if total_len < 1: return start_time = time.time() logging.debug('-' * 60) logging.debug(' creating ncc, counts: %d', total_len) ncc_obj = bpy.data.objects.new('ncc', None) bpy.context.scene.objects.link(ncc_obj) ncc_obj.location = [0, 0, 0] ncc_obj.empty_draw_size = 0.5 ncc_obj.empty_draw_type = 'ARROWS' ncc_obj.mmd_type = 'NON_COLLISION_CONSTRAINT' ncc_obj.hide_render = True ncc_obj.parent = self.temporaryGroupObject() with bpyutils.select_object(ncc_obj): bpy.ops.rigidbody.constraint_add(type='GENERIC') rb = ncc_obj.rigid_body_constraint rb.disable_collisions = True ncc_objs = [] last_selected = [ncc_obj] while len(ncc_objs) < total_len: bpy.ops.object.duplicate() ncc_objs.extend(bpy.context.selected_objects) remain = total_len - len(ncc_objs) - len(bpy.context.selected_objects) if remain < 0: last_selected = bpy.context.selected_objects for i in range(-remain): last_selected[i].select = False else: for i in range(min(remain, len(last_selected))): last_selected[i].select = True last_selected = bpy.context.selected_objects logging.debug(' created %d ncc.', len(ncc_objs)) for i in range(total_len): rb = ncc_objs[i].rigid_body_constraint rb.object1, rb.object2 = nonCollisionJointTable[i] logging.debug(' finish in %f seconds.', time.time() - start_time) logging.debug('-' * 60)
def execute(self, context): obj = context.active_object root = mmd_model.Model.findRoot(obj) rig = mmd_model.Model(root) mmd_root = root.mmd_root meshObj = obj selected = meshObj.select with bpyutils.select_object(meshObj) as data: morph = mmd_root.uv_morphs[mmd_root.active_morph] mesh = meshObj.data base_uv_name = mesh.uv_layers.active.name[5:] if base_uv_name not in mesh.uv_layers: self.report({'ERROR'}, ' * UV map "%s" not found' % base_uv_name) return {'CANCELLED'} base_uv_data = mesh.uv_layers[base_uv_name].data temp_uv_data = mesh.uv_layers.active.data axis_type = 'ZW' if base_uv_name.startswith('_') else 'XY' from collections import namedtuple __OffsetData = namedtuple('OffsetData', 'index, offset') offsets = {} vertices = mesh.vertices for l, i0, i1 in zip(mesh.loops, base_uv_data, temp_uv_data): if vertices[ l. vertex_index].select and l.vertex_index not in offsets: dx, dy = i1.uv - i0.uv if abs(dx) > 0.0001 or abs(dy) > 0.0001: offsets[l.vertex_index] = __OffsetData( l.vertex_index, (dx, dy, dx, dy)) FnMorph.store_uv_morph_data(meshObj, morph, offsets.values(), axis_type) morph.data_type = 'VERTEX_GROUP' meshObj.select = selected return {'FINISHED'}
def execute(self, context): obj = context.active_object root = mmd_model.Model.findRoot(obj) rig = mmd_model.Model(root) mmd_root = root.mmd_root meshObj = obj selected = meshObj.select with bpyutils.select_object(meshObj) as data: bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.select_mode(type='VERT', action='ENABLE') bpy.ops.mesh.reveal() # unhide all vertices bpy.ops.mesh.select_all(action='DESELECT') bpy.ops.object.mode_set(mode='OBJECT') vertices = meshObj.data.vertices for l, d in zip(meshObj.data.loops, meshObj.data.uv_layers.active.data): if d.select: vertices[l.vertex_index].select = True bpy.ops.object.mode_set(mode='EDIT') meshObj.select = selected return {'FINISHED'}
def execute(self, context): obj = context.active_object root = mmd_model.Model.findRoot(obj) rig = mmd_model.Model(root) mmd_root = root.mmd_root meshes = tuple(rig.meshes()) if len(meshes) == 1: obj = meshes[0] elif obj not in meshes: self.report({'ERROR'}, 'Please select a mesh object') return {'CANCELLED'} meshObj = obj bpy.ops.mmd_tools.clear_uv_morph_view() selected = meshObj.select with bpyutils.select_object(meshObj) as data: morph = mmd_root.uv_morphs[mmd_root.active_morph] mesh = meshObj.data uv_textures = getattr(mesh, 'uv_textures', mesh.uv_layers) base_uv_layers = [ l for l in mesh.uv_layers if not l.name.startswith('_') ] if morph.uv_index >= len(base_uv_layers): self.report({'ERROR'}, "Invalid uv index: %d" % morph.uv_index) return {'CANCELLED'} uv_layer_name = base_uv_layers[morph.uv_index].name if morph.uv_index == 0 or uv_textures.active.name not in { uv_layer_name, '_' + uv_layer_name }: uv_textures.active = uv_textures[uv_layer_name] uv_layer_name = uv_textures.active.name uv_tex = uv_textures.new(name='__uv.%s' % uv_layer_name) if uv_tex is None: self.report({'ERROR'}, "Failed to create a temporary uv layer") return {'CANCELLED'} offsets = FnMorph.get_uv_morph_offset_map(meshObj, morph).items() offsets = { k: getattr(Vector(v), 'zw' if uv_layer_name.startswith('_') else 'xy') for k, v in offsets } if len(offsets) > 0: base_uv_data = mesh.uv_layers.active.data temp_uv_data = mesh.uv_layers[uv_tex.name].data for i, l in enumerate(mesh.loops): select = temp_uv_data[i].select = (l.vertex_index in offsets) if select: temp_uv_data[i].uv = base_uv_data[i].uv + offsets[ l.vertex_index] uv_textures.active = uv_tex uv_tex.active_render = True meshObj.hide = False meshObj.select = selected return {'FINISHED'}
def createRigidBody(self, **kwargs): ''' Create a object for MMD rigid body dynamics. ### Parameters ### @param shape_type the shape type. @param location location of the rigid body object. @param rotation rotation of the rigid body object. @param size @param dynamics_type the type of dynamics mode. (STATIC / DYNAMIC / DYNAMIC2) @param collision_group_number @param collision_group_mask list of boolean values. (length:16) @param name Object name (Optional) @param name_e English object name (Optional) @param bone ''' shape_type = kwargs['shape_type'] location = kwargs['location'] rotation = kwargs['rotation'] size = kwargs['size'] dynamics_type = kwargs['dynamics_type'] collision_group_number = kwargs.get('collision_group_number') collision_group_mask = kwargs.get('collision_group_mask') name = kwargs.get('name') name_e = kwargs.get('name_e') bone = kwargs.get('bone') friction = kwargs.get('friction') mass = kwargs.get('mass') angular_damping = kwargs.get('angular_damping') linear_damping = kwargs.get('linear_damping') bounce = kwargs.get('bounce') if shape_type == rigid_body.SHAPE_SPHERE: bpy.ops.mesh.primitive_uv_sphere_add(segments=16, ring_count=8, radius=1, enter_editmode=False) size = mathutils.Vector([1, 1, 1]) * size[0] rigid_type = 'SPHERE' bpy.ops.object.shade_smooth() elif shape_type == rigid_body.SHAPE_BOX: bpy.ops.mesh.primitive_cube_add(enter_editmode=False) size = mathutils.Vector(size) rigid_type = 'BOX' elif shape_type == rigid_body.SHAPE_CAPSULE: obj = bpyutils.makeCapsule(radius=size[0], height=size[1]) size = mathutils.Vector([1, 1, 1]) rigid_type = 'CAPSULE' with bpyutils.select_object(obj): bpy.ops.object.shade_smooth() else: raise ValueError('Unknown shape type: %s' % (str(shape_type))) obj = bpy.context.active_object bpy.ops.rigidbody.object_add(type='ACTIVE') obj.location = location obj.rotation_mode = 'YXZ' obj.rotation_euler = rotation obj.scale = size obj.hide_render = True obj.mmd_type = 'RIGID_BODY' obj.mmd_rigid.shape = rigid_type obj.mmd_rigid.type = str(dynamics_type) obj.display_type = 'WIRE' obj.show_wire = True with bpyutils.select_object(obj): bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) if collision_group_number is not None: obj.data.materials.append( RigidBodyMaterial.getMaterial(collision_group_number)) obj.mmd_rigid.collision_group_number = collision_group_number obj.display_type = 'SOLID' obj.show_transparent = True if collision_group_mask is not None: obj.mmd_rigid.collision_group_mask = collision_group_mask if name is not None: obj.name = name obj.mmd_rigid.name = name if name_e is not None: obj.mmd_rigid.name_e = name_e obj.rigid_body.collision_shape = rigid_type rb = obj.rigid_body if friction is not None: rb.friction = friction if mass is not None: rb.mass = mass if angular_damping is not None: rb.angular_damping = angular_damping if linear_damping is not None: rb.linear_damping = linear_damping if bounce: rb.restitution = bounce constraint = obj.constraints.new('CHILD_OF') constraint.target = self.armature() if bone is not None and bone != '': constraint.subtarget = bone constraint.name = 'mmd_tools_rigid_parent' constraint.mute = True obj.parent = self.rigidGroupObject() obj.select_set(False) self.__root.mmd_root.is_built = False return obj
def createJoint(self, **kwargs): ''' Create a joint object for MMD rigid body dynamics. ### Parameters ### @param shape_type the shape type. @param location location of the rigid body object. @param rotation rotation of the rigid body object. @param size @param dynamics_type the type of dynamics mode. (STATIC / DYNAMIC / DYNAMIC2) @param collision_group_number @param collision_group_mask list of boolean values. (length:16) @param name Object name @param name_e English object name (Optional) @param bone ''' location = kwargs['location'] rotation = kwargs['rotation'] size = kwargs['size'] rigid_a = kwargs['rigid_a'] rigid_b = kwargs['rigid_b'] max_loc = kwargs['maximum_location'] min_loc = kwargs['minimum_location'] max_rot = kwargs['maximum_rotation'] min_rot = kwargs['minimum_rotation'] spring_angular = kwargs['spring_angular'] spring_linear = kwargs['spring_linear'] name = kwargs['name'] name_e = kwargs.get('name_e') obj = bpy.data.objects.new('J.' + name, None) bpy.context.scene.collection.objects.link(obj) obj.mmd_type = 'JOINT' obj.mmd_joint.name_j = name if name_e is not None: obj.mmd_joint.name_e = name_e obj.location = location obj.rotation_euler = rotation obj.empty_display_size = size obj.empty_display_type = 'ARROWS' obj.hide_render = True obj.parent = self.armature() with bpyutils.select_object(obj): bpy.ops.rigidbody.constraint_add(type='GENERIC_SPRING') rbc = obj.rigid_body_constraint rbc.object1 = rigid_a rbc.object2 = rigid_b rbc.disable_collisions = False rbc.use_limit_ang_x = True rbc.use_limit_ang_y = True rbc.use_limit_ang_z = True rbc.use_limit_lin_x = True rbc.use_limit_lin_y = True rbc.use_limit_lin_z = True rbc.use_spring_x = True rbc.use_spring_y = True rbc.use_spring_z = True rbc.limit_lin_x_upper = max_loc[0] rbc.limit_lin_y_upper = max_loc[1] rbc.limit_lin_z_upper = max_loc[2] rbc.limit_lin_x_lower = min_loc[0] rbc.limit_lin_y_lower = min_loc[1] rbc.limit_lin_z_lower = min_loc[2] rbc.limit_ang_x_upper = min_rot[0] rbc.limit_ang_y_upper = min_rot[1] rbc.limit_ang_z_upper = min_rot[2] rbc.limit_ang_x_lower = max_rot[0] rbc.limit_ang_y_lower = max_rot[1] rbc.limit_ang_z_lower = max_rot[2] obj.mmd_joint.spring_linear = spring_linear obj.mmd_joint.spring_angular = spring_angular obj.parent = self.jointGroupObject() obj.select_set(False) self.__root.mmd_root.is_built = False return obj
def updateRigid(self, rigid_obj): if rigid_obj.mmd_type != 'RIGID_BODY': raise TypeError('rigid_obj must be a mmd_rigid object') rigid = rigid_obj.mmd_rigid relation = rigid_obj.constraints['mmd_tools_rigid_parent'] arm = relation.target bone_name = relation.subtarget target_bone = None if arm is not None and bone_name != '': target_bone = arm.pose.bones[bone_name] if target_bone is not None: for i in target_bone.constraints: if i.name == 'mmd_tools_rigid_track': target_bone.constraints.remove(i) if int(rigid.type) == rigid_body.MODE_STATIC: rigid_obj.rigid_body.kinematic = True else: rigid_obj.rigid_body.kinematic = False if int(rigid.type) == rigid_body.MODE_STATIC: if arm is not None and bone_name != '': relation.mute = False relation.inverse_matrix = mathutils.Matrix(target_bone.matrix).inverted() else: relation.mute = True else: relation.mute = True if int(rigid.type) in [rigid_body.MODE_DYNAMIC, rigid_body.MODE_DYNAMIC_BONE] and arm is not None and target_bone is not None: empty = bpy.data.objects.new( 'mmd_bonetrack', None) bpy.context.scene.objects.link(empty) empty.location = target_bone.tail empty.empty_draw_size = 0.1 empty.empty_draw_type = 'ARROWS' empty.mmd_type = 'TRACK_TARGET' empty.hide = True empty.parent = self.temporaryGroupObject() rigid_obj.mmd_rigid.bone = relation.subtarget rigid_obj.constraints.remove(relation) bpyutils.setParent(empty, rigid_obj) empty.select = False empty.hide = True for i in target_bone.constraints: if i.type == 'IK': i.mute = True const = target_bone.constraints.new('DAMPED_TRACK') const.name = 'mmd_tools_rigid_track' const.target = empty t = rigid_obj.hide with bpyutils.select_object(rigid_obj): bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) rigid_obj.hide = t rigid_obj.rigid_body.collision_shape = rigid.shape
def createJoint(self, **kwargs): ''' Create a joint object for MMD rigid body dynamics. ### Parameters ### @param shape_type the shape type. @param location location of the rigid body object. @param rotation rotation of the rigid body object. @param size @param dynamics_type the type of dynamics mode. (STATIC / DYNAMIC / DYNAMIC2) @param collision_group_number @param collision_group_mask list of boolean values. (length:16) @param name Object name @param name_e English object name (Optional) @param bone ''' location = kwargs['location'] rotation = kwargs['rotation'] size = kwargs['size'] rigid_a = kwargs['rigid_a'] rigid_b = kwargs['rigid_b'] max_loc = kwargs['maximum_location'] min_loc = kwargs['minimum_location'] max_rot = kwargs['maximum_rotation'] min_rot = kwargs['minimum_rotation'] spring_angular = kwargs['spring_angular'] spring_linear = kwargs['spring_linear'] name = kwargs['name'] name_e = kwargs.get('name_e') obj = bpy.data.objects.new( 'J.' + name, None) bpy.context.scene.objects.link(obj) obj.mmd_type = 'JOINT' obj.mmd_joint.name_j = name if name_e is not None: obj.mmd_joint.name_e = name_e obj.location = location obj.rotation_euler = rotation obj.empty_draw_size = size obj.empty_draw_type = 'ARROWS' obj.hide_render = True obj.parent = self.armature() with bpyutils.select_object(obj): bpy.ops.rigidbody.constraint_add(type='GENERIC_SPRING') rbc = obj.rigid_body_constraint rbc.object1 = rigid_a rbc.object2 = rigid_b rbc.disable_collisions = False rbc.use_limit_ang_x = True rbc.use_limit_ang_y = True rbc.use_limit_ang_z = True rbc.use_limit_lin_x = True rbc.use_limit_lin_y = True rbc.use_limit_lin_z = True rbc.use_spring_x = True rbc.use_spring_y = True rbc.use_spring_z = True rbc.limit_lin_x_upper = max_loc[0] rbc.limit_lin_y_upper = max_loc[1] rbc.limit_lin_z_upper = max_loc[2] rbc.limit_lin_x_lower = min_loc[0] rbc.limit_lin_y_lower = min_loc[1] rbc.limit_lin_z_lower = min_loc[2] rbc.limit_ang_x_upper = min_rot[0] rbc.limit_ang_y_upper = min_rot[1] rbc.limit_ang_z_upper = min_rot[2] rbc.limit_ang_x_lower = max_rot[0] rbc.limit_ang_y_lower = max_rot[1] rbc.limit_ang_z_lower = max_rot[2] obj.mmd_joint.spring_linear = spring_linear obj.mmd_joint.spring_angular = spring_angular obj.parent = self.jointGroupObject() obj.select = False self.__root.mmd_root.is_built = False return obj
def createRigidBody(self, **kwargs): ''' Create a object for MMD rigid body dynamics. ### Parameters ### @param shape_type the shape type. @param location location of the rigid body object. @param rotation rotation of the rigid body object. @param size @param dynamics_type the type of dynamics mode. (STATIC / DYNAMIC / DYNAMIC2) @param collision_group_number @param collision_group_mask list of boolean values. (length:16) @param name Object name (Optional) @param name_e English object name (Optional) @param bone ''' shape_type = kwargs['shape_type'] location = kwargs['location'] rotation = kwargs['rotation'] size = kwargs['size'] dynamics_type = kwargs['dynamics_type'] collision_group_number = kwargs.get('collision_group_number') collision_group_mask = kwargs.get('collision_group_mask') name = kwargs.get('name') name_e = kwargs.get('name_e') bone = kwargs.get('bone') friction = kwargs.get('friction') mass = kwargs.get('mass') angular_damping = kwargs.get('angular_damping') linear_damping = kwargs.get('linear_damping') bounce = kwargs.get('bounce') if shape_type == rigid_body.SHAPE_SPHERE: bpy.ops.mesh.primitive_uv_sphere_add( segments=16, ring_count=8, size=1, view_align=False, enter_editmode=False ) size = mathutils.Vector([1, 1, 1]) * size[0] rigid_type = 'SPHERE' bpy.ops.object.shade_smooth() elif shape_type == rigid_body.SHAPE_BOX: bpy.ops.mesh.primitive_cube_add( view_align=False, enter_editmode=False ) size = mathutils.Vector(size) rigid_type = 'BOX' elif shape_type == rigid_body.SHAPE_CAPSULE: obj = bpyutils.makeCapsule(radius=size[0], height=size[1]) size = mathutils.Vector([1, 1, 1]) rigid_type = 'CAPSULE' with bpyutils.select_object(obj): bpy.ops.object.shade_smooth() else: raise ValueError('Unknown shape type: %s' % (str(shape_type))) obj = bpy.context.active_object bpy.ops.rigidbody.object_add(type='ACTIVE') obj.location = location obj.rotation_mode = 'YXZ' obj.rotation_euler = rotation obj.scale = size obj.hide_render = True obj.mmd_type = 'RIGID_BODY' obj.mmd_rigid.shape = rigid_type obj.mmd_rigid.type = str(dynamics_type) obj.draw_type = 'WIRE' obj.show_wire = True with bpyutils.select_object(obj): bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) if collision_group_number is not None: obj.data.materials.append(RigidBodyMaterial.getMaterial(collision_group_number)) obj.mmd_rigid.collision_group_number = collision_group_number obj.draw_type = 'SOLID' obj.show_transparent = True if collision_group_mask is not None: obj.mmd_rigid.collision_group_mask = collision_group_mask if name is not None: obj.name = name obj.mmd_rigid.name = name if name_e is not None: obj.mmd_rigid.name_e = name_e obj.rigid_body.collision_shape = rigid_type rb = obj.rigid_body if friction is not None: rb.friction = friction if mass is not None: rb.mass = mass if angular_damping is not None: rb.angular_damping = angular_damping if linear_damping is not None: rb.linear_damping = linear_damping if bounce: rb.restitution = bounce constraint = obj.constraints.new('CHILD_OF') constraint.target = self.armature() if bone is not None and bone != '': constraint.subtarget = bone constraint.name = 'mmd_tools_rigid_parent' constraint.mute = True obj.parent = self.rigidGroupObject() obj.select = False self.__root.mmd_root.is_built = False return obj
def updateRigid(self, rigid_obj): if rigid_obj.mmd_type != 'RIGID_BODY': raise TypeError('rigid_obj must be a mmd_rigid object') rigid = rigid_obj.mmd_rigid relation = rigid_obj.constraints['mmd_tools_rigid_parent'] arm = relation.target bone_name = relation.subtarget target_bone = None if arm is not None and bone_name != '': target_bone = arm.pose.bones[bone_name] if target_bone is not None: for i in target_bone.constraints: if i.name == 'mmd_tools_rigid_track': target_bone.constraints.remove(i) if int(rigid.type) == rigid_body.MODE_STATIC: rigid_obj.rigid_body.kinematic = True else: rigid_obj.rigid_body.kinematic = False if int(rigid.type) == rigid_body.MODE_STATIC: if arm is not None and bone_name != '': relation.mute = False relation.inverse_matrix = mathutils.Matrix( target_bone.matrix).inverted() else: relation.mute = True else: relation.mute = True if int(rigid.type) in [ rigid_body.MODE_DYNAMIC, rigid_body.MODE_DYNAMIC_BONE ] and arm is not None and target_bone is not None: empty = bpy.data.objects.new('mmd_bonetrack', None) bpy.context.scene.collection.objects.link(empty) empty.location = target_bone.tail empty.empty_display_size = 0.1 empty.empty_display_type = 'ARROWS' empty.mmd_type = 'TRACK_TARGET' empty.hide_set(True) empty.parent = self.temporaryGroupObject() rigid_obj.mmd_rigid.bone = relation.subtarget rigid_obj.constraints.remove(relation) bpyutils.setParent(empty, rigid_obj) empty.select_set(False) empty.hide_set(True) for i in target_bone.constraints: if i.type == 'IK': i.mute = True const = target_bone.constraints.new('DAMPED_TRACK') const.name = 'mmd_tools_rigid_track' const.target = empty t = rigid_obj.hide_get() with bpyutils.select_object(rigid_obj): bpy.ops.object.transform_apply(location=False, rotation=False, scale=True) rigid_obj.hide_set(t) rigid_obj.rigid_body.collision_shape = rigid.shape