X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=swig%2Fblender%2Fpmd_export.py;h=d3a9a1ea12724dd39fcc9bc3ffa6d27f9dc9628a;hb=68a0b4bad4103f2c036484bcfbf5743ca5d6380b;hp=2690b82886493227750d320ffbd7aa2ea7ab37bb;hpb=2cef52b4ee664d7136509bddf974464e3cc2c758;p=meshio%2Fmeshio.git diff --git a/swig/blender/pmd_export.py b/swig/blender/pmd_export.py index 2690b82..d3a9a1e 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,12 +16,35 @@ 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. +1.3 20100619: fix rigid body, bone weight. +1.4 20100626: refactoring. """ 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' +#RIGID_LOCATION='rigid_loation' +RIGID_GROUP='ribid_group' +RIGID_INTERSECTION_GROUP='rigid_intersection_group' +RIGID_WEIGHT='rigid_weight' +RIGID_LINEAR_DAMPING='rigid_linear_damping' +RIGID_ANGULAR_DAMPING='rigid_angular_damping' +RIGID_RESTITUTION='rigid_restitution' +RIGID_FRICTION='rigid_friction' +CONSTRAINT_NAME='constraint_name' +CONSTRAINT_A='const_a' +CONSTRAINT_B='const_b' +CONSTRAINT_POS_MIN='const_pos_min' +CONSTRAINT_POS_MAX='const_pos_max' +CONSTRAINT_ROT_MIN='const_rot_min' +CONSTRAINT_ROT_MAX='const_rot_max' +CONSTRAINT_SPRING_POS='const_spring_pos' +CONSTRAINT_SPRING_ROT='const_spring_rot' ############################################################################### @@ -29,8 +52,6 @@ BASE_SHAPE_NAME='Basis' ############################################################################### import os import sys -import re -import math # C extension from meshio import pmd, englishmap @@ -46,6 +67,25 @@ if isBlender24(): # wrapper import bl24 as bl + + def setMaterialParams(material, m): + # diffuse + material.diffuse.r=m.R + material.diffuse.g=m.G + material.diffuse.b=m.B + material.diffuse.a=m.alpha + # specular + material.sinness=0 if m.spec<1e-5 else m.spec*10 + material.specular.r=m.specR + material.specular.g=m.specG + material.specular.b=m.specB + # ambient + material.ambient.r=m.mirR + material.ambient.g=m.mirG + material.ambient.b=m.mirB + # flag + material.flag=1 if m.enableSSS else 0 + else: # for 2.5 import bpy @@ -57,6 +97,23 @@ else: xrange=range + def setMaterialParams(material, m): + # diffuse + material.diffuse.r=m.diffuse_color[0] + material.diffuse.g=m.diffuse_color[1] + material.diffuse.b=m.diffuse_color[2] + material.diffuse.a=m.alpha + # specular + material.sinness=0 if m.specular_toon_size<1e-5 else m.specular_hardness*10 + material.specular.r=m.specular_color[0] + material.specular.g=m.specular_color[1] + material.specular.b=m.specular_color[2] + # ambient + material.ambient.r=m.mirror_color[0] + material.ambient.g=m.mirror_color[1] + material.ambient.b=m.mirror_color[2] + # flag + material.flag=1 if m.subsurface_scattering.enabled else 0 class Node(object): __slots__=['o', 'children'] @@ -78,12 +135,15 @@ class VertexKey(object): 重複頂点の検索キー """ __slots__=[ + 'obj', 'index', 'x', 'y', 'z', # 位置 'nx', 'ny', 'nz', # 法線 'u', 'v', # uv ] - def __init__(self, x, y, z, nx, ny, nz, u, v): + def __init__(self, obj, index, x, y, z, nx, ny, nz, u, v): + self.obj=obj + self.index=index self.x=x self.y=y self.z=z @@ -104,7 +164,8 @@ class VertexKey(object): def __eq__(self, rhs): #return near(self.x, rhs.x) and near(self.y, rhs.y) and near(self.z, rhs.z) and near(self.nx, rhs.nx) and near(self.ny, rhs.ny) and near(self.nz, rhs.nz) and near(self.u, rhs.u) and near(self.v, rhs.v) #return near(self.x, rhs.x) and near(self.y, rhs.y) and near(self.z, rhs.z) - return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z + #return self.x==rhs.x and self.y==rhs.y and self.z==rhs.z + return self.obj==rhs.obj and self.index==rhs.index class VertexArray(object): @@ -135,11 +196,18 @@ class VertexArray(object): self.vertices, self.normals, self.uvs, self.b0, self.b1, self.weight) - def __getIndex(self, base_index, pos, normal, uv, b0, b1, weight0): + def each(self): + keys=[key for key in self.indexArrays.keys()] + keys.sort() + for key in keys: + yield(key, self.indexArrays[key]) + + def __getIndex(self, obj, base_index, pos, normal, uv, b0, b1, weight0): """ 頂点属性からその頂点のインデックスを得る """ key=VertexKey( + obj, base_index, pos[0], pos[1], pos[2], normal[0], normal[1], normal[2], uv[0], uv[1]) @@ -170,7 +238,7 @@ class VertexArray(object): return self.indexMap[base_index] def addTriangle(self, - material, + obj, material, base_index0, base_index1, base_index2, pos0, pos1, pos2, n0, n1, n2, @@ -182,9 +250,9 @@ class VertexArray(object): if not material in self.indexArrays: self.indexArrays[material]=[] - index0=self.__getIndex(base_index0, pos0, n0, uv0, b0_0, b1_0, weight0) - index1=self.__getIndex(base_index1, pos1, n1, uv1, b0_1, b1_1, weight1) - index2=self.__getIndex(base_index2, pos2, n2, uv2, b0_2, b1_2, weight2) + index0=self.__getIndex(obj, base_index0, pos0, n0, uv0, b0_0, b1_0, weight0) + index1=self.__getIndex(obj, base_index1, pos1, n1, uv1, b0_1, b1_1, weight1) + index2=self.__getIndex(obj, base_index2, pos2, n2, uv2, b0_2, b1_2, weight2) self.indexArrays[material]+=[index0, index1, index2] @@ -219,11 +287,17 @@ class IKSolver(object): class OneSkinMesh(object): - __slots__=['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 def __str__(self): return "" % ( @@ -231,16 +305,25 @@ class OneSkinMesh(object): len(self.morphList)) def addMesh(self, obj): - if bl.objectIsVisible(obj): + if bl.object.isVisible(obj): # 非表示 return + self.__mesh(obj) + self.__skin(obj) + self.__rigidbody(obj) + self.__constraint(obj) - print("export", obj.name) + def __mesh(self, obj): + if isBlender24(): + pass + else: + if RIGID_SHAPE_TYPE in obj: + return + if CONSTRAINT_A in obj: + return - ############################################################ - # bone weight - ############################################################ - mesh=bl.objectGetData(obj) + print("export", obj.name) + mesh=bl.object.getData(obj) weightMap={} secondWeightMap={} def setWeight(i, name, w): @@ -267,7 +350,7 @@ class OneSkinMesh(object): weightMap[i]=(name, w) if isBlender24(): - for name in bl.meshVertexGroupNames(obj): + for name in bl.object.getVertexGroupNames(obj): for i, w in mesh.getVertsFromGroup(name, 1): setWeight(i, name, w) else: @@ -287,144 +370,188 @@ class OneSkinMesh(object): print("no weight vertex") weightMap[i]=("", 0) secondWeightMap[i]=("", 0) - - ############################################################ + # メッシュのコピーを生成してオブジェクトの行列を適用する - ############################################################ - copyMesh, copyObj=bl.objectDuplicate(self.scene, obj) + copyMesh, copyObj=bl.object.duplicate(obj) if len(copyMesh.verts)==0: return for i, face in enumerate(copyMesh.faces): - faceVertexCount=bl.faceVertexCount(face) - material=copyMesh.materials[bl.faceMaterialIndex(face)] - v=[copyMesh.verts[index] for index in bl.faceVertices(face)] - uv=bl.meshFaceUv(copyMesh, i, face) + faceVertexCount=bl.face.getVertexCount(face) + material=copyMesh.materials[bl.face.getMaterialIndex(face)] + v=[copyMesh.verts[index] for index in bl.face.getVertices(face)] + uv=bl.mesh.getFaceUV(copyMesh, i, face) + # flip triangle if faceVertexCount==3: # triangle self.vertexArray.addTriangle( - material.name, - v[0].index, v[1].index, v[2].index, - v[0].co, v[1].co, v[2].co, + self.obj_index, material.name, + v[2].index, + v[1].index, + v[0].index, + v[2].co, + v[1].co, + v[0].co, # ToDo vertex normal #v0.no, v1.no, v2.no, - bl.faceNormal(face), - bl.faceNormal(face), - bl.faceNormal(face), - uv[0], uv[1], uv[2], - weightMap[v[0].index][0], - weightMap[v[1].index][0], + bl.face.getNormal(face), + bl.face.getNormal(face), + bl.face.getNormal(face), + uv[2], + uv[1], + uv[0], weightMap[v[2].index][0], - secondWeightMap[v[0].index][0], - secondWeightMap[v[1].index][0], + weightMap[v[1].index][0], + weightMap[v[0].index][0], secondWeightMap[v[2].index][0], - weightMap[v[0].index][1], + secondWeightMap[v[1].index][0], + secondWeightMap[v[0].index][0], + weightMap[v[2].index][1], weightMap[v[1].index][1], - weightMap[v[2].index][1] + weightMap[v[0].index][1] ) elif faceVertexCount==4: # quadrangle self.vertexArray.addTriangle( - material.name, - v[0].index, v[1].index, v[2].index, - v[0].co, v[1].co, v[2].co, + self.obj_index, material.name, + v[2].index, + v[1].index, + v[0].index, + v[2].co, + v[1].co, + v[0].co, #v0.no, v1.no, v2.no, - bl.faceNormal(face), - bl.faceNormal(face), - bl.faceNormal(face), - uv[0], uv[1], uv[2], - weightMap[v[0].index][0], - weightMap[v[1].index][0], + bl.face.getNormal(face), + bl.face.getNormal(face), + bl.face.getNormal(face), + uv[2], + uv[1], + uv[0], weightMap[v[2].index][0], - secondWeightMap[v[0].index][0], - secondWeightMap[v[1].index][0], + weightMap[v[1].index][0], + weightMap[v[0].index][0], secondWeightMap[v[2].index][0], - weightMap[v[0].index][1], + secondWeightMap[v[1].index][0], + secondWeightMap[v[0].index][0], + weightMap[v[2].index][1], weightMap[v[1].index][1], - weightMap[v[2].index][1] + weightMap[v[0].index][1] ) self.vertexArray.addTriangle( - material.name, - v[2].index, v[3].index, v[0].index, - v[2].co, v[3].co, v[0].co, + self.obj_index, material.name, + v[0].index, + v[3].index, + v[2].index, + v[0].co, + v[3].co, + v[2].co, #v2.no, v3.no, v0.no, - bl.faceNormal(face), - bl.faceNormal(face), - bl.faceNormal(face), - uv[2], uv[3], uv[0], - weightMap[v[2].index][0], - weightMap[v[3].index][0], + bl.face.getNormal(face), + bl.face.getNormal(face), + bl.face.getNormal(face), + uv[0], + uv[3], + uv[2], weightMap[v[0].index][0], - secondWeightMap[v[2].index][0], - secondWeightMap[v[3].index][0], + weightMap[v[3].index][0], + weightMap[v[2].index][0], secondWeightMap[v[0].index][0], - weightMap[v[2].index][1], + secondWeightMap[v[3].index][0], + secondWeightMap[v[2].index][0], + weightMap[v[0].index][1], weightMap[v[3].index][1], - weightMap[v[0].index][1] + weightMap[v[2].index][1] ) - bl.objectDelete(self.scene, copyObj) + bl.object.delete(copyObj) + self.obj_index+=1 + + def __skin(self, obj): + if not bl.object.hasShapeKey(obj): + return - ############################################################ - # skin - ############################################################ indexRelativeMap={} - blenderMesh=bl.objectGetData(obj) + blenderMesh=bl.object.getData(obj) baseMorph=None - if bl.objectHasShapeKey(obj): - # base - for b in bl.objectShapeKeys(obj): - if b.name=='Basis': - print(b.name) - baseMorph=self.__getOrCreateMorph('base', 0) - relativeIndex=0 - basis=b - - for index in bl.meshVertexGroup(obj, MMD_SHAPE_GROUP_NAME): - v=b.data[index] - pos=[v[0], v[1], v[2]] - indices=self.vertexArray.getMappedIndices(index) - for i in indices: - baseMorph.add(i, pos) - indexRelativeMap[i]=relativeIndex - relativeIndex+=1 - - break - assert(basis) - - if(len(baseMorph.offsets)>0): - baseMorph.sort() - - # shape keys - vg=obj.getData(mesh=True).getVertsFromGroup( - MMD_SHAPE_GROUP_NAME) - for b in obj.getData(mesh=True).key.blocks: - if b.name=='Basis': - continue - - print(b.name) - morph=self.__getOrCreateMorph(b.name, 4) - for index, src, dst in zip( - xrange(len(blenderMesh.verts)), - basis.data, - b.data): - offset=[dst[0]-src[0], dst[1]-src[1], dst[2]-src[2]] - if index in vg: - indices=self.vertexArray.getMappedIndices(index) - for i in indices: - morph.add(indexRelativeMap[i], offset) - assert(len(morph.offsets)==len(baseMorph.offsets)) - - # sort skinmap - original=self.morphList[:] - def getIndex(morph): - for i, v in enumerate(englishmap.skinMap): - if v[0]==morph.name: - return i - print(morph) - if isBlender24(): - self.morphList.sort(lambda l, r: getIndex(l)-getIndex(r)) - else: - self.morphList.sort(key=getIndex) + + # shape keys + vg=bl.object.getVertexGroup(obj, MMD_SHAPE_GROUP_NAME) + + # base + used=set() + for b in bl.object.getShapeKeys(obj): + if b.name==BASE_SHAPE_NAME: + baseMorph=self.__getOrCreateMorph('base', 0) + basis=b + + relativeIndex=0 + for index in vg: + v=bl.shapekey.getByIndex(b, index) + pos=[v[0], v[1], v[2]] + indices=self.vertexArray.getMappedIndices(index) + for i in indices: + if i in used: + continue + used.add(i) + + baseMorph.add(i, pos) + indexRelativeMap[i]=relativeIndex + relativeIndex+=1 + + break + assert(basis) + print(basis.name, len(baseMorph.offsets)) + + if len(baseMorph.offsets)==0: + return + + # shape keys + for b in bl.object.getShapeKeys(obj): + if b.name==BASE_SHAPE_NAME: + continue + + print(b.name) + morph=self.__getOrCreateMorph(b.name, 4) + used=set() + for index, src, dst in zip( + xrange(len(blenderMesh.verts)), + bl.shapekey.get(basis), + bl.shapekey.get(b)): + offset=[dst[0]-src[0], dst[1]-src[1], dst[2]-src[2]] + if offset[0]==0 and offset[1]==0 and offset[2]==0: + continue + if index in vg: + indices=self.vertexArray.getMappedIndices(index) + for i in indices: + if i in used: + continue + used.add(i) + morph.add(indexRelativeMap[i], offset) + + # sort skinmap + original=self.morphList[:] + def getIndex(morph): + for i, v in enumerate(englishmap.skinMap): + if v[0]==morph.name: + return i + print(morph) + if isBlender24(): + self.morphList.sort(lambda l, r: getIndex(l)-getIndex(r)) + 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: @@ -459,7 +586,7 @@ class Bone(object): return "" % (self.name, self.type) class BoneBuilder(object): - __slots__=['bones', 'boneMap', 'ik_list'] + __slots__=['bones', 'boneMap', 'ik_list', ] def __init__(self): self.bones=[] self.boneMap={} @@ -470,13 +597,13 @@ class BoneBuilder(object): return print("gather bones") - armature=armatureObj.getData() + armature=bl.object.getData(armatureObj) for b in armature.bones.values(): if b.name=='center': # root bone bone=Bone(b.name, - b.head['ARMATURESPACE'][0:3], - b.tail['ARMATURESPACE'][0:3]) + bl.bone.getHeadLocal(b), + bl.bone.getTailLocal(b)) self.__addBone(bone) self.__getBone(bone, b) @@ -484,8 +611,8 @@ class BoneBuilder(object): if not b.parent and b.name!='center': # root bone bone=Bone(b.name, - b.head['ARMATURESPACE'][0:3], - b.tail['ARMATURESPACE'][0:3]) + bl.bone.getHeadLocal(b), + bl.bone.getTailLocal(b)) self.__addBone(bone) self.__getBone(bone, b) @@ -495,17 +622,14 @@ class BoneBuilder(object): self.__checkConnection(b, None) print("gather ik") - pose = armatureObj.getPose() - cSetting=Blender.Constraint.Settings + pose = bl.object.getPose(armatureObj) for b in pose.bones.values(): for c in b.constraints: - if c.type==Blender.Constraint.Type.IKSOLVER: + if bl.constraint.isIKSolver(c): #################### # IK target #################### - assert(c[cSetting.TARGET]==armatureObj) - target=self.__boneByName( - c[Blender.Constraint.Settings.BONE]) + target=self.__boneByName(bl.constraint.ikTarget(c)) target.type=2 #################### @@ -517,7 +641,7 @@ class BoneBuilder(object): # IK chain e=b.parent - chainLength=c[cSetting.CHAINLEN] + chainLength=bl.constraint.ikChainLen(c) for i in range(chainLength): # IK影響下 chainBone=self.__boneByName(e.name) @@ -526,22 +650,37 @@ class BoneBuilder(object): e=e.parent self.ik_list.append( IKSolver(target, link, chainLength, - int(c[cSetting.ITERATIONS] * 0.1), - c[cSetting.ROTWEIGHT] + int(bl.constraint.ikItration(c) * 0.1), + bl.constraint.ikRotationWeight(c) )) + # boneのsort + self._sortBy() + self._fix() + # IKのsort + def getIndex(ik): + for i, v in enumerate(englishmap.boneMap): + if v[0]==ik.target.name: + return i + return len(englishmap.boneMap) + if isBlender24(): + self.ik_list.sort(lambda l, r: getIndex(l)-getIndex(r)) + else: + self.ik_list.sort(key=getIndex) + def __checkConnection(self, b, p): - if Blender.Armature.CONNECTED in b.options: + if bl.bone.isConnected(b): parent=self.__boneByName(p.name) parent.isConnect=True for c in b.children: self.__checkConnection(c, b) - def sortBy(self, boneMap): + def _sortBy(self): """ boneMap順に並べ替える """ + boneMap=englishmap.boneMap original=self.bones[:] def getIndex(bone): for i, k_v in enumerate(boneMap): @@ -567,6 +706,26 @@ class BoneBuilder(object): if b.ik_index>0: b.ik_index=sortMap[b.ik_index] + def _fix(self): + """ + 調整 + """ + for b in self.bones: + # parent index + if b.parent_index==None: + b.parent_index=0xFFFF + else: + if b.type==6 or b.type==7: + # fix tail bone + parent=self.bones[b.parent_index] + parent.tail_index=b.index + + for b in self.bones: + if b.tail_index==None: + b.tail_index=0 + elif b.type==9: + b.tail_index==0 + def getIndex(self, bone): for i, b in enumerate(self.bones): if b==bone: @@ -574,10 +733,13 @@ class BoneBuilder(object): assert(false) def indexByName(self, name): - return self.getIndex(self.__boneByName(name)) + if name=='': + return 0 + else: + return self.getIndex(self.__boneByName(name)) def __boneByName(self, name): - return self.bones[self.boneMap[name]] + return self.boneMap[name] def __getBone(self, parent, b): if len(b.children)==0: @@ -586,8 +748,8 @@ class BoneBuilder(object): for i, c in enumerate(b.children): bone=Bone(c.name, - c.head['ARMATURESPACE'][0:3], - c.tail['ARMATURESPACE'][0:3]) + bl.bone.getHeadLocal(c), + bl.bone.getTailLocal(c)) self.__addBone(bone) if parent: bone.parent_index=parent.index @@ -598,7 +760,7 @@ class BoneBuilder(object): def __addBone(self, bone): bone.index=len(self.bones) self.bones.append(bone) - self.boneMap[bone.name]=bone.index + self.boneMap[bone.name]=bone class PmdExporter(object): @@ -611,9 +773,12 @@ 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) + # ルートを得る root=object_node_map[scene.objects.active] @@ -626,28 +791,19 @@ class PmdExporter(object): # skeleton self.builder=BoneBuilder() self.builder.build(self.armatureObj) - self.builder.sortBy(englishmap.boneMap) - def getIndex(ik): - for i, v in enumerate(englishmap.boneMap): - if v[0]==ik.target.name: - return i - return len(englishmap.boneMap) - if isBlender24(): - self.builder.ik_list.sort(lambda l, r: getIndex(l)-getIndex(r)) - else: - self.builder.ik_list.sort(key=getIndex) def __createOneSkinMesh(self, node): ############################################################ # search armature modifier ############################################################ for m in node.o.modifiers: - if m.name=="Armature": - armatureObj=bl.armatureModifierGetObject(m) + if bl.modifier.isType(m, 'ARMATURE'): + armatureObj=bl.modifier.getArmatureObject(m) 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) @@ -673,43 +829,18 @@ class PmdExporter(object): v.normal.z=normal[1] v.uv.x=uv[0] v.uv.y=uv[1] - v.bone0=self.builder.boneMap[b0] if b0 in self.builder.boneMap else 0 - v.bone1=self.builder.boneMap[b1] if b1 in self.builder.boneMap else 0 + v.bone0=self.builder.indexByName(b0) + v.bone1=self.builder.indexByName(b1) v.weight0=int(100*weight) v.edge_flag=0 # edge flag, 0: enable edge, 1: not edge # 面とマテリアル vertexCount=self.oneSkinMesh.getVertexCount() - for material_name, indices in self.oneSkinMesh.vertexArray.indexArrays.items(): - m=bl.materialGet(self.scene, material_name) + for material_name, indices in self.oneSkinMesh.vertexArray.each(): + m=bl.material.get(material_name) # マテリアル material=io.addMaterial() - if isBlender24(): - material.diffuse.r=m.R - material.diffuse.g=m.G - material.diffuse.b=m.B - material.diffuse.a=m.alpha - material.sinness=0 if m.spec<1e-5 else m.spec*10 - material.specular.r=m.specR - material.specular.g=m.specG - material.specular.b=m.specB - material.ambient.r=m.mirR - material.ambient.g=m.mirG - material.ambient.b=m.mirB - material.flag=1 if m.enableSSS else 0 - else: - material.diffuse.r=m.diffuse_color[0] - material.diffuse.g=m.diffuse_color[1] - material.diffuse.b=m.diffuse_color[2] - material.diffuse.a=m.alpha - material.sinness=0 if m.specular_hardness<1e-5 else m.specular_hardness*10 - material.specular.r=m.specular_color[0] - material.specular.g=m.specular_color[1] - material.specular.b=m.specular_color[2] - material.ambient.r=m.mirror_color[0] - material.ambient.g=m.mirror_color[1] - material.ambient.b=m.mirror_color[2] - material.flag=1 if m.subsurface_scattering.enabled else 0 + setMaterialParams(material, m) material.vertex_count=len(indices) material.toon_index=0 @@ -720,32 +851,25 @@ class PmdExporter(object): assert(i