private static void WriteUVGroup(StreamWriter writer, MDL0UVNode uv)
 {
     writer.WriteLine();
     writer.WriteLine("#UVs");
     foreach (Vector2 v in uv.Points)
         writer.WriteLine("vt {0} {1}", v._x, v._y);
 }
        //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])._opaMaterial != null)
                        node._name += "_" + ((MDL0ObjectNode)model._objList[index])._opaMaterial._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 = (short)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])._opaMaterial != null)
                        node._name += "_" + ((MDL0ObjectNode)model._objList[index])._opaMaterial._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])._opaMaterial != null)
                        node._name += "_" + ((MDL0ObjectNode)model._objList[index])._opaMaterial._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]];
            }
        }
        public MDL0UVNode NewUV()
        {
            if (_modelViewerOpen)
                return null;

            MDL0Node model = ((MDL0Node)_resource);

            MDL0GroupNode g = model._uvGroup;
            if (g == null)
            {
                model.AddChild(g = new MDL0GroupNode(MDLResourceType.UVs), true);
                model._uvGroup = g; model._uvList = g.Children;
            }

            MDL0UVNode node = new MDL0UVNode() { Name = "#" + ((MDL0Node)_resource)._uvList.Count };
            node.Points = new Vector2[] { new Vector2(0) };
            g.AddChild(node, true);
            node._forceRebuild = true;
            node.Rebuild(true);
            node.SignalPropertyChange();

            FindResource(node, true).EnsureVisible();

            return node;
        }