def bakeFrames(self, tobake): myipoName = tobake.getName() debug('Baking frames for scene %s material %s to ipo %s' % (bpy.data.scenes.active.getName(), self.material.getName(), myipoName)) ipos = self.getCurves(tobake) #TODO: Gui setup idea: myOffset # reset action to start at frame 1 or at location myOffset = 0 #=1-staframe #loop through frames in the animation. Often, there is rollup and the mocap starts late staframe, endframe, curframe = getRangeFromIpo(self.material.getIpo()) for frame in range(staframe, endframe + 1): #tell Blender to advace to frame Blender.Set( 'curframe', frame ) # computes the constrained location of the 'real' objects #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen key = self.getColor( self.material ) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame myframe = frame + myOffset Blender.Set('curframe', myframe) time = Blender.Get('curtime') #for BezTriple ipos = addPoint(time, key, ipos) #add this data at this time to the ipos debug('%s %i %.3f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3])) Blender.Set('curframe', staframe) return tobake
def getImageFilesFromStateSet(stateset): list = [] if DEBUG: debug("stateset %s" % str(stateset)) if stateset is not None and len(stateset.texture_attributes) > 0: for unit, attributes in stateset.texture_attributes.items(): for a in attributes: if a.className() == "Texture2D": list.append(a.source_image) return list
def getRangeFromIpo(ipo): first_frame = 1 last_frame = 1 for channel in ipo: for key in channel.bezierPoints: if key.vec[1][0] > last_frame: last_frame = int(key.vec[1][0]) debug("range of ipo %s : %s %s " % (ipo.name, first_frame, last_frame)) return (first_frame, last_frame, first_frame)
def getRangeFromIpo(ipo): first_frame = 1 last_frame = 1 for channel in ipo: for key in channel.bezierPoints: if key.vec[1][0] > last_frame: last_frame = int(key.vec[1][0]) debug("range of ipo %s : %s %s " % (ipo.name, first_frame,last_frame)) return (first_frame, last_frame, first_frame)
def getLocRot(self, ob, space): if space in xrange(len(COORDINATE_SYSTEMS)): if space == COORD_LOCAL: key = self.getLocLocal(ob) return key elif space == COORD_REAL: key = self.getLocReal(ob) return key else: #hey, programmers make mistakes too. debug('Fatal Error: getLoc called with %i' % space) return
def getTypeOfIpo(self, ipo): if DEBUG: debug("%s curvs consts %s" % (ipo.name, str(ipo.curveConsts))) try: ipo.curveConsts['MA_R'] return "Material" except: pass try: ipo.curveConsts['OB_LOCX'] return "Object" except: pass return None
def createAnimationsFromList(self, animation_list): if DEBUG: debug("create animation from list %s" % (str(animation_list))) animations_result = {} for anim in animation_list: res = None if len(list(bpy.data.ipos)) and type(anim) is type(list(bpy.data.ipos)[0]): ipo2animation = BlenderIpoOrActionToAnimation(ipo = anim, config = self.config) res = ipo2animation.createAnimationFromIpo() elif len(list(bpy.data.actions)) and type(anim) is type(list(bpy.data.actions)[0]): action2animation = BlenderIpoOrActionToAnimation(action = anim, config = self.config) res = action2animation.createAnimationFromAction() if res is not None: if DEBUG: debug("animation \"%s\" created" % (res.name)) self.animations[res.name] = res else: log("WARNING can't create animation from %s" % anim)
def adjustUVLayerFromMaterial(self, geom, material): uvs = geom.uvs if DEBUG: debug("geometry uvs %s" % (str(uvs))) geom.uvs = {} texture_list = material.getTextures() if DEBUG: debug("texture list %s" % str(texture_list)) # find a default channel if exist uv default_uv = None default_uv_key = None if (len(uvs)) == 1: default_uv_key = uvs.keys()[0] default_uv = uvs[default_uv_key] for i in range(0, len(texture_list)): if texture_list[i] is not None: uv_layer = texture_list[i].uvlayer if len(uv_layer) > 0 and not uvs.has_key(uv_layer): log("WARNING your material '%s' with texture '%s' use an uv layer '%s' that does not exist on the mesh '%s', use the first uv channel as fallback" % (material.getName(), texture_list[i], uv_layer, geom.name)) if len(uv_layer) > 0 and uvs.has_key(uv_layer): if DEBUG: debug("texture %s use uv layer %s" % (i, uv_layer)) geom.uvs[i] = TexCoordArray() geom.uvs[i].array = uvs[uv_layer].array geom.uvs[i].index = i elif default_uv: if DEBUG: debug("texture %s use default uv layer %s" % (i, default_uv_key)) geom.uvs[i] = TexCoordArray() geom.uvs[i].index = i geom.uvs[i].array = default_uv.array # adjust uvs channels if no textures assigned if len(geom.uvs.keys()) == 0: if DEBUG: debug("no texture set, adjust uvs channels, in arbitrary order") index = 0 for k in uvs.keys(): uvs[k].index = index index += 1 geom.uvs = uvs return
def createAnimationFromIpo(self, name = None): ipo = self.ipos if name is None: name = "unknown" ipos_baked = ipo if self.config.anim_bake.lower() == "force": ipotype = self.getTypeOfIpo(ipo) if DEBUG: debug("createAnimationFromIpo ipo %s of type %s" % (str(name), str(ipotype))) if ipotype == "Object": obj = findObjectForIpo(ipo) baker = BakeIpoForObject(object = obj, ipo = ipo, config = None) ipos_baked = baker.getBakedIpos() elif ipotype == "Material": mat = findMaterialForIpo(ipo) baker = BakeIpoForMaterial(material = mat, ipo = ipo, config = None) ipos_baked = baker.getBakedIpos() else: log("WARNING dont know ipo type %s" % ipo.getName()) animation = Animation() animation.setName(ipo.name + "_ipo") self.convertIpoToAnimation(name, animation, ipos_baked) self.animation = animation return animation
def bakeFrames(self, tobake): myipoName = tobake.getName() debug('Baking frames for scene %s material %s to ipo %s' % (bpy.data.scenes.active.getName(),self.material.getName(),myipoName)) ipos = self.getCurves(tobake) #TODO: Gui setup idea: myOffset # reset action to start at frame 1 or at location myOffset=0 #=1-staframe #loop through frames in the animation. Often, there is rollup and the mocap starts late staframe,endframe,curframe = getRangeFromIpo(self.material.getIpo()) for frame in range(staframe, endframe+1): #tell Blender to advace to frame Blender.Set('curframe',frame) # computes the constrained location of the 'real' objects #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen key = self.getColor(self.material) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame myframe= frame+myOffset Blender.Set('curframe',myframe) time = Blender.Get('curtime') #for BezTriple ipos = addPoint(time, key, ipos) #add this data at this time to the ipos debug('%s %i %.3f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3])) Blender.Set('curframe',staframe) return tobake
def bakeFrames( self, myipo ): #bakes an object in a scene, returning the IPO containing the curves myipoName = myipo.getName() debug('Baking frames for scene %s object %s to ipo %s' % (bpy.data.scenes.active.getName(), self.object.getName(), myipoName)) ipos = self.getCurves(myipo) #TODO: Gui setup idea: myOffset # reset action to start at frame 1 or at location myOffset = 0 #=1-staframe #loop through frames in the animation. Often, there is rollup and the mocap starts late staframe, endframe, curframe = getRangeFromIpo(self.object.getIpo()) for frame in range(staframe, endframe + 1): #tell Blender to advace to frame Blender.Set( 'curframe', frame ) # computes the constrained location of the 'real' objects #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen key = self.getLocRot( self.object, usrCoord ) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame key = [a + b for a, b in zip(key, usrDelta)] #offset to the new location myframe = frame + myOffset Blender.Set('curframe', myframe) time = Blender.Get('curtime') #for BezTriple ipos = addPoint(time, key, ipos) #add this data at this time to the ipos debug('%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8])) Blender.Set('curframe', staframe) return myipo
def bakeFrames(self, myipo): #bakes an object in a scene, returning the IPO containing the curves myipoName = myipo.getName() debug('Baking frames for scene %s object %s to ipo %s' % (bpy.data.scenes.active.getName(),self.object.getName(),myipoName)) ipos = self.getCurves(myipo) #TODO: Gui setup idea: myOffset # reset action to start at frame 1 or at location myOffset=0 #=1-staframe #loop through frames in the animation. Often, there is rollup and the mocap starts late staframe,endframe,curframe = getRangeFromIpo(self.object.getIpo()) for frame in range(staframe, endframe+1): #tell Blender to advace to frame Blender.Set('curframe',frame) # computes the constrained location of the 'real' objects #using the constrained Loc Rot of the object, set the location of the unconstrained clone. Yea! Clones are FreeMen key = self.getLocRot(self.object,usrCoord) #a key is a set of specifed exact channel values (LocRotScale) for a certain frame key = [a+b for a,b in zip(key, usrDelta)] #offset to the new location myframe= frame+myOffset Blender.Set('curframe',myframe) time = Blender.Get('curtime') #for BezTriple ipos = addPoint(time,key,ipos) #add this data at this time to the ipos debug('%s %i %.3f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f' % (myipoName, myframe, time, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8])) Blender.Set('curframe',staframe) return myipo
def getBakedAction(self, sample_rate = 25): """ Bakes supplied action for supplied armature. Returns baked action. """ pose = self.armature.getPose() armature_data = self.armature.getData(); pose_bones = pose.bones.values() rest_bones = armature_data.bones POSE_XFORM = [Blender.Object.Pose.LOC, Blender.Object.Pose.ROT, Blender.Object.Pose.SIZE ] #POSE_XFORM= [Object.Pose.LOC,Object.Pose.ROT,Object.Pose.SIZE] blender_fps = 25 if sample_rate > blender_fps: sample_rate = blender_fps step = blender_fps / sample_rate startFrame= min(self.action.getFrameNumbers()); endFrame= max(self.action.getFrameNumbers()); dummy_action_name = "_" + self.action.name # Get the dummy action if it has no users try: baked_action = bpy.data.actions[dummy_action_name] except: baked_action = None if not baked_action: baked_action = bpy.data.actions.new(dummy_action_name) baked_action.fakeUser = False for channel in baked_action.getChannelNames(): baked_action.removeChannel(channel) old_quats={} old_locs={} old_sizes={} baked_locs={} baked_quats={} baked_sizes={} self.action.setActive(self.armature) frames = range(startFrame, endFrame+1, int(step)) if frames[-1:] != endFrame : frames.append(endFrame) for current_frame in frames: Blender.Set('curframe', current_frame) time = Blender.Get('curtime') #for BezTriple debug('%s %i %.3f' % (self.action.name, current_frame, time)) for i in range(len(pose_bones)): bone_name=pose_bones[i].name rest_bone=rest_bones[bone_name] matrix = Matrix(pose_bones[i].poseMatrix) rest_matrix= Matrix(rest_bone.matrix['ARMATURESPACE']) parent_bone=rest_bone.parent if parent_bone: parent_pose_bone=pose.bones[parent_bone.name] matrix=matrix * Matrix(parent_pose_bone.poseMatrix).invert() rest_matrix=rest_matrix * Matrix(parent_bone.matrix['ARMATURESPACE']).invert() #print "before\n", matrix #print "before quat\n", pose_bones[i].quat; #print "localised pose matrix\n", matrix #print "localised rest matrix\n", rest_matrix matrix=matrix * Matrix(rest_matrix).invert() old_quats[bone_name] = Quaternion(pose_bones[i].quat); old_locs[bone_name] = Vector(pose_bones[i].loc); old_sizes[bone_name] = Vector(pose_bones[i].size); baked_locs[bone_name] = Vector(matrix.translationPart()) baked_quats[bone_name] = Quaternion(matrix.toQuat()) baked_sizes[bone_name] = Vector(matrix.scalePart()) baked_action.setActive(self.armature) Blender.Set('curframe', current_frame) for i in range(len(pose_bones)): pose_bones[i].quat = baked_quats[pose_bones[i].name] pose_bones[i].loc = baked_locs[pose_bones[i].name] pose_bones[i].size = baked_sizes[pose_bones[i].name] pose_bones[i].insertKey(self.armature, current_frame, POSE_XFORM) self.action.setActive(self.armature) Blender.Set('curframe', current_frame) for name, quat in old_quats.iteritems(): pose.bones[name].quat=quat for name, loc in old_locs.iteritems(): pose.bones[name].loc=loc pose.update() self.result_action = baked_action return baked_action
def getBakedAction(self, sample_rate=25): """ Bakes supplied action for supplied armature. Returns baked action. """ pose = self.armature.getPose() armature_data = self.armature.getData() pose_bones = pose.bones.values() rest_bones = armature_data.bones POSE_XFORM = [ Blender.Object.Pose.LOC, Blender.Object.Pose.ROT, Blender.Object.Pose.SIZE ] #POSE_XFORM= [Object.Pose.LOC,Object.Pose.ROT,Object.Pose.SIZE] blender_fps = 25 if sample_rate > blender_fps: sample_rate = blender_fps step = blender_fps / sample_rate startFrame = min(self.action.getFrameNumbers()) endFrame = max(self.action.getFrameNumbers()) dummy_action_name = "_" + self.action.name # Get the dummy action if it has no users try: baked_action = bpy.data.actions[dummy_action_name] except: baked_action = None if not baked_action: baked_action = bpy.data.actions.new(dummy_action_name) baked_action.fakeUser = False for channel in baked_action.getChannelNames(): baked_action.removeChannel(channel) old_quats = {} old_locs = {} old_sizes = {} baked_locs = {} baked_quats = {} baked_sizes = {} self.action.setActive(self.armature) frames = range(startFrame, endFrame + 1, int(step)) if frames[-1:] != endFrame: frames.append(endFrame) for current_frame in frames: Blender.Set('curframe', current_frame) time = Blender.Get('curtime') #for BezTriple debug('%s %i %.3f' % (self.action.name, current_frame, time)) for i in range(len(pose_bones)): bone_name = pose_bones[i].name rest_bone = rest_bones[bone_name] matrix = Matrix(pose_bones[i].poseMatrix) rest_matrix = Matrix(rest_bone.matrix['ARMATURESPACE']) parent_bone = rest_bone.parent if parent_bone: parent_pose_bone = pose.bones[parent_bone.name] matrix = matrix * Matrix( parent_pose_bone.poseMatrix).invert() rest_matrix = rest_matrix * Matrix( parent_bone.matrix['ARMATURESPACE']).invert() #print "before\n", matrix #print "before quat\n", pose_bones[i].quat; #print "localised pose matrix\n", matrix #print "localised rest matrix\n", rest_matrix matrix = matrix * Matrix(rest_matrix).invert() old_quats[bone_name] = Quaternion(pose_bones[i].quat) old_locs[bone_name] = Vector(pose_bones[i].loc) old_sizes[bone_name] = Vector(pose_bones[i].size) baked_locs[bone_name] = Vector(matrix.translationPart()) baked_quats[bone_name] = Quaternion(matrix.toQuat()) baked_sizes[bone_name] = Vector(matrix.scalePart()) baked_action.setActive(self.armature) Blender.Set('curframe', current_frame) for i in range(len(pose_bones)): pose_bones[i].quat = baked_quats[pose_bones[i].name] pose_bones[i].loc = baked_locs[pose_bones[i].name] pose_bones[i].size = baked_sizes[pose_bones[i].name] pose_bones[i].insertKey(self.armature, current_frame, POSE_XFORM) self.action.setActive(self.armature) Blender.Set('curframe', current_frame) for name, quat in old_quats.iteritems(): pose.bones[name].quat = quat for name, loc in old_locs.iteritems(): pose.bones[name].loc = loc pose.update() self.result_action = baked_action return baked_action
def createGeomForMaterialIndex(self, material_index, mesh): geom = Geometry() geom.groups = {} if (len(mesh.faces) == 0): #log("object %s has no faces, so no materials" % self.object.getName()) log("object %s has no faces, so no materials, checking for vertexes" % self.object.getName()) result = self.createModelWithoutFaces(mesh, geom) return result if len(mesh.materials): title = "mesh %s with material %s" % (self.object.getName(), mesh.materials[material_index]) else: title = "mesh %s without material" % (self.object.getName()) log(title) vertexes = [] collected_faces = [] for face in mesh.faces: if face.mat != material_index: continue f = [] if DEBUG: fdebug = [] for vertex in face.verts: index = len(vertexes) vertexes.append(vertex) f.append(index) if DEBUG: fdebug.append(vertex.index) if DEBUG: debug("true face %s" % str(fdebug)) if DEBUG: debug("face %s" % str(f)) collected_faces.append((face,f)) if (len(collected_faces) == 0): log("object %s has no faces for sub material slot %s" % (self.object.getName(), str(material_index))) end_title = '-' * len(title) log(end_title) return None colors = {} if mesh.vertexColors: names = mesh.getColorLayerNames() backup_name = mesh.activeColorLayer for name in names: mesh.activeColorLayer = name mesh.update() color_array = [] for face,f in collected_faces: for i in range(0, len(face.verts)): color_array.append(face.col[i]) colors[name] = color_array mesh.activeColorLayer = backup_name mesh.update() uvs = {} if mesh.faceUV: names = mesh.getUVLayerNames() backup_name = mesh.activeUVLayer for name in names: mesh.activeUVLayer = name mesh.update() uv_array = [] for face,f in collected_faces: for i in range(0, len(face.verts)): uv_array.append(face.uv[i]) uvs[name] = uv_array mesh.activeUVLayer = backup_name mesh.update() normals = [] for face,f in collected_faces: if face.smooth: for vert in face.verts: normals.append(vert.no) else: for vert in face.verts: normals.append(face.no) mapping_vertexes = [] merged_vertexes = [] tagged_vertexes = [] for i in range(0,len(vertexes)): merged_vertexes.append(i) tagged_vertexes.append(False) def get_vertex_key(index): return ( (vertexes[index].co[0], vertexes[index].co[1], vertexes[index].co[2]), (normals[index][0], normals[index][1], normals[index][2]), tuple([tuple(uvs[x][index]) for x in uvs.keys()]), tuple([tuple(colors[x][index]) for x in colors.keys()]) ) # Build a dictionary of indexes to all the vertexes that # are equal. vertex_dict = {} for i in range(0, len(vertexes)): key = get_vertex_key(i) if vertex_dict.has_key(key): vertex_dict[key].append(i) else: vertex_dict[key] = [i] for i in range(0, len(vertexes)): if tagged_vertexes[i] is True: # avoid processing more than one time a vertex continue index = len(mapping_vertexes) merged_vertexes[i] = index mapping_vertexes.append([i]) if DEBUG: debug("process vertex %s" % i) vertex_indexes = vertex_dict[get_vertex_key(i)] for j in vertex_indexes: if j <= i: continue if tagged_vertexes[j] is True: # avoid processing more than one time a vertex continue if DEBUG: debug(" vertex %s is the same" % j) merged_vertexes[j] = index tagged_vertexes[j] = True mapping_vertexes[index].append(j) if DEBUG: for i in range(0, len(mapping_vertexes)): debug("vertex %s contains %s" % (str(i), str(mapping_vertexes[i]))) if len(mapping_vertexes) != len(vertexes): log("vertexes reduced from %s to %s" % (str(len(vertexes)),len(mapping_vertexes))) else: log("vertexes %s" % str(len(vertexes))) faces = [] for (original, face) in collected_faces: f = [] if DEBUG: fdebug = [] for v in face: f.append(merged_vertexes[v]) if DEBUG: fdebug.append(vertexes[mapping_vertexes[merged_vertexes[v]][0]].index) faces.append(f) if DEBUG: debug("new face %s" % str(f)) if DEBUG: debug("true face %s" % str(fdebug)) log("faces %s" % str(len(faces))) vgroups = {} original_vertexes2optimized = {} for i in range(0, len(mapping_vertexes)): for k in mapping_vertexes[i]: index = vertexes[k].index if not original_vertexes2optimized.has_key(index): original_vertexes2optimized[index] = [] original_vertexes2optimized[index].append(i) for i in mesh.getVertGroupNames(): verts = {} for idx, weight in mesh.getVertsFromGroup(i, 1): if weight < 0.001: log( "WARNING " + str(idx) + " to has a weight too small (" + str(weight) + "), skipping vertex") continue if original_vertexes2optimized.has_key(idx): for v in original_vertexes2optimized[idx]: if not verts.has_key(v): verts[v] = weight #verts.append([v, weight]) if len(verts) == 0: log( "WARNING " + str(i) + " has not vertexes, skip it, if really unsued you should clean it") else: vertex_weight_list = [ list(e) for e in verts.items() ] vg = VertexGroup() vg.targetGroupName = i vg.vertexes = vertex_weight_list vgroups[i] = vg if (len(vgroups)): log("vertex groups %s" % str(len(vgroups))) geom.groups = vgroups osg_vertexes = VertexArray() osg_normals = NormalArray() osg_uvs = {} osg_colors = {} for vertex in mapping_vertexes: vindex = vertex[0] coord = vertexes[vindex].co osg_vertexes.array.append([coord[0], coord[1], coord[2] ]) ncoord = normals[vindex] osg_normals.array.append([ncoord[0], ncoord[1], ncoord[2]]) for name in uvs.keys(): if not osg_uvs.has_key(name): osg_uvs[name] = TexCoordArray() osg_uvs[name].array.append(uvs[name][vindex]) if (len(osg_uvs)): log("uvs channels %s - %s" % (len(osg_uvs), str(osg_uvs.keys()))) nlin = 0 ntri = 0 nquad = 0 # counting number of lines, triangles and quads for face in faces: nv = len(face) if nv == 2: nlin = nlin + 1 elif nv == 3: ntri = ntri + 1 elif nv == 4: nquad = nquad + 1 else: log("WARNING can't manage faces with %s vertices" % nv) # counting number of primitives (one for lines, one for triangles and one for quads) numprims = 0 if (nlin > 0): numprims = numprims + 1 if (ntri > 0): numprims = numprims + 1 if (nquad > 0): numprims = numprims + 1 # Now we write each primitive primitives = [] if nlin > 0: lines = DrawElements() lines.type = "LINES" nface=0 for face in faces: nv = len(face) if nv == 2: lines.indexes.append(face[0]) lines.indexes.append(face[1]) nface = nface + 1 primitives.append(lines) if ntri > 0: triangles = DrawElements() triangles.type = "TRIANGLES" nface=0 for face in faces: nv = len(face) if nv == 3: triangles.indexes.append(face[0]) triangles.indexes.append(face[1]) triangles.indexes.append(face[2]) nface = nface + 1 primitives.append(triangles) if nquad > 0: quads = DrawElements() quads.type = "QUADS" nface=0 for face in faces: nv = len(face) if nv == 4: quads.indexes.append(face[0]) quads.indexes.append(face[1]) quads.indexes.append(face[2]) quads.indexes.append(face[3]) nface = nface + 1 primitives.append(quads) geom.uvs = osg_uvs geom.vertexes = osg_vertexes geom.normals = osg_normals geom.primitives = primitives geom.setName(self.object.getName()) geom.stateset = self.createStateSet(material_index, mesh, geom) if len(mesh.materials) > 0 and mesh.materials[material_index] is not None: self.adjustUVLayerFromMaterial(geom, mesh.materials[material_index]) end_title = '-' * len(title) log(end_title) return geom
def createStateSet(self, index_material, mesh, geom): s = StateSet() if len(mesh.materials) > 0: mat_source = mesh.materials[index_material] if self.uniq_stateset.has_key(mat_source): #s = ShadowObject(self.uniq_stateset[mat_source]) s = self.uniq_stateset[mat_source] return s if mat_source is not None: self.uniq_stateset[mat_source] = s m = Material() m.setName(mat_source.getName()) s.setName(mat_source.getName()) anim = createAnimationMaterialAndSetCallback(m, mat_source, self.config) if anim : self.material_animations[anim.name] = anim mode = mat_source.getMode() if mode & Blender.Material.Modes['SHADELESS']: s.modes["GL_LIGHTING"] = "OFF" refl = mat_source.getRef() m.diffuse = (mat_source.R * refl, mat_source.G * refl, mat_source.B * refl, mat_source.alpha) # if alpha not 1 then we set the blending mode on if DEBUG: debug("state material alpha %s" % str(mat_source.alpha)) if mat_source.alpha != 1.0: s.modes["GL_BLEND"] = "ON" ambient_factor = mat_source.getAmb() m.ambient = (mat_source.R * ambient_factor, mat_source.G * ambient_factor, mat_source.B * ambient_factor, 1) spec = mat_source.getSpec() m.specular = (mat_source.specR * spec, mat_source.specG * spec, mat_source.specB * spec, 1) emissive_factor = mat_source.getEmit() m.emission = (mat_source.R * emissive_factor, mat_source.G * emissive_factor, mat_source.B * emissive_factor, 1) m.shininess = (mat_source.getHardness() / 512.0) * 128.0 s.attributes.append(m) texture_list = mat_source.getTextures() if DEBUG: debug("texture list %s" % str(texture_list)) for i in range(0, len(texture_list)): if texture_list[i] is not None: t = self.createTexture2D(texture_list[i]) if DEBUG: debug("texture %s %s" % (i, texture_list[i])) if t is not None: if not s.texture_attributes.has_key(i): s.texture_attributes[i] = [] s.texture_attributes[i].append(t) try: if t.source_image.getDepth() > 24: # there is an alpha s.modes["GL_BLEND"] = "ON" except: log("can't read the source image file for texture %s" % t) if DEBUG: debug("state set %s" % str(s)) return s
def exportKeyframeSplitRotationTranslationScale(self, ipo, fps): SUPPORTED_IPOS = ( 'RotX', 'RotY', 'RotZ', 'QuatW', 'QuatX', 'QuatY', 'QuatZ', 'LocX', 'LocY', 'LocZ', 'ScaleX', 'ScaleY', 'ScaleZ', 'R', 'G', 'B', 'Alpha' ) channels = [] channel_times = {'EulerX': set(), 'EulerY': set(), 'EulerZ': set(), 'Rotation': set(), 'Translation': set(), 'Scale': set(), 'Color' : set() } channel_names = {'EulerX': 'euler_x', 'EulerY': 'euler_y', 'EulerZ': 'euler_z', 'Rotation': 'rotation', 'Translation': 'translate', 'Scale': 'scale', 'Color' : 'color'} channel_samplers = {'EulerX': None, 'EulerY': None, 'EulerZ': None, 'Rotation': None, 'Translation': None, 'Scale': None, 'Color' : None} channel_ipos = {'EulerX': [], 'EulerY': [], 'EulerZ': [], 'Rotation': [], 'Translation': [], 'Scale': [], 'Color': []} duration = 0 for curve in ipo: if DEBUG: debug("ipo %s curve %s with %s keys" % (ipo.getName(), curve.name, len(curve.bezierPoints))) if curve.name not in SUPPORTED_IPOS: if DEBUG: debug("ipo %s curve %s not supported" % (ipo.getName(), curve.name)) continue elif curve.name == "QuatX" or curve.name == "QuatY" or curve.name == "QuatZ" or curve.name == "QuatW": times = channel_times['Rotation'] channel_ipos['Rotation'].append(curve) elif curve.name == "RotX": times = channel_times['EulerX'] channel_ipos['EulerX'].append(curve) elif curve.name == "RotY": times = channel_times['EulerY'] channel_ipos['EulerY'].append(curve) elif curve.name == "RotZ": times = channel_times['EulerZ'] channel_ipos['EulerZ'].append(curve) elif curve.name == "LocX" or curve.name == "LocY" or curve.name == "LocZ": times = channel_times['Translation'] channel_ipos['Translation'].append(curve) elif curve.name == "ScaleX" or curve.name == "ScaleY" or curve.name == "ScaleZ": times = channel_times['Scale'] channel_ipos['Scale'].append(curve) elif curve.name == "R" or curve.name == "G" or curve.name == "B" or curve.name == "Alpha": times = channel_times['Color'] channel_ipos['Color'].append(curve) for p in curve.bezierPoints: times.add(p.pt[0]) if DEBUG: debug("ipo %s sort time for curves" % (ipo.getName())) for key in channel_times.iterkeys(): time = list(channel_times[key]) time.sort() channel_times[key] = time if len(time) > 0: channel_samplers[key] = Channel() if DEBUG: debug("ipo %s time sorted %s %s" % (ipo.getName(), key, len(time))) if DEBUG: debug("ipo %s fill channels" % (ipo.getName())) for key in channel_times.iterkeys(): if channel_samplers[key] is None: if DEBUG: debug("ipo %s nothing to fill for channel %s" % (ipo.getName(), key)) continue if DEBUG: debug("ipo %s fill channel %s" % (ipo.getName(), key)) #if DEBUG: debug("ipo %s process %s " % (ipo.getName(), key)) times = channel_times[key] for time in times: realtime = (time - 1) / fps if realtime > duration: duration = realtime trans = Vector() quat = Quaternion() scale = Vector() rot = Euler() color = [1,1,1,1] rtype = None # I know this can be cleaned up... for curve in channel_ipos[key]: val = curve[time] if DEBUG: debug("ipo %s process curve %s at %s value is %s" % (ipo.getName(), curve.name, time, val)) bezPoints = curve.bezierPoints if curve.name == 'LocX': trans[0] = val elif curve.name == 'LocY': trans[1] = val elif curve.name == 'LocZ': trans[2] = val elif curve.name == 'QuatW': quat.w = val elif curve.name == 'QuatX': quat.x = val elif curve.name == 'QuatY': quat.y = val elif curve.name == 'QuatZ': quat.z = val elif curve.name == 'ScaleX': scale[0] = val elif curve.name == 'ScaleY': scale[1] = val elif curve.name == 'ScaleZ': scale[2] = val elif curve.name == 'RotX': rot.x = val * 10 elif curve.name == 'RotY': rot.y = val * 10 elif curve.name == 'RotZ': rot.z = val * 10 elif curve.name == 'R': color[0] = val elif curve.name == 'G': color[1] = val elif curve.name == 'B': color[2] = val elif curve.name == 'Alpha': color[3] = val else: continue if key == 'Scale': # if DEBUG: debug("ipo %s process %s %s %s %s %s" % (ipo.getName(), key, realtime, scale[0], scale[1], scale[2])) channel_samplers[key].keys.append((realtime, scale[0], scale[1], scale[2])) channel_samplers[key].type = "Vec3LinearChannel" channel_samplers[key].setName("scale") elif key == 'Rotation': quat.normalize() channel_samplers[key].keys.append((realtime, quat.x, quat.y, quat.z, quat.w)) channel_samplers[key].type = "QuatSphericalLinearChannel" channel_samplers[key].setName("quaternion") elif key == 'EulerX': channel_samplers[key].keys.append((realtime, math.radians(rot.x))) channel_samplers[key].type = "FloatLinearChannel" channel_samplers[key].setName("euler_x") elif key == 'EulerY': channel_samplers[key].keys.append((realtime, math.radians(rot.y))) channel_samplers[key].type = "FloatLinearChannel" channel_samplers[key].setName("euler_y") elif key == 'EulerZ': channel_samplers[key].keys.append((realtime, math.radians(rot.z) )) channel_samplers[key].type = "FloatLinearChannel" channel_samplers[key].setName("euler_z") elif key == 'Translation': channel_samplers[key].keys.append((realtime, trans[0], trans[1], trans[2])) channel_samplers[key].type = "Vec3LinearChannel" channel_samplers[key].setName("translate") elif key == 'Color': channel_samplers[key].keys.append((realtime, color[0], color[1], color[2], color[3])) channel_samplers[key].type = "Vec4LinearChannel" channel_samplers[key].setName("diffuse") channels.append(channel_samplers[key]) #print channel_samplers[key] return channels