internal static unsafe void Build(Collada form, ModelLinker linker, MDL0Header *header, int length, bool force) { byte *groupAddr = (byte *)header + linker._headerLen + linker._tableLen; byte *dataAddr = groupAddr + linker._groupLen + linker._texLen; //Definitions start here byte *assetAddr = dataAddr + linker._defLen + linker._boneLen + linker._dataLen; linker.Header = header; if (form != null) { form.Say("Writing header..."); } //Create new model header *header = new MDL0Header(length, linker.Version); MDL0Props *props = header->Properties; if (form != null) { form.Say("Writing node table..."); } //Write node table, assign node ids WriteNodeTable(linker); if (form != null) { form.Say("Writing definitions..."); } //Write def table WriteDefs(linker, ref groupAddr, ref dataAddr); //Set format list for each polygon's UVAT groups SetFormatLists(linker); //Write assets first, but only if the model is an import if (linker.Model._isImport) { WriteAssets(form, linker, ref assetAddr); } //Write groups linker.Write(form, ref groupAddr, ref dataAddr, force); //Write Part2 Entries if (linker.Model._part2Entries.Count > 0 && linker.Version != 9) { header->_part2Offset = (int)dataAddr - (int)header; Part2Data *part2 = header->Part2; if (part2 != null) { part2->_totalLen = 0x1C + linker.Model._part2Entries.Count * 0x2C; ResourceGroup *pGroup = part2->Group; *pGroup = new ResourceGroup(linker.Model._part2Entries.Count); ResourceEntry *pEntry = &pGroup->_first + 1; byte * pData = (byte *)pGroup + pGroup->_totalSize; foreach (string s in linker.Model._part2Entries) { (pEntry++)->_dataOffset = (int)pData - (int)pGroup; Part2DataEntry *p = (Part2DataEntry *)pData; *p = new Part2DataEntry(1); pData += 0x1C; } } } else { header->_part2Offset = 0; } //Write textures WriteTextures(linker, ref groupAddr); //Set box min and box max if (linker.Model._isImport) { SetBox(linker); } //Store group offsets linker.Finish(); //Set new properties *props = new MDL0Props(linker.Version, linker.Model._numVertices, linker.Model._numFaces, linker.Model._numNodes, linker.Model._unk1, linker.Model._unk2, linker.Model._unk3, linker.Model._unk4, linker.Model._unk5, linker.Model._unk6, linker.Model.BoxMin, linker.Model.BoxMax); }
public void RecalcOffsets(MDL0Bone *header, VoidPtr address, int length) { MDL0BoneNode bone; int index = 0, offset; //Sub-entries if (_entries.Count > 0) { header->_part2Offset = 0xD0; *(bint *)((byte *)address + 0xD0) = 0x1C + (_entries.Count * 0x2C); ResourceGroup *pGroup = (ResourceGroup *)((byte *)address + 0xD4); ResourceEntry *pEntry = &pGroup->_first + 1; byte * pData = (byte *)pGroup + pGroup->_totalSize; *pGroup = new ResourceGroup(_entries.Count); foreach (string s in _entries) { (pEntry++)->_dataOffset = (int)pData - (int)pGroup; Part2DataEntry *p = (Part2DataEntry *)pData; *p = new Part2DataEntry(1); pData += 0x1C; } } else { header->_part2Offset = 0; } //Set first child if (_children.Count > 0) { header->_firstChildOffset = length; } else { header->_firstChildOffset = 0; } if (_parent != null) { index = _parent._children.IndexOf(this); //Parent if (_parent is MDL0BoneNode) { header->_parentOffset = (int)_parent.WorkingUncompressed.Address - (int)address; } else { header->_parentOffset = 0; } //Prev if (index == 0) { header->_prevOffset = 0; } else { //Link to prev bone = _parent._children[index - 1] as MDL0BoneNode; offset = (int)bone.Header - (int)address; header->_prevOffset = offset; bone.Header->_nextOffset = -offset; } //Next if (index == (_parent._children.Count - 1)) { header->_nextOffset = 0; } } }