Sluicer Posted June 21, 2021 Share Posted June 21, 2021 I finally found some time to play around with LEGO SW2 again. Here is a noesis script to look into the hgp files: from inc_noesis import * import noesis import rapi def registerNoesisTypes(): '''Register the plugin. Just change the Game name and extension.''' handle = noesis.register("LEGO Star Wars 2", ".hgp") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadModel(handle, noepyLoadModel) return 1 def noepyCheckType(data): '''Verify that the format is supported by this plugin. Default yes''' bs = NoeBitStream(data) tmp = bs.readInt() tmp = bs.readInt() if tmp == 0x3032554e: #4e553230: # NU20 return 1 return 0 def noepyLoadModel(data, mdlList): bs = NoeBitStream(data) ctx = rapi.rpgCreateContext() stack = [] textures = [] materials = [] fileSize = bs.readInt() #NU20 fourCC = bs.readInt() numberTextures = bs.readInt() print("NumberTextures %d" % numberTextures) offsetTextures = bs.readInt() numberMaterials = bs.readInt() print("NumberMaterials %d" % numberMaterials) offsetMaterials = bs.readInt() numberMatix = bs.readInt() print("NumberMatix %d" % numberMatix) offsetMatix1 = bs.readInt() offsetMatix2 = bs.readInt() offsetMatix3 = bs.readInt() numberUnk1 = bs.readInt() print("NumberUnk1 %d" % numberUnk1) offsetUnk1 = bs.readInt() offsetText = bs.readInt() lenthText = bs.readInt() numberUnk = bs.readInt() #print("NumberBones %d" % numberBones) offsetUnk = bs.readInt() numberAttachment = bs.readInt() #print("NumberAttachment %d" % numberAttachment) offsetAttachment = bs.readInt() numberLayer = bs.readInt() print("NumberLayer %d" % numberLayer) offsetLayer = bs.readInt() offsetMini3D = bs.readInt() # end header bs.seek(offsetTextures, NOESEEK_ABS) offsetTextures2 = bs.readInt() bs.seek(offsetTextures2, NOESEEK_ABS) bs.readInt() #numberOfTextures = bs.readInt() textureHeaderSize = bs.readInt() textureDataOffset = bs.readInt() bs.readInt() bs.seek(offsetTextures2+textureHeaderSize, NOESEEK_ABS) for i in range (1, numberTextures+1): width = bs.readInt() height = bs.readInt() bs.readInt() ddsType = bs.readInt() if ddsType == 0x0C: size = width * height imgType = noesis.NOESISTEX_DXT3 elif ddsType == 0x0F: size = width * height imgType = noesis.NOESISTEX_DXT5 else: print('Unknown dds type: ' + repr(ddsType)) imageOffset = bs.readInt() tmp = bs.tell() bs.seek(offsetTextures2+textureDataOffset+imageOffset+0x80, NOESEEK_ABS) print("Image{0} @ {1:8x}: width = {2:4d}; height = {3:4d}".format(i, offsetTextures2+textureDataOffset+imageOffset, width, height)) data = bs.readBytes(size) #texture = rapi.loadTexByHandler(data, ".dds") #NoeTexture(str(i), width, height, data, imgType) texture = NoeTexture(str(i), width, height, data, imgType) texture.name = "tex%03i"%i textures.append(texture) bs.seek(tmp, NOESEEK_ABS) bs.seek(offsetMaterials, NOESEEK_ABS) materialOffsets = [] for i in range (0, numberMaterials): materialOffsets.append(bs.readInt()) i = 0 for m in (materialOffsets): bs.seek(m, NOESEEK_ABS) material = NoeMaterial("mat%03i"%i, "") #create a material bs.seek(84, NOESEEK_REL) # red = bs.readFloat() green = bs.readFloat() blue = bs.readFloat() alpha = bs.readFloat() material.setDiffuseColor(NoeVec4([red, green, blue, alpha])) #print("DiffuseColor: ", i, red, green, blue, alpha) bs.seek(0x14, NOESEEK_REL) # texId = bs.readShort() #print("TexId: ", texId) if (texId != 0): material.setTexture("tex%03i"%texId) #else: # material.setTexture(None) materials.append(material) i += 1 bones = [] bones0 = [] bones1 = [] bones2 = [] boneNames = [] bonePIndices = [] bs.seek(offsetMatix1, NOESEEK_ABS) for i in range (0, numberMatix): boneMat = NoeMat44.fromBytes(bs.readBytes(0x40)).toMat43() bs.seek(0xc, NOESEEK_REL) offsetText = bs.readInt() mem = bs.tell() bs.seek(offsetText, NOESEEK_ABS) boneName = bs.readString() boneNames.append(boneName) bs.seek(mem, NOESEEK_ABS) bonePIndex = bs.readByte() bonePIndices.append(bonePIndex) bs.readByte() bs.readByte() bs.readByte() bs.readInt() bs.readInt() bs.readInt() print(boneName + ": " + repr(i) + "-->" + repr(bonePIndex)) bones0.append(boneMat) for i in range (0, numberMatix): boneMat = NoeMat44.fromBytes(bs.readBytes(0x40)).toMat43() #print(boneMat) if (bonePIndices[i] != -1): boneMat = boneMat.__mul__(bones1[bonePIndices[i]]) bone = NoeBone(i, boneNames[i], boneMat, None, bonePIndices[i]) bones.append(bone) bones1.append(boneMat) for i in range (0, numberMatix): boneMat = NoeMat44.fromBytes(bs.readBytes(0x40)).toMat43() #print(boneMat) bones2.append(boneMat) layerList = [] bs.seek(offsetLayer, NOESEEK_ABS) for i in range (0, numberLayer): print("Layer %d" % i) parseLayer(bs, numberMatix, layerList) bs.seek(offsetTextures, NOESEEK_ABS) offsetImages = bs.readInt() offsetMesh = bs.readInt() bs.seek(offsetMesh, NOESEEK_ABS) #print("MESH @ 0x%x" % (bs.tell())) numberVertexLists = bs.readInt() #print("{0:08x} numberVertexLists: 0x{1:08x}".format(bs.tell()-4, numberVertexLists)) numberUnk = bs.readInt() size = bs.readInt() type = bs.readInt() offsetMeshHeader = bs.readInt() sizeVertices = bs.readInt() bs.readInt() offsetIndices = bs.readInt() sizeIndices = bs.readInt() bs.seek(offsetMesh+0x30, NOESEEK_ABS) sizeList = [] offsetList = [] for i in range (0, numberVertexLists): sizeList.append(bs.readInt()) id = bs.readInt() offsetList.append(bs.readInt()) bs.seek(offsetMesh+offsetMeshHeader, NOESEEK_ABS) #print("Vertices @ 0x%x" % (bs.tell())) vertexLists = [] for i in range (0, numberVertexLists): bs.seek(offsetMesh+offsetMeshHeader+offsetList[i], NOESEEK_ABS) vertexLists.append(bs.readBytes(sizeList[i])) bs.seek(offsetMesh+offsetIndices, NOESEEK_ABS) #print("Indices @ 0x%x" % (bs.tell())) indexLists = [] indexLists.append(bs.readBytes(sizeIndices)) #print("EOF @ 0x%x" % (bs.tell())) #for layer in (layerList): for i in range (0, numberLayer): layer = layerList[i] for part in (layer): #print("Part") #print("Indices @ 0x%x" % (part.VertexListType[0])) if (part.BoneId != -1): rapi.rpgSetTransform(bones1[part.BoneId]) else: rapi.rpgSetTransform(None) if (part.VertexListType[0] == 0x5D): bytesForPositions = (vertexLists[part.VertexList[0]][part.offsetVertex*0x38:part.offsetVertex*0x38+part.numberVertex*0x38]) rapi.rpgBindPositionBuffer(bytesForPositions, noesis.RPGEODATA_FLOAT, 0x38, 0) rapi.rpgBindBoneWeightBufferOfs(bytesForPositions, noesis.RPGEODATA_FLOAT, 0x38, 0x0c, 2) rapi.rpgBindBoneIndexBufferOfs(bytesForPositions, noesis.RPGEODATA_FLOAT, 0x38, 0x14, 2) rapi.rpgBindUV1BufferOfs(bytesForPositions, noesis.RPGEODATA_FLOAT, 0x38, 0x30) if (part.VertexListType[0] == 0x59): bytesForPositions = (vertexLists[part.VertexList[0]][part.offsetVertex*0x24:part.offsetVertex*0x24+part.numberVertex*0x24]) rapi.rpgBindPositionBuffer(bytesForPositions, noesis.RPGEODATA_FLOAT, 0x24, 0) rapi.rpgBindBoneWeightBufferOfs(bytesForPositions, noesis.RPGEODATA_FLOAT, 0x24, 0x0c, 2) rapi.rpgBindBoneIndexBufferOfs(bytesForPositions, noesis.RPGEODATA_FLOAT, 0x24, 0x14, 2) rapi.rpgBindUV1BufferOfs(bytesForPositions, noesis.RPGEODATA_FLOAT, 0x24, 0x1C) bytesForIndexBuffer = (indexLists[0][part.offsetIndex*2:part.offsetIndex*2+(part.numberIndex+2)*2]) rapi.rpgSetMaterial("mat%03i"%part.MadId) rapi.rpgCommitTriangles(bytesForIndexBuffer, noesis.RPGEODATA_SHORT, part.numberIndex+2, noesis.RPGEO_TRIANGLE_STRIP, 1) rapi.rpgClearBufferBinds() mdl = rapi.rpgConstructModel() mdl.setModelMaterials(NoeModelMaterials(textures, materials)) mdl.setBones(bones) mdlList.append(mdl) #important, don't forget to put your loaded model in the mdlList return 1 def parseLayer(bs, numberMatix, layerList): partList = [] layerMeta1 = bs.readInt() layerMeta2 = bs.readInt() #print(" layerMeta2 %d" % layerMeta2) mem = bs.tell() if (layerMeta2 != 0): bs.seek(layerMeta2, NOESEEK_ABS) parseLayerMeta2(bs, numberMatix, partList) bs.seek(mem, NOESEEK_ABS) layerMeta3 = bs.readInt() #print(" layerMeta3 %d" % layerMeta3) mem = bs.tell() if (layerMeta3 != 0): bs.seek(layerMeta3, NOESEEK_ABS) parsePartHeader(bs, partList, -1) bs.seek(mem, NOESEEK_ABS) layerMeta4 = bs.readInt() layerMeta5 = bs.readInt() #print(" layerMeta5 %d" % layerMeta5) mem = bs.tell() if (layerMeta5 != 0): bs.seek(layerMeta5, NOESEEK_ABS) parsePartHeader(bs, partList, -1) bs.seek(mem, NOESEEK_ABS) layerList.append(partList) def parseLayerMeta2(bs, numberMatix, partList): for i in range (0, numberMatix): tmp = bs.readInt() mem = bs.tell() if (tmp != 0): bs.seek(tmp, NOESEEK_ABS) #print(" offsetLayerPart %d" % tmp) parsePartHeader(bs, partList, i) bs.seek(mem, NOESEEK_ABS) def parsePartHeader(bs, partList, boneId): bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readFloat() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() pos = bs.tell() #print(" pos 4 next %x" % pos) next = bs.readInt() #print(" next %d" % next) parsePart(bs, partList, boneId) while (next != 0): bs.seek(next, NOESEEK_ABS) next = bs.readInt() #print(" next %d" % next) parsePart(bs, partList, boneId) def parsePart(bs, partList, boneId): part = Part() part.BoneId = boneId pos = bs.tell() #print(" pos %x" % pos) bs.readInt() part.MadId = bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() fourCC = bs.readInt() bs.readInt() bs.readInt() ext = bs.readInt() bs.readInt() bs.readInt() numberVertexLists = bs.readInt() for i in range (0, 8): part.VertexList.append(bs.readInt()) for i in range (0, 8): part.VertexListType.append(bs.readInt()) bs.readInt() bs.readInt() bs.readInt() bs.readInt() bs.readInt() chunk6 = bs.readInt() bs.readShort() bs.readShort() bs.readInt() bs.readInt() bs.readShort() bs.seek(17*2, NOESEEK_REL) chunk5 = bs.readInt() part.offsetVertex = bs.readInt() bs.readInt() part.numberVertex = bs.readInt() part.offsetIndex = bs.readInt() part.numberIndex = bs.readInt() pos = bs.tell() #print(" pos %x" % pos) print(" PartMeta: ", part.offsetVertex, part.numberVertex, part.offsetIndex, part.numberIndex) partList.append(part) class Part(): def __init__(self): self.VertexList = [] self.VertexListType = [] self.BoneId = 0 self.MadId = -1 self.offsetVertex = 0 self.numberVertex = 0 self.offsetIndex = 0 self.numberIndex = 0 Cirevam 1 Link to comment Share on other sites More sharing options...
Recommended Posts