private void CreateNode() { TreeView.BeginUpdate(); int id = 1; string name = "NewBone0"; MDL0Node model = ((MDL0BoneNode)_resource).Model; Top: foreach (MDL0BoneNode b in model._linker.BoneCache) { if (b.Name == name) { name = "NewBone" + id++; goto Top; } } MDL0BoneNode bone = new MDL0BoneNode { Name = name, _entryIndex = model._linker.BoneCache.Length }; bone.FrameState = bone.BindState = FrameState.Neutral; _resource.AddChild(bone, true); bone.RecalcFrameState(); bone.RecalcBindState(false, false, false); model._linker.RegenerateBoneCache(); TreeView.EndUpdate(); Nodes[Nodes.Count - 1].EnsureVisible(); //TreeView.SelectedNode = Nodes[Nodes.Count - 1]; }
public IModel ImportModel(string filePath, ImportType type) { IModel model = null; ModelType = type; BoneType = ModelType == ImportType.MDL0 ? typeof(MDL0BoneNode) : null; //TransformMatrix = Matrix.TransformMatrix(_importOptions._modifyScale, _importOptions._modifyRotation, new Vector3()); switch (type) { case ImportType.MDL0: MDL0Node m = new MDL0Node() { _name = Path.GetFileNameWithoutExtension(filePath), _version = _importOptions._modelVersion.Clamp(8, 11) }; if (_importOptions._setOrigPath) { m._originalPath = filePath; } m.BeginImport(); model = m; break; } CurrentModel = model; Error = "There was a problem reading the model."; using (DecoderShell shell = DecoderShell.Import(filePath)) try { Error = "There was a problem reading texture entries."; //Extract images, removing duplicates foreach (ImageEntry img in shell._images) { string name = img._path != null? Path.GetFileNameWithoutExtension(img._path) : img._name != null ? img._name : img._id; switch (type) { case ImportType.MDL0: img._node = ((MDL0Node)model).FindOrCreateTexture(name); break; } } Error = "There was a problem creating a default shader."; //Create a shader ResourceNode shader = null; switch (type) { case ImportType.MDL0: MDL0Node m = (MDL0Node)model; MDL0ShaderNode shadNode = new MDL0ShaderNode() { _ref0 = 0, _ref1 = -1, _ref2 = -1, _ref3 = -1, _ref4 = -1, _ref5 = -1, _ref6 = -1, _ref7 = -1, }; shadNode._parent = m._shadGroup; m._shadList.Add(shadNode); switch (_importOptions._mdlType) { case ImportOptions.MDLType.Character: for (int i = 0; i < 3; i++) { switch (i) { case 0: shadNode.AddChild(new MDL0TEVStageNode(0x28F8AF, 0x08F2F0, 0, TevKColorSel.ConstantColor0_RGB, TevKAlphaSel.ConstantColor0_Alpha, TexMapID.TexMap0, TexCoordID.TexCoord0, ColorSelChan.LightChannel0, true)); break; case 1: shadNode.AddChild(new MDL0TEVStageNode(0x08FEB0, 0x081FF0, 0, TevKColorSel.ConstantColor1_RGB, TevKAlphaSel.ConstantColor0_Alpha, TexMapID.TexMap7, TexCoordID.TexCoord7, ColorSelChan.LightChannel0, false)); break; case 2: shadNode.AddChild(new MDL0TEVStageNode(0x0806EF, 0x081FF0, 0, TevKColorSel.ConstantColor0_RGB, TevKAlphaSel.ConstantColor0_Alpha, TexMapID.TexMap7, TexCoordID.TexCoord7, ColorSelChan.Zero, false)); break; } } break; case ImportOptions.MDLType.Stage: shadNode.AddChild(new MDL0TEVStageNode(0x28F8AF, 0x08F2F0, 0, TevKColorSel.ConstantColor0_RGB, TevKAlphaSel.ConstantColor0_Alpha, TexMapID.TexMap0, TexCoordID.TexCoord0, ColorSelChan.LightChannel0, true)); break; } shader = shadNode; break; } Error = "There was a problem extracting materials."; //Extract materials foreach (MaterialEntry mat in shell._materials) { List <ImageEntry> imgEntries = new List <ImageEntry>(); //Find effect if (mat._effect != null) { foreach (EffectEntry eff in shell._effects) { if (eff._id == mat._effect) //Attach textures and effects to material { if (eff._shader != null) { foreach (LightEffectEntry l in eff._shader._effects) { if (l._type == LightEffectType.diffuse && l._texture != null) { string path = l._texture; foreach (EffectNewParam p in eff._newParams) { if (p._sid == l._texture) { path = p._sampler2D._url; if (!String.IsNullOrEmpty(p._sampler2D._source)) { foreach (EffectNewParam p2 in eff._newParams) { if (p2._sid == p._sampler2D._source) { path = p2._path; } } } } } foreach (ImageEntry img in shell._images) { if (img._id == path) { imgEntries.Add(img); break; } } } } } } } } switch (type) { case ImportType.MDL0: MDL0MaterialNode matNode = new MDL0MaterialNode(); MDL0Node m = (MDL0Node)model; matNode._parent = m._matGroup; m._matList.Add(matNode); matNode._name = mat._name != null ? mat._name : mat._id; matNode.ShaderNode = shader as MDL0ShaderNode; mat._node = matNode; matNode._cull = _importOptions._culling; foreach (ImageEntry img in imgEntries) { MDL0MaterialRefNode mr = new MDL0MaterialRefNode(); (mr._texture = img._node as MDL0TextureNode)._references.Add(mr); mr._name = mr._texture.Name; matNode._children.Add(mr); mr._parent = matNode; mr._minFltr = mr._magFltr = 1; mr._uWrap = mr._vWrap = (int)_importOptions._wrap; } break; } } Say("Extracting scenes..."); List <ObjectInfo> _objects = new List <ObjectInfo>(); ResourceNode boneGroup = null; switch (type) { case ImportType.MDL0: boneGroup = ((MDL0Node)model)._boneGroup; break; } //Extract bones and objects and create bone tree foreach (SceneEntry scene in shell._scenes) { foreach (NodeEntry node in scene._nodes) { EnumNode(node, boneGroup, scene, model, shell, _objects, TransformMatrix, Matrix.Identity); } } //Add root bone if there are no bones if (boneGroup.Children.Count == 0) { switch (type) { case ImportType.MDL0: MDL0BoneNode bone = new MDL0BoneNode(); bone.Scale = new Vector3(1); bone.RecalcBindState(false, false); bone._name = "TopN"; TempRootBone = bone; break; } } //Create objects foreach (ObjectInfo obj in _objects) { NodeEntry node = obj._node; string w = obj._weighted ? "" : "un"; string w2 = obj._weighted ? "\nOne or more vertices may not be weighted correctly." : ""; string n = node._name != null ? node._name : node._id; Error = String.Format("There was a problem decoding {0}weighted primitives for the object {1}.{2}", w, n, w2); Say(String.Format("Decoding {0}weighted primitives for {1}...", w, n)); obj.Initialize(model, shell); } //Finish switch (type) { case ImportType.MDL0: MDL0Node mdl0 = (MDL0Node)model; if (TempRootBone != null) { mdl0._boneGroup._children.Add(TempRootBone); TempRootBone._parent = mdl0._boneGroup; } FinishMDL0(mdl0); break; } } #if !DEBUG catch (Exception x) { MessageBox.Show("Cannot continue importing this model.\n" + Error + "\n\nException:\n" + x.ToString()); model = null; Close(); } #endif finally { //Clean up the mess we've made GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); } CurrentModel = null; Error = null; return(model); }
private void EnumNode( NodeEntry node, ResourceNode parent, SceneEntry scene, IModel model, DecoderShell shell, List <ObjectInfo> objects, Matrix bindMatrix, Matrix parentInvMatrix) { bindMatrix *= node._matrix; if (node._type == NodeType.JOINT || (node._type == NodeType.NONE && node._instances.Count == 0)) { Error = "There was a problem creating a new bone."; Influence inf = null; switch (ModelType) { case ImportType.MDL0: MDL0BoneNode bone = new MDL0BoneNode(); bone._name = node._name != null ? node._name : node._id; bone._bindState = node._matrix.Derive(); node._node = bone; parent._children.Add(bone); bone._parent = parent; bone.RecalcBindState(false, false); bone.CalcFlags(); parent = bone; inf = new Influence(bone); break; } if (inf != null) { model.Influences._influences.Add(inf); } } //parentInvMatrix *= node._matrix.Invert(); foreach (NodeEntry e in node._children) { EnumNode(e, parent, scene, model, shell, objects, bindMatrix, parentInvMatrix); } foreach (InstanceEntry inst in node._instances) { if (inst._type == InstanceType.Controller) { foreach (SkinEntry skin in shell._skins) { if (skin._id == inst._url) { foreach (GeometryEntry g in shell._geometry) { if (g._id == skin._skinSource) { objects.Add(new ObjectInfo(true, g, bindMatrix, skin, scene, inst, parent, node)); break; } } break; } } } else if (inst._type == InstanceType.Geometry) { foreach (GeometryEntry g in shell._geometry) { if (g._id == inst._url) { objects.Add(new ObjectInfo(false, g, bindMatrix, null, null, inst, parent, node)); break; } } } else { foreach (NodeEntry e in shell._nodes) { if (e._id == inst._url) { EnumNode(e, parent, scene, model, shell, objects, bindMatrix, parentInvMatrix); } } } } }
protected unsafe virtual void modelPanel1_MouseMove(object sender, MouseEventArgs e) { if (_playing) { return; } ModelPanel panel = sender as ModelPanel; ModelPanelViewport viewport = panel.CurrentViewport; Vector3?point; if (_boneSelection.IsMoving() && SelectedBone != null) { Vector3 transform = GetLocalTransform(e, viewport, GetBoneWorldMtx(), GetBoneInvWorldMtx(), GetBoneParentTransformMtx(), _boneSelection, out point); if (Alt && !_createdNewBone) { if (SelectedBone is MDL0BoneNode) { _createdNewBone = true; MDL0BoneNode b = SelectedBone as MDL0BoneNode; MDL0Node model = b.Model; MDL0BoneNode newBone = new MDL0BoneNode(); string name = "NewBone"; if (model != null) { name += "0"; int id = 1; Top: foreach (MDL0BoneNode x in model._linker.BoneCache) { if (x.Name == name) { name = "NewBone" + id++; goto Top; } } newBone._entryIndex = model._linker.BoneCache.Length; } newBone.Name = name; newBone.FrameState = newBone.BindState = FrameState.Neutral; b.AddChild(newBone); newBone.RecalcFrameState(); newBone.RecalcBindState(false, false, false); model?._linker.RegenerateBoneCache(); BonesPanel?.Reset(); SelectedBone = newBone; } } if (point != null) { for (int i = 0; i < 3; i++) { _boneTransform[(int)ControlType](i, transform[i]); } _boneSelection._lastPointLocal = GetBoneInvWorldMtx() * point.Value; } } if (_vertexSelection.IsMoving() && VertexLoc != null) { Vector3 center = VertexLoc.Value; Vector3 transform = GetLocalTransform(e, viewport, Matrix.TranslationMatrix(center), Matrix.TranslationMatrix(-center), Matrix.Identity, _vertexSelection, out point); if (point != null) { switch (ControlType) { case TransformType.Scale: foreach (Vertex3 vertex in _selectedVertices) { vertex.WeightedPosition = Maths.ScaleAboutPoint(vertex.WeightedPosition, center, transform); } break; case TransformType.Rotation: foreach (Vertex3 vertex in _selectedVertices) { vertex.WeightedPosition = Maths.RotateAboutPoint(vertex.WeightedPosition, center, transform); } break; case TransformType.Translation: foreach (Vertex3 vertex in _selectedVertices) { vertex.WeightedPosition += transform; } break; } _vertexLoc = null; _vertexSelection._lastPointLocal = Matrix.TranslationMatrix(-VertexLoc.Value) * point.Value; } UpdateModel(); } bool allowHighlight = !DoNotHighlightOnMouseMove; bool draggingSelection = viewport.Selecting; //if not dragging a point AND (highlighting is allowed, or not but selecting) if (!_boneSelection.IsMoving() && !_vertexSelection.IsMoving() && (allowHighlight || (!allowHighlight && draggingSelection))) { HighlightStuff(e, panel); } }
internal unsafe void BoxChanged(object sender, EventArgs e) { if (_transformObject == null) { return; } NumericInputBox box = sender as NumericInputBox; int index = (int)box.Tag; if (_transformObject is MDL0BoneNode) { MDL0BoneNode bone = _transformObject as MDL0BoneNode; if ((_selectedAnim != null) && (_animFrame > 0)) { //Find bone anim and change transform CHR0EntryNode entry = _selectedAnim.FindChild(bone.Name, false) as CHR0EntryNode; if (entry == null) //Create new bone animation { if (!float.IsNaN(box.Value)) { entry = _selectedAnim.CreateEntry(); entry._name = bone.Name; //Set initial values FrameState state = bone._bindState; float * p = (float *)&state; for (int i = 0; i < 3; i++) { if (p[i] != 1.0f) { entry.SetKeyframe(KeyFrameMode.ScaleX + i, 0, p[i]); } } for (int i = 3; i < 9; i++) { if (p[i] != 0.0f) { entry.SetKeyframe(KeyFrameMode.ScaleX + i, 0, p[i]); } } entry.SetKeyframe(KeyFrameMode.ScaleX + index, _animFrame - 1, box.Value); } } else //Set existing { if (float.IsNaN(box.Value)) { entry.RemoveKeyframe(KeyFrameMode.ScaleX + index, _animFrame - 1); } else { entry.SetKeyframe(KeyFrameMode.ScaleX + index, _animFrame - 1, box.Value); } } } else { //Change base transform FrameState state = bone._bindState; float * p = (float *)&state; p[index] = float.IsNaN(box.Value) ? (index > 2 ? 0.0f : 1.0f) : box.Value; state.CalcTransforms(); bone._bindState = state; bone.RecalcBindState(); bone.SignalPropertyChange(); } _targetModel.ApplyCHR(_selectedAnim, _animFrame); ResetBox(index); if (RenderStateChanged != null) { RenderStateChanged(this, null); } } }