from pandac.PandaModules import * from direct.distributed.PyDatagramIterator import PyDatagramIterator from direct.distributed.PyDatagram import PyDatagram from direct.stdpy.file import * import DNAUtil import DNAError import DNAAnimBuilding import DNAAnimProp import DNACornice import DNADoor import DNAFlatBuilding import DNAFlatDoor import DNAGroup import DNAInteractiveProp import DNALandmarkBuilding import DNANode import DNAProp import DNASign import DNASignBaseline import DNASignGraphic import DNASignText import DNAStreet import DNAVisGroup import DNAWall import DNAWindows import DNABattleCell import DNASuitPoint import zlib import sys sys.setrecursionlimit(10000) compClassTable = { 1: DNAGroup.DNAGroup, 2: DNAVisGroup.DNAVisGroup, 3: DNANode.DNANode, 4: DNAProp.DNAProp, 5: DNASign.DNASign, 6: DNASignBaseline.DNASignBaseline, 7: DNASignText.DNASignText, 8: DNASignGraphic.DNASignGraphic, 9: DNAFlatBuilding.DNAFlatBuilding, 10: DNAWall.DNAWall, 11: DNAWindows.DNAWindows, 12: DNACornice.DNACornice, 13: DNALandmarkBuilding.DNALandmarkBuilding, 14: DNAAnimProp.DNAAnimProp, 15: DNAInteractiveProp.DNAInteractiveProp, 16: DNAAnimBuilding.DNAAnimBuilding, 17: DNADoor.DNADoor, 18: DNAFlatDoor.DNAFlatDoor, 19: DNAStreet.DNAStreet } childlessComps = ( 7, # DNASignText 11, # DNAWindows 12, # DNACornice 17, # DNADoor 18, # DNAFlatDoor 19 # DNAStreet ) class DNALoader: def __init__(self): self.dnaStorage = None self.prop = None def destroy(self): del self.dnaStorage del self.prop def handleStorageData(self, dgi): # Catalog Codes numRoots = dgi.getUint16() for _ in xrange(numRoots): root = DNAUtil.dgiExtractString8(dgi) numCodes = dgi.getUint8() for i in xrange(numCodes): code = DNAUtil.dgiExtractString8(dgi) self.dnaStorage.storeCatalogCode(root, code) # Textures numTextures = dgi.getUint16() for _ in xrange(numTextures): code = DNAUtil.dgiExtractString8(dgi) filename = DNAUtil.dgiExtractString8(dgi) self.dnaStorage.storeTexture(code, loader.pdnaTexture(filename, okMissing=True)) # Fonts numFonts = dgi.getUint16() for _ in xrange(numFonts): code = DNAUtil.dgiExtractString8(dgi) filename = DNAUtil.dgiExtractString8(dgi) self.dnaStorage.storeFont(code, loader.pdnaFont(filename)) # Nodes self.handleNode(dgi, target = self.dnaStorage.storeNode) self.handleNode(dgi, target = self.dnaStorage.storeHoodNode) self.handleNode(dgi, target = self.dnaStorage.storePlaceNode) # Blocks numBlocks = dgi.getUint16() for _ in xrange(numBlocks): number = dgi.getUint8() zone = dgi.getUint16() title = DNAUtil.dgiExtractString8(dgi) article = DNAUtil.dgiExtractString8(dgi) bldgType = DNAUtil.dgiExtractString8(dgi) self.dnaStorage.storeBlock(number, title, article, bldgType, zone) # Suit Points numPoints = dgi.getUint16() for _ in xrange(numPoints): index = dgi.getUint16() pointType = dgi.getUint8() x, y, z = (dgi.getInt32() / 100.0 for i in xrange(3)) graph = dgi.getUint8() landmarkBuildingIndex = dgi.getInt8() self.dnaStorage.storeSuitPoint(DNASuitPoint.DNASuitPoint(index, pointType, LVector3f(x, y, z), landmarkBuildingIndex)) # Suit Edges numEdges = dgi.getUint16() for _ in xrange(numEdges): index = dgi.getUint16() numPoints = dgi.getUint16() for i in xrange(numPoints): endPoint = dgi.getUint16() zoneId = dgi.getUint16() self.dnaStorage.storeSuitEdge(index, endPoint, zoneId) # Battle Cells numCells = dgi.getUint16() for _ in xrange(numCells): w = dgi.getUint8() h = dgi.getUint8() x, y, z = (dgi.getInt32() / 100.0 for i in xrange(3)) self.dnaStorage.storeBattleCell(DNABattleCell.DNABattleCell(w, h, LVector3f(x, y, z))) def handleCompData(self, dgi): while True: propCode = dgi.getUint8() if propCode == 255: if self.prop == None: raise DNAError.DNAError('Unexpected 255 found.') prop = self.prop.getParent() if prop is not None: self.prop = prop else: assert self.prop.getName() == 'root' elif propCode in compClassTable: propClass = compClassTable[propCode] if propClass.__init__.func_code.co_argcount > 1: newComp = propClass('unnamed_comp') else: newComp = propClass() if propCode == 2: newComp.makeFromDGI(dgi, self.dnaStorage) self.dnaStorage.storeDNAVisGroup(newComp) else: newComp.makeFromDGI(dgi) else: raise DNAError.DNAError('Invalid prop code: %d' % propCode) if dgi.getRemainingSize(): if propCode != 255: if self.prop is not None: newComp.setParent(self.prop) self.prop.add(newComp) if propCode not in childlessComps: self.prop = newComp continue break def handleNode(self, dgi, target = None): if target is None: return numNodes = dgi.getUint16() for _ in xrange(numNodes): code = DNAUtil.dgiExtractString8(dgi) file = DNAUtil.dgiExtractString8(dgi) node = DNAUtil.dgiExtractString8(dgi) np = NodePath(loader.pdnaModel(file)) if node: newNode = np.find('**/' + node).copyTo(NodePath()) np.removeNode() np = newNode np.setTag('DNACode', code) np.setTag('DNARoot', node) target(np, code) def loadDNAFileBase(self, dnaStorage, file): self.dnaStorage = dnaStorage dnaFile = open(file, 'rb') dnaData = dnaFile.read() dg = PyDatagram(dnaData) dgi = PyDatagramIterator(dg) dnaFile.close() header = dgi.extractBytes(5) if header != 'PDNA\n': raise DNAError.DNAError('Invalid header: %s' % (header)) compressed = dgi.getBool() dgi.skipBytes(1) if compressed: data = dgi.getRemainingBytes() data = zlib.decompress(data) dg = PyDatagram(data) dgi = PyDatagramIterator(dg) self.handleStorageData(dgi) self.handleCompData(dgi) def loadDNAFile(self, dnaStorage, file): self.loadDNAFileBase(dnaStorage, file) nodePath = NodePath(PandaNode('dna')) self.prop.traverse(nodePath, self.dnaStorage) return nodePath def loadDNAFileAI(self, dnaStorage, file): self.loadDNAFileBase(dnaStorage, file) return self.prop