public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            if (Model._isImport || _forceRebuild)
            {
                MDL0VertexData *header = (MDL0VertexData *)address;

                header->_dataLen     = length;
                header->_dataOffset  = 0x40;
                header->_index       = _entryIndex;
                header->_isXYZ       = _enc._hasZ ? 1 : 0;
                header->_type        = (int)_enc._type;
                header->_divisor     = (byte)_enc._scale;
                header->_entryStride = (byte)_enc._dstStride;
                header->_numVertices = (short)_enc._srcCount;
                header->_eMin        = _enc._min;
                header->_eMax        = _enc._max;
                header->_pad1        = header->_pad2 = 0;

                //Write data
                _enc.Write(Vertices, (byte *)address + 0x40);
                _enc.Dispose();
                _enc = null;

                _forceRebuild = false;
            }
            else
            {
                base.OnRebuild(address, length, force);
            }
        }
        protected internal override void PostProcess(VoidPtr mdlAddress, VoidPtr dataAddress, StringTable stringTable)
        {
            MDL0VertexData *header = (MDL0VertexData *)dataAddress;

            header->_mdl0Offset   = (int)mdlAddress - (int)dataAddress;
            header->_stringOffset = (int)stringTable[Name] + 4 - (int)dataAddress;
            header->_index        = Index;
        }
Exemple #3
0
        public static Vector3[] ExtractVertices(MDL0VertexData *vertices)
        {
            if (vertices != null)
            {
                return(ExtractVertices(vertices->Data, vertices->_numVertices, vertices->_isXYZ != 0, vertices->Type,
                                       1 << vertices->_divisor));
            }

            return(null);
        }
        protected override bool OnInitialize()
        {
            MDL0VertexData *header = Header;

            base.OnInitialize();

            SetSizeInternal(header->_dataLen);

            if ((_name == null) && (Header->_stringOffset != 0))
            {
                _name = Header->ResourceString;
            }

            return(false);
        }
Exemple #5
0
        public static UnsafeBuffer Decode(MDL0VertexData *header)
        {
            int            count   = header->_numVertices;
            float          scale   = VQuant.DeQuantTable[header->_divisor];
            int            type    = ((header->_isXYZ == 0) ? (int)ElementCodec.CodecType.XY : (int)ElementCodec.CodecType.XYZ) + (int)header->_type;
            ElementDecoder decoder = ElementCodec.Decoders[type];
            UnsafeBuffer   buffer  = new UnsafeBuffer(count * 12);

            byte *pIn = (byte *)header->Data, pOut = (byte *)buffer.Address;

            for (int i = 0; i < count; i++)
            {
                decoder(ref pIn, ref pOut, scale);
            }

            return(buffer);
        }
        protected internal override void OnRebuild(VoidPtr address, int length, bool force)
        {
            //Write header
            MDL0VertexData *header = (MDL0VertexData *)address;

            header->_dataLen     = length;
            header->_dataOffset  = 0x40;
            header->_index       = _entryIndex;
            header->_isXYZ       = _enc._hasZ ? 1 : 0;
            header->_type        = (int)_enc._type;
            header->_divisor     = (byte)_enc._scale;
            header->_entryStride = (byte)_enc._dstStride;
            header->_numVertices = (short)_enc._srcCount;
            header->_eMin        = _enc._min;
            header->_eMax        = _enc._max;
            header->_pad1        = header->_pad2 = 0;

            //Write data
            _enc.Write(Vertices, (byte *)address + 0x40);
            _enc.Dispose();
            _enc = null;
        }
Exemple #7
0
        //Write assets will only be used for model imports.
        private static void WriteAssets(Collada form, ModelLinker linker, ref byte *pData)
        {
            int      index;
            MDL0Node model = linker.Model;

            if (linker._vertices != null && linker._vertices.Count != 0)
            {
                model.LinkGroup(new MDL0GroupNode(MDLResourceType.Vertices));
                model._vertGroup._parent = model;

                index = 0;
                foreach (VertexCodec c in linker._vertices)
                {
                    MDL0VertexNode node = new MDL0VertexNode();

                    node._name = model.Name + "_" + model._objList[index]._name;
                    if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null)
                    {
                        node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name;
                    }

                    if (form != null)
                    {
                        form.Say("Writing Vertices - " + node.Name);
                    }

                    MDL0VertexData *header = (MDL0VertexData *)pData;
                    header->_dataLen     = c._dataLen.Align(0x20) + 0x40;
                    header->_dataOffset  = 0x40;
                    header->_index       = index++;
                    header->_isXYZ       = c._hasZ ? 1 : 0;
                    header->_type        = (int)c._type;
                    header->_divisor     = (byte)c._scale;
                    header->_entryStride = (byte)c._dstStride;
                    header->_numVertices = (ushort)c._dstCount;
                    header->_eMin        = c._min;
                    header->_eMax        = c._max;
                    header->_pad1        = header->_pad2 = 0;

                    c.Write(pData + 0x40);

                    node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen);
                    model._vertGroup.AddChild(node, false);

                    pData += header->_dataLen;
                }
            }

            if (linker._normals != null && linker._normals.Count != 0)
            {
                model.LinkGroup(new MDL0GroupNode(MDLResourceType.Normals));
                model._normGroup._parent = model;

                index = 0;
                foreach (VertexCodec c in linker._normals)
                {
                    MDL0NormalNode node = new MDL0NormalNode();

                    node._name = model.Name + "_" + model._objList[index]._name;
                    if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null)
                    {
                        node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name;
                    }

                    if (form != null)
                    {
                        form.Say("Writing Normals - " + node.Name);
                    }

                    MDL0NormalData *header = (MDL0NormalData *)pData;
                    header->_dataLen     = c._dataLen.Align(0x20) + 0x20;
                    header->_dataOffset  = 0x20;
                    header->_index       = index++;
                    header->_isNBT       = 0;
                    header->_type        = (int)c._type;
                    header->_divisor     = (byte)c._scale;
                    header->_entryStride = (byte)c._dstStride;
                    header->_numVertices = (ushort)c._dstCount;

                    c.Write(pData + 0x20);

                    node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen);
                    model._normGroup.AddChild(node, false);

                    pData += header->_dataLen;
                }
            }

            if (linker._colors != null && linker._colors.Count != 0)
            {
                model.LinkGroup(new MDL0GroupNode(MDLResourceType.Colors));
                model._colorGroup._parent = model;

                index = 0;
                foreach (ColorCodec c in linker._colors)
                {
                    MDL0ColorNode node = new MDL0ColorNode();

                    node._name = model.Name + "_" + model._objList[index]._name;
                    if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null)
                    {
                        node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name;
                    }

                    if (form != null)
                    {
                        form.Say("Writing Colors - " + node.Name);
                    }

                    MDL0ColorData *header = (MDL0ColorData *)pData;
                    header->_dataLen     = c._dataLen.Align(0x20) + 0x20;
                    header->_dataOffset  = 0x20;
                    header->_index       = index++;
                    header->_isRGBA      = c._hasAlpha ? 1 : 0;
                    header->_format      = (int)c._outType;
                    header->_entryStride = (byte)c._dstStride;
                    header->_pad         = 0;
                    header->_numEntries  = (ushort)c._dstCount;

                    c.Write(pData + 0x20);

                    node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen);
                    model._colorGroup.AddChild(node, false);

                    pData += header->_dataLen;
                }
            }

            if (linker._uvs != null && linker._uvs.Count != 0)
            {
                model.LinkGroup(new MDL0GroupNode(MDLResourceType.UVs));
                model._uvGroup._parent = model;

                index = 0;
                foreach (VertexCodec c in linker._uvs)
                {
                    MDL0UVNode node = new MDL0UVNode()
                    {
                        _name = "#" + index
                    };

                    if (form != null)
                    {
                        form.Say("Writing UVs - " + node.Name);
                    }

                    MDL0UVData *header = (MDL0UVData *)pData;
                    header->_dataLen     = c._dataLen.Align(0x20) + 0x40;
                    header->_dataOffset  = 0x40;
                    header->_index       = index++;
                    header->_format      = (int)c._type;
                    header->_divisor     = (byte)c._scale;
                    header->_isST        = 1;
                    header->_entryStride = (byte)c._dstStride;
                    header->_numEntries  = (ushort)c._dstCount;
                    header->_min         = (Vector2)c._min;
                    header->_max         = (Vector2)c._max;
                    header->_pad1        = header->_pad2 = header->_pad3 = header->_pad4 = 0;

                    c.Write(pData + 0x40);

                    node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen);
                    model._uvGroup.AddChild(node, false);

                    pData += header->_dataLen;
                }
            }

            //Clean groups
            if (model._vertList != null && model._vertList.Count > 0)
            {
                model._children.Add(model._vertGroup);
                linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._vertGroup.Name)] = model._vertGroup;
            }
            else
            {
                model.UnlinkGroup(model._vertGroup);
            }

            if (model._normList != null && model._normList.Count > 0)
            {
                model._children.Add(model._normGroup);
                linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._normGroup.Name)] = model._normGroup;
            }
            else
            {
                model.UnlinkGroup(model._normGroup);
            }

            if (model._uvList != null && model._uvList.Count > 0)
            {
                model._children.Add(model._uvGroup);
                linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._uvGroup.Name)] = model._uvGroup;
            }
            else
            {
                model.UnlinkGroup(model._uvGroup);
            }

            if (model._colorList != null && model._colorList.Count > 0)
            {
                model._children.Add(model._colorGroup);
                linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._colorGroup.Name)] = model._colorGroup;
            }
            else
            {
                model.UnlinkGroup(model._colorGroup);
            }

            //Link sets
            if (model._objList != null)
            {
                foreach (MDL0ObjectNode poly in model._objList)
                {
                    if (poly._elementIndices[0] != -1 && model._vertList != null && model._vertList.Count > poly._elementIndices[0])
                    {
                        poly._vertexNode = (MDL0VertexNode)model._vertGroup._children[poly._elementIndices[0]];
                    }
                    if (poly._elementIndices[1] != -1 && model._normList != null && model._normList.Count > poly._elementIndices[1])
                    {
                        poly._normalNode = (MDL0NormalNode)model._normGroup._children[poly._elementIndices[1]];
                    }
                    for (int i = 2; i < 4; i++)
                    {
                        if (poly._elementIndices[i] != -1 && model._colorList != null && model._colorList.Count > poly._elementIndices[i])
                        {
                            poly._colorSet[i - 2] = (MDL0ColorNode)model._colorGroup._children[poly._elementIndices[i]];
                        }
                    }
                    for (int i = 4; i < 12; i++)
                    {
                        if (poly._elementIndices[i] != -1 && model._uvList != null && model._uvList.Count > poly._elementIndices[i])
                        {
                            poly._uvSet[i - 4] = (MDL0UVNode)model._uvGroup._children[poly._elementIndices[i]];
                        }
                    }
                }
            }
        }
        private static void WriteAssets(ModelLinker linker, ref byte *pGroup, ref byte *pData)
        {
            ResourceGroup *group;
            ResourceEntry *entry;
            int            index;

            if (linker._vertices != null)
            {
                linker.Vertices = group = (ResourceGroup *)pGroup;
                *group = new ResourceGroup(linker._vertices.Count);
                entry = &group->_first + 1;

                index = 0;
                foreach (VertexCodec c in linker._vertices)
                {
                    (entry++)->_dataOffset = (int)(pData - pGroup);

                    MDL0VertexData *header = (MDL0VertexData *)pData;
                    header->_dataLen     = c._dataLen.Align(0x20) + 0x40;
                    header->_dataOffset  = 0x40;
                    header->_index       = index;
                    header->_isXYZ       = c._hasZ ? 1 : 0;
                    header->_type        = (int)c._type;
                    header->_divisor     = (byte)c._scale;
                    header->_entryStride = (byte)c._dstStride;
                    header->_numVertices = (short)c._dstCount;
                    header->_eMin        = c._min;
                    header->_eMax        = c._max;
                    header->_pad1        = header->_pad2 = 0;

                    c.Write(pData + 0x40);
                    pData += header->_dataLen;
                }

                pGroup += group->_totalSize;
            }

            if (linker._normals != null)
            {
                linker.Normals = group = (ResourceGroup *)pGroup;
                *group = new ResourceGroup(linker._normals.Count);
                entry = &group->_first + 1;

                index = 0;
                foreach (VertexCodec c in linker._normals)
                {
                    (entry++)->_dataOffset = (int)(pData - pGroup);

                    MDL0NormalData *header = (MDL0NormalData *)pData;
                    header->_dataLen     = c._dataLen.Align(0x20) + 0x20;
                    header->_dataOffset  = 0x20;
                    header->_index       = index;
                    header->_isNBT       = 0;
                    header->_type        = (int)c._type;
                    header->_divisor     = (byte)c._scale;
                    header->_entryStride = (byte)c._dstStride;
                    header->_numVertices = (ushort)c._dstCount;

                    c.Write(pData + 0x20);
                    pData += header->_dataLen;
                }

                pGroup += group->_totalSize;
            }

            if (linker._colors != null)
            {
                linker.Colors = group = (ResourceGroup *)pGroup;
                *group = new ResourceGroup(linker._colors.Count);
                entry = &group->_first + 1;

                index = 0;
                foreach (ColorCodec c in linker._colors)
                {
                    (entry++)->_dataOffset = (int)(pData - pGroup);

                    MDL0ColorData *header = (MDL0ColorData *)pData;
                    header->_dataLen     = c._dataLen.Align(0x20) + 0x20;
                    header->_dataOffset  = 0x20;
                    header->_index       = index;
                    header->_isRGBA      = c._hasAlpha ? 1 : 0;
                    header->_format      = (int)c._outType;
                    header->_entryStride = (byte)c._dstStride;
                    header->_scale       = 0;
                    header->_numEntries  = (ushort)c._dstCount;

                    c.Write(pData + 0x20);
                    pData += header->_dataLen;
                }
                pGroup += group->_totalSize;
            }

            if (linker._uvs != null)
            {
                linker.UVs = group = (ResourceGroup *)pGroup;
                *group = new ResourceGroup(linker._uvs.Count);
                entry = &group->_first + 1;

                index = 0;
                foreach (VertexCodec c in linker._uvs)
                {
                    (entry++)->_dataOffset = (int)(pData - pGroup);

                    MDL0UVData *header = (MDL0UVData *)pData;
                    header->_dataLen     = c._dataLen.Align(0x20) + 0x40;
                    header->_dataOffset  = 0x40;
                    header->_index       = index;
                    header->_format      = (int)c._type;
                    header->_divisor     = (byte)c._scale;
                    header->_isST        = 1;
                    header->_entryStride = (byte)c._dstStride;
                    header->_numEntries  = (ushort)c._dstCount;
                    header->_min         = (Vector2)c._min;
                    header->_max         = (Vector2)c._max;
                    header->_pad1        = header->_pad2 = header->_pad3 = header->_pad4 = 0;

                    c.Write(pData + 0x40);
                    pData += header->_dataLen;
                }

                pGroup += group->_totalSize;
            }
        }