public void NameColor()
        {
            MDL0Node      model = ((MDL0Node)_resource);
            MDL0GroupNode g     = model._colorGroup;

            if (g != null)
            {
                foreach (MDL0ColorNode v in g.Children)
                {
                    string name = model.Name + "_";
                    if (v._objects.Count > 0)
                    {
                        MDL0ObjectNode o = v._objects[0];
                        name += o.Name;
                        if (o._drawCalls.Count > 0)
                        {
                            DrawCall c = o._drawCalls[0];
                            if (c.MaterialNode != null && c.VisibilityBoneNode != null)
                            {
                                name += "_" + c.Material + "_" + c.VisibilityBone;
                            }
                        }
                    }
                    else
                    {
                        name += "ColorArray";
                    }

                    v.Name = g.FindName(name);
                }
            }
        }
示例#2
0
        //Moves an edited world position back into the stored position
        public void Unweight(bool updateVertexSets = true)
        {
            //Unweight overall position
            _position = GetInvMatrix() * WeightedPosition;

            //Distribute weights for the position across all vertex set influences
            if (updateVertexSets)
            {
                if (_weights != null && _nodes != null)
                {
                    Vector3 trans = _weightedPosition - _bCenter;
                    for (int i = 0; i < _nodes.Length; i++)
                    {
                        MDL0VertexNode set = _nodes[i];
                        SetPosition(set, GetInvMatrix() * (GetMatrix() * set.Vertices[_facepoints[0]._vertexIndex] + trans));
                    }
                    MDL0ObjectNode obj = (MDL0ObjectNode)_parent;
                    SetPosition(obj._vertexNode, GetInvMatrix() * ((GetMatrix() * obj._vertexNode.Vertices[_facepoints[0]._vertexIndex]) + trans));
                }
                else
                {
                    SetPosition();
                }
            }
        }
 public void Duplicate()
 {
     MDL0ObjectNode node = ((MDL0ObjectNode)_resource).HardCopy();
     node.Name += " - Copy";
     ((MDL0ObjectNode)_resource).Model._objGroup.AddChild(node);
     //((MDL0ObjectNode)_resource).Model.Rebuild(true);
 }
示例#4
0
 public ObjectOptimization(MDL0ObjectNode o)
 {
     _object     = o;
     _facepoints = _object._manager.MergeExternalFaceData(_object);
     _pointCount = _object._numFacepoints;
     _faceCount  = _object._numFaces;
 }
示例#5
0
        private void SelectVerts(MDL0ObjectNode o)
        {
            foreach (Vertex3 v in o._manager._vertices)
            {
                //Project each vertex into screen coordinates.
                //Then check to see if the 2D coordinates lie within the selection box.
                //In Soviet Russia, vertices come to YOUUUUU

                Vector3 vec3 = v.WeightedPosition;
                Vector2 vec2 = (Vector2)modelPanel.Project(vec3);
                Point start = modelPanel._selStart, end = modelPanel._selEnd;
                Vector2 min = new Vector2(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y));
                Vector2 max = new Vector2(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y));
                if ((vec2 <= max) && (vec2 >= min))
                    if (Alt)
                    {
                        v._selected = false;
                        if (_selectedVertices.Contains(v))
                            _selectedVertices.Remove(v);
                        v._highlightColor = Color.Transparent;
                    }
                    else if (!v._selected)
                    {
                        v._selected = true;

                        if (!Ctrl || !_selectedVertices.Contains(v))
                            _selectedVertices.Add(v);
                        v._highlightColor = Color.Orange;
                    }
            }
        }
示例#6
0
        private void GetBaseInfluence()
        {
            ResourceNode[] boneCache = _externalModel._linker.BoneCache;
            if ((_node = (MDL0ObjectNode)comboBox1.SelectedItem).Weighted)
            {
                int least = int.MaxValue;
                foreach (IMatrixNode inf in _node.Influences)
                {
                    if (inf is MDL0BoneNode && ((MDL0BoneNode)inf).BoneIndex < least)
                    {
                        least = ((MDL0BoneNode)inf).BoneIndex;
                    }
                }

                if (least != int.MaxValue)
                {
                    MDL0BoneNode temp = (MDL0BoneNode)boneCache[least];
                    _baseInf = (IMatrixNode)temp.Parent;
                }
            }
            else
            {
                _baseInf = _node.MatrixNode;
            }

            if (_baseInf is Influence)
            {
                label2.Hide();
                comboBox2.Hide();
            }
            else if (_baseInf is MDL0BoneNode)
            {
                label2.Show();
                comboBox2.Show();
            }

            baseBone.Text = _baseInf.ToString();

            if (comboBox3.SelectedIndex == 0 && _baseInf is MDL0BoneNode)
            {
                int i = 0;
                foreach (MDL0BoneNode s in comboBox2.Items)
                {
                    if (s.Name == baseBone.Text)
                    {
                        comboBox2.SelectedIndex = i;
                        break;
                    }
                    i++;
                }
            }

            modelPanel1.AddTarget(_node);
            Vector3 min, max;

            _node.GetBox(out min, out max);
            modelPanel1.SetCamWithBox(min, max);
        }
示例#7
0
        private void MergeChildren(MDL0BoneNode parent, MDL0BoneNode child, ResourceNode res)
        {
            bool         found = false;
            MDL0BoneNode bone  = null;

            foreach (MDL0BoneNode b1 in parent.Children)
            {
                if (b1.Name == child.Name)
                {
                    found = true;
                    bone  = b1;
                    foreach (MDL0BoneNode b in child.Children)
                    {
                        MergeChildren(b1, b, res);
                    }

                    break;
                }
            }

            if (!found)
            {
                MDL0BoneNode b = child.Clone();
                parent.InsertChild(b, true, child.Index);
                bone = b;
            }
            else
            {
                found = false;
            }

            if (res is MDL0ObjectNode)
            {
                MDL0ObjectNode poly = res as MDL0ObjectNode;
                foreach (Vertex3 v in poly._manager._vertices)
                {
                    if (v.MatrixNode == child)
                    {
                        v.MatrixNode = bone;
                    }
                }
            }
            else if (res is MDL0Node)
            {
                MDL0Node mdl = res as MDL0Node;
                foreach (MDL0ObjectNode poly in mdl.FindChild("Objects", true).Children)
                {
                    foreach (Vertex3 v in poly._manager._vertices)
                    {
                        if (v.MatrixNode == child)
                        {
                            v.MatrixNode = bone;
                        }
                    }
                }
            }
        }
示例#8
0
        private static void WritePolygon(StreamWriter writer, DrawCall c)
        {
            MDL0ObjectNode poly = c._parentObject;

            if (poly._manager._vertices != null)
            {
                int       count    = poly._manager._vertices.Count;
                Vector3[] Vertices = new Vector3[count];

                //Weight vertices
                poly.Model.WeightMeshes();

                //Set weighted positions
                for (int i = 0; i < count; i++)
                {
                    Vertices[i] = poly._manager._vertices[i].WeightedPosition;
                }

                WriteVertexGroup(writer, Vertices);
            }

            if (poly._manager._faceData[1] != null)
            {
                WriteNormalGroup(writer, poly._manager, true);
            }

            for (int i = 0; i < 1; i++) //Obj only supports 1 uv coord set...
            {
                if (poly._manager._faceData[i + 4] != null)
                {
                    WriteUVGroup(writer, poly._manager._faceData[i + 4]);
                }
            }

            writer.WriteLine();
            writer.WriteLine(string.Format("g {0}", poly.Name));
            if (c._material != null)
            {
                WriteMaterial(writer, c._material);
            }

            if (poly._manager != null)
            {
                if (poly._manager._triangles != null)
                {
                    WriteTriList(writer, poly._manager);
                }
                //if (poly._manager._lines != null)
                //{

                //}
                //if (poly._manager._points != null)
                //{

                //}
            }
        }
示例#9
0
        private void SetNormals()
        {
            MDL0ObjectNode obj = _parent as MDL0ObjectNode;

            if (obj != null)
            {
                obj.SetEditedNormals();
            }
        }
示例#10
0
        private bool CompareVertexDistance(Vector3 point, ref Vertex3 match)
        {
            if (TargetModel._polyIndex != -1)
            {
                MDL0ObjectNode o = TargetModel._objList[TargetModel._polyIndex] as MDL0ObjectNode;
                if (o._render)
                {
                    foreach (Vertex3 v in o._manager._vertices)
                    {
                        float t = v.WeightedPosition.TrueDistance(point);
                        if (Math.Abs(t) < 0.025f)
                        {
                            match = v;
                            return(true);
                        }
                    }
                }
                else
                {
                    foreach (MDL0ObjectNode w in TargetModel._objList)
                    {
                        if (w._render)
                        {
                            foreach (Vertex3 v in w._manager._vertices)
                            {
                                float t = v.WeightedPosition.TrueDistance(point);
                                if (Math.Abs(t) < 0.025f)
                                {
                                    match = v;
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (MDL0ObjectNode o in TargetModel._objList)
                {
                    if (o._render)
                    {
                        foreach (Vertex3 v in o._manager._vertices)
                        {
                            float t = v.WeightedPosition.TrueDistance(point);
                            if (Math.Abs(t) < 0.025f)
                            {
                                match = v;
                                return(true);
                            }
                        }
                    }
                }
            }

            return(false);
        }
示例#11
0
 private static void SetFormatLists(ModelLinker linker)
 {
     if (linker.Model._objList != null)
     {
         for (int i = 0; i < linker.Model._objList.Count; i++)
         {
             MDL0ObjectNode poly = (MDL0ObjectNode)linker.Model._objList[i];
             poly._manager.SetFormatList(poly, linker);
         }
     }
 }
示例#12
0
        private unsafe void button5_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(this, "Are you sure you want to continue?\nThis will edit the model and make the selected object's vertices default to the current morph.", "Are you sure?", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
            {
                return;
            }

            MDL0ObjectNode poly = VertexSet._objects[0];

            poly.SetVerticesFromWeighted();
        }
        public bool SetTarget(MDL0ObjectNode o)
        {
            //lstDrawCalls.Items.Clear();
            lstDrawCalls.DataSource = null;
            modelPanel.ClearAll();
            cboMaterial.Items.Clear();
            cboVisBone.Items.Clear();
            try
            {
                if ((_targetObject = o) != null)
                {
                    _targetObject.IsRendering = true;

                    cboMaterial.Items.AddRange(o.Model.MaterialList.ToArray());
                    cboVisBone.Items.AddRange(o.Model._linker.BoneCache.ToArray());
                    lstDrawCalls.DataSource = o._drawCalls;
                    //lstDrawCalls.DisplayMember = "";
                    //lstDrawCalls.ValueMember = "_isXLU";

                    modelPanel.AddTarget(o);
                    //if (o._drawCalls.Count > 0)
                    //    lstDrawCalls.SelectedIndex = 0;
                    modelPanel.SetCamWithBox(o.GetBox());
                    return(true);
                }
            }
            catch
            {
                // ignored
            }

            if (_targetObject != null)
            {
                try
                {
                    _targetObject.IsRendering = false;
                }
                catch
                {
                    // ignored
                }
            }

            _targetObject           = null;
            lstDrawCalls.DataSource = null;
            modelPanel.ClearAll();
            cboMaterial.Items.Clear();
            cboVisBone.Items.Clear();

            return(false);
        }
示例#14
0
        public void SelectedPolygonChanged()
        {
            //We can't return here if the selected polygon is set to null.
            //If the target model is changed or the selected object is cleared,
            //things relying on the selected object must be updated to reflect that.
            //if (leftPanel.SelectedPolygon == null) return;

            //This sets the selected object index internally in the model.
            //This determines the target object for focus editing vertices, normals, etc in the viewer
            //If the selected object is set to null, the poly index will be set to -1 by IndexOf.
            //This means vertices, normals etc will be drawn for all objects, if enabled.
            _targetModel.SelectedObjectIndex = _targetModel.Objects.IndexOf(leftPanel.SelectedObject);

            //If this setting is enabled, we need to show the user what textures only this object uses.
            //If the polygon is set to null, all of the model's texture references will be shown.
            if (SyncTexturesToObjectList)
            {
                leftPanel.UpdateTextures();
            }

            //Update the VIS editor to show the entries for the selected object
            if (TargetAnimType == NW4RAnimType.VIS &&
                leftPanel.SelectedObject != null &&
                vis0Editor.listBox1.Items.Count != 0 &&
                leftPanel.SelectedObject is MDL0ObjectNode)
            {
                MDL0ObjectNode o = (MDL0ObjectNode)leftPanel.SelectedObject;

                int x = 0;
                foreach (object i in vis0Editor.listBox1.Items)
                {
                    if (o._drawCalls.Count > 0 && i.ToString() == o._drawCalls[0].VisibilityBone)
                    {
                        vis0Editor.listBox1.SelectedIndex = x;
                        break;
                    }
                    else
                    {
                        x++;
                    }
                }

                if (x == vis0Editor.listBox1.Items.Count)
                {
                    vis0Editor.listBox1.SelectedIndex = -1;
                }
            }

            ModelPanel.Invalidate();
        }
示例#15
0
        private unsafe void UpdateNormals(Matrix m, Matrix inv)
        {
            MDL0ObjectNode obj = _parent as MDL0ObjectNode;

            if (obj != null && obj._manager._faceData[1] != null)
            {
                Vector3 *pData = (Vector3 *)obj._manager._faceData[1].Address;
                for (int i = 0; i < _faceDataIndices.Count; i++)
                {
                    Vector3 n = pData[_faceDataIndices[i]];
                    n *= m.GetRotationMatrix();
                    n *= inv.GetRotationMatrix();
                    pData[_faceDataIndices[i]] = n;
                }
            }
        }
示例#16
0
        public void LoadModel(MDL0Node model)
        {
            model.Populate();
            model._renderAttribs._renderBones     = false;
            model._renderAttribs._renderPolygons  = true;
            model._renderAttribs._renderWireframe = false;
            model._renderAttribs._renderVertices  = false;
            model.ApplyCHR(null, 0);
            model.ApplySRT(null, 0);

            if (UseExceptions)
            {
                foreach (string texname in TexturesToDisable)
                {
                    MDL0TextureNode tex = model.TextureGroup.FindChild(texname, false) as MDL0TextureNode;
                    if (tex != null)
                    {
                        tex.Enabled = false;
                    }
                }
            }

            modelPanel1.ClearAll();
            modelPanel1.AddTarget((IRenderedObject)model);

            if (UseExceptions && PolygonsToDisable.ContainsKey(_charString))
            {
                foreach (int polygonNum in PolygonsToDisable[_charString])
                {
                    MDL0ObjectNode poly = model.PolygonGroup.FindChild("polygon" + polygonNum, false) as MDL0ObjectNode;
                    if (poly != null)
                    {
                        poly.IsRendering = false;
                    }
                }
            }

            Box     box = model.GetBox();
            Vector3 min = box.Min, max = box.Max;

            if (ZoomOut)
            {
                min._x += 20;
                max._x -= 20;
            }
            modelPanel1.SetCamWithBox(min, max);
        }
        public override ResourceNode Duplicate()
        {
            MDL0ObjectNode node = ((MDL0ObjectNode)_resource).HardCopy();
            // Set the name programatically (based on Windows' implementation)
            int index = _resource.Index;
            int n     = 0;

            while (_resource.Parent.FindChildrenByName(node.Name).Length >= 1)
            {
                // Get the last index of the last duplicated node in order to place it after that one
                index = Math.Max(index, _resource.Parent.FindChildrenByName(node.Name).Last().Index);
                // Set the name based on the number of duplicate nodes found
                node.Name = $"{_resource.Name} ({++n})";
            }
            ((MDL0ObjectNode)_resource).Model._objGroup.InsertChild(node, true, index + 1);
            return(node);
        }
        public void LoadModel(MDL0Node model)
        {
            model.Populate();
            model.ResetToBindState();

            if (UseExceptions)
            {
                foreach (string texname in TexturesToDisable)
                {
                    ResourceNode textureGroup = model.TextureGroup;
                    if (textureGroup != null)
                    {
                        MDL0TextureNode tex = textureGroup.FindChild(texname, false) as MDL0TextureNode;
                        if (tex != null)
                        {
                            tex.Enabled = false;
                        }
                    }
                }
            }

            modelPanel1.ClearAll();
            modelPanel1.AddTarget((IRenderedObject)model);

            if (UseExceptions && PolygonsToDisable.ContainsKey(_charString))
            {
                foreach (string polygonNum in PolygonsToDisable[_charString])
                {
                    MDL0ObjectNode poly = model.PolygonGroup.FindChild(polygonNum, false) as MDL0ObjectNode;
                    if (poly != null)
                    {
                        poly.IsRendering = false;
                    }
                }
            }

            Box     box = model.GetBox();
            Vector3 min = box.Min, max = box.Max;

            if (ZoomOut)
            {
                min._x += 20;
                max._x -= 20;
            }
            modelPanel1.SetCamWithBox(min, max);
        }
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (lstDrawCalls.SelectedIndices != null)
            {
                for (int x = lstDrawCalls.SelectedIndices.Count - 1; x >= 0; x--)
                {
                    DrawCall drawCall = lstDrawCalls.Items[lstDrawCalls.SelectedIndices[x]] as DrawCall;
                    if (drawCall != null)
                    {
                        MDL0ObjectNode o = drawCall._parentObject;

                        o._drawCalls.Remove(drawCall);
                        o.OnDrawCallsChanged();
                        o.Model.RegenerateVIS0Indices();
                        o.SignalPropertyChange();
                    }
                }
            }
        }
示例#20
0
        public void SetPosition(MDL0VertexNode node, Vector3 pos)
        {
            //if (node == null)
            //    return;

            //node.Vertices[_facepoints[0]._vertexIndex] = pos;
            //node.ForceRebuild = true;
            //if (node.Format == WiiVertexComponentType.Float)
            //    node.ForceFloat = true;

            //Have to use this function instead of setting the vertices directly
            //This is because the vertex set may be used by other objects
            MDL0ObjectNode obj = _parent as MDL0ObjectNode;

            if (obj != null)
            {
                obj.SetEditedVertices();
            }
        }
示例#21
0
        public static void SetUniforms(MDL0ObjectNode obj)
        {
            //MDL0MaterialNode mat = obj.UsableMaterialNode;

            //int pHandle = obj._programHandle;
            //int u = -1;

            //u = GL.GetUniformLocation(pHandle, "C1Amb");
            //if (u > -1)
            //    GL.Uniform4(u,
            //    mat.C1AmbientColor.R * RGBAPixel.ColorFactor,
            //    mat.C1AmbientColor.G * RGBAPixel.ColorFactor,
            //    mat.C1AmbientColor.B * RGBAPixel.ColorFactor,
            //    mat.C1AmbientColor.A * RGBAPixel.ColorFactor);

            //u = GL.GetUniformLocation(pHandle, "C2Amb");
            //if (u > -1)
            //    GL.Uniform4(u,
            //    mat.C2AmbientColor.R * RGBAPixel.ColorFactor,
            //    mat.C2AmbientColor.G * RGBAPixel.ColorFactor,
            //    mat.C2AmbientColor.B * RGBAPixel.ColorFactor,
            //    mat.C2AmbientColor.A * RGBAPixel.ColorFactor);

            //u = GL.GetUniformLocation(pHandle, "C1Mat");
            //if (u > -1)
            //    GL.Uniform4(u,
            //    mat.C1MaterialColor.R * RGBAPixel.ColorFactor,
            //    mat.C1MaterialColor.G * RGBAPixel.ColorFactor,
            //    mat.C1MaterialColor.B * RGBAPixel.ColorFactor,
            //    mat.C1MaterialColor.A * RGBAPixel.ColorFactor);

            //u = GL.GetUniformLocation(pHandle, "C2Mat");
            //if (u > -1)
            //    GL.Uniform4(u,
            //    mat.C2MaterialColor.R * RGBAPixel.ColorFactor,
            //    mat.C2MaterialColor.G * RGBAPixel.ColorFactor,
            //    mat.C2MaterialColor.B * RGBAPixel.ColorFactor,
            //    mat.C2MaterialColor.A * RGBAPixel.ColorFactor);
        }
示例#22
0
        private static void WritePolygon(StreamWriter writer, MDL0ObjectNode poly)
        {
            if (poly._manager._vertices != null)
            {
                int          count    = poly._manager._vertices.Count;
                Vector3[]    Vertices = new Vector3[count];
                DialogResult result   = MessageBox.Show("Do you want to export the weighted positions of the vertices?", "", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
                if (result == DialogResult.Yes)
                {
                    //Weight vertices
                    foreach (Influence inf in (poly.Model)._influences._influences)
                    {
                        inf.CalcMatrix();
                    }
                    poly._manager.Weight();

                    //Set weighted positions
                    for (int i = 0; i < count; i++)
                    {
                        if (poly._manager._vertices[i].WeightedPosition.ToString() != "(0,0,0)")
                        {
                            Vertices[i] = poly._manager._vertices[i].WeightedPosition;
                        }
                        else
                        {
                            Vertices[i] = poly._manager._vertices[i].Position;
                        }
                    }
                }
                else if (result == DialogResult.No)
                {
                    //Set raw positions
                    for (int i = 0; i < count; i++)
                    {
                        Vertices[i] = poly._manager._vertices[i].Position;
                    }
                }
                if (result != DialogResult.Cancel) //Export
                {
                    WriteVertexGroup(writer, Vertices);
                }
            }
            if (poly._manager._faceData[1] != null)
            {
                WriteNormalGroup(writer, poly._manager, true);
            }

            for (int i = 0; i < 1; i++) //Obj only supports 1 uv coord set...
            {
                if (poly._manager._faceData[i + 4] != null)
                {
                    WriteUVGroup(writer, poly._manager._faceData[i + 4]);
                }
            }

            writer.WriteLine();
            writer.WriteLine(String.Format("g {0}", poly.Name));
            //if (poly._material != null)
            //    WriteMaterial(writer, poly._material);
            //if (poly.Primitives != null)
            //    foreach (Primitive p in poly.Primitives)
            //    {
            //        switch (p._type)
            //        {
            //            case GLPrimitiveType.TriangleFan:
            //                WriteTriFan(writer, p);
            //                break;
            //            case GLPrimitiveType.TriangleStrip:
            //                WriteTriStrip(writer, p);
            //                break;
            //            case GLPrimitiveType.Triangles:
            //                WriteTriList(writer, p);
            //                break;
            //            case GLPrimitiveType.Quads:
            //                WriteQuadList(writer, p);
            //                break;
            //        }
            //    }
            if (poly._manager != null)
            {
                if (poly._manager._triangles != null)
                {
                    WriteTriList(writer, poly._manager);
                }
                //if (poly._manager._lines != null)
                //{

                //}
                //if (poly._manager._points != null)
                //{

                //}
            }
        }
示例#23
0
        private void ImportObject(MDL0ObjectNode node)
        {
            MDL0ObjectNode newNode = node.SoftCopy();

            if (node._vertexNode != null)
            {
                _internalModel.VertexGroup.AddChild(node._vertexNode);
                (newNode._vertexNode = (MDL0VertexNode)_internalModel.VertexGroup.Children[_internalModel._vertList.Count - 1])._objects.Add(newNode);
            }
            if (node.NormalNode != null)
            {
                _internalModel.NormalGroup.AddChild(node._normalNode);
                (newNode._normalNode = (MDL0NormalNode)_internalModel.NormalGroup.Children[_internalModel._normList.Count - 1])._objects.Add(newNode);
            }
            for (int i = 0; i < 8; i++)
            {
                if (node._uvSet[i] != null)
                {
                    _internalModel.UVGroup.AddChild(node._uvSet[i]);
                    newNode._uvSet[i]      = (MDL0UVNode)_internalModel.UVGroup.Children[_internalModel._uvList.Count - 1];
                    newNode._uvSet[i].Name = "#" + (_internalModel._uvList.Count - 1);
                    newNode._uvSet[i]._objects.Add(newNode);
                }
            }

            for (int i = 0; i < 2; i++)
            {
                if (node._colorSet[i] != null)
                {
                    _internalModel.ColorGroup.AddChild(node._colorSet[i]);
                    (newNode._colorSet[i] = (MDL0ColorNode)_internalModel.ColorGroup.Children[_internalModel._colorList.Count - 1])._objects.Add(newNode);
                }
            }

            if (node.OpaMaterialNode != null)
            {
                _internalModel._matGroup.AddChild(node.OpaMaterialNode);
                newNode.OpaMaterialNode = (MDL0MaterialNode)_internalModel.MaterialGroup.Children[_internalModel._matList.Count - 1];

                _internalModel._shadGroup.AddChild(node.OpaMaterialNode._shader);
                newNode.OpaMaterialNode.ShaderNode = (MDL0ShaderNode)_internalModel.ShaderGroup.Children[_internalModel._shadList.Count - 1];

                foreach (MDL0MaterialRefNode r in newNode.OpaMaterialNode.Children)
                {
                    if (r._texture != null)
                    {
                        (r._texture = _internalModel.FindOrCreateTexture(r.TextureNode.Name))._references.Add(r);
                    }

                    if (r._palette != null)
                    {
                        (r._palette = _internalModel.FindOrCreatePalette(r.PaletteNode.Name))._references.Add(r);
                    }
                }
            }
            if (node.XluMaterialNode != null)
            {
                _internalModel._matGroup.AddChild(node.XluMaterialNode);
                newNode.XluMaterialNode = (MDL0MaterialNode)_internalModel.MaterialGroup.Children[_internalModel._matList.Count - 1];

                _internalModel._shadGroup.AddChild(node.XluMaterialNode._shader);
                newNode.XluMaterialNode.ShaderNode = (MDL0ShaderNode)_internalModel.ShaderGroup.Children[_internalModel._shadList.Count - 1];

                foreach (MDL0MaterialRefNode r in newNode.XluMaterialNode.Children)
                {
                    if (r._texture != null)
                    {
                        (r._texture = _internalModel.FindOrCreateTexture(r.TextureNode.Name))._references.Add(r);
                    }

                    if (r._palette != null)
                    {
                        (r._palette = _internalModel.FindOrCreatePalette(r.PaletteNode.Name))._references.Add(r);
                    }
                }
            }

            newNode._manager = node._manager;

            if (newNode.Weighted)
            {
                foreach (Vertex3 vert in newNode._manager._vertices)
                {
                    if (vert._matrixNode != null)
                    {
                        //To do:
                        //Get difference between new and old influence matrices
                        //and add it to the weighted position
                        //to fit the mesh to the new bones if it doesn't already.

                        //Matrix m = vert.MatrixNode.Matrix;
                        //Matrix invm = vert.MatrixNode.InverseMatrix;
                        if (vert._matrixNode is Influence)
                        {
                            for (int i = 0; i < vert.MatrixNode.Weights.Count; i++)
                            {
                                MDL0BoneNode b = vert.MatrixNode.Weights[i].Bone;
                                if (b != null)
                                {
                                    vert.MatrixNode.Weights[i].Bone = _internalModel._boneGroup.FindChildByType(b.Name, true, ResourceType.MDL0Bone) as MDL0BoneNode;
                                }
                            }

                            vert.MatrixNode = _internalModel._influences.FindOrCreate((Influence)vert._matrixNode, true);
                        }
                        else
                        {
                            vert.MatrixNode = _internalModel.BoneGroup.FindChildByType(((MDL0BoneNode)vert.MatrixNode).Name, true, ResourceType.MDL0Bone) as IMatrixNode;
                        }

                        //Matrix m2 = vert.MatrixNode.Matrix * invm;
                        //vert.WeightedPosition = vert.WeightedPosition * m2;
                    }
                }

                //foreach (Vertex3 vert in newNode._manager._vertices)
                //    vert.Unweight();
            }
            else if (newNode._matrixNode != null)
            {
                if (newNode._matrixNode is Influence)
                {
                    for (int i = 0; i < newNode.MatrixNode.Weights.Count; i++)
                    {
                        newNode.MatrixNode.Weights[i].Bone = _internalModel._boneGroup.FindChildByType(newNode.MatrixNode.Weights[i].Bone.Name, true, ResourceType.MDL0Bone) as MDL0BoneNode;
                    }

                    newNode.MatrixNode = _internalModel._influences.FindOrCreate((Influence)newNode._matrixNode, true);
                }
                else
                {
                    newNode.MatrixNode = _internalModel.BoneGroup.FindChildByType(((MDL0BoneNode)newNode.MatrixNode).Name, true, ResourceType.MDL0Bone) as IMatrixNode;
                }
            }

            newNode.RecalcIndices();
            newNode._bone    = (MDL0BoneNode)_internalModel.BoneGroup.Children[0];
            newNode.Name     = "polygon" + (_internalModel._objList.Count);
            newNode._rebuild = true;
            newNode.SignalPropertyChange();
            _internalModel._objGroup.AddChild(newNode);
        }
示例#24
0
        //Returns true if the vertex's matrix node is changed.
        private bool Weight(float value, Vertex3 vertex, WeightType type)
        {
            if (_targetBone == null || _targetBone.Locked)
            {
                return(false);
            }

            Influence  targetInf    = null;
            BoneWeight targetWeight = null;
            float      max          = 1.0f;

            //Get the matrix that influences this vertex
            IMatrixNode node = vertex.GetMatrixNode();

            bool startsAsBone = false;

            //Convert a single bone into an influence so bones can be added to it later
            if (node is MDL0BoneNode)
            {
                startsAsBone = true;
                node         = new Influence(node as MDL0BoneNode);
            }

            //Duplicate the influence if it affects more than just this vertex
            targetInf = node.Users.Count > 1 ?
                        (node as Influence).Clone() :
                        node as Influence;

            //Find or add the current bone to the influence
            List <BoneWeight> weights = targetInf.Weights;
            int selectedIndex         = weights.Select(x => x.Bone).ToArray().IndexOf(TargetBone);

            if (selectedIndex < 0)
            {
                weights.Add(new BoneWeight(TargetBone, 0.0f));
                selectedIndex = weights.Count - 1;
            }

            //Get the weight at the index of the current bone
            targetWeight = targetInf.Weights[selectedIndex];

            //Can't do anything to a locked weight
            if (targetWeight.Locked)
            {
                return(false);
            }

            //Get the sum of all weights that can be edited by subtracting all locked values from 1.0f
            max = 1.0f;
            foreach (BoneWeight b in weights)
            {
                if (b.Locked)
                {
                    max -= b.Weight;
                }
            }

            //Get the new value for the target weight
            //Clamp it between 0.0f and the max value
            switch (type)
            {
            default:
                value = RoundValue(value, max);
                break;

            case WeightType.Add:
                value = RoundValue(targetWeight.Weight + value, max);
                break;

            case WeightType.Multiply:
                value = RoundValue(targetWeight.Weight * value, max);
                break;
            }

            //Nothing to do if there's no change in value
            if (targetWeight.Weight == value)
            {
                return(false);
            }

            //Collect all unlocked weights that are not the current weight
            //These are weights that will be changed to accomodate the current weight edit
            List <int> editableWeights = new List <int>();

            for (int i = 0; i < targetInf.Weights.Count; i++)
            {
                if (!targetInf.Weights[i].Locked && i != selectedIndex)
                {
                    editableWeights.Add(i);
                }
            }

            //Return if nothing can be edited
            if (editableWeights.Count == 0)
            {
                return(false);
            }

            //Set the current weight with the calculated value
            targetWeight.Weight = value;

            //Get the change in value, divide it by all other editable weights,
            //and then add that value to those weights to bring the overall weight sum back to 1.0f
            float perBoneDiff = (targetWeight.Weight - value) / editableWeights.Count;

            if (value < max)
            {
                foreach (int i in editableWeights)
                {
                    targetInf.Weights[i].Weight = RoundValue(targetInf.Weights[i].Weight + perBoneDiff, 1.0f);
                }
            }
            else
            {
                foreach (int i in editableWeights)
                {
                    targetInf.Weights[i].Weight = 0.0f;
                }
            }

            //Normalize the influence just in case, this will scale all weights so they add up to 1.0f
            //Don't let the modified value be normalized, lock it
            bool locked = targetWeight.Locked;

            targetWeight.Locked = true;
            targetInf.Normalize();
            targetWeight.Locked = locked;

            //Clean influence by removing zero weights
            for (int i = 0; i < targetInf.Weights.Count; i++)
            {
                if (targetInf.Weights[i].Weight <= 0.0f)
                {
                    targetInf.Weights.RemoveAt(i--);
                }
            }

            MDL0ObjectNode obj   = vertex.Parent as MDL0ObjectNode;
            MDL0Node       model = obj.Model;
            IMatrixNode    matrixNode;

            //See if the influence is just one bone
            if (targetInf.Weights.Count == 1)
            {
                matrixNode = targetInf.Weights[0].Bone;
                if (!startsAsBone && !_anyConverted.Contains(obj))
                {
                    _anyConverted.Add(obj);
                }
            }
            else
            {
                matrixNode = model._influences.FindOrCreate(targetInf);
                if (startsAsBone && !_anyConverted.Contains(obj))
                {
                    _anyConverted.Add(obj);
                }
            }

            //Move influence to each vertex before modifying the influence of one vertex
            if (obj.MatrixNode != null)
            {
                obj.TryConvertMatrixToVertex();
            }

            vertex.DeferUpdateAssets();
            vertex.MatrixNode = matrixNode;

            return(true);
        }
示例#25
0
        private static void CreateMDL0Object(
            InstanceEntry inst,
            NodeEntry node,
            ResourceNode parent,
            PrimitiveManager manager,
            MDL0Node model,
            DecoderShell shell)
        {
            if (manager != null)
            {
                Error = "There was a problem creating a new object for " + (node._name != null ? node._name : node._id);

                MDL0ObjectNode poly = new MDL0ObjectNode()
                {
                    _manager   = manager,
                    _name      = node._name != null ? node._name : node._id,
                    _drawCalls = new BindingList <DrawCall>()
                };

                //Attach material
                if (inst._material != null)
                {
                    foreach (MaterialEntry mat in shell._materials)
                    {
                        if (mat._id == inst._material._target)
                        {
                            poly._drawCalls.Add(new DrawCall(poly)
                            {
                                MaterialNode = mat._node as MDL0MaterialNode
                            });
                        }
                    }
                }

                model._numTriangles  += poly._numFaces = manager._faceCount = manager._pointCount / 3;
                model._numFacepoints += poly._numFacepoints = manager._pointCount;

                poly._parent = model._objGroup;
                model._objList.Add(poly);

                model.ResetToBindState();

                //Attach single-bind
                if (parent != null && parent is MDL0BoneNode)
                {
                    MDL0BoneNode bone = (MDL0BoneNode)parent;
                    poly.DeferUpdateAssets();
                    poly.MatrixNode = bone;

                    foreach (DrawCall c in poly._drawCalls)
                    {
                        c.VisibilityBoneNode = bone;
                    }
                }
                else if (model._boneList.Count == 0)
                {
                    Error = String.Format("There was a problem rigging {0} to a single bone.", poly._name);

                    Box          box  = poly.GetBox();
                    MDL0BoneNode bone = new MDL0BoneNode()
                    {
                        Scale       = Vector3.One,
                        Translation = (box.Max + box.Min) / 2.0f,
                        _name       = "TransN_" + poly.Name,
                        Parent      = TempRootBone,
                    };

                    poly.DeferUpdateAssets();
                    poly.MatrixNode = bone;
                    ((MDL0BoneNode)TempRootBone).RecalcBindState(true, false, false);

                    foreach (DrawCall c in poly._drawCalls)
                    {
                        c.VisibilityBoneNode = bone;
                    }
                }
                else
                {
                    Error = String.Format("There was a problem checking if {0} is rigged to a single bone.", poly._name);

                    foreach (DrawCall c in poly._drawCalls)
                    {
                        c.VisibilityBoneNode = model._boneList[0] as MDL0BoneNode;
                    }

                    IMatrixNode mtxNode    = null;
                    bool        singlebind = true;

                    foreach (Vertex3 v in poly._manager._vertices)
                    {
                        if (v.MatrixNode != null)
                        {
                            if (mtxNode == null)
                            {
                                mtxNode = v.MatrixNode;
                            }

                            if (v.MatrixNode != mtxNode)
                            {
                                singlebind = false;
                                break;
                            }
                        }
                    }

                    if (singlebind && poly._matrixNode == null)
                    {
                        //Reassign reference entries
                        if (poly._manager._vertices[0].MatrixNode != null)
                        {
                            poly._manager._vertices[0].MatrixNode.Users.Add(poly);
                        }

                        foreach (Vertex3 v in poly._manager._vertices)
                        {
                            if (v.MatrixNode != null)
                            {
                                v.MatrixNode.Users.Remove(v);
                            }
                        }

                        poly._nodeId = -2; //Continued on polygon rebuild
                    }
                }
            }
        }
示例#26
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
                    {
                        _name = model.Name + "_" + model._objList[index]._name
                    };

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

                    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
                    {
                        _name = model.Name + "_" + model._objList[index]._name
                    };
                    MDL0ObjectNode n = (MDL0ObjectNode)model._objList[index];
                    if (n._drawCalls.Count > 0 && n._drawCalls[0].MaterialNode != null)
                    {
                        node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name;
                    }

                    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
                    {
                        _name = model.Name + "_" + model._objList[index]._name
                    };
                    MDL0ObjectNode n = (MDL0ObjectNode)model._objList[index];
                    if (n._drawCalls.Count > 0 && n._drawCalls[0].MaterialNode != null)
                    {
                        node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name;
                    }

                    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
                    };

                    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]];
                        }
                    }
                }
            }
        }
示例#27
0
        public static int CalcSize(Collada form, ModelLinker linker)
        {
            MDL0Node model = linker.Model;

            model._needsNrmMtxArray = model._needsTexMtxArray = false;
            model._numFacepoints    = model._numTriangles = 0;

            int headerLen,
                groupLen = 0,
                tableLen = 0,
                texLen   = 0,
                boneLen  = 0,
                dataLen  = 0,
                defLen   = 0,
                assetLen = 0,
                treeLen  = 0,
                mixLen   = 0,
                opaLen   = 0,
                xluLen   = 0;

            int aInd, aLen;

            //Get header length
            switch (linker.Version)
            {
            case 0x08:
            case 0x09: headerLen = 0x80; break;

            case 0x0A: headerLen = 0x88; break;

            case 0x0B: headerLen = 0x8C; break;

            default: headerLen = 0x80;
                //Unsupported version. Change to 9 as default.
                linker.Version = 9; break;
            }

            //Assign node indices
            AssignNodeIndices(linker);

            //Get table length
            tableLen = (linker._nodeCount + 1) << 2;

            //Get group/data length
            List <MDLResourceType> iList = ModelLinker.IndexBank[linker.Version];

            foreach (MDLResourceType resType in iList)
            {
                IEnumerable entryList = null;
                int         entries   = 0;

                switch (resType)
                {
                case MDLResourceType.Definitions:

                    //NodeTree
                    treeLen = linker.BoneCache.Length * 5;

                    //NodeMix
                    foreach (Influence i in model._influences._influences)
                    {
                        mixLen += 4;
                        foreach (BoneWeight w in i.Weights)
                        {
                            MDL0BoneNode bone = w.Bone as MDL0BoneNode;
                            if (bone != null && w.Weight != 0 && bone._nodeIndex < linker.NodeCache.Length && bone._nodeIndex >= 0 && linker.NodeCache[bone._nodeIndex] is MDL0BoneNode)
                            {
                                mixLen += 6;
                            }
                        }
                    }
                    foreach (MDL0BoneNode b in linker.BoneCache)
                    {
                        if (b._weightCount > 0)
                        {
                            mixLen += 5;
                        }
                    }

                    //DrawOpa and DrawXlu
                    //Get assigned materials and categorize
                    if (model._objList != null)
                    {
                        for (int i = 0; i < model._objList.Count; i++)
                        {
                            //Entries are ordered by material, not by polygon.
                            //Using the material's attached polygon list is untrustable if the definitions were corrupt on parse.
                            MDL0ObjectNode poly = model._objList[i] as MDL0ObjectNode;

                            model._numTriangles  += poly._numFaces;
                            model._numFacepoints += poly._numFacepoints;

                            foreach (DrawCall c in poly._drawCalls)
                            {
                                if (c.DrawPass == DrawCall.DrawPassType.Opaque)
                                {
                                    opaLen += 8;
                                }
                                else
                                {
                                    xluLen += 8;
                                }
                            }
                        }
                    }

                    //Add terminate byte and set model def flags
                    if (model._hasTree = (treeLen > 0))
                    {
                        treeLen++; entries++;
                    }
                    if (model._hasMix = (mixLen > 0))
                    {
                        mixLen++; entries++;
                    }
                    if (model._hasOpa = (opaLen > 0))
                    {
                        opaLen++; entries++;
                    }
                    if (model._hasXlu = (xluLen > 0))
                    {
                        xluLen++; entries++;
                    }

                    //Align data
                    defLen += (treeLen + mixLen + opaLen + xluLen).Align(4);

                    break;

                case MDLResourceType.Vertices:
                    if (model._vertList != null)
                    {
                        entryList = model._vertList;
                        break;
                    }
                    else
                    {
                        aInd = 0;     //Set the ID
                        aLen = 1;     //Offset count
                    }

EvalAssets:

                    List <ResourceNode> polyList = model._objList;
                    if (polyList == null)
                    {
                        break;
                    }

                    string str = "";

                    bool direct = linker._forceDirectAssets[aInd];

                    //Create asset lists
                    IList aList;
                    switch (aInd)     //Switch by the set ID
                    {
                    case 0: aList = linker._vertices = new List <VertexCodec>(polyList.Count); str = "Vertices "; break;

                    case 1: aList = linker._normals = new List <VertexCodec>(polyList.Count); str = "Normals "; break;

                    case 2: aList = linker._colors = new List <ColorCodec>(polyList.Count); str = "Colors "; break;

                    default: aList = linker._uvs = new List <VertexCodec>(polyList.Count); str = "UVs "; break;
                    }

                    aLen += aInd;
                    for (int i = 0; i < polyList.Count; i++)
                    {
                        MDL0ObjectNode obj = polyList[i] as MDL0ObjectNode;
                        for (int x = aInd; x < aLen; x++)
                        {
                            if (obj._manager._faceData[x] != null)
                            {
                                //Remap color nodes
                                if ((x == 2 || x == 3))
                                {
                                    if (Collada._importOptions._rmpClrs)
                                    {
                                        obj._elementIndices[x] = -1;
                                        foreach (MDL0ObjectNode thatObj in polyList.OrderBy(c => - ((MDL0ObjectNode)c)._manager.GetColors(x - 2, false).Length))
                                        {
                                            //Only compare up to the current object
                                            if (thatObj == obj)
                                            {
                                                break;
                                            }

                                            var  thatArr = thatObj._manager.GetColors(x - 2, false);
                                            var  thisArr = obj._manager.GetColors(x - 2, false);
                                            bool equals  = true;
                                            if (thisArr.Length == thatArr.Length)
                                            {
                                                for (int n = 0; n < thisArr.Length; n++)
                                                {
                                                    if (thisArr[n] != thatArr[n])
                                                    {
                                                        equals = false;
                                                        break;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                foreach (RGBAPixel px in thisArr)
                                                {
                                                    if (Array.IndexOf(thatArr, px) < 0)
                                                    {
                                                        equals = false;
                                                        break;
                                                    }
                                                }
                                            }

                                            if (equals)
                                            {
                                                //Found a match
                                                obj._elementIndices[x]         = thatObj._elementIndices[x];
                                                obj._manager._newClrObj[x - 2] = thatObj.Index;
                                                break;
                                            }
                                        }
                                        if (obj._elementIndices[x] != -1)
                                        {
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        obj._manager._newClrObj[x - 2] = i;
                                    }
                                }

                                obj._elementIndices[x] = (short)aList.Count;

                                if (form != null)
                                {
                                    form.Say("Encoding " + str + (x - aInd) + " for Object " + i + ": " + obj.Name);
                                }

                                VertexCodec vert;
                                switch (aInd)
                                {
                                case 0:
                                    vert = new VertexCodec(obj._manager.GetVertices(false), false, Collada._importOptions._fltVerts);
                                    aList.Add(vert);
                                    if (!direct)
                                    {
                                        assetLen += vert._dataLen.Align(0x20) + 0x40;
                                    }
                                    break;

                                case 1:
                                    vert = new VertexCodec(obj._manager.GetNormals(false), false, Collada._importOptions._fltNrms);
                                    aList.Add(vert);
                                    if (!direct)
                                    {
                                        assetLen += vert._dataLen.Align(0x20) + 0x20;
                                    }
                                    break;

                                case 2:
                                    ColorCodec col = new ColorCodec(obj._manager.GetColors(x - 2, false));
                                    aList.Add(col);
                                    if (!direct)
                                    {
                                        assetLen += col._dataLen.Align(0x20) + 0x20;
                                    }
                                    break;

                                default:
                                    vert = new VertexCodec(obj._manager.GetUVs(x - 4, false), Collada._importOptions._fltUVs);
                                    aList.Add(vert);
                                    if (!direct)
                                    {
                                        assetLen += vert._dataLen.Align(0x20) + 0x40;
                                    }
                                    break;
                                }
                            }
                            else
                            {
                                obj._elementIndices[x] = -1;
                            }
                        }
                    }
                    if (!direct)
                    {
                        entries = aList.Count;
                    }
                    break;

                case MDLResourceType.Normals:
                    if (model._normList != null)
                    {
                        entryList = model._normList;
                    }
                    else
                    {
                        aInd = 1;     //Set the ID
                        aLen = 1;     //Offset count
                        goto EvalAssets;
                    }
                    break;

                case MDLResourceType.Colors:
                    if (model._colorList != null)
                    {
                        entryList = model._colorList;
                    }
                    else
                    {
                        if (Collada._importOptions._useOneNode)
                        {
                            HashSet <RGBAPixel> pixels = new HashSet <RGBAPixel>();
                            if (model._objList != null)
                            {
                                foreach (MDL0ObjectNode obj in model._objList)
                                {
                                    for (int i = 0; i < 2; i++)
                                    {
                                        var arr = obj._manager.GetColors(i, false);
                                        if (arr.Length > 0)
                                        {
                                            obj._elementIndices[i + 2] = 0;
                                            foreach (RGBAPixel p in arr)
                                            {
                                                pixels.Add(p);
                                            }
                                        }
                                        else
                                        {
                                            obj._elementIndices[i + 2] = -1;
                                        }
                                    }
                                }
                            }
                            var le = pixels.ToList();
                            le.Sort();

                            if (le.Count == 0)
                            {
                                break;
                            }

                            Collada._importOptions._singleColorNodeEntries = le.ToArray();

                            ColorCodec col = new ColorCodec(Collada._importOptions._singleColorNodeEntries);
                            linker._colors = new List <ColorCodec>()
                            {
                                col
                            };
                            assetLen += col._dataLen.Align(0x20) + 0x20;
                            entries   = 1;
                        }
                        else
                        {
                            aInd = 2;     //Set the ID
                            aLen = 2;     //Offset count
                            goto EvalAssets;
                        }
                    }
                    break;

                case MDLResourceType.UVs:
                    if (model._uvList != null)
                    {
                        entryList = model._uvList;
                    }
                    else
                    {
                        aInd = 4;     //Set the ID
                        aLen = 8;     //Offset count
                        goto EvalAssets;
                    }
                    break;

                case MDLResourceType.Bones:
                    int index = 0;
                    foreach (MDL0BoneNode b in linker.BoneCache)
                    {
                        if (form != null)
                        {
                            form.Say("Calculating the size of the Bones - " + b.Name);
                        }

                        b._entryIndex = index++;
                        boneLen      += b.CalculateSize(true);
                    }
                    entries = linker.BoneCache.Length;
                    break;

                case MDLResourceType.Materials:
                    if (model._matList != null)
                    {
                        entries = model._matList.Count;
                    }
                    break;

                case MDLResourceType.Objects:
                    if (model._objList != null)
                    {
                        entryList = model._objList;
                        foreach (MDL0ObjectNode n in model._objList)
                        {
                            if (n.NormalNode != null || n._manager._faceData[1] != null)
                            {
                                model._needsNrmMtxArray = true;
                            }
                            if (n.HasTexMtx)
                            {
                                model._needsTexMtxArray = true;
                            }
                        }
                    }
                    break;

                case MDLResourceType.Shaders:
                    if (model._matList != null && (entryList = model.GetUsedShaders()) != null)
                    {
                        entries = model._matList.Count;
                    }
                    break;

                case MDLResourceType.Textures:
                    if (model._texList != null)
                    {
                        List <MDL0TextureNode> texNodes = new List <MDL0TextureNode>();
                        foreach (MDL0TextureNode tex in model._texList)
                        {
                            texNodes.Add(tex);
                            texLen += (tex._references.Count * 8) + 4;
                        }
                        entries = (linker._texList = texNodes).Count;
                    }
                    break;

                case MDLResourceType.Palettes:
                    if (model._pltList != null)
                    {
                        List <MDL0TextureNode> pltNodes = new List <MDL0TextureNode>();
                        foreach (MDL0TextureNode plt in model._pltList)
                        {
                            pltNodes.Add(plt);
                            texLen += (plt._references.Count * 8) + 4;
                        }
                        entries = (linker._pltList = pltNodes).Count;
                    }
                    break;
                }

                if (entryList != null)
                {
                    int index = 0;
                    foreach (MDL0EntryNode e in entryList)
                    {
                        if (form != null)
                        {
                            if (resType == MDLResourceType.Objects)
                            {
                                form.Say("Encoding the " + resType.ToString() + " - " + e.Name);
                            }
                            else
                            {
                                form.Say("Calculating the size of the " + resType.ToString() + " - " + e.Name);
                            }
                        }

                        e._entryIndex = index++;
                        dataLen      += e.CalculateSize(true);
                    }
                    if (entries == 0)
                    {
                        entries = index;
                    }
                }

                if (entries > 0)
                {
                    groupLen += (entries * 0x10) + 0x18;
                }
            }

            //Align the materials perfectly using the data length
            int temp = 0;

            if (model._matList != null && iList.IndexOf(MDLResourceType.Materials) != -1)
            {
                int index             = 0;
                MDL0MaterialNode prev = null;
                foreach (MDL0MaterialNode e in model._matList)
                {
                    if (form != null)
                    {
                        form.Say("Calculating the size of the Materials - " + e.Name);
                    }

                    if (index != 0)
                    {
                        e._mdlOffset = (prev = ((MDL0MaterialNode)model._matList[index - 1]))._mdlOffset + prev._calcSize;
                    }
                    else if ((temp = (e._mdlOffset = headerLen + tableLen + groupLen + texLen + defLen + boneLen).Align(0x10)) != e._mdlOffset)
                    {
                        e._dataAlign = temp - e._mdlOffset;
                    }

                    e._entryIndex = index++;
                    dataLen      += e.CalculateSize(true);
                }
            }

            if (model._isImport && model._objList != null)
            {
                foreach (MDL0ObjectNode obj1 in model._objList)
                {
                    if (obj1 == null || obj1._drawCalls == null || obj1._drawCalls.Count == 0)
                    {
                        continue;
                    }

                    MDL0MaterialNode p = obj1._drawCalls[0].MaterialNode;
                    if (p == null)
                    {
                        continue;
                    }

                    //Set materials to use register color if option set
                    if (!Collada._importOptions._useReg &&
                        linker._colors != null &&
                        linker._colors.Count > 0)
                    {
                        p.C1AlphaMaterialSource = GXColorSrc.Vertex;
                        p.C1ColorMaterialSource = GXColorSrc.Vertex;
                    }
                    else
                    {
                        p.C1MaterialColor       = Collada._importOptions._dfltClr;
                        p.C1ColorMaterialSource = GXColorSrc.Register;
                        p.C1AlphaMaterialSource = GXColorSrc.Register;
                    }
                }
            }

            return
                ((linker._headerLen = headerLen) +
                 (linker._tableLen = tableLen) +
                 (linker._groupLen = groupLen) +
                 (linker._texLen = texLen) +
                 (linker._defLen = defLen) +
                 (linker._boneLen = boneLen) +
                 (linker._assetLen = assetLen) +
                 (linker._dataLen = dataLen) +
                 (linker.Version > 9 ? model._userEntries.GetSize() : 0));
        }
示例#28
0
        private void GetBaseInfluence()
        {
            if (_node != null)
            {
                modelPanel1.RemoveReference(_node);
            }

            MDL0BoneNode[] boneCache = _externalModel._linker.BoneCache;
            if ((_node = (MDL0ObjectNode)comboBox1.SelectedItem).Weighted)
            {
                int least = int.MaxValue;
                foreach (IMatrixNode inf in _node.Influences)
                {
                    if (inf is MDL0BoneNode && ((MDL0BoneNode)inf).BoneIndex < least)
                    {
                        least = ((MDL0BoneNode)inf).BoneIndex;
                    }
                }

                if (least != int.MaxValue)
                {
                    MDL0BoneNode temp = boneCache[least];
                    _baseInf = (IMatrixNode)temp.Parent;
                }
            }
            else
            {
                _baseInf = _node.MatrixNode;
            }

            if (_baseInf is Influence)
            {
                label2.Hide();
                comboBox2.Hide();
            }
            else if (_baseInf is MDL0BoneNode)
            {
                label2.Show();
                comboBox2.Show();
            }

            baseBone.Text = _baseInf.ToString();

            if (comboBox3.SelectedIndex == 0 && _baseInf is MDL0BoneNode)
            {
                int i = 0;
                foreach (MDL0BoneNode s in comboBox2.Items)
                {
                    if (s.Name == baseBone.Text)
                    {
                        comboBox2.SelectedIndex = i;
                        break;
                    }

                    i++;
                }
            }

            _node.IsRendering = true;
            modelPanel1.ClearTargets();
            modelPanel1.AddTarget(_node, false);
            modelPanel1.SetCamWithBox(_node.GetBox());
        }
示例#29
0
 private void ImportObject(MDL0ObjectNode node)
 {
     _internalModel.ReplaceOrAddMesh(node, false, false, true);
 }
示例#30
0
        private unsafe void button5_Click(object sender, EventArgs e)
        {
            //Set vertices (0), normals (1), and/or colors (2, 3)
            //UVs are not morphed so there's no need to set them

            if (SelectedAnimation == null ||
                SelectedSource == null ||
                TargetModel == null ||
                TargetModel.Objects == null ||
                TargetModel.Objects.Length == 0)
            {
                return;
            }

            SHP0EntryNode entry = SelectedAnimation.FindChild(SelectedSource, false) as SHP0EntryNode;

            if (entry == null)
            {
                return;
            }

            if (MessageBox.Show(this, "Are you sure you want to continue?\nThis will edit the model and make the selected object's vertices, normals and/or colors default to the current morph.", "Are you sure?", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
            {
                return;
            }

            //Set the model to be only the bind pose with the SHP0 applied
            //This is so when the data is unweighted,
            //only the influence of the SHP0 will be set to the model.
            //Otherwise the entire CHR0 pose would be set as well
            float    frame = CurrentFrame;
            SHP0Node shp   = _mainWindow.SelectedSHP0;
            CHR0Node chr   = _mainWindow.SelectedCHR0;

            if (TargetModel != null)
            {
                TargetModel.ApplyCHR(null, 0);
                TargetModel.ApplySHP(shp, frame);
            }

            ResourceNode[] nodes = ((ResourceNode)TargetModel).FindChildrenByName(SelectedSource);
            foreach (ResourceNode n in nodes)
            {
                if (n is MDL0VertexNode)
                {
                    MDL0VertexNode   node = (MDL0VertexNode)n;
                    MDL0ObjectNode[] o    = new MDL0ObjectNode[node._objects.Count];
                    node._objects.CopyTo(o);
                    foreach (MDL0ObjectNode obj in o)
                    {
                        //Set the unweighted positions using the weighted positions
                        //Created using the SHP0
                        obj.Unweight(false);
                        obj.SetEditedAssets(true, true, false, false, false);
                    }
                }
                else if (n is MDL0NormalNode)
                {
                    MDL0NormalNode   node = (MDL0NormalNode)n;
                    MDL0ObjectNode[] o    = new MDL0ObjectNode[node._objects.Count];
                    node._objects.CopyTo(o);
                    foreach (MDL0ObjectNode obj in o)
                    {
                        obj.SetEditedAssets(true, false, true, false, false);
                    }
                }
                else if (n is MDL0ColorNode)
                {
                    MDL0ColorNode    node = (MDL0ColorNode)n;
                    MDL0ObjectNode[] o    = new MDL0ObjectNode[node._objects.Count];
                    node._objects.CopyTo(o);
                    foreach (MDL0ObjectNode obj in o)
                    {
                        obj.SetEditedAssets(true, false, false, true, true);
                    }
                }
            }

            if (TargetModel != null)
            {
                TargetModel.ApplyCHR(chr, frame);
                TargetModel.ApplySHP(shp, frame);
            }
        }