Пример #1
0
def readFile(fileTree, fileList, fileID):
	# fileID = fileID.upper()
	if not tempFiles.exists(fileID):
		decompressDatafile(fileTree, fileList, fileID)
	data = tempFiles.read(fileID)
	if len(data) == 0:
		raise Exception('file '+fileID+' is empty')
	data = data[0]
	
	if data['resourceType'] == '415D9568':	#mesh (textures looked up)
		print 'Exporting '+data['fileName']
		readModel(fileTree, fileList, fileID)
		exportOBJ(fileTree, fileList, fileID)
	elif data['resourceType'] == 'AC2BBF68': #datablock (includes world data)
		exportDataBlockModels(fileTree, fileList, fileID)
	elif data['resourceType'] == 'A2B7E917': #texture
		exportTexture(fileTree, fileList, fileID)
	elif data['resourceType'] == '85C817C3': #material (containing textures)
		textureIDs = getMaterialIDs(fileTree, fileList, fileID)
		if textureIDs == None:
			return
		else:
			for hexid in textureIDs:
				exportTexture(fileTree, fileList, textureIDs[hexid])
	elif data['resourceType'] =='C69A7F31':	#fakes
		exportFakes(fileTree, fileList, fileID)
	else:
		if 'dev' in sys.argv:
			reload(formatFile)  # for development
		formatFile.topLevelFormat(fileTree, fileList, fileID)
Пример #2
0
 def onClick(self, event):
     fileID = self.fileTree.selection()[0]
     if len(fileID.split('|')) == 3 and len(
             self.fileTree.get_children(fileID)) == 0:
         decompressDatafile(self.fileTree, self.fileList,
                            fileID.split('|')[2],
                            fileID.split('|')[1])
Пример #3
0
 def info(self, input=None):
     if self.search.get() == '' and input == None:
         return
     if self.search.get() != '':
         fileID = self.search.get().replace(' ', '').upper()
     if input != None:
         fileID = input.replace(' ', '').upper()
     if not tempFiles.exists(fileID):
         decompressDatafile(self.fileTree, self.fileList, fileID)
     if not tempFiles.exists(fileID):
         raise Exception()
     print fileID
     print tempFiles.read(fileID)
Пример #4
0
def readID(fileTree, fileList, fIn, fOut):
    val = fIn.read(8)
    fileID = BEHEX2(val)
    if dev:
        fOut.write(hexSpaces(val))
        fOut.write('\t\t')
        if not tempFiles.exists(fileID):
            decompressDatafile(fileTree, fileList, fileID)
        data = tempFiles.read(fileID)
        if len(data) == 0:
            fOut.write('Unknown File ID')
        else:
            data = data[0]
            fOut.write(data["fileName"])
            fOut.write('\t\t')
            fOut.write(data["resourceType"])
        fOut.write('\n')
    return fileID
Пример #5
0
def exportFakes(fileTree, fileList, fileID):
    if not tempFiles.exists(fileID):
        decompressDatafile(fileTree, fileList, fileID)
    data = tempFiles.read(fileID)
    if len(data) == 0:
        raise Exception('file ' + fileID + ' is empty')
    data = data[0]

    fIn = open(data['dir'], 'rb')
    fReadIn = fIn.read()
    fIn.close()

    files = fReadIn.split(binascii.unhexlify('000000000000000024B57FD7'))[1:]

    fileIDList = []
    for n in files:
        if binascii.unhexlify('298D65EC') not in n:
            continue
        fileContainer = {}
        fileContainer['transformationMtx'] = [[], [], [], []]
        fileContainer['transformationMtx'][0].append(float32(n[15:19]))
        fileContainer['transformationMtx'][1].append(float32(n[19:23]))
        fileContainer['transformationMtx'][2].append(float32(n[23:27]))
        fileContainer['transformationMtx'][3].append(float32(n[27:31]))
        fileContainer['transformationMtx'][0].append(float32(n[31:35]))
        fileContainer['transformationMtx'][1].append(float32(n[35:39]))
        fileContainer['transformationMtx'][2].append(float32(n[39:43]))
        fileContainer['transformationMtx'][3].append(float32(n[43:47]))
        fileContainer['transformationMtx'][0].append(float32(n[47:51]))
        fileContainer['transformationMtx'][1].append(float32(n[51:55]))
        fileContainer['transformationMtx'][2].append(float32(n[55:59]))
        fileContainer['transformationMtx'][3].append(float32(n[59:63]))
        fileContainer['transformationMtx'][0].append(float32(n[63:67]))
        fileContainer['transformationMtx'][1].append(float32(n[67:71]))
        fileContainer['transformationMtx'][2].append(float32(n[71:75]))
        fileContainer['transformationMtx'][3].append(float32(n[75:79]))
        visualLoc = n.find(binascii.unhexlify('298D65EC'))
        fileContainer['fileID'] = BEHEX2(n[visualLoc + 8:visualLoc +
                                           16]).upper()
        fileIDList.append(fileContainer)

    exportOBJMulti(fileTree, fileList, fileID, fileIDList)
Пример #6
0
def topLevelFormat(fileTree, fileList, fileID):
    if not tempFiles.exists(fileID):
        decompressDatafile(fileTree, fileList, fileID)
    data = tempFiles.read(fileID)
    if len(data) == 0:
        raise Exception('file ' + fileID + ' is empty')
    data = data[0]
    log.info(__name__, 'Formatting ' + fileID + ':' + data["fileName"])
    fIn = open(data["dir"], 'rb')
    if dev:
        fOut = open(data["dir"] + '.format', 'w')
    else:
        fOut = None

    fileContainer = {}

    # file header
    readStr(fIn, fOut, 2)
    fileContainer['fileID'] = readID(fileTree, fileList, fIn, fOut)
    fileContainer['fileType'] = readType(fIn, fOut)
    fOutWrite(fOut, '\n')

    subFileContainer = recursiveFormat(fileTree, fileList,
                                       data["resourceType"], fIn, fOut)
    for key in subFileContainer:
        fileContainer[key] = subFileContainer[key]

    fileContainer['readRest'] = ReadRest(fIn, fOut)

    fIn.close()
    if dev:
        fOut.close()
        print data["dir"] + '.format'
        os.system('"' + data['dir'] + '.format"')

    return fileContainer
Пример #7
0
def exportOBJMulti(fileTree, fileList, rootID, fileIDList):
    print fileIDList
    #fileIDList format
    # [
    # {'fileID':'0000000000000000', 'transformationMtx': },
    # {'fileID':'0000000000000000', 'transformationMtx': },
    # {'fileID':'0000000000000000', 'transformationMtx': }
    # ]

    # fileIDList format V2
    # {
    # '0000000000000000' : [{'tm':[<transformationMtx1.1>, <transformationMtx1.2>, ...],'BB':[]}, {'tm':[<transformationMtx2.1>, <transformationMtx2.2>, ...],'BB':[]}, ...],
    # '0000000000000000' : [{'tm':[<transformationMtx1.1>, <transformationMtx1.2>, ...],'BB':[]}, {'tm':[<transformationMtx2.1>, <transformationMtx2.2>, ...],'BB':[]}, ...],
    # ...
    # }

    if not tempFiles.exists(rootID):
        decompressDatafile(fileTree, fileList, rootID)
    rootData = tempFiles.read(rootID)
    if len(rootData) == 0:
        raise Exception('file ' + rootID + ' is empty')
    rootData = rootData[0]

    # remove models that couldn't be read
    meshCount = 0
    ticker = 0
    failedModels = []
    for fileID in fileIDList:

        if not tempFiles.exists(fileID):
            decompressDatafile(fileTree, fileList, fileID)
        data = tempFiles.read(fileID)
        if len(data) == 0:
            raise Exception('file ' + fileID + ' is empty')
        data = data[0]

        if not os.path.isfile(data['dir'].replace('.acu', '.json')):
            try:
                readModel(fileTree, fileList, fileID)
            except:
                print 'Failed reading model ' + data['fileName']
        if os.path.isfile(data['dir'].replace('.acu', '.json')):
            meshCount += len(fileIDList[fileID])
            ticker += 1
            print 'read model ' + str(ticker) + ' of ' + str(len(fileIDList))
        else:
            failedModels.append(fileID)
    for fileID in failedModels:
        del fileIDList[fileID]

    rootID = rootID.upper()
    fileName = rootData['fileName']
    savePath = CONFIG['dumpFolder'] + os.sep + fileName
    # savePath = path[:-4] + ".obj"
    # str1 = os.sep.join(savePath.split(os.sep)[:-1])	#save path folder
    # while (treeNode1.Parent != null)
    # treeNode1 = treeNode1.Parent;
    # string str2 = treeNode1.Tag.ToString().ToLower();					'acu'

    # obj file
    fio = open(savePath + ".obj", 'w')  # open obj
    fio.write("# Wavefront Object File\n")  # write text
    fio.write("# Exported by ACExplorer based on code from ARchive_neXt\n")
    fio.write("mtllib " + fileName + ".mtl\n")
    fio.write('\n')
    offset = 0
    tempFileRepeat = {}

    # mtl file
    fim = open(savePath + ".mtl", 'w')
    fim.write("# Material Library\n")
    fim.write("# Exported by ACExplorer based on code from ARchive_neXt\n")
    fim.write("\n")
    idsAdded = []
    missingNo = False
    meshNo = 0

    for index0, fileID in enumerate(fileIDList):

        if not tempFiles.exists(fileID):
            decompressDatafile(fileTree, fileList, fileID)
        data = tempFiles.read(fileID)
        if len(data) == 0:
            raise Exception('file ' + fileID + ' is empty')
        data = data[0]

        # used in face data section to define unique names
        if fileID not in tempFileRepeat:
            tempFileRepeat[fileID] = 0
        else:
            tempFileRepeat[fileID] += 1

        with open(data['dir'].replace('.acu', '.json')) as f:
            try:
                model = json.loads(f.read())
            except:
                print data['fileName']
                raise Exception()
            #num2 = model['modelScale']# * 0.0002 * 10 * 0.2	# model scale
            num3 = 2048.0
            num4 = 0
            # if model['typeSwitch'] != 3:
            # num2 = 100.0
            # else:
            # num2 = 0.00305
            # num2 = 1

            # vertex data

            # Transformation Matrix fileContainer['tm'][0-3][0-3]
            # [M11 M12 M13 M14][x]
            # |M21 M22 M23 M24||y|
            # |M31 M32 M33 M34||z|
            # [M41 M42 M43 M44][1]
            for fileContainer in fileIDList[fileID]:
                meshNo += 1
                for vertex in model['vertData']['vertex']:
                    vertex = [vertex['X'], vertex['Y'], vertex['Z']]
                    for tm in reversed(fileContainer['tm']):
                        vertex = transform(tm, vertex)
                    fio.write("v " + str(round(vertex[0], 6)) + " " +
                              str(round(vertex[1], 6)) + " " +
                              str(round(vertex[2], 6)) + '\n')
                print 'written vertex data ' + str(meshNo) + ' of ' + str(
                    meshCount)

                # texture coordinates
                for tVert in model['vertData']['tVert']:
                    fio.write("vt " + str(round((tVert['X'] / num3), 6)) +
                              " " + str(round((tVert['Y'] / -num3), 6)) + '\n')
                print 'written texture coordinates ' + str(
                    meshNo) + ' of ' + str(meshCount)

                # face mappings
                for index1, meshData in enumerate(model['meshData']):
                    num5 = meshData['vertCount']  #vertex number?
                    num6 = meshData['vertStart'] / 3
                    if model['typeSwitch'] == 0 and model[
                            'faceCount'] != model['facesUsed']:
                        if index1 > 0:
                            num6 = num4 * 64
                            num4 += model['meshFaceBlocks'][index1]
                        else:
                            num4 = model['meshFaceBlocks'][index1]
                    fio.write("g " + data['fileName'] + "_" +
                              str(tempFileRepeat[fileID]) + '_' + str(index1) +
                              '\n')

                    textureIDs = getMaterialIDs(fileTree, fileList,
                                                model['materialId'][index1])

                    if textureIDs == None:
                        fio.write("usemtl missingNo\n")
                    else:
                        for hexid in textureIDs:
                            exportTexture(fileTree, fileList,
                                          textureIDs[hexid])
                        data2 = tempFiles.read(
                            model['materialId'][index1].upper())
                        if len(data2) == 0:
                            raise Exception(
                                'file ' + model['materialId'][index1].upper() +
                                ' is empty')
                        data2 = data2[0]
                        material = data2['fileName']
                        fio.write("usemtl " + material + '\n')
                    fio.write("s 0\n")
                    if model['typeSwitch'] != 3:
                        num7 = meshData['X']
                    else:
                        num7 = 0
                    for index2 in range(num6, num5 + num6):
                        fio.write("f " + str(
                            int(model['faceData'][index2]['Y'] + 1.0 + num7 +
                                offset)) + "/" + str(
                                    int(model['faceData'][index2]['Y'] + 1.0 +
                                        num7 + offset)) + " " +
                                  str(
                                      int(model['faceData'][index2]['X'] +
                                          1.0 + num7 + offset)) + "/" +
                                  str(
                                      int(model['faceData'][index2]['X'] +
                                          1.0 + num7 + offset)) + " " +
                                  str(
                                      int(model['faceData'][index2]['Z'] +
                                          1.0 + num7 + offset)) + "/" +
                                  str(
                                      int(model['faceData'][index2]['Z'] +
                                          1.0 + num7 + offset)) + '\n')
                    fio.write("# " + str(num5) + " triangles\n\n")
                offset += len(model['vertData']['vertex'])
                print 'written triangle data ' + str(meshNo) + ' of ' + str(
                    meshCount)

            # material data in mtl
            for materialId in model['materialId']:
                if materialId in idsAdded:
                    continue
                else:
                    idsAdded.append(materialId)

                data2 = tempFiles.read(materialId.upper())
                if len(data2) == 0:
                    raise Exception('file ' + materialId.upper() + ' is empty')
                data2 = data2[0]

                material = data2['fileName']
                if material != "NULL":
                    textureIDs = getMaterialIDs(fileTree, fileList, materialId)

                    if textureIDs == None:
                        missingNo = True
                        continue
                    fim.write("newmtl " + material + '\n')
                    fim.write("Ka 1.000 1.000 1.000\n")
                    fim.write("Kd 1.000 1.000 1.000\n")
                    fim.write("Ks 0.000 0.000 0.000\n")
                    fim.write("Ns 0.000\n")
                    for texType in textureIDs:
                        if texType == 'diffuse':
                            fim.write("map_Kd ")
                        elif texType == 'normal':
                            fim.write("bump -bm 0.300 ")
                        elif texType == 'specular':
                            fim.write("map_Ks ")
                        else:
                            continue

                        data3 = tempFiles.read(textureIDs[texType].upper())
                        if len(data3) == 0:
                            raise Exception('file ' +
                                            textureIDs[texType].upper() +
                                            ' is empty')
                        data3 = data3[0]

                        fim.write(data3['fileName'] + '.dds\n')
                        if texType == 'diffuse':
                            fim.write("map_d ")
                            fim.write(data3['fileName'] + '.dds\n')

                    fim.write('\n')
            print 'written material data ' + str(index0) + ' of ' + str(
                len(fileIDList))

    fio.close()

    # write misingNo texture if used
    if missingNo:
        fim.write("newmtl missingNo\n")
        fim.write("Ka 1.000 1.000 1.000\n")
        fim.write("Kd 1.000 1.000 1.000\n")
        fim.write("Ks 0.000 0.000 0.000\n")
        fim.write("Ns 0.000\n")
        fim.write("map_Kd missingNo.png\n")
        fim.write('\n')
    fim.close()

    print 'Done'
Пример #8
0
def readModel(fileTree, fileList, fileID):
	if not tempFiles.exists(fileID):
		decompressDatafile(fileTree, fileList, fileID)
	data = tempFiles.read(fileID)
	if len(data) == 0:
		raise Exception('file '+fileID+' is empty')
	data = data[0]
	# str1 = strArray[1]			#MDL or HDMDL
	fIn = open(data['dir'], 'rb')				#open parent file
	
	if dev:
		fOut = open(data["dir"]+'.format', 'w')
	else:
		fOut = None
	
	
	
	model = {}
	
	readStr(fIn, fOut, 2)
	# file id
	readID(fileTree, fileList, fIn, fOut)
	# file type (should be a model)
	model['fileType'] = readType(fIn, fOut)
	fOutWrite(fOut, '\n')

	readStr(fIn, fOut, 1)		#skip an empty byte
	model['modelType'] = readStr(fIn, fOut, 4)	#
	readStr(fIn, fOut, 1)
	model['aCount'] = readInt(fIn, fOut, 4)
	if model['aCount'] > 0:
		raise Exception('aCount not accounted for')
	# {
		# readStr(fIn, fOut, 1)
		# for (int index1 = 0; index1 < 2; ++index1)
		# {
			  # binaryReader.BaseStream.Position += 13L;
			  # if (fi.read(4) > 0)
			  # {
				# int num3 = (int) MessageBox.Show("Undetermined block of model information.", "Block 1 Issue", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				# return;
			  # }
			  # int num4 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num4 * 4);
			  # int num5 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num5 * 4);
			  # int num6 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num6 * 4);
			  # int num7 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) num7;
			  # int num8 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num8 * 12);
			  # int num9 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num9 * 12);
			  # int num10 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num10 * 12);
			  # int num11 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num11 * 12);
			  # int num12 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num12 * 4);
			  # if (fi.read(4) > 0)
			  # {
				# int num3 = (int) MessageBox.Show("Undetermined block of model information.", "Block 11 Issue", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				# return;
			  # }
			  # ++binaryReader.BaseStream.Position;
			  # int num13 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num13 * 4);
			  # int num14 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num14 * 2);
			  # int num15 = fi.read(4);
			  # binaryReader.BaseStream.Position += (long) (num15 * 2);
			  # int num16 = fi.read(4);
			  # for (int index2 = 0; index2 < num16; ++index2)
			  # {
				# if (fi.read(4) > 0)
				# {
				  # int num3 = (int) MessageBox.Show("Undetermined block of model information.", "Block 15 Issue", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				  # return;
				# }
				# if (fi.read(4) > 0)
				# {
				  # int num3 = (int) MessageBox.Show("Undetermined block of model information.", "Block 16 Issue", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				  # return;
				# }
				# binaryReader.BaseStream.Position += 4L;
				# if (fi.read(4) > 0)
				# {
				  # int num3 = (int) MessageBox.Show("Undetermined block of model information.", "Block 17 Issue", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				  # return;
				# }
				# ++binaryReader.BaseStream.Position;
				# int num17 = fi.read(4);
				# binaryReader.BaseStream.Position += (long) (num17 * 8);
				# int num18 = fi.read(4);
				# binaryReader.BaseStream.Position += (long) (num18 * 4);
			# }
			# binaryReader.BaseStream.Position += 12L;
		# }
	# }
	model['boneCount'] = readInt(fIn, fOut, 4)
	if model['boneCount'] > 0:
		raise Exception('boneCount not accounted for')
	# {
	# arxForm.acModel.boneStruct = new arxForm.acBoneStruct[arxForm.acModel.boneCount];
	# for (int index = 0; index < arxForm.acModel.boneCount; ++index)
	# {
	  # arxForm.acModel.boneStruct[index].boneID = string.Format("{0:X8}", (object) fi.read(8)).PadLeft(16, '0');
	  # arxForm.acModel.boneStruct[index].boneType = string.Format("{0:X4}", (object) fi.read(4)).PadLeft(8, '0');
	  # arxForm.acModel.boneStruct[index].boneName = string.Format("{0:X4}", (object) fi.read(4)).PadLeft(8, '0');
	  # arxForm.acModel.boneStruct[index].transMatrix.M11 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M12 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M13 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M14 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M21 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M22 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M23 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M24 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M31 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M32 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M33 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M34 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M41 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M42 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M43 = binaryReader.ReadSingle();
	  # arxForm.acModel.boneStruct[index].transMatrix.M44 = binaryReader.ReadSingle();
	  # ++binaryReader.BaseStream.Position;
	  # arxForm.acModel.boneStruct[index].transMatrix.Invert();
	# }
	# }
	
	# readStr(fIn, fOut, 41)
	model['boundingBox'] = {}
	model['boundingBox']['minx'] = readFloat32(fIn, fOut)
	model['boundingBox']['miny'] = readFloat32(fIn, fOut)
	model['boundingBox']['minz'] = readFloat32(fIn, fOut)
	readStr(fIn, fOut, 4)
	model['boundingBox']['maxx'] = readFloat32(fIn, fOut)
	model['boundingBox']['maxy'] = readFloat32(fIn, fOut)
	model['boundingBox']['maxz'] = readFloat32(fIn, fOut)
	readStr(fIn, fOut, 4)
	readStr(fIn, fOut, 1)
	# readStr(fIn, fOut, 33) # this may be a bounding box. (float32)
	#First three are all negative followed by a set of zeros
	# Next three three are all positive followed by a set of zeros and a null byte
	readID(fileTree, fileList, fIn, fOut)
	if readStr(fIn, fOut, 4).upper() == "FC9E1595":
		readStr(fIn, fOut, 4)
		fOutWrite(fOut, 'Typeswitch\n')
		model['typeSwitch'] = readInt(fIn, fOut, 4)
		if model['typeSwitch'] == 0:
			readStr(fIn, fOut, 14)
			fOutWrite(fOut, 'Vert table length\n')
			model['vertTableSize'] = readInt(fIn, fOut, 4)
			model['unkLng2'] = readInt(fIn, fOut, 4)
			readStr(fIn, fOut, 24)
			model['length1'] = readInt(fIn, fOut, 4)
			model['length2'] = readInt(fIn, fOut, 4)
			model['meshFaceBlocks'] = []
			model['shadowFaceBlocks'] = []
			fOutWrite(fOut, 'Mesh Face Blocks\n')
			for index in range(model['length1']):
				model['meshFaceBlocks'].append(readInt(fIn, fOut, 4))
			for index in range(model['length2']):
				model['shadowFaceBlocks'].append(readInt(fIn, fOut, 4))
			model['unkLng'] = readInt(fIn, fOut, 4)
			model['unkByt'] = readStr(fIn, fOut, 1);
			fOutWrite(fOut, 'Vert count\n')
			num3 = readInt(fIn, fOut, 4)
			model['vertCount'] = num3 / model['vertTableSize'];
			model['vertData'] = {}
			model['vertData']['vertex'] = []
			model['vertData']['tVert'] = []
			model['vertData']['normals'] = []
			# arxForm.acModel.vertData = new arxForm.acVertStruct[arxForm.acModel.vertCount];
			fOutWrite(fOut, '\nVert Table\n')
			for index in range(model['vertCount']):
				if model['vertTableSize'] == 48:
					raise Exception('48')
					# arxForm.acModel.vertData[index].vertex.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 2L;
					# arxForm.acModel.vertData[index].normals.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 6L;
					# arxForm.acModel.vertData[index].tVert.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].tVert.Y = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 4L;
					# arxForm.acModel.vertData[index].boneNum.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.W = (float) binaryReader.ReadByte();
					# binaryReader.BaseStream.Position += 4L;
					# break;
				elif model['vertTableSize'] == 40:
					raise Exception('40')
					# arxForm.acModel.vertData[index].vertex.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 2L;
					# arxForm.acModel.vertData[index].normals.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 6L;
					# arxForm.acModel.vertData[index].tVert.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].tVert.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].boneNum.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.W = (float) binaryReader.ReadByte();
					# break;
				elif model['vertTableSize'] == 36:
					raise Exception('36')
					# arxForm.acModel.vertData[index].vertex.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 2L;
					# arxForm.acModel.vertData[index].normals.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 6L;
					# arxForm.acModel.vertData[index].tVert.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].tVert.Y = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 4L;
					# arxForm.acModel.vertData[index].boneNum.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.W = (float) binaryReader.ReadByte();
					# break;
				elif model['vertTableSize'] == 32:
					raise Exception('32')
					# arxForm.acModel.vertData[index].vertex.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 2L;
					# arxForm.acModel.vertData[index].normals.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 6L;
					# arxForm.acModel.vertData[index].tVert.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].tVert.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].boneNum.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.W = (float) binaryReader.ReadByte();
					# break;
				elif model['vertTableSize'] == 28:
					model['vertData']['vertex'].append({})
					model['vertData']['vertex'][index]['X'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['X'] >= 2**15:
						model['vertData']['vertex'][index]['X'] -= 2**16
					model['vertData']['vertex'][index]['Y'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['Y'] >= 2**15:
						model['vertData']['vertex'][index]['Y'] -= 2**16
					model['vertData']['vertex'][index]['Z'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['Z'] >= 2**15:
						model['vertData']['vertex'][index]['Z'] -= 2**16
					num4 = float(readInt(fIn, fOut, 2))
					if num4 >= 2**15:
						num4 -= 2**16
					model['vertData']['vertex'][index]['X'] /= num4
					model['vertData']['vertex'][index]['Y'] /= num4
					model['vertData']['vertex'][index]['Z'] /= num4
					model['vertData']['normals'].append({})
					model['vertData']['normals'][index]['X'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['normals'][index]['X'] >= 2**15:
						model['vertData']['normals'][index]['X'] -= 2**16
					model['vertData']['normals'][index]['Y'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['normals'][index]['Y'] >= 2**15:
						model['vertData']['normals'][index]['Y'] -= 2**16
					model['vertData']['normals'][index]['Z'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['normals'][index]['Z'] >= 2**15:
						model['vertData']['normals'][index]['Z'] -= 2**16
					readStr(fIn, fOut, 6)
					model['vertData']['tVert'].append({})
					model['vertData']['tVert'][index]['X'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['tVert'][index]['X'] >= 2**15:
						model['vertData']['tVert'][index]['X'] -= 2**16
					model['vertData']['tVert'][index]['Y'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['tVert'][index]['Y'] >= 2**15:
						model['vertData']['tVert'][index]['Y'] -= 2**16
					readStr(fIn, fOut, 4)
				elif model['vertTableSize'] == 24:
					raise Exception('24')
					# arxForm.acModel.vertData[index].vertex.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 2L;
					# arxForm.acModel.vertData[index].normals.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 6L;
					# arxForm.acModel.vertData[index].tVert.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].tVert.Y = (float) fi.read(2);
					# break;
				elif model['vertTableSize'] == 20:
					model['vertData']['vertex'].append({})
					model['vertData']['vertex'][index]['X'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['X'] >= 2**15:
						model['vertData']['vertex'][index]['X'] -= 2**16
					model['vertData']['vertex'][index]['Y'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['Y'] >= 2**15:
						model['vertData']['vertex'][index]['Y'] -= 2**16
					model['vertData']['vertex'][index]['Z'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['Z'] >= 2**15:
						model['vertData']['vertex'][index]['Z'] -= 2**16
					num6 = float(readInt(fIn, fOut, 2))
					if num6 >= 2**15:
						num6 -= 2**16
					model['vertData']['vertex'][index]['X'] /= num6
					model['vertData']['vertex'][index]['Y'] /= num6
					model['vertData']['vertex'][index]['Z'] /= num6
					model['vertData']['normals'].append({})
					model['vertData']['normals'][index]['X'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['normals'][index]['X'] >= 2**15:
						model['vertData']['normals'][index]['X'] -= 2**16
					model['vertData']['normals'][index]['Y'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['normals'][index]['Y'] >= 2**15:
						model['vertData']['normals'][index]['Y'] -= 2**16
					model['vertData']['normals'][index]['Z'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['normals'][index]['Z'] >= 2**15:
						model['vertData']['normals'][index]['Z'] -= 2**16
					readStr(fIn, fOut, 2)
					model['vertData']['tVert'].append({})
					model['vertData']['tVert'][index]['X'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['tVert'][index]['X'] >= 2**15:
						model['vertData']['tVert'][index]['X'] -= 2**16
					model['vertData']['tVert'][index]['Y'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['tVert'][index]['Y'] >= 2**15:
						model['vertData']['tVert'][index]['Y'] -= 2**16
				elif model['vertTableSize'] == 16:
					model['vertData']['vertex'].append({})
					model['vertData']['vertex'][index]['X'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['X'] >= 2**15:
						model['vertData']['vertex'][index]['X'] -= 2**16
					model['vertData']['vertex'][index]['Y'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['Y'] >= 2**15:
						model['vertData']['vertex'][index]['Y'] -= 2**16
					model['vertData']['vertex'][index]['Z'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['vertex'][index]['Z'] >= 2**15:
						model['vertData']['vertex'][index]['Z'] -= 2**16
					num5 = float(readInt(fIn, fOut, 2))
					if num5 >= 2**15:
						num5 -= 2**16
					model['vertData']['vertex'][index]['X'] /= num5
					model['vertData']['vertex'][index]['Y'] /= num5
					model['vertData']['vertex'][index]['Z'] /= num5
					readStr(fIn, fOut, 4)
					model['vertData']['tVert'].append({})
					model['vertData']['tVert'][index]['X'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['tVert'][index]['X'] >= 2**15:
						model['vertData']['tVert'][index]['X'] -= 2**16
					model['vertData']['tVert'][index]['Y'] = float(readInt(fIn, fOut, 2))
					if model['vertData']['tVert'][index]['Y'] >= 2**15:
						model['vertData']['tVert'][index]['Y'] -= 2**16
				else:
					raise Exception("Not yet implemented!\n\nvertTableSize = " + str(vertTableSize))
			
			# scale verticies based on bouding box
			model['modelBoundingBox'] = {}
			vertTemp = [a['X'] for a in model['vertData']['vertex']]
			model['modelBoundingBox']['minx'] = min(vertTemp)
			model['modelBoundingBox']['maxx'] = max(vertTemp)
			vertTemp = [a['Y'] for a in model['vertData']['vertex']]
			model['modelBoundingBox']['miny'] = min(vertTemp)
			model['modelBoundingBox']['maxy'] = max(vertTemp)
			vertTemp = [a['Z'] for a in model['vertData']['vertex']]
			model['modelBoundingBox']['minz'] = min(vertTemp)
			model['modelBoundingBox']['maxz'] = max(vertTemp)
			
			if model['boundingBox'] != {"maxz": 0.0,"maxx": 0.0,"maxy": 0.0,"minx": 0.0,"miny": 0.0,"minz": 0.0}:
				for coord in 'xyz':
					for index in model['vertData']['vertex']:
						modelMin = model['modelBoundingBox']['min'+coord]
						modelMax = model['modelBoundingBox']['max'+coord]
						worldMin = model['boundingBox']['min'+coord]
						worldMax = model['boundingBox']['max'+coord]
						index[coord.upper()] = ((index[coord.upper()] - modelMin) / (modelMax - modelMin)) * (worldMax-worldMin) + worldMin
			else:
				for index in model['vertData']['vertex']:
					for coord in 'xyz':
						index[coord.upper()] /= 200.0
			
			
			fOutWrite(fOut, 'Face table\n')
			model['length3'] = readInt(fIn, fOut, 4) / 6
			model['faceData'] = []
			for index in range(model['length3']):
				model['faceData'].append({})
				model['faceData'][index]['Y'] = readInt(fIn, fOut, 2)
				model['faceData'][index]['X'] = readInt(fIn, fOut, 2)
				model['faceData'][index]['Z'] = readInt(fIn, fOut, 2)
			model['facesUsed'] = model['length3'];
			# cAry = new int[5];
			for index in range(5):
				# arxForm.acModel.cAry[index] = fi.read(4);
				# binaryReader.BaseStream.Position += (long) arxForm.acModel.cAry[index];
				model['cAry'] = readInt(fIn, fOut, 4)
				fOutWrite(fOut, '\t')
				readStr(fIn, fOut, model['cAry'])
			# the last two iterations of the loop always seem to be 0 and I think go with the type below as an empty id
			readType(fIn, fOut)
			readStr(fIn, fOut, 3)
			fOutWrite(fOut, 'Mesh Count\n')
			model['meshCount'] = readInt(fIn, fOut, 4)
			model['meshData'] = []
			model['faceCount'] = 0
			fOutWrite(fOut, 'Mesh Table\n')
			for index in range(model['meshCount']):
				readStr(fIn, fOut, 12)
				model['meshData'].append({})
				model['meshData'][index]['X'] = float(readInt(fIn, fOut, 4))
				readStr(fIn, fOut, 4)
				model['meshData'][index]['materialTempID'] = float(readInt(fIn, fOut, 4))
				model['meshData'][index]['vertStart'] = readInt(fIn, fOut, 4) #verticy start
				model['meshData'][index]['vertCount'] = readInt(fIn, fOut, 4) #number of verticies
				readStr(fIn, fOut, 4)
				model['faceCount'] += model['meshData'][index]['vertCount']
			fOutWrite(fOut, 'Shadow Count\n')
			model['shadowCount'] = readInt(fIn, fOut, 4)
			model['shadowData'] = []
			fOutWrite(fOut, 'Shadow Table\n')
			for index in range(model['shadowCount']):
				readStr(fIn, fOut, 12)
				model['shadowData'].append({})
				model['shadowData'][index]['X'] = float(readInt(fIn, fOut, 4))
				readStr(fIn, fOut, 4)
				model['shadowData'][index]['Y'] = float(readInt(fIn, fOut, 4))
				model['shadowData'][index]['Z'] = float(readInt(fIn, fOut, 4))
				model['shadowData'][index]['W'] = float(readInt(fIn, fOut, 4))
				readStr(fIn, fOut, 4)
			for index in range(2):
				num4 = readInt(fIn, fOut, 4)
				fOutWrite(fOut, '\t')
				readStr(fIn, fOut, num4)
		elif model['typeSwitch'] == 3:
			raise Exception('typeSwitch 3 not implimented')
			# binaryReader.BaseStream.Position += 11L;
			# arxForm.acModel.vertTableSize = (int) binaryReader.ReadByte();
			# arxForm.acModel.meshCount = fi.read(4);
			# arxForm.acModel.meshData = new arxForm.acMeshStruct[arxForm.acModel.meshCount];
			# for (int index = 0; index < arxForm.acModel.meshCount; ++index)
			# {
				# binaryReader.BaseStream.Position += 12L;
				# arxForm.acModel.meshData[index].meshTable.X = (float) fi.read(4);
				# binaryReader.BaseStream.Position += 4L;
				# arxForm.acModel.meshData[index].meshTable.Y = (float) fi.read(4);
				# arxForm.acModel.meshData[index].meshTable.Z = (float) fi.read(4);
				# arxForm.acModel.meshData[index].meshTable.W = (float) fi.read(4);
				# binaryReader.BaseStream.Position += 4L;
			# }
			# arxForm.acModel.shadowCount = fi.read(4);
			# arxForm.acModel.shadowData = new arxForm.acMeshStruct[arxForm.acModel.shadowCount];
			# for (int index = 0; index < arxForm.acModel.shadowCount; ++index)
			# {
				# binaryReader.BaseStream.Position += 12L;
				# arxForm.acModel.shadowData[index].meshTable.X = (float) fi.read(4);
				# binaryReader.BaseStream.Position += 4L;
				# arxForm.acModel.shadowData[index].meshTable.Y = (float) fi.read(4);
				# arxForm.acModel.shadowData[index].meshTable.Z = (float) fi.read(4);
				# arxForm.acModel.shadowData[index].meshTable.W = (float) fi.read(4);
				# binaryReader.BaseStream.Position += 4L;
			# }
			# int num8 = fi.read(4);
			# arxForm.acModel.vertCount = num8 / arxForm.acModel.vertTableSize;
			# arxForm.acModel.vertData = new arxForm.acVertStruct[arxForm.acModel.vertCount];
			# for (int index = 0; index < arxForm.acModel.vertCount; ++index)
			# {
			# switch (arxForm.acModel.vertTableSize)
				# {
				# case 20:
					# arxForm.acModel.vertData[index].vertex.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Z = (float) fi.read(2);
					# short num4 = fi.read(2);
					# arxForm.acModel.vertData[index].vertex.X /= (float) num4;
					# arxForm.acModel.vertData[index].vertex.Y /= (float) num4;
					# arxForm.acModel.vertData[index].vertex.Z /= (float) num4;
					# arxForm.acModel.vertData[index].normals.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 2L;
					# arxForm.acModel.vertData[index].tVert.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].tVert.Y = (float) fi.read(2);
					# break;
				# case 32:
					# arxForm.acModel.vertData[index].vertex.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Z = (float) fi.read(2);
					# short num5 = fi.read(2);
					# arxForm.acModel.vertData[index].vertex.X /= (float) num5;
					# arxForm.acModel.vertData[index].vertex.Y /= (float) num5;
					# arxForm.acModel.vertData[index].vertex.Z /= (float) num5;
					# arxForm.acModel.vertData[index].normals.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 6L;
					# arxForm.acModel.vertData[index].tVert.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].tVert.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].boneNum.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.W = (float) binaryReader.ReadByte();
					# break;
				# case 40:
					# arxForm.acModel.vertData[index].vertex.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].vertex.Z = (float) fi.read(2);
					# short num6 = fi.read(2);
					# arxForm.acModel.vertData[index].vertex.X /= (float) num6;
					# arxForm.acModel.vertData[index].vertex.Y /= (float) num6;
					# arxForm.acModel.vertData[index].vertex.Z /= (float) num6;
					# arxForm.acModel.vertData[index].normals.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].normals.Z = (float) fi.read(2);
					# binaryReader.BaseStream.Position += 6L;
					# arxForm.acModel.vertData[index].tVert.X = (float) fi.read(2);
					# arxForm.acModel.vertData[index].tVert.Y = (float) fi.read(2);
					# arxForm.acModel.vertData[index].boneNum.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneNum2.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt.W = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.X = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.Y = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.Z = (float) binaryReader.ReadByte();
					# arxForm.acModel.vertData[index].boneWgt2.W = (float) binaryReader.ReadByte();
					# break;
				# default:
					# int num7 = (int) MessageBox.Show("Not yet implemented!\n\nvertTableSize = " + (object) arxForm.acModel.vertTableSize, "Vert Read", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					# return;
				# }
			# }
			# int num9 = fi.read(4);
			# string str3 = str1;
			# if (!(str3 == "HDMDL"))
			# {
				# if (str3 == "MDL")
				# arxForm.acModel.faceCount = num9 / 6;
			# }
			# else
				# arxForm.acModel.faceCount = num9 / 12;
			# arxForm.acModel.faceData = new arxForm.acFaceStruct[arxForm.acModel.faceCount];
			# for (int index = 0; index < arxForm.acModel.faceCount; ++index)
			# {
				# string str4 = str1;
				# if (!(str4 == "HDMDL"))
				# {
				# if (str4 == "MDL")
				# {
					# arxForm.acModel.faceData[index].faceIndex.Y = (float) binaryReader.ReadUInt16();
					# arxForm.acModel.faceData[index].faceIndex.X = (float) binaryReader.ReadUInt16();
					# arxForm.acModel.faceData[index].faceIndex.Z = (float) binaryReader.ReadUInt16();
				# }
				# }
				# else
				# {
				# arxForm.acModel.faceData[index].faceIndex.Y = (float) binaryReader.ReadUInt32();
				# arxForm.acModel.faceData[index].faceIndex.X = (float) binaryReader.ReadUInt32();
				# arxForm.acModel.faceData[index].faceIndex.Z = (float) binaryReader.ReadUInt32();
				# }
			# }
			# break;
		else:
			raise Exception("New switchType found")
		fOutWrite(fOut, 'Skin Data Table\n')
		model['length4'] = readInt(fIn, fOut, 4)
		model['skinData'] = []
		for index1 in range(model['length4']):
			readStr(fIn, fOut, 17)
			model['skinData'].append({})
			model['skinData'][index1]['boneCount'] = readInt(fIn, fOut, 2)
			readStr(fIn, fOut, 11)
			model['skinData'][index1]['boneNo'] = []
			for index2 in range(model['skinData'][index1]['boneCount']):
				model['skinData'][index1]['boneNo'].append(readInt(fIn, fOut, 2))
			readStr(fIn, fOut, (256 - model['skinData'][index1]['boneCount'] * 2))
		readStr(fIn, fOut, 8)
		fOutWrite(fOut, 'Model Scale\n')
		model['modelScale'] = readFloat32(fIn, fOut)
		fOutWrite(fOut, 'Material Table\n')
		model['materialCount'] = readInt(fIn, fOut, 4)
		model['materialId'] = []
		# model['materials'] = {}
		for index in range(model['materialCount']):
			# model['materials'][index] = {}
			readStr(fIn, fOut, 2)
			model['materialId'].append(readID(fileTree, fileList, fIn, fOut))
			
			
		ReadRest(fIn, fOut)
			
		fIn.close()
		if dev:
			fOut.close()
			print data["dir"]+'.format'
			os.system('"'+data['dir']+'.format"')
	else:
		raise Exception("Error reading model file!")
	tmpdict = open(data['dir'].replace('.acu', '.json'), 'w')
	tmpdict.write(json.dumps(model))
	tmpdict.close()
Пример #9
0
def getMaterialIDs(fileTree, fileList, fileID):
    if not tempFiles.exists(fileID):
        decompressDatafile(fileTree, fileList, fileID)
    data = tempFiles.read(fileID)
    if len(data) == 0:
        raise Exception('file ' + fileID + ' is empty')
    data = data[0]
    fileDir = data['dir']
    materialFile = open(fileDir, 'rb')
    _ = materialFile.read(26)
    materialTemplateID = BEHEX2(materialFile.read(8)).upper()
    materialFile.close()

    if not tempFiles.exists(materialTemplateID):
        decompressDatafile(fileTree, fileList, materialTemplateID)

    try:
        materialTemplate = open(
            tempFiles.read(materialTemplateID)[0]['dir'], 'rb')
    except:
        return
    textures = {}
    _ = materialTemplate.read(16)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        textures['diffuse'] = idtemp

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        textures['normal'] = idtemp

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        textures['specular'] = idtemp

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        textures['height'] = idtemp

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        raise Exception(data['dir'] + ' has an id in position 5')

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        textures['TransmissionMap'] = idtemp

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        raise Exception(data['dir'] + ' has an id in position 7')

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        textures['mask1map'] = idtemp

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        textures['mask2map'] = idtemp

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        raise Exception(data['dir'] + ' has an id in position 10')

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        raise Exception(data['dir'] + ' has an id in position 11')

    _ = materialTemplate.read(2)
    idtemp = BEHEX2(materialTemplate.read(8)).upper()
    if idtemp != '0000000000000000':
        raise Exception(data['dir'] + ' has an id in position 12')

    materialTemplate.close()

    return textures
Пример #10
0
def exportDataBlockModels(fileTree, fileList, fileID):
    if not tempFiles.exists(fileID):
        decompressDatafile(fileTree, fileList, fileID)
    data = tempFiles.read(fileID)
    if len(data) == 0:
        raise Exception('file ' + fileID + ' is empty')
    data = data[0]

    if data['resourceType'] != 'AC2BBF68':
        return

    if 'dev' in sys.argv:
        reload(formatFile)  # for development
    dataBlock = formatFile.topLevelFormat(fileTree, fileList, fileID)
    # fileID, data and dataBlock all relate to the DataBlock file (Type AC2BBF68)
    # This is a list of every file called by that DataBlock
    # formatFile.topLevelFormat will return this list of files into dataBlock

    fileIDList = {}

    for n, fileID2 in enumerate(dataBlock['dataBlock']):
        if not tempFiles.exists(fileID2):
            decompressDatafile(fileTree, fileList, fileID2)
        data2 = tempFiles.read(fileID2)
        if len(data2) == 0:
            raise Exception('file ' + fileID2 + ' is empty')
        data2 = data2[0]

        print 'Reading ' + data2['fileName'] + '. ' + str(
            n + 1) + ' of ' + str(len(dataBlock['dataBlock']))

        dataBlockChild = formatFile.topLevelFormat(fileTree, fileList, fileID2)
        # fileID2, data2 and dataBlockChild all relate to the files contained in
        # the DataBlock file. The file could be of a number of types including
        # entities and entity groups
        if dataBlockChild['fileType'] == '0984415E':  # entity
            if 'fileIDList' in dataBlockChild:
                for fileID3 in dataBlockChild['fileIDList']:
                    if not tempFiles.exists(fileID3):
                        decompressDatafile(fileTree, fileList, fileID3)
                    data3 = tempFiles.read(fileID3)
                    if len(data3) == 0:
                        raise Exception('file ' + fileID3 + ' is empty')
                    data3 = data3[0]
                    if data3['resourceType'] == '415D9568':
                        if fileID3 not in fileIDList:
                            fileIDList[fileID3] = []
                        fileIDList[fileID3] += dataBlockChild['fileIDList'][
                            fileID3]
                        # fileIDList.append({'fileID':fileID3, 'transformationMtx': dataBlockChild['transformationMtx']})
                    else:
                        raise Exception(fileID3 + ' is not a 3D model')

        elif dataBlockChild['fileType'] == '1CBDE084':
            if 'files' in dataBlockChild:
                for fileID3 in dataBlockChild['files']:
                    if not tempFiles.exists(fileID3):
                        decompressDatafile(fileTree, fileList, fileID3)
                    data3 = tempFiles.read(fileID3)
                    if len(data3) == 0:
                        continue
                        raise Exception('file ' + fileID3 + ' is empty')
                    data3 = data3[0]

                    if data3['resourceType'] in ['0984415E',
                                                 '3F742D26']:  # entity
                        dataBlockChild2 = formatFile.topLevelFormat(
                            fileTree, fileList, fileID3)
                        if 'fileIDList' in dataBlockChild2:
                            for fileID4 in dataBlockChild2['fileIDList']:
                                if not tempFiles.exists(fileID4):
                                    decompressDatafile(fileTree, fileList,
                                                       fileID4)
                                data4 = tempFiles.read(fileID4)
                                if len(data4) == 0:
                                    raise Exception('file ' + fileID4 +
                                                    ' is empty')
                                data4 = data4[0]
                                if data4['resourceType'] == '415D9568':

                                    # fileIDList.append({'fileID':fileID4, 'transformationMtx': dataBlockChild2['transformationMtx']})
                                    if fileID4 not in fileIDList:
                                        fileIDList[fileID4] = []
                                    fileIDList[fileID4] += dataBlockChild2[
                                        'fileIDList'][fileID4]
                                else:
                                    raise Exception(fileID4 +
                                                    ' is not a 3D model')
                    else:
                        raise Exception('found file type {}'.format(
                            data3['resourceType']))

        else:
            print 'Could not read following file. Unsupported type.'
            print data2['fileName']
            print dataBlockChild['fileType']
            print dataBlockChild['fileID']

    # fIn = open(data['dir'], 'rb')
    # fIn.seek(14)

    # count = LE2DEC2(fIn.read(4))
    # fileIDList = {}
    # ticker = 0
    # for n in range(count):
    # fIn.seek(2,1)
    # fileID2 = BEHEX2(fIn.read(8)).upper()
    # if not tempFiles.exists(fileID2):
    # decompressDatafile(fileTree, fileList, fileID2)
    # data2 = tempFiles.read(fileID2)
    # if len(data2) == 0:
    # raise Exception('file '+fileID2+' is empty')
    # data2 = data2[0]

    # print 'Reading '+data2['fileName']+'. '+str(n+1)+' of '+str(count)

    # if data2['resourceType'] == '0984415E':
    # fIn2 = open(data2['dir'], 'rb')
    # fIn2.seek(14)
    # fIn2.seek(49, 1)
    # xpos = float32(fIn2.read(4))
    # ypos = float32(fIn2.read(4))
    # zpos = float32(fIn2.read(4))
    # filePointer = fIn2.tell()
    # tempFile = fIn2.read()
    # meshLoc = tempFile.find('\x3B\x96\x6E\x53')
    # if meshLoc == -1:
    # continue
    # fIn2.seek(filePointer)
    # fIn2.seek(meshLoc+5, 1)
    # fileID3 = BEHEX2(fIn2.read(8)).upper()
    # if not tempFiles.exists(fileID3):
    # decompressDatafile(fileTree, fileList, fileID3)
    # data3 = tempFiles.read(fileID3)
    # if len(data3) == 0:
    # raise Exception('file '+fileID3+' is empty')
    # data3 = data3[0]
    # if data3['resourceType'] == '415D9568':
    # fileIDList[ticker] = {'id':fileID3, 'x':xpos, 'y':ypos, 'z':zpos}
    # ticker += 1
    # else:
    # raise Exception(fileID3+' is not a 3D model')

    print 'done reading'
    print 'exporting'

    exportOBJMulti(fileTree, fileList, fileID, fileIDList)
Пример #11
0
def exportTexture(fileTree, fileList, fileID):
    if not tempFiles.exists(fileID):
        decompressDatafile(fileTree, fileList, fileID)
    data = tempFiles.read(fileID)
    if len(data) == 0:
        raise Exception('file ' + fileID + ' is empty')
    data = data[0]
    path1 = data['dir']
    fileName = data['fileName']
    path2 = CONFIG['dumpFolder'] + os.sep + fileName + '.dds'
    if os.path.isfile(path2):
        return
    fi = open(path1, 'rb')
    _ = fi.read(14)
    num1 = fi.read(4)
    num2 = fi.read(4)
    _ = fi.read(4)
    imgDXT = LE2DEC2(fi.read(4))
    _ = fi.read(8)
    num3 = fi.read(4)
    _ = fi.read(84)
    count = fi.read(4)
    buffer = fi.read(LE2DEC2(count))

    fi.close()

    fi = open(path2, 'wb')
    fi.write('DDS ')
    fi.write('\x7C\x00\x00\x00\x07\x10\x0A\x00')
    fi.write(num2)
    fi.write(num1)
    fi.write(count)
    fi.write('\x00\x00\x00\x00')
    fi.write(num3)
    for index in range(11):
        fi.write('\x00\x00\x00\x00')
    fi.write('\x20\x00\x00\x00')
    if imgDXT == 0 or imgDXT == 7:
        fi.write('\x40\x00\x00\x00')
    else:
        fi.write('\x04\x00\x00\x00')
    if imgDXT in [0, 7]:
        fi.write('\x44\x58\x54\x30')  #DXT0
    elif imgDXT in [1, 2, 3]:
        fi.write('\x44\x58\x54\x31')  #DXT1
    elif imgDXT == 4:
        fi.write('\x44\x58\x54\x33')  #DXT3
    elif imgDXT == 5:
        fi.write('\x44\x58\x54\x35')  #DXT5
    elif imgDXT == 8:
        fi.write('\x44\x58\x31\x30')  #DX10

    for index in range(5):
        fi.write('\x00\x00\x00\x00')
    fi.write('\x08\x10\x40\x00')
    for index in range(4):
        fi.write('\x00\x00\x00\x00')
    if imgDXT == 8:
        fi.write('\x62\x00\x00\x00')
        fi.write('\x03\x00\x00\x00')
        fi.write('\x00\x00\x00\x00')
        fi.write('\x01\x00\x00\x00')
        fi.write('\x00\x00\x00\x00')
    fi.write(buffer)
    fi.close()
    if imgDXT == 8:
        texconv = '"' + CONFIG['texconv'] + '" '
        # else
        # {
        # str4 = arxForm.tempDir + "\\" + tNode.Parent.Parent.Parent.Text + "\\dx9_";
        # path2 = arxForm.tempDir + "\\" + tNode.Parent.Parent.Parent.Text + "\\dx9_" + tNode.Text + "." + strArray3[1];
        # }
        arguments = "-fl 9.1 -y -px " + CONFIG[
            'dumpFolder'] + os.sep + " -f BC3_UNORM " + path2
        os.system(texconv + arguments)
Пример #12
0
def exportOBJ(fileTree, fileList, fileID):
    if not tempFiles.exists(fileID):
        decompressDatafile(fileTree, fileList, fileID)
    data = tempFiles.read(fileID)
    if len(data) == 0:
        raise Exception('file ' + fileID + ' is empty')
    data = data[0]
    fileName = data['fileName']
    with open(data['dir'].replace('.acu', '.json')) as f:
        model = json.loads(f.read())
    savePath = CONFIG['dumpFolder'] + os.sep + fileName
    # savePath = path[:-4] + ".obj"
    str1 = os.sep.join(savePath.split(os.sep)[:-1])  #save path folder
    # while (treeNode1.Parent != null)
    # treeNode1 = treeNode1.Parent;
    # if model['typeSwitch'] != 3:
    # num2 = 100.0
    # else:
    # num2 = 0.00305
    # string str2 = treeNode1.Tag.ToString().ToLower();					'acu'
    fio = open(savePath + ".obj", 'w')  # open obj
    fio.write("#Wavefront Object File\n")  # write text
    fio.write("#Exported by gentlegiantJGC based on code from ARchive_neXt\n")
    if len(model['materialId']) > 0:
        fio.write("mtllib " + fileName + ".mtl\n")
    fio.write('\n')
    for vertex in model['vertData']['vertex']:
        fio.write("v " + str(round((vertex['X'] * model['modelScale']), 6)) +
                  " " + str(round((vertex['Y'] * model['modelScale']), 6)) +
                  " " + str(round((vertex['Z'] * model['modelScale']), 6)) +
                  '\n')
    fio.write("# " + str(len(model['vertData']['vertex'])) + " vertices\n")
    fio.write('\n')
    num3 = 2048.0
    for tVert in model['vertData']['tVert']:
        fio.write("vt " + str(round((tVert['X'] / num3), 6)) + " " +
                  str(round((tVert['Y'] / -num3), 6)) + '\n')
    fio.write("# " + str(len(model['vertData']['tVert'])) +
              " texture coordinates\n")
    fio.write('\n')
    num4 = 0
    for index1, meshData in enumerate(model['meshData']):
        num5 = meshData['vertCount']  #vertex number?
        num6 = meshData['vertStart'] / 3
        if model['typeSwitch'] == 0 and model['faceCount'] != model[
                'facesUsed']:
            if index1 > 0:
                num6 = num4 * 64
                num4 += model['meshFaceBlocks'][index1]
            else:
                num4 = model['meshFaceBlocks'][index1]
        fio.write("g " + fileName + "_" + str(index1) + '\n')

        textureIDs = getMaterialIDs(fileTree, fileList,
                                    model['materialId'][index1])
        if textureIDs == None:
            fio.write("usemtl missingNo\n")
        # print textureIDs
        else:
            for hexid in textureIDs:
                # textureFile = getFile(workingDir, textureIDs[hexid])
                exportTexture(fileTree, fileList, textureIDs[hexid])
            material = tempFiles.read(
                model['materialId'][index1].upper())[0]['fileName']
            fio.write("usemtl " + material + '\n')
        fio.write("s 0\n")
        if model['typeSwitch'] != 3:
            num7 = meshData['X']
        else:
            num7 = 0
        for index2 in range(num6, num5 + num6):
            fio.write(
                "f " + str(int(model['faceData'][index2]['Y'] + 1.0 + num7)) +
                "/" + str(int(model['faceData'][index2]['Y'] + 1.0 + num7)) +
                " " + str(int(model['faceData'][index2]['X'] + 1.0 + num7)) +
                "/" + str(int(model['faceData'][index2]['X'] + 1.0 + num7)) +
                " " + str(int(model['faceData'][index2]['Z'] + 1.0 + num7)) +
                "/" + str(int(model['faceData'][index2]['Z'] + 1.0 + num7)) +
                '\n')
        fio.write("# " + str(num5) + " triangles\n\n")
    fio.close()

    if len(model['materialId']) > 0:
        fim = open(savePath + ".mtl", 'w')
        fim.write("# Material Library\n")
        fim.write("# Exported by code based on ARchive_neXt\n")
        fim.write("\n")
        idsAdded = []
        for materialId in model['materialId']:
            if materialId in idsAdded:
                continue
            else:
                idsAdded.append(materialId)
            material = tempFiles.read(materialId.upper())[0]['fileName']
            if material != "NULL":
                textureIDs = getMaterialIDs(fileTree, fileList, materialId)
                if textureIDs == None:
                    fim.write("newmtl missingNo\n")
                else:
                    fim.write("newmtl " + material + '\n')
                fim.write("Ka 1.000 1.000 1.000\n")
                fim.write("Kd 1.000 1.000 1.000\n")
                fim.write("Ks 0.000 0.000 0.000\n")
                fim.write("Ns 0.000\n")
                if textureIDs == None:
                    fim.write("map_Kd " + CONFIG["missingNo"] + "\n")
                else:
                    for texType in textureIDs:
                        if texType == 'diffuse':
                            fim.write("map_Kd ")
                        elif texType == 'normal':
                            fim.write("bump -bm 0.300 ")
                        elif texType == 'specular':
                            fim.write("map_Ks ")
                        else:
                            continue
                        fim.write(
                            tempFiles.read(textureIDs[texType].upper())[0]
                            ['fileName'] + '.dds\n')
                        if texType == 'diffuse':
                            fim.write("map_d ")
                            fim.write(
                                tempFiles.read(textureIDs[texType].upper())[0]
                                ['fileName'] + '.dds\n')

                fim.write('\n')
    fim.close()

    print 'done'