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); } } }
//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); }
public ObjectOptimization(MDL0ObjectNode o) { _object = o; _facepoints = _object._manager.MergeExternalFaceData(_object); _pointCount = _object._numFacepoints; _faceCount = _object._numFaces; }
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; } } }
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); }
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; } } } } }
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) //{ //} } }
private void SetNormals() { MDL0ObjectNode obj = _parent as MDL0ObjectNode; if (obj != null) { obj.SetEditedNormals(); } }
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); }
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); } } }
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); }
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(); }
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; } } }
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(); } } } }
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(); } }
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); }
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) //{ //} } }
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); }
//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); }
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 } } } }
//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]]; } } } } }
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)); }
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()); }
private void ImportObject(MDL0ObjectNode node) { _internalModel.ReplaceOrAddMesh(node, false, false, true); }
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); } }