//Initialize should only be called from parent group during parse. //Bones need not be imported/exported anyways protected override bool OnInitialize() { MDL0Bone *header = Header; SetSizeInternal(header->_headerLen); //Assign true parent using parent header offset int offset = header->_parentOffset; //Offsets are always < 0, because parent entries are listed before children if (offset < 0) { //Get address of parent header MDL0Bone *pHeader = (MDL0Bone *)((byte *)header + offset); //Search bone list for matching header foreach (MDL0BoneNode bone in _parent._children) { if (pHeader == bone.Header) { _parent = bone; break; } //Assign parent and break } } //Conditional name assignment if ((_name == null) && (header->_stringOffset != 0)) { _name = header->ResourceString; } //Assign fields _flags = (BoneFlags)(uint)header->_flags; _nodeIndex = header->_nodeId; _boneIndex = header->_index; _permanentID = header->_index; _bindState = _frameState = new FrameState(header->_scale, header->_rotation, header->_translation); (_bindState._quaternion = new Quaternion()).FromEuler(header->_rotation); _bindMatrix = _frameMatrix = header->_transform; _inverseBindMatrix = _inverseFrameMatrix = header->_transformInv; _bMin = header->_boxMin; _bMax = header->_boxMax; if (header->_part2Offset != 0) { Part2Data * part2 = (Part2Data *)((byte *)header + header->_part2Offset); ResourceGroup *group = part2->Group; ResourceEntry *pEntry = &group->_first + 1; int count = group->_numEntries; for (int i = 0; i < count; i++) { _entries.Add(new String((sbyte *)group + (pEntry++)->_stringOffset)); } } //We don't want to process children because not all have been parsed yet. //Child assigning will be handled by the parent group. return(false); }
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); }