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);
        }
Beispiel #2
0
        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;
                }
            }
        }