def importZoneObjects(path, zoneName, importTextures): objPath = os.path.join(path, "%s_obj.s3d" % zoneName) with S3DArchive(objPath) as objArchive: wldObjMeshes = WLDData.fromArchive(objArchive, "%s_obj.wld" % zoneName) # load meshes in blender objectMeshes = {} for meshFrag in wldObjMeshes.fragmentsByType(0x36): objectMeshes[meshFrag.ID] = importWldMesh(objArchive, meshFrag, importTextures) actorMap = {f.name: f for f in wldObjMeshes.fragmentsByType(0x14)} # place objects that use the meshes zonePath = os.path.join(path, "%s.s3d" % zoneName) with S3DArchive(zonePath) as zoneArchive: wldObjDefs = WLDData.fromArchive(zoneArchive, "objects.wld") for objectDef in wldObjDefs.fragmentsByType(0x15): actor = actorMap.get(objectDef.Reference) if actor: for meshRef in actor.models: #XXX: this can be a skeleton instead of a mesh. Okay, maybe not for placeable objects. mesh = objectMeshes.get(meshRef.Mesh.ID) if mesh: obj = bpy.data.objects.new(actor.name, mesh) obj.location = objectDef.location #obj.rotation_euler = objectDef.rotation obj.scale = objectDef.scale bpy.context.scene.objects.link(obj) else: print("Actor '%s' not found" % objectDef.name)
def listCharacters(s3dPath, wldName): with S3DArchive(s3dPath) as a: wld = WLDData.fromArchive(a, wldName) actors = {} importCharacters(wld, actors) importCharacterPalettes(wld, actors) dumpCharacters(wld, actors)
def importZoneGeometry(path, zoneName, importTextures): zonePath = os.path.join(path, "%s.s3d" % zoneName) with S3DArchive(zonePath) as zoneArchive: wldZone = WLDData.fromArchive(zoneArchive, "%s.wld" % zoneName) zoneMeshFrags = list(wldZone.fragmentsByType(0x36)) zoneMeshes = importWldMeshes(zoneArchive, zoneMeshFrags, importTextures) for frag, mesh in zip(zoneMeshFrags, zoneMeshes): obj = bpy.data.objects.new(frag.name, mesh) obj.location = (frag.CenterX, frag.CenterY, frag.CenterZ) bpy.context.scene.objects.link(obj)
def list_palettes(dir_path): files = [f for f in os.listdir(dir_path) if f.endswith(".s3d")] files.sort() print("s3d,wld,palettes,maxMatsPerPalette,totalMats") for file in files: path = os.path.join(dir_path, file) with S3DArchive(path) as a: for entry in a.files: if not entry.endswith(".wld"): continue try: wld = WLDData.fromArchive(a, entry) except Exception as e: continue palettes = list(wld.fragmentsByType(0x31)) if palettes: max_mats = max(len(pal.Textures) for pal in palettes) total_mats = sum(len(pal.Textures) for pal in palettes) print("%s,%s,%d,%d,%d" % (file, entry, len(palettes), max_mats, total_mats))
def importZoneCharacter(path, zoneName, actorName, animName, frame, importTextures): chrPath = os.path.join(path, "%s_chr.s3d" % zoneName) with S3DArchive(chrPath) as chrArchive: wldChrMeshes = WLDData.fromArchive(chrArchive, "%s_chr.wld" % zoneName) actorFrag = wldChrMeshes.findFragment(0x14, actorName) if not actorFrag: raise Exception("Actor not found '%s' in archive" % actorName) meshes = [] skeletons = skeleton.skeletonsFromWld(wldChrMeshes) for modelFrag in actorFrag.models: if (modelFrag.type == 0x11) and modelFrag.Reference: skelFrag = modelFrag.Reference skel = skeletons.get(skelFrag.name[0:3]) if skel: meshes.extend(importCharacterFromSkeletonDef(chrArchive, skel, animName, frame, importTextures)) elif (modelFrag.type == 0x2d) and modelFrag.Mesh: meshFrag = modelFrag.Mesh meshes.append((meshFrag, importWldMesh(chrArchive, meshFrag, importTextures))) actorObj = bpy.data.objects.new(actorName, None) bpy.context.scene.objects.link(actorObj) for meshFrag, mesh in meshes: obj = bpy.data.objects.new(meshFrag.name, mesh) obj.parent = actorObj bpy.context.scene.objects.link(obj)
return {pieceID: (name, trans[:], rot[:]) for pieceID, (name, trans, rot) in transforms.items()} else: return transforms def computePieceTransformation(self, transforms, tree, pieceID, frame, parentLoc, parentRot): piece, track = tree[pieceID], self.tracks[pieceID].Reference pieceLoc, pieceRot = Vector3(*track.location(frame)), Quaternion(*track.rotation(frame)) try: transLoc = (parentRot * pieceLoc) + parentLoc except Exception: print(repr(pieceLoc), repr(parentRot)) raise transRot = parentRot * pieceRot transforms[pieceID] = (piece.name, transLoc, transRot) for childID in piece.children: self.computePieceTransformation(transforms, tree, childID, frame, transLoc, transRot) if __name__ == "__main__": if len(sys.argv) < 2: print("usage: %s <.S3D file>" % sys.argv[0]) path = sys.argv[1] with S3DArchive(path) as a: wldName = os.path.basename(path).replace(".s3d", ".wld") wld = WLDData.fromArchive(a, wldName) skeletons = skeletonsFromWld(wld) for name, skel in skeletons.items(): print(name) for anim in skel.animations.values(): print(" %s %d" % (anim.name, anim.frameCount)) print(" %s" % "\n ".join(["%s %d" % (f.name, len(f.Reference.frames)) for f in anim.tracks]))