OSDN Git Service

add constraint.
[meshio/meshio.git] / swig / blender / pmd_import.py
index 8b0463f..3a7050e 100644 (file)
@@ -7,7 +7,7 @@
  Tooltip: 'Import PMD file for MikuMikuDance.'
 """
 __author__= ["ousttrue"]
-__version__= "1.1"
+__version__= "1.2"
 __url__=()
 __bpydoc__="""
 pmd Importer
@@ -24,11 +24,16 @@ This script imports a pmd into Blender for editing.
 0.8: 20100521: add shape_key group.
 1.0: 20100530: add invisilbe bone tail(armature layer 2).
 1.1: 20100608: integrate 2.4 and 2.5.
+1.2: 20100616: implement rigid body.
 """
 
 MMD_SHAPE_GROUP_NAME='_MMD_SHAPE'
 BASE_SHAPE_NAME='Basis'
-
+RIGID_SHAPE_TYPE='rigid_shape_type'
+RIGID_PROCESS_TYPE='rigid_process_type'
+RIGID_BONE_NAME='rigid_bone_name'
+CONSTRAINT_A='constraint_a'
+CONSTRAINT_B='constraint_b'
 
 ###############################################################################
 # import
@@ -560,6 +565,120 @@ def __importMesh(scene, io, tex_dir):
     return mesh_objects
 
 
+def __importConstraints(scene, io):
+    if isBlender24():
+        return
+    print("create constrains")
+    container=bl.createEmptyObject(scene, 'Constraints')
+    layer=[
+            True, False, False, False, False, False, False, False,
+            False, False, False, False, False, False, False, False,
+            False, False, False, False, False, False, False, False,
+            False, False, False, False, False, False, False, False,
+            ]
+    material=bl.createMaterial('constraint')
+    material.diffuse_color=(1, 0, 0)
+    constraintMeshes=[]
+    for c in io.constraints:
+        bpy.ops.mesh.primitive_uv_sphere_add(
+                segments=8,
+                rings=4,
+                size=0.1,
+                location=(c.pos.x, c.pos.z, c.pos.y),
+                layer=layer
+                )
+        meshObject=scene.objects.active
+        constraintMeshes.append(meshObject)
+        mesh=bl.objectGetData(meshObject)
+        bl.meshAddMaterial(mesh, material)
+        meshObject.name='c'+c.getName()
+        #meshObject.draw_transparent=True
+        #meshObject.draw_wire=True
+        meshObject.max_draw_type='SOLID'
+        rot=c.rot
+        meshObject.rotation_euler=(-rot.x, -rot.z, -rot.y)
+
+        meshObject[CONSTRAINT_A]=io.rigidbodies[c.rigidA].getName()
+        meshObject[CONSTRAINT_B]=io.rigidbodies[c.rigidB].getName()
+
+    for meshObject in reversed(constraintMeshes):
+        bl.objectMakeParent(container, meshObject)
+
+    return container
+
+
+def __importRigidBodies(scene, io):
+    if isBlender24():
+        return
+    print("create rigid bodies")
+
+    container=bl.createEmptyObject(scene, 'RigidBodies')
+    layer=[
+            True, False, False, False, False, False, False, False,
+            False, False, False, False, False, False, False, False,
+            False, False, False, False, False, False, False, False,
+            False, False, False, False, False, False, False, False,
+            ]
+    material=bl.createMaterial('rigidBody')
+    rigidMeshes=[]
+    for rigid in io.rigidbodies:
+        if rigid.boneIndex==0xFFFF:
+            # no reference bone
+            bone=io.bones[0]
+        else:
+            bone=io.bones[rigid.boneIndex]
+        pos=bone.pos+rigid.position
+
+        if rigid.shapeType==pmd.SHAPE_SPHERE:
+            bpy.ops.mesh.primitive_ico_sphere_add(
+                    location=(pos.x, pos.z, pos.y),
+                    layer=layer
+                    )
+            bpy.ops.transform.resize(
+                    value=(rigid.w, rigid.w, rigid.w))
+        elif rigid.shapeType==pmd.SHAPE_BOX:
+            bpy.ops.mesh.primitive_cube_add(
+                    location=(pos.x, pos.z, pos.y),
+                    layer=layer
+                    )
+            bpy.ops.transform.resize(
+                    value=(rigid.w, rigid.d, rigid.h))
+        elif rigid.shapeType==pmd.SHAPE_CAPSULE:
+            bpy.ops.mesh.primitive_tube_add(
+                    location=(pos.x, pos.z, pos.y),
+                    layer=layer
+                    )
+            bpy.ops.transform.resize(
+                    value=(rigid.w, rigid.w, rigid.h))
+        else:
+            assert(False)
+
+        meshObject=scene.objects.active
+        mesh=bl.objectGetData(meshObject)
+        rigidMeshes.append(meshObject)
+        bl.meshAddMaterial(mesh, material)
+        meshObject.name=rigid.getName()
+        #meshObject.draw_transparent=True
+        #meshObject.draw_wire=True
+        meshObject.max_draw_type='WIRE'
+        rot=rigid.rotation
+        meshObject.rotation_euler=(-rot.x, -rot.z, -rot.y)
+
+        # custom properties
+        meshObject[RIGID_SHAPE_TYPE]=rigid.shapeType
+        meshObject[RIGID_PROCESS_TYPE]=rigid.processType
+
+        bone_name = englishmap.getEnglishBoneName(bone.getName())
+        if not bone_name:
+            bone_name=bone.getName()
+        meshObject[RIGID_BONE_NAME]=bone_name
+
+    for meshObject in reversed(rigidMeshes):
+        bl.objectMakeParent(container, meshObject)
+
+    return container
+
+
 def __execute(filename, scene):
     """
     load pmd file to context.
@@ -598,6 +717,16 @@ def __execute(filename, scene):
         for n, b in bl.objectGetPose(armature_object).bones.items():
             bl.poseBoneLimit(n, b)
 
+    # import rigid bodies
+    rigidBodies=__importRigidBodies(scene, io)
+    if rigidBodies:
+        bl.objectMakeParent(root, rigidBodies)
+
+    # import constraints
+    constraints=__importConstraints(scene, io)
+    if constraints:
+        bl.objectMakeParent(root, constraints)
+
     # select objects
     bl.objectSelect(root)
     for o in mesh_objects: