public unsafe void ResetBox() { MDL0VertexNode vSet = VertexSet; SHP0EntryNode entry; SHP0VertexSetNode v; if (VertexSet == null || SelectedDestination == null) { return; } if ((SelectedAnimation != null) && (CurrentFrame > 0) && ((entry = SelectedAnimation.FindChild(vSet.Name, false) as SHP0EntryNode) != null) && (v = entry.FindChild(SelectedDestination.Name, false) as SHP0VertexSetNode) != null) { KeyframeEntry e = v.Keyframes.GetKeyframe(CurrentFrame - 1); if (e == null) { textBox1.Value = v.Keyframes[CurrentFrame - 1] * 100.0f; textBox1.BackColor = Color.White; } else { textBox1.Value = e._value * 100.0f; textBox1.BackColor = Color.Yellow; } } else { textBox1.Value = 0; textBox1.BackColor = Color.White; } updating = true; trackBar1.Value = ((int)(textBox1.Value * 10.0f)).Clamp(trackBar1.Minimum, trackBar1.Maximum); updating = false; }
private void listBox2_SelectedValueChanged(object sender, EventArgs e) { button2.Enabled = listBox2.SelectedItem != null; _selectedDest = listBox2.SelectedItem as MDL0VertexNode; _mainWindow.KeyframePanel.TargetSequence = VertexSetDest; _mainWindow.UpdatePropDisplay(); }
//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 MDL0VertexNode NewVertex() { MDL0Node model = ((MDL0Node)_resource); MDL0GroupNode g = model._vertGroup; if (g == null) { model.AddChild(g = new MDL0GroupNode(MDLResourceType.Vertices), true); model._vertGroup = g; model._vertList = g.Children; } MDL0VertexNode node = new MDL0VertexNode() { Name = "VertexSet" + ((MDL0Node)_resource)._vertList.Count }; node.Vertices = new Vector3[] { new Vector3(0) }; g.AddChild(node, true); node._forceRebuild = true; node.Rebuild(true); node.SignalPropertyChange(); FindResource(node, true).EnsureVisible(); return(node); }
public void SetPosition(MDL0VertexNode node, Vector3 pos) { node.Vertices[_facepoints[0]._vertexIndex] = pos; node.ForceRebuild = true; if (node.Format == WiiVertexComponentType.Float) { node.ForceFloat = true; } }
public void SetPosition() { MDL0VertexNode node = ((MDL0ObjectNode)_parent)._vertexNode; if (node == null) { return; } node.Vertices[_facepoints[0]._vertexIndex] = Position; node.ForceRebuild = true; if (node.Format == WiiVertexComponentType.Float) { node.ForceFloat = true; } }
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(); } }
internal unsafe void PercentChanged(object sender, EventArgs e) { if (VertexSet == null || SelectedDestination == null || updating) { return; } MDL0VertexNode vSet = VertexSet; if ((SelectedAnimation != null) && (CurrentFrame > 0)) { SHP0EntryNode entry = SelectedAnimation.FindChild(vSet.Name, false) as SHP0EntryNode; SHP0VertexSetNode v; if (entry == null) { (v = (entry = SelectedAnimation.FindOrCreateEntry(vSet.Name)).Children[0] as SHP0VertexSetNode).Name = SelectedDestination.Name; } else if ((v = entry.FindChild(SelectedDestination.Name, false) as SHP0VertexSetNode) == null) { if (!float.IsNaN(textBox1.Value)) { v = entry.FindOrCreateEntry(SelectedDestination.Name); v.SetKeyframe(CurrentFrame - 1, textBox1.Value / 100.0f); } } else if (float.IsNaN(textBox1.Value)) { v.RemoveKeyframe(CurrentFrame - 1); } else { v.SetKeyframe(CurrentFrame - 1, textBox1.Value / 100.0f); } } //TargetModel.ApplyCHR(SelectedCHR0, CurrentFrame); //TargetModel.ApplySHP(SelectedAnimation, CurrentFrame); //ResetBox(); //_mainWindow.modelPanel1.Invalidate(); _mainWindow.UpdateModel(); }
public void Unweight() { if (weights == null || nodes == null) { _position = GetInvMatrix() * WeightedPosition; } else { 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)); } _position = GetInvMatrix() * ((GetMatrix() * _object._vertexNode.Vertices[_facepoints[0]._vertexIndex]) + trans); } SetPosition(_object._vertexNode, _position); }
public unsafe void ResetBox() { MDL0VertexNode vSet = VertexSet; SHP0EntryNode entry; SHP0VertexSetNode v; if (VertexSet == null || SelectedDestination == null) { return; } if ((SelectedAnimation != null) && (CurrentFrame > 0) && ((entry = SelectedAnimation.FindChild(vSet.Name, false) as SHP0EntryNode) != null) && (v = entry.FindChild(SelectedDestination.Name, false) as SHP0VertexSetNode) != null) { KeyframeEntry e = v.Keyframes.GetKeyframe(KeyFrameMode.ScaleX, CurrentFrame - 1); if (e == null) { float val = v.Keyframes[KeyFrameMode.ScaleX, CurrentFrame - 1]; textBox1.Value = (val > 1 ? 1 : val < 0 ? 0 : val) * 100.0f; textBox1.BackColor = Color.White; } else { textBox1.Value = (e._value > 1 ? 1 : e._value < 0 ? 0 : e._value) * 100.0f; textBox1.BackColor = Color.Yellow; } } else { textBox1.Value = 0; textBox1.BackColor = Color.White; } updating = true; trackBar1.Value = (int)(textBox1.Value * 10.0f); updating = false; }
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); } }
//Write assets will only be used for model imports. private static void WriteAssets(Collada form, ModelLinker linker, ref byte *pData) { int index; MDL0Node model = linker.Model; if (linker._vertices != null && linker._vertices.Count != 0) { model.LinkGroup(new MDL0GroupNode(MDLResourceType.Vertices)); model._vertGroup._parent = model; index = 0; foreach (VertexCodec c in linker._vertices) { MDL0VertexNode node = new MDL0VertexNode(); node._name = model.Name + "_" + model._objList[index]._name; if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null) { node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name; } if (form != null) { form.Say("Writing Vertices - " + node.Name); } MDL0VertexData *header = (MDL0VertexData *)pData; header->_dataLen = c._dataLen.Align(0x20) + 0x40; header->_dataOffset = 0x40; header->_index = index++; header->_isXYZ = c._hasZ ? 1 : 0; header->_type = (int)c._type; header->_divisor = (byte)c._scale; header->_entryStride = (byte)c._dstStride; header->_numVertices = (ushort)c._dstCount; header->_eMin = c._min; header->_eMax = c._max; header->_pad1 = header->_pad2 = 0; c.Write(pData + 0x40); node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen); model._vertGroup.AddChild(node, false); pData += header->_dataLen; } } if (linker._normals != null && linker._normals.Count != 0) { model.LinkGroup(new MDL0GroupNode(MDLResourceType.Normals)); model._normGroup._parent = model; index = 0; foreach (VertexCodec c in linker._normals) { MDL0NormalNode node = new MDL0NormalNode(); node._name = model.Name + "_" + model._objList[index]._name; if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null) { node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name; } if (form != null) { form.Say("Writing Normals - " + node.Name); } MDL0NormalData *header = (MDL0NormalData *)pData; header->_dataLen = c._dataLen.Align(0x20) + 0x20; header->_dataOffset = 0x20; header->_index = index++; header->_isNBT = 0; header->_type = (int)c._type; header->_divisor = (byte)c._scale; header->_entryStride = (byte)c._dstStride; header->_numVertices = (ushort)c._dstCount; c.Write(pData + 0x20); node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen); model._normGroup.AddChild(node, false); pData += header->_dataLen; } } if (linker._colors != null && linker._colors.Count != 0) { model.LinkGroup(new MDL0GroupNode(MDLResourceType.Colors)); model._colorGroup._parent = model; index = 0; foreach (ColorCodec c in linker._colors) { MDL0ColorNode node = new MDL0ColorNode(); node._name = model.Name + "_" + model._objList[index]._name; if (((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode != null) { node._name += "_" + ((MDL0ObjectNode)model._objList[index])._drawCalls[0].MaterialNode._name; } if (form != null) { form.Say("Writing Colors - " + node.Name); } MDL0ColorData *header = (MDL0ColorData *)pData; header->_dataLen = c._dataLen.Align(0x20) + 0x20; header->_dataOffset = 0x20; header->_index = index++; header->_isRGBA = c._hasAlpha ? 1 : 0; header->_format = (int)c._outType; header->_entryStride = (byte)c._dstStride; header->_pad = 0; header->_numEntries = (ushort)c._dstCount; c.Write(pData + 0x20); node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen); model._colorGroup.AddChild(node, false); pData += header->_dataLen; } } if (linker._uvs != null && linker._uvs.Count != 0) { model.LinkGroup(new MDL0GroupNode(MDLResourceType.UVs)); model._uvGroup._parent = model; index = 0; foreach (VertexCodec c in linker._uvs) { MDL0UVNode node = new MDL0UVNode() { _name = "#" + index }; if (form != null) { form.Say("Writing UVs - " + node.Name); } MDL0UVData *header = (MDL0UVData *)pData; header->_dataLen = c._dataLen.Align(0x20) + 0x40; header->_dataOffset = 0x40; header->_index = index++; header->_format = (int)c._type; header->_divisor = (byte)c._scale; header->_isST = 1; header->_entryStride = (byte)c._dstStride; header->_numEntries = (ushort)c._dstCount; header->_min = (Vector2)c._min; header->_max = (Vector2)c._max; header->_pad1 = header->_pad2 = header->_pad3 = header->_pad4 = 0; c.Write(pData + 0x40); node._replSrc = node._replUncompSrc = new DataSource(header, header->_dataLen); model._uvGroup.AddChild(node, false); pData += header->_dataLen; } } //Clean groups if (model._vertList != null && model._vertList.Count > 0) { model._children.Add(model._vertGroup); linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._vertGroup.Name)] = model._vertGroup; } else { model.UnlinkGroup(model._vertGroup); } if (model._normList != null && model._normList.Count > 0) { model._children.Add(model._normGroup); linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._normGroup.Name)] = model._normGroup; } else { model.UnlinkGroup(model._normGroup); } if (model._uvList != null && model._uvList.Count > 0) { model._children.Add(model._uvGroup); linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._uvGroup.Name)] = model._uvGroup; } else { model.UnlinkGroup(model._uvGroup); } if (model._colorList != null && model._colorList.Count > 0) { model._children.Add(model._colorGroup); linker.Groups[(int)(MDLResourceType)Enum.Parse(typeof(MDLResourceType), model._colorGroup.Name)] = model._colorGroup; } else { model.UnlinkGroup(model._colorGroup); } //Link sets if (model._objList != null) { foreach (MDL0ObjectNode poly in model._objList) { if (poly._elementIndices[0] != -1 && model._vertList != null && model._vertList.Count > poly._elementIndices[0]) { poly._vertexNode = (MDL0VertexNode)model._vertGroup._children[poly._elementIndices[0]]; } if (poly._elementIndices[1] != -1 && model._normList != null && model._normList.Count > poly._elementIndices[1]) { poly._normalNode = (MDL0NormalNode)model._normGroup._children[poly._elementIndices[1]]; } for (int i = 2; i < 4; i++) { if (poly._elementIndices[i] != -1 && model._colorList != null && model._colorList.Count > poly._elementIndices[i]) { poly._colorSet[i - 2] = (MDL0ColorNode)model._colorGroup._children[poly._elementIndices[i]]; } } for (int i = 4; i < 12; i++) { if (poly._elementIndices[i] != -1 && model._uvList != null && model._uvList.Count > poly._elementIndices[i]) { poly._uvSet[i - 4] = (MDL0UVNode)model._uvGroup._children[poly._elementIndices[i]]; } } } } }
public override ResourceNode Duplicate(bool changeName) { if (_resource.Parent == null) { return(null); } string tempPath = Path.GetTempFileName(); _resource.Export(tempPath); // Initialize node in a way that will not cause crashes ResourceNode rNode2; switch (Resource.ResourceFileType) { case ResourceType.MDL0Color: rNode2 = new MDL0ColorNode(); break; case ResourceType.MDL0UV: rNode2 = new MDL0UVNode(); break; case ResourceType.MDL0Material: rNode2 = new MDL0MaterialNode(); break; case ResourceType.MDL0Shader: rNode2 = new MDL0ShaderNode(); break; case ResourceType.MDL0Texture: rNode2 = new MDL0TextureNode(); break; case ResourceType.MDL0Normal: rNode2 = new MDL0NormalNode(); break; case ResourceType.MDL0Bone: rNode2 = new MDL0BoneNode(); break; case ResourceType.MDL0Vertex: rNode2 = new MDL0VertexNode(); break; default: throw new NotSupportedException("Unsupported type for MDL0 Duplication"); } rNode2._name = _resource.Name; rNode2.Replace(tempPath); if (rNode2 == null) { MessageBox.Show("The node could not be duplicated correctly.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } // Remove the node from the parent temporarily rNode2.Remove(); // Set the name programatically (based on Windows' implementation) int index = _resource.Index; int n = 0; if (changeName) { while (_resource.Parent.FindChildrenByName(rNode2.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(rNode2.Name).Last().Index); // Set the name based on the number of duplicate nodes found rNode2.Name = $"{_resource.Name} ({++n})"; } } // Place the node in the same containing parent, after the last duplicated node. _resource.Parent.InsertChild(rNode2, true, index + 1); // Update name again in order to refresh things that need refreshing when name is updated rNode2.OnRenamed(); return(rNode2); }