From: ousttrue Date: Wed, 16 Jun 2010 20:55:03 +0000 (+0900) Subject: add constraint. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=af0f7ea2da9ace619ff51edef564fe4669582074;p=meshio%2Fmeshio.git add constraint. --- diff --git a/include/pmd.h b/include/pmd.h index ac706b3..75e4f47 100644 --- a/include/pmd.h +++ b/include/pmd.h @@ -333,6 +333,9 @@ struct RigidBody float friction; //! „‘̃^ƒCƒv PROCESS_TYPE processType; + + std::wstring getName()const; + void setName(const char *src); }; //! Joint(•¨—‰‰ŽZ‚Å‚ÌJoint‚ÆConstraint‚Í“¯‚¶ˆÓ–¡) @@ -357,6 +360,9 @@ struct Constraint //! ‚Î‚Ë Vector3 springPos; Vector3 springRot; + + std::wstring getName()const; + void setName(const char *src); }; diff --git a/src/pmd.cpp b/src/pmd.cpp old mode 100644 new mode 100755 index 17397b6..23059ab --- a/src/pmd.cpp +++ b/src/pmd.cpp @@ -47,6 +47,20 @@ std::wstring std::string(english_name, english_name+20))); } +std::wstring + RigidBody::getName()const + { + return text::trim(text::to_WideChar(CP_OEMCP, + std::string(name, name+20))); + } + +std::wstring + Constraint::getName()const + { + return text::trim(text::to_WideChar(CP_OEMCP, + std::string(name, name+20))); + } + // 38bytes template void @@ -684,6 +698,69 @@ bool IO::write(binary::IWriter &w) w.writeArray(toon_textures[i].name, 100); } + //////////////////////////////////////////////////////////// + // rigid bodies + //////////////////////////////////////////////////////////// + w.writeValue(rigidbodies.size()); + for(size_t i=0; i(rb.name, 20); + w.writeValue(rb.boneIndex); + w.writeValue(rb.group); + w.writeValue(rb.target); + w.writeValue(rb.shapeType); + w.writeValue(rb.w); + w.writeValue(rb.h); + w.writeValue(rb.d); + w.writeValue(rb.position.x); + w.writeValue(rb.position.y); + w.writeValue(rb.position.z); + w.writeValue(rb.rotation.x); + w.writeValue(rb.rotation.y); + w.writeValue(rb.rotation.z); + w.writeValue(rb.weight); + w.writeValue(rb.linearDamping); + w.writeValue(rb.angularDamping); + w.writeValue(rb.restitution); + w.writeValue(rb.friction); + w.writeValue(rb.processType); + } + + //////////////////////////////////////////////////////////// + // constraints + //////////////////////////////////////////////////////////// + w.writeValue(constraints.size()); + for(size_t i=0; i(c.name, 20); + w.writeValue(c.rigidA); + w.writeValue(c.rigidB); + w.writeValue(c.pos.x); + w.writeValue(c.pos.y); + w.writeValue(c.pos.z); + w.writeValue(c.rot.x); + w.writeValue(c.rot.y); + w.writeValue(c.rot.z); + w.writeValue(c.constraintPosMin.x); + w.writeValue(c.constraintPosMin.y); + w.writeValue(c.constraintPosMin.z); + w.writeValue(c.constraintPosMax.x); + w.writeValue(c.constraintPosMax.y); + w.writeValue(c.constraintPosMax.z); + w.writeValue(c.constraintRotMin.x); + w.writeValue(c.constraintRotMin.y); + w.writeValue(c.constraintRotMin.z); + w.writeValue(c.constraintRotMax.x); + w.writeValue(c.constraintRotMax.y); + w.writeValue(c.constraintRotMax.z); + w.writeValue(c.springPos.x); + w.writeValue(c.springPos.y); + w.writeValue(c.springPos.z); + w.writeValue(c.springRot.x); + w.writeValue(c.springRot.y); + w.writeValue(c.springRot.z); + } + return true; } @@ -729,6 +806,17 @@ void Morph::setEnglishName(const char *src) strncpy(english_name, src, 20); } +void RigidBody::setName(const char *src) +{ + strncpy(name, src, 20); +} + +void Constraint::setName(const char *src) +{ + strncpy(name, src, 20); +} + + } // namespace } // namespace diff --git a/swig/blender/bl24.py b/swig/blender/bl24.py index a1a5133..f75052c 100644 --- a/swig/blender/bl24.py +++ b/swig/blender/bl24.py @@ -455,6 +455,9 @@ def createEmptyObject(scene, name): empty.setName(name) return empty +def createMaterial(name): + material = Blender.Material.New(name) + return material def createMqoMaterial(m): material = Blender.Material.New(m.getName().encode(INTERNAL_ENCODING)) diff --git a/swig/blender/bl25.py b/swig/blender/bl25.py index 85284f3..f842242 100644 --- a/swig/blender/bl25.py +++ b/swig/blender/bl25.py @@ -66,6 +66,9 @@ def createEmptyObject(scene, name): scene.objects.link(empty) return empty +def createMaterial(name): + material = bpy.data.materials.new(name) + return material def createMqoMaterial(m): material = bpy.data.materials.new(m.getName()) diff --git a/swig/blender/pmd_export.py b/swig/blender/pmd_export.py index 998e76c..f5a599b 100644 --- a/swig/blender/pmd_export.py +++ b/swig/blender/pmd_export.py @@ -7,7 +7,7 @@ Tooltip: 'Export PMD file for MikuMikuDance.' """ __author__= ["ousttrue"] -__version__= "1.0" +__version__= "1.2" __url__=() __bpydoc__=""" pmd Importer @@ -16,13 +16,18 @@ This script exports a pmd model. 0.1 20100318: first implementation. 0.2 20100519: refactoring. use C extension. -1.0 20100530: implement, basic features. +1.0 20100530: implement basic features. 1.1 20100612: 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 @@ -224,10 +229,15 @@ class IKSolver(object): class OneSkinMesh(object): - __slots__=['obj_index', 'scene', 'vertexArray', 'morphList'] + __slots__=['obj_index', 'scene', 'vertexArray', 'morphList', + 'rigidbodies', + 'constraints', + ] def __init__(self, scene): self.vertexArray=VertexArray() self.morphList=[] + self.rigidbodies=[] + self.constraints=[] self.scene=scene self.obj_index=0 @@ -240,16 +250,21 @@ class OneSkinMesh(object): if bl.objectIsVisible(obj): # 非表示 return - - print("export", obj.name) - - # bone weight - weightMap=self.__mesh(obj) - - # skin + self.__mesh(obj) self.__skin(obj) + self.__rigidbody(obj) + self.__constraint(obj) def __mesh(self, obj): + if isBlender24(): + pass + else: + if RIGID_SHAPE_TYPE in obj: + return + if CONSTRAINT_A in obj: + return + + print("export", obj.name) mesh=bl.objectGetData(obj) weightMap={} secondWeightMap={} @@ -447,6 +462,20 @@ class OneSkinMesh(object): else: self.morphList.sort(key=getIndex) + def __rigidbody(self, obj): + if isBlender24(): + return + if not RIGID_SHAPE_TYPE in obj: + return + self.rigidbodies.append(obj) + + def __constraint(self, obj): + if isBlender24(): + return + if not CONSTRAINT_A in obj: + return + self.constraints.append(obj) + def __getOrCreateMorph(self, name, type): for m in self.morphList: if m.name==name: @@ -629,7 +658,9 @@ class PmdExporter(object): object_node_map={} for o in scene.objects: object_node_map[o]=Node(o) - for node in object_node_map.values(): + for o in scene.objects: + #for node in object_node_map.values(): + node=object_node_map[o] if node.o.parent: object_node_map[node.o.parent].children.append(node) @@ -657,7 +688,6 @@ class PmdExporter(object): self.builder.ik_list.sort(key=getIndex) def __createOneSkinMesh(self, node): - print(node) ############################################################ # search armature modifier ############################################################ @@ -667,7 +697,8 @@ class PmdExporter(object): if not self.armatureObj: self.armatureObj=armatureObj elif self.armatureObj!=armatureObj: - print("warning! found multiple armature. ignored.", armatureObj.name) + print("warning! found multiple armature. ignored.", + armatureObj.name) if node.o.type.upper()=='MESH': self.oneSkinMesh.addMesh(node.o) @@ -745,16 +776,12 @@ class PmdExporter(object): io.indices.append(indices[i+2]) # bones - for b in self.builder.bones: - if b.name.endswith("_t"): - if b.name.startswith("arm twist1_") or b.name.startswith("arm twist2_"): - # skip - print("skip %s" % b.name) - continue - + boneNameMap={} + for i, b in enumerate(self.builder.bones): bone=io.addBone() # name + boneNameMap[b.name]=i v=englishmap.getUnicodeBoneName(b.name) assert(v) cp932=v[1].encode('cp932') @@ -865,10 +892,56 @@ class PmdExporter(object): io.english_name="blender export" io.english_coment="blender export" + # toon for i in range(10): io.getToonTexture(i).name="toon%02d.bmp\n" % i + # rigid body + rigidNameMap={} + for i, obj in enumerate(self.oneSkinMesh.rigidbodies): + rigidBody=io.addRigidBody() + rigidBody.setName(obj.name.encode('cp932')) + rigidNameMap[obj.name]=i + boneIndex=boneNameMap[obj[RIGID_BONE_NAME]] + if boneIndex==0: + boneIndex=0xFFFF + rigidBody.boneIndex=boneIndex + rigidBody.position.x=obj.location[0] + rigidBody.position.y=obj.location[2] + rigidBody.position.z=obj.location[1] + rigidBody.rotation.x=-obj.rotation_euler[0] + rigidBody.rotation.y=-obj.rotation_euler[2] + rigidBody.rotation.z=-obj.rotation_euler[1] + rigidBody.processType=obj[RIGID_PROCESS_TYPE] + rigidBody.group=0 + rigidBody.target=0 + rigidBody.weight=1 + rigidBody.linearDamping=0 + rigidBody.angularDamping=0 + rigidBody.restitution=0 + rigidBody.friction=0 + if obj[RIGID_SHAPE_TYPE]==0: + rigidBody.shapeType=pmd.SHAPE_SPHERE + rigidBody.w=obj.scale[0] + elif obj[RIGID_SHAPE_TYPE]==1: + rigidBody.shapeType=pmd.SHAPE_CAPSULE + rigidBody.w=obj.scale[0] + rigidBody.h=obj.scale[2] + elif obj[RIGID_SHAPE_TYPE]==2: + rigidBody.shapeType=pmd.SHAPE_BOX + rigidBody.w=obj.scale[0] + rigidBody.d=obj.scale[1] + rigidBody.h=obj.scale[2] + + # constraint + for obj in self.oneSkinMesh.constraints: + constraint=io.addConstraint() + constraint.setName(obj.name[1:].encode('cp932')) + constraint.rigidA=rigidNameMap[obj[CONSTRAINT_A]] + constraint.rigidB=rigidNameMap[obj[CONSTRAINT_B]] + # 書き込み + print('write', path) return io.write(path) diff --git a/swig/blender/pmd_import.py b/swig/blender/pmd_import.py index 8b0463f..3a7050e 100644 --- a/swig/blender/pmd_import.py +++ b/swig/blender/pmd_import.py @@ -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: diff --git a/swig/pmd.i b/swig/pmd.i index c07ce3a..d2325f8 100644 --- a/swig/pmd.i +++ b/swig/pmd.i @@ -130,5 +130,17 @@ meshio::pmd::ToonTexture *getToonTexture(int index) return &($self->toon_textures[index]); } +meshio::pmd::RigidBody *addRigidBody() +{ + $self->rigidbodies.push_back(meshio::pmd::RigidBody()); + return &($self->rigidbodies.back()); +} + +meshio::pmd::Constraint *addConstraint() +{ + $self->constraints.push_back(meshio::pmd::Constraint()); + return &($self->constraints.back()); +} + }