public void Remap()
        {
            MDL0BoneNode b = _resource as MDL0BoneNode;

            if (b != null)
            {
                MDL0Node m = b.Model;
                if (m != null)
                {
                    b._entryIndex = m._linker.BoneCache.Length;
                    m._linker.RegenerateBoneCache();
                    OnUpdateProperties(null, null);
                    b.SignalPropertyChange();
                }
            }
        }
示例#2
0
        public DialogResult ShowDialog(MDL0Node internalModel, MDL0Node externalModel)
        {
            _internalModel = internalModel;
            _externalModel = externalModel;

            _externalModel.ApplyCHR(null, 0);

            externalModelChildren = _externalModel.FindChild("Objects", true).Children.ToArray();

            comboBox1.Items.AddRange(_externalModel.FindChild("Objects", true).Children.ToArray());
            comboBox2.Items.AddRange(_internalModel._linker.BoneCache);

            comboBox1.SelectedIndex = comboBox2.SelectedIndex = comboBox3.SelectedIndex = 0;
            _parent = (MDL0BoneNode)comboBox2.SelectedItem;

            return(base.ShowDialog(null));
        }
示例#3
0
        /// <summary>
        /// Call twice; before and after changes
        /// </summary>
        public void BoneChange(MDL0BoneNode bone)
        {
            SaveState state = new SaveState();

            state._bone       = bone;
            state._frameState = bone._frameState;
            state._animation  = SelectedCHR0;
            state._frameIndex = CurrentFrame;

            if (before)
            {
                AddUndo(state);
            }
            else
            {
                AddRedo(state);
            }

            before = !before;
        }
示例#4
0
        private void CreateNode()
        {
            MDL0GroupNode group = _resource as MDL0GroupNode;
            MDL0Node      model = group.Parent as MDL0Node;

            switch (group._type.ToString("g"))
            {
            case "Bones":
                MDL0BoneNode bone = new MDL0BoneNode {
                    Name = "NewBone"
                };
                model._boneGroup.InsertChild(bone, false, 0);
                bone._boneFlags         = (BoneFlags)284;
                bone.Scale              = new Vector3(1, 1, 1);
                bone._bindMatrix        = Matrix.Identity;
                bone._inverseBindMatrix = Matrix.Identity;
                bone.OnMoved();
                break;
            }
        }
示例#5
0
        private bool CompareDistanceRecursive(MDL0BoneNode bone, Vector3 point, ref MDL0BoneNode match)
        {
            Vector3 center = bone._frameMatrix.GetPoint();
            float   dist   = center.TrueDistance(point);

            if (Math.Abs(dist - MDL0BoneNode._nodeRadius) < 0.01)
            {
                match = bone;
                return(true);
            }

            foreach (MDL0BoneNode b in bone.Children)
            {
                if (CompareDistanceRecursive(b, point, ref match))
                {
                    return(true);
                }
            }

            return(false);
        }
示例#6
0
        private static unsafe void WriteBone(MDL0BoneNode bone, XmlWriter writer)
        {
            writer.WriteStartElement("node");
            writer.WriteAttributeString("id", bone._name);
            writer.WriteAttributeString("name", bone._name);
            writer.WriteAttributeString("type", "JOINT");

            writer.WriteStartElement("matrix");

            Matrix m = bone._bindState._transform;
            float *p = (float *)&m;

            for (int y = 0; y < 4; y++)
            {
                for (int x = 0; x < 4; x++)
                {
                    if ((x != 0) || (y != 0))
                    {
                        writer.WriteValue(" ");
                    }
                    writer.WriteValue(p[(x << 2) + y].ToString());
                }
            }

            writer.WriteEndElement(); //matrix

            //Write single-bind geometry
            foreach (MDL0PolygonNode poly in bone._infPolys)
            {
                WritePolyInstance(poly, writer);
            }

            foreach (MDL0BoneNode b in bone.Children)
            {
                WriteBone(b, writer);
            }

            writer.WriteEndElement(); //node
        }
示例#7
0
        public Color GetWeightColor(MDL0BoneNode targetBone)
        {
            float weight = -1;

            if (_matrixNode == null || targetBone == null)
            {
                return(Color.Transparent);
            }
            if (_matrixNode is MDL0BoneNode)
            {
                if (_matrixNode == targetBone)
                {
                    weight = 1.0f;
                }
                else
                {
                    return(Color.Transparent);
                }
            }
            else
            {
                foreach (BoneWeight b in ((Influence)_matrixNode)._weights)
                {
                    if (b.Bone == targetBone)
                    {
                        weight = b.Weight;
                        break;
                    }
                }
            }
            if (weight == -1)
            {
                return(Color.Transparent);
            }
            int r = ((int)(weight * 255.0f)).Clamp(0, 0xFF);

            return(Color.FromArgb(r, 0, 0xFF - r));
        }
        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
            };

            bone.Scale = new Vector3(1);

            bone._bindMatrix                     =
                bone._inverseBindMatrix          =
                    bone._frameMatrix            =
                        bone._inverseFrameMatrix =
                            Matrix.Identity;

            _resource.AddChild(bone, true);
            bone.Moved = true;

            TreeView.EndUpdate();

            Nodes[Nodes.Count - 1].EnsureVisible();
            //TreeView.SelectedNode = Nodes[Nodes.Count - 1];
        }
示例#9
0
        private void lstBones_SelectedValueChanged(object sender, EventArgs e)
        {
            if (_selectedBone != null)
            {
                _selectedBone._boneColor = _selectedBone._nodeColor = Color.Transparent;
            }

            if ((_targetObject = _selectedBone = lstBones.SelectedItem as MDL0BoneNode) != null)
            {
                _selectedBone._boneColor = Color.FromArgb(0, 128, 255);
                _selectedBone._nodeColor = Color.FromArgb(255, 128, 0);
            }

            if (SelectedBoneChanged != null)
            {
                SelectedBoneChanged(this, null);
            }

            if (RenderStateChanged != null)
            {
                RenderStateChanged(this, null);
            }
        }
示例#10
0
        public DialogResult ShowDialog(MDL0Node internalModel, MDL0Node externalModel)
        {
            if (internalModel?._linker?.BoneCache == null || internalModel._linker.BoneCache.Length == 0)
            {
                MessageBox.Show("The target model must have at least one bone.", "Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(DialogResult.Cancel);
            }
            ResourceNode[] objects = externalModel.FindChild("Objects", true)?.Children.ToArray();
            if (objects == null || objects.Length == 0)
            {
                MessageBox.Show("The imported model must have at least one object.", "Import Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(DialogResult.Cancel);
            }
            _internalModel = internalModel;
            _externalModel = externalModel;

            comboBox1.Items.AddRange(objects);
            comboBox2.Items.AddRange(_internalModel._linker.BoneCache);

            comboBox1.SelectedIndex = comboBox2.SelectedIndex = comboBox3.SelectedIndex = 0;
            _parent = (MDL0BoneNode)comboBox2.SelectedItem;

            return(ShowDialog(null));
        }
示例#11
0
        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];
        }
示例#12
0
        protected override void OnShown(EventArgs e)
        {
            modelEditControl1._openedFiles.Add(Program.RootNode);

            MainForm.Instance.Visible =
                !Properties.Settings.Default.ViewerSettings.HideMainWindow;

            if (_models.Count != 0)
            {
                for (int i = 0; i < _models.Count; i++)
                {
                    if (_models[i] != null)
                    {
                        modelEditControl1.AppendTarget(_models[i]);
                    }
                }

                modelEditControl1.TargetModel = _models[0];
                modelEditControl1.EditingAll  = _models.Count > 1;
                modelEditControl1.ResetBoneColors();
            }
            else
            {
                modelEditControl1.TargetModel = null;
            }

            if (_collisions.Count != 0)
            {
                foreach (CollisionNode node in _collisions)
                {
                    modelEditControl1.AppendTarget(node);

                    // Link bones
                    foreach (CollisionObject obj in node.Children)
                    {
                        if (obj._modelName == "" || obj._boneName == "")
                        {
                            continue;
                        }

                        MDL0Node model = _models.Where(m => m is MDL0Node && ((ResourceNode)m).Name == obj._modelName)
                                         .FirstOrDefault() as MDL0Node;

                        if (model != null)
                        {
                            MDL0BoneNode bone =
                                model._linker.BoneCache.Where(b => b.Name == obj._boneName)
                                .FirstOrDefault() as MDL0BoneNode;
                            if (bone != null)
                            {
                                obj._linkedBone = bone;
                            }
                        }
                    }
                }
            }

            modelEditControl1.ModelPanel.Capture();
            ReadSettings();

            base.OnShown(e);
        }
示例#13
0
        public void RunEvent(int eventIndex)
        {
            //Get the current event and its id
            e = this[eventIndex];

            //Run event only if allowed or if an exception
            if (e == null || !_runEvents && !_runExceptions.Contains(eventId >> 16))
            {
                return;
            }

            uint eventIdTemp = eventId & 0xFFFFFF00; //Cut out unk value
            //if (_events.ContainsKey(eventIdTemp))
            //    _events[eventIdTemp].Invoke(this, null);

            //Variables that are used often
            int                 id;
            Script              script;
            Event               ev;
            int                 index;
            ArticleInfo         articleInfo;
            HitBox              hitbox;
            RequirementInfo     reqInfo;
            ActionChangeInfo    aChangeInfo;
            SubActionChangeInfo sChangeInfo;

            //Code what to do for each event here!
            switch (eventIdTemp)
            {
            case 0x01000000:     //Loop Rest 1 for Goto
                Application.DoEvents();
                break;

            case 0x00010100:     //Synchronous Timer
                _waitFrames = (int)(e[0].RealValue + 0.5f);
                break;

            case 0x00020000:     //No Operation
                break;

            case 0x00020100:     //Asynchronous Timer
                _waitFrames = Math.Max((int)(e[0].RealValue + 0.5f) - _frameIndex, 0);
                break;

            case 0x00040100:     //Set loop data
                _loopCount      = e[0];
                _loopStartIndex = e.Index + 1;
                _runEvents      = false;
                break;

            case 0x00050000:     //Start looping
                _looping      = true;
                _loopEndIndex = e.Index;
                _eventIndex   = _loopStartIndex;
                _runEvents    = true;
                break;

            case 0x000A0100:     //If
            case 0x000A0200:     //If Value
            case 0x000A0300:     //If Unk
            case 0x000A0400:     //If Comparison
                if (_runEvents)
                {
                    _currentIf = _ifIndex++;
                    _runEvents = false;
                    _ifInfo    = new IfInfo();

                    index = eventIndex + 1;
                    while (true)
                    {
                        if (index < Count)
                        {
                            ev = this[index];
                            id = (int)ev.EventID;
                            if (id == 0x000B0100 ||
                                id == 0x000B0200 ||
                                id == 0x000B0300 ||
                                id == 0x000B0400)
                            {
                                index++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    _ifInfo._reqIndices = new List <int>();
                    _ifInfo._reqIndices.Add(index);

                    _ifEndIndices.Add(0);
                    reqInfo = new RequirementInfo(e[0]);
                    for (int i = 1; i < ((eventId >> 8) & 0xFF); i++)
                    {
                        reqInfo._values.Add(e[i]);
                    }
                    _ifInfo._requirements = new List <List <RequirementInfo> >();
                    _ifInfo._requirements.Add(new List <RequirementInfo>());
                    _ifInfo._requirements[0].Add(reqInfo);
                }
                else
                {
                    _ifIndex++;
                }
                break;

            case 0x000E0000:     //Else
                if (!_runEvents)
                {
                    if (_ifIndex == _currentIf)
                    {
                        _ifInfo._elseIndex = eventIndex;
                    }
                }
                else
                {
                    if (_ifIndex == _currentIf + 1)
                    {
                        _eventIndex = _ifInfo._endIndex;
                    }
                }
                break;

            case 0x000D0100:     //Else If (req)
            case 0x000D0200:     //Else If Value (req val)
            case 0x000D0300:     //Else If Unk (req val unk)
            case 0x000D0400:     //Else If Comparison (req var val var)

                if (!_runEvents)
                {
                    if (_ifIndex == _currentIf)
                    {
                        index = eventIndex + 1;
                        while (true)
                        {
                            if (index < Count)
                            {
                                ev = this[index];
                                id = (int)ev.EventID;
                                if (id == 0x000B0100 ||
                                    id == 0x000B0200 ||
                                    id == 0x000B0300 ||
                                    id == 0x000B0400)
                                {
                                    index++;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        _ifInfo._reqIndices.Add(index);
                    }
                }
                else
                {
                    if (_ifIndex == _currentIf + 1)
                    {
                        _eventIndex = _ifInfo._endIndex;
                    }
                }

                if (!_runEvents && _ifIndex == _currentIf + 1)
                {
                    reqInfo = new RequirementInfo(e[0]);
                    for (int i = 1; i < eCount; i++)
                    {
                        reqInfo._values.Add(e[i]);
                    }
                    _ifInfo._requirements.Add(new List <RequirementInfo>());
                    _ifInfo._requirements[0].Add(reqInfo);
                }
                break;

            case 0x000B0100:     //And If
            case 0x000B0200:     //And If Value
            case 0x000B0300:     //And If Unk
            case 0x000B0400:     //And If Comparison
                if (!_runEvents && _ifIndex == _currentIf + 1)
                {
                    reqInfo = new RequirementInfo(e[0]);
                    for (int i = 1; i < eCount; i++)
                    {
                        reqInfo._values.Add(e[i]);
                    }
                    _ifInfo._requirements.Add(new List <RequirementInfo>());
                    _ifInfo._requirements[0].Add(reqInfo);
                }
                break;

            case 0x000F0000:     //End if
                _ifIndex--;
                if (!_runEvents)
                {
                    if (_ifIndex == _currentIf)
                    {
                        _ifInfo._endIndex = _ifEndIndices[_currentIf] = eventIndex + 1;
                        _eventIndex       = _ifInfo.Run();
                        _runEvents        = true;
                    }
                }
                break;

            case 0x00100200:     //Switch
                _cases       = new List <Parameter>();
                _caseIndices = new List <int>();

                //Turn off events to examine them until end switch
                //Then the examined data will be evaluated
                _runEvents = false;

                _switchStartIndex = eventIndex;
                break;

            case 0x00110100:     //Case
                if (!_runEvents)
                {
                    if (_cases != null && _caseIndices != null)
                    {
                        _cases.Add(e[0]);
                        _caseIndices.Add(e.Index);
                    }
                }
                else
                {
                    _eventIndex     = _switchEndIndex + 1;
                    _switchEndIndex = -1;
                }
                break;

            case 0x00120000:     //Default Case
                _defaultCaseIndex = e.Index;
                break;

            case 0x00130000:     //End Switch
                _runEvents      = true;
                _switchEndIndex = e.Index;

                //Apply cases
                index = 0;
                if (_switchStartIndex >= 0 && _switchStartIndex < Count)
                {
                    Parameter Switch = this[_switchStartIndex][1];
                    foreach (Parameter param in _cases)
                    {
                        if (Switch.Compare(param, 2))
                        {
                            _eventIndex = _caseIndices[index] + 1;
                            break;
                        }
                        index++;
                    }
                }

                if (_cases != null && index == _cases.Count && _defaultCaseIndex != -1)
                {
                    _eventIndex = _defaultCaseIndex + 1;
                }

                _defaultCaseIndex = -1;
                _switchStartIndex = -1;
                _cases            = null;

                break;

            case 0x00180000:     //Break
                _eventIndex     = _switchEndIndex + 1;
                _switchEndIndex = -1;
                break;

            case 0x10050200:     //Article Visiblity
                id = e[0];
                if (id < 0 || id >= RunTime._articles.Length)
                {
                    break;
                }
                articleInfo = RunTime._articles[id];
                if (articleInfo != null && articleInfo._model != null)
                {
                    articleInfo._model.IsRendering = e[1] != 0;
                }
                break;

            case 0x01010000:     //Loop Rest
                _waitFrames = 1;
                break;

            case 0x06000D00:     //Offensive Collison
            case 0x062B0D00:     //Thrown Collision
                hitbox            = new HitBox(e, Article != null ? Article.Index : -1);
                hitbox.HitboxID   = (int)(e[0] & 0xFFFF);
                hitbox.HitboxSize = e[5];
                RunTime._hitBoxes.Add(hitbox);
                break;

            case 0x06050100:     //Body Collision
                _hurtBoxType = e[0];
                break;

            case 0x06080200:     //Bone Collision
                id = e[0];
                if (Root.Model != null && Root.Model._linker.BoneCache.Length > id && id >= 0)
                {
                    MDL0BoneNode bone = Root.Model._linker.BoneCache[id] as MDL0BoneNode;
                    switch ((int)e[1])
                    {
                    case 0:
                        bone._nodeColor = Color.Transparent;
                        bone._boneColor = Color.Transparent;
                        break;

                    case 1:
                        bone._nodeColor = bone._boneColor = Color.FromArgb(255, 255, 0);
                        break;

                    default:
                        bone._nodeColor = bone._boneColor = Color.FromArgb(0, 0, 255);
                        break;
                    }
                    _boneCollisions.Add(bone);
                }
                break;

            case 0x06060100:     //Undo Bone Collision
                foreach (MDL0BoneNode bone in _boneCollisions)
                {
                    bone._nodeColor = bone._boneColor = Color.Transparent;
                }
                _boneCollisions = new List <MDL0BoneNode>();
                break;

            case 0x060A0800:     //Catch Collision 1
            case 0x060A0900:     //Catch Collision 2
            case 0x060A0A00:     //Catch Collision 3
                hitbox            = new HitBox(e, Article != null ? Article.Index : -1);
                hitbox.HitboxID   = e[0];
                hitbox.HitboxSize = e[2];
                RunTime._hitBoxes.Add(hitbox);
                break;

            case 0x060D0000:     //Terminate Catch Collisions
                for (int i = 0; i < RunTime._hitBoxes.Count; i++)
                {
                    if (RunTime._hitBoxes[i].IsCatch())
                    {
                        RunTime._hitBoxes.RemoveAt(i--);
                    }
                }
                break;

            case 0x00060000:     //Loop break
                _looping    = false;
                _eventIndex = _loopEndIndex + 1;
                _loopTime   = 0;
                break;

            case 0x06150F00:     //Special Offensive Collison
                hitbox            = new HitBox(e, Article != null ? Article.Index : -1);
                hitbox.HitboxID   = (int)(e[0] & 0xFFFF);
                hitbox.HitboxSize = e[5];
                RunTime._hitBoxes.Add(hitbox);
                break;

            case 0x06040000:     //Terminate Collisions
                for (int i = 0; i < RunTime._hitBoxes.Count; i++)
                {
                    if (RunTime._hitBoxes[i].IsOffensive(true))
                    {
                        RunTime._hitBoxes.RemoveAt(i--);
                    }
                }
                break;

            case 0x06030100:     //Delete hitbox
                for (int i = 0; i < RunTime._hitBoxes.Count; i++)
                {
                    HitBox hbox = RunTime._hitBoxes[i];
                    if (hbox.HitboxID == e[0] && hbox.IsOffensive(true))
                    {
                        RunTime._hitBoxes.RemoveAt(i--);
                        break;
                    }
                }
                break;

            case 0x060C0100:     //Delete Catch Collision
                for (int i = 0; i < RunTime._hitBoxes.Count; i++)
                {
                    HitBox hbox = RunTime._hitBoxes[i];
                    if (hbox.HitboxID == e[0] && hbox.IsCatch())
                    {
                        RunTime._hitBoxes.RemoveAt(i--);
                        break;
                    }
                }
                break;

            case 0x061B0500:     //Move hitbox
                foreach (HitBox hbox in RunTime._hitBoxes)
                {
                    if (hbox.HitboxID == e[0] && hbox.IsOffensive(true))
                    {
                        hbox._parameters[1] = e[1];
                        hbox._parameters[6] = e[2];
                        hbox._parameters[7] = e[3];
                        hbox._parameters[8] = e[4];
                        break;
                    }
                }
                break;

            case 0x04060100:     //Set animation frame
                //if (Article == null)
                //    RunTime.SetFrame((int)(e[0].RealValue + 0.05f));
                //else
                //    RunTime._articles[Article.Index].SetFrame((int)(e[0].RealValue + 0.05f));
                break;

            case 0x00070100:     //Subroutine
                script = (e[0] as EventOffset)._script;
                if (script != null && script != _script)
                {
                    script.Reset();
                    RunTime._runningScripts.Add(script);
                    script.SetFrame(0);
                }
                break;

            case 0x00080000:     //Return
                _return     = true;
                _eventIndex = Count;
                if (RunTime._runningScripts.Contains(_script))
                {
                    RunTime._runningScripts.Remove(_script);
                }
                break;

            case 0x00090100:     //Go to
                script = (e[0] as EventOffset)._script;
                if (script != null && script != _script)
                {
                    RunTime._runningScripts.Remove(_script);
                    script.Reset();
                    RunTime._runningScripts.Add(script);
                    script.SetFrame(0);
                }
                break;

            case 0x0A030100:     //Stop sound
                id = e[0];
                if (RunTime._playingSounds.ContainsKey(id))
                {
                    List <AudioInfo> aList = RunTime._playingSounds[id];
                    foreach (AudioInfo aInfo in aList)
                    {
                        if (aInfo._buffer != null)
                        {
                            aInfo._buffer.Stop();
                            aInfo._buffer.Dispose();
                            aInfo._stream.Dispose();
                        }
                    }
                    RunTime._playingSounds.Remove(id);
                }
                break;

            case 0x0A000100:     //Play sound
            case 0x0A010100:
            case 0x0A020100:
            case 0x0A040100:
            case 0x0A050100:
            case 0x0A060100:
            case 0x0A070100:
            case 0x0A080100:
            case 0x0A090100:
            case 0x0A0A0100:
            case 0x0A0B0100:
            case 0x0A0C0100:
            case 0x0A0D0100:
            case 0x0A0E0100:
            case 0x0A0F0100:

                if (RunTime._muteSFX)
                {
                    break;
                }

                if (Manager.SoundArchive != null)
                {
                    RSARNode             node   = Manager.SoundArchive;
                    List <RSAREntryNode> sounds = node._infoCache[0];

                    id = e[0];
                    if (sounds != null && id >= 0 && id < sounds.Count)
                    {
                        RSARSoundNode s = sounds[id] as RSARSoundNode;
                        if (s != null)
                        {
                            IAudioStream stream = s.CreateStreams()[0];
                            AudioBuffer  b      = Manager._audioProvider.CreateBuffer(stream);
                            AudioInfo    info   = new AudioInfo(b, stream);

                            if (RunTime._playingSounds.ContainsKey(id))
                            {
                                RunTime._playingSounds[id].Add(info);
                            }
                            else
                            {
                                RunTime._playingSounds[id] = new List <AudioInfo>()
                                {
                                    info
                                }
                            };

                            b.Reset();
                            b.Seek(0);
                            b.Play();
                        }
                    }
                }
                break;

            case 0x0B000200:     //Model Changer 1
            case 0x0B010200:     //Model Changer 2

                ModelVisibility visNode = null;
                if (Article != null)
                {
                    //Check if we have data to work with
                    articleInfo = RunTime._articles[Article.Index];

                    if (articleInfo == null ||
                        articleInfo._model == null ||
                        articleInfo._model._objList == null ||
                        articleInfo._article._mdlVis == null ||
                        articleInfo._article._mdlVis.Count == 0)
                    {
                        break;
                    }

                    visNode = articleInfo._article._mdlVis;
                }
                else
                {
                    //Check if we have data to work with
                    if (Root.Model == null ||
                        Root.Model._objList == null ||
                        Root.Data._modelVis.Count == 0)
                    {
                        break;
                    }

                    visNode = Root.Data._modelVis;
                }
                if (visNode != null)
                {
                    int refId    = ((int)((eventId >> 16) & 0xFF));
                    int switchId = e[0];
                    int groupId  = e[1];
                    visNode.ApplyVisibility(refId, switchId, groupId);
                }
                break;

            case 0x0B020100:     //Model visibility
                if (Article == null)
                {
                    Root.Model.IsRendering = e[0] != 0;
                }
                else if (Article.Index < RunTime._articles.Length && RunTime._articles[Article.Index]._model != null)
                {
                    RunTime._articles[Article.Index]._model.IsRendering = e[0] != 0;
                }
                break;

            case 0x0D000200:     //Concurrent Infinite Loop
                index = e[0];
                EventOffset off = (e[1] as EventOffset);
                if (off._script != null)
                {
                    if (RunTime._concurrentLoopScripts.ContainsKey(index))
                    {
                        RunTime._concurrentLoopScripts.Remove(index);
                    }
                    RunTime._concurrentLoopScripts.Add(index, off._script);
                }
                break;

            case 0x0D010100:     //Terminate Concurrent Infinite Loop
                index = e[0];
                if (RunTime._concurrentLoopScripts.ContainsKey(index))
                {
                    RunTime._concurrentLoopScripts.Remove(index);
                }
                break;

            case 0x0E000100:     //Set Air/Ground
                RunTime._location = (RunTime.Location)((int)e[0]);
                break;

            case 0x10000100:     //Generate Article
            case 0x10000200:     //Generate Article
            case 0x10030100:     //Remove Article

                //These events do a similar job!
                bool removeArticle = eID == 3;

                //Make sure we have all the data we need available
                MainControl main  = MainForm.Instance._mainControl;
                MovesetNode mNode = Manager.Moveset;
                if (mNode == null)
                {
                    break;
                }
                DataSection d = mNode.Data;
                if (d == null)
                {
                    break;
                }

                //Get the id of the article to be called and check it
                int aId2 = e[0];
                if (aId2 < 0 || aId2 >= RunTime._articles.Length)
                {
                    break;
                }

                //Get the called article from the article list
                articleInfo = RunTime._articles[aId2];

                if (articleInfo == null)
                {
                    return;
                }

                articleInfo.Running = !removeArticle;

                break;

            case 0x10040200:     //Set Anchored Article SubAction
            case 0x10070200:     //Set Remote Article SubAction
                id = e[0];
                int sId = e[1];
                if (id < 0 || id >= RunTime._articles.Length)
                {
                    break;
                }

                //Get the called article from the article list
                articleInfo = RunTime._articles[id];
                if (articleInfo != null)
                {
                    articleInfo.SubactionIndex = sId;
                    articleInfo._setAt         = _frameIndex;
                }
                break;

            case 0x10010200:     //Set Ex-Anchored Article Action
                break;

            case 0x12000200:     //Basic Var Set
            case 0x12060200:     //Float Var Set
                e[1].RealValue = e[0].RealValue;
                break;

            case 0x12010200:     //Basic Var Add
            case 0x12070200:     //Float Var Add
                e[1].RealValue = e[1].RealValue + e[0].RealValue;
                break;

            case 0x12020200:     //Basic Var Sub
            case 0x12080200:     //Float Var Sub
                e[1].RealValue = e[1].RealValue - e[0].RealValue;
                break;

            case 0x12030100:     //Basic Var Inc
                e[0].RealValue = e[0].RealValue + 1.0f;
                break;

            case 0x12040100:     //Basic Var Dec
                e[0].RealValue = e[0].RealValue - 1.0f;
                break;

            case 0x120A0100:     //Bit Variable Set
                e[0].RealValue = 1.0f;
                break;

            case 0x120B0100:     //Bit Variable Clear
                e[0].RealValue = 0.0f;
                break;

            case 0x120F0200:     //Float Variable Multiply
                e[1].RealValue = e[1].RealValue * e[0].RealValue;
                break;

            case 0x12100200:     //Float Variable Divide
                if (e[0].RealValue != 0)
                {
                    e[1].RealValue = e[1].RealValue / e[0].RealValue;
                }
                break;

            case 0x64000000:     //Allow Interrupt
                RunTime._allowInterrupt = true;
                break;

            case 0x02000300:     //Change Action Status
            case 0x02000400:
            case 0x02000500:
            case 0x02000600:

                break;

            case 0x02010200:     //Change Action
            case 0x02010300:
            case 0x02010400:
            case 0x02010500:
                aChangeInfo = new ActionChangeInfo(e[0]);
                reqInfo     = new RequirementInfo(e[1]);
                for (int i = 2; i < Count; i++)
                {
                    reqInfo._values.Add(e[i]);
                }
                aChangeInfo._requirements.Add(reqInfo);
                RunTime.AddActionChangeInfo(aChangeInfo);
                break;

            case 0x02040100:     //Additional Change Action Requirement
            case 0x02040200:
            case 0x02040300:
            case 0x02040400:

                break;

            case 0x02060100:     //Enable Action Status ID
                break;

            case 0x02080100:     //Disable Action Status ID
                break;

            case 0x02090200:     //Invert Action Status ID
                break;

            case 0x020A0100:     //Allow Specific Interrupt
                break;

            case 0x020B0100:     //Disallow Specific Interrupt
                break;

            case 0x020C0100:     //Unregister Interrupt
                break;

            case 0x04000100:     //Change Subaction
            case 0x04000200:
                sChangeInfo = new SubActionChangeInfo(e[0], eCount == 2 && e[1] != 0);
                RunTime.AddSubActionChangeInfo(sChangeInfo);
                break;

            case 0x04010200:     //Change Subaction
                sChangeInfo = new SubActionChangeInfo(e[0], false);
                sChangeInfo._requirements.Add(new RequirementInfo(e[1]));
                RunTime.AddSubActionChangeInfo(sChangeInfo);
                break;

            case 0x11010A00:     //External Graphic Effect
            case 0x11001000:     //Same as prev but with random offset and rotation
                bool random = ((eventId >> 16) & 0xFF) == 0;

                break;

            case 0x111A1000:     //Graphic Effect; no file

                break;
            }
        }
示例#14
0
        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);
        }
        public void FlipY(bool allowBoundaryFix)
        {
            MDL0Node model             = ((MDL0Node)_resource);
            bool     boundaryFixActive = false;

            if (allowBoundaryFix)
            {
                if (model.Name == "StgPosition" || model.Name == "Stgposition" || model.Name == "stgPosition" || model.Name == "stgposition" || model.Name == "StagePosition" || model.Name == "Stageposition" || model.Name == "stagePosition" || model.Name == "stageposition")
                {
                    boundaryFixActive = true;
                }
                else if (model.Name.Length == 13)
                {
                    //Console.WriteLine(model + " was found to be 13 characters long");
                    if (model.Name.Substring(0, 11) == "PokeTrainer" || model.Name.Substring(0, 11) == "Poketrainer" || model.Name.Substring(0, 11) == "pokeTrainer" || model.Name.Substring(0, 11) == "poketrainer")
                    {
                        //Console.WriteLine("It's a pokemon trainer");
                        boundaryFixActive = true;
                    }
                }
            }

            if (model.FindBoneByIndex(0) != null)
            {
                MDL0BoneNode b  = model.FindBoneByIndex(0);
                MDL0BoneNode b2 = null;
                int          j  = 0;
                float        camPositionSaverY   = 0;
                float        deathPositionSaverY = 0;
                bool         camPositionSaved    = false;
                bool         deathPositionSaved  = false;
                bool         camPositionSet      = false;
                bool         deathPositionSet    = false;

                bool isRestrictedName = false;

                while (b != null)
                {
                    j++;
                    if (boundaryFixActive)
                    {
                        //
                        if (b.Name == "CamLimit0N" && !camPositionSet)
                        {
                            isRestrictedName = true;
                            if (!camPositionSaved)
                            {
                                camPositionSaverY = b.getManualTranslation('Y');
                                camPositionSaved  = true;
                            }
                            else
                            {
                                b2 = model.FindBone("CamLimit1N");
                                if (b2 != null)
                                {
                                    float tempCam0 = b.getManualTranslation('Y');
                                    b.setManualTranslation('Y', 0 - camPositionSaverY);
                                    b2.setManualTranslation('Y', 0 - tempCam0);
                                    camPositionSet = true;
                                }
                            }
                        }
                        else if (b.Name == "CamLimit1N" && !camPositionSet)
                        {
                            isRestrictedName = true;
                            if (!camPositionSaved)
                            {
                                camPositionSaverY = b.getManualTranslation('Y');
                                camPositionSaved  = true;
                            }
                            else
                            {
                                b2 = model.FindBone("CamLimit0N");
                                if (b2 != null)
                                {
                                    float tempCam1 = b.getManualTranslation('Y');
                                    b.setManualTranslation('Y', 0 - camPositionSaverY);
                                    b2.setManualTranslation('Y', 0 - tempCam1);
                                    camPositionSet = true;
                                }
                            }
                        }
                        else if (b.Name == "Dead0N" && !deathPositionSet)
                        {
                            isRestrictedName = true;
                            if (!deathPositionSaved)
                            {
                                deathPositionSaverY = b.getManualTranslation('Y');
                                deathPositionSaved  = true;
                            }
                            else
                            {
                                b2 = model.FindBone("Dead1N");
                                if (b2 != null)
                                {
                                    float tempDead0 = b.getManualTranslation('Y');
                                    b.setManualTranslation('Y', 0 - deathPositionSaverY);
                                    b2.setManualTranslation('Y', 0 - tempDead0);
                                    deathPositionSet = true;
                                }
                            }
                        }
                        else if (b.Name == "Dead1N" && !deathPositionSet)
                        {
                            isRestrictedName = true;
                            if (!deathPositionSaved)
                            {
                                deathPositionSaverY = b.getManualTranslation('Y');
                                deathPositionSaved  = true;
                            }
                            else
                            {
                                b2 = model.FindBone("Dead0N");
                                if (b2 != null)
                                {
                                    float tempDead1 = b.getManualTranslation('Y');
                                    b.setManualTranslation('Y', 0 - deathPositionSaverY);
                                    b2.setManualTranslation('Y', 0 - tempDead1);
                                    deathPositionSet = true;
                                }
                            }
                        }
                        else if (b.Name.EndsWith("E"))
                        {
                            //Console.WriteLine("Found E Bone: " + b);
                            string b2Finder = b.Name.Remove(b.Name.Length - 1, 1) + "N";
                            //Console.WriteLine("Searching for " + b2Finder);
                            b2 = model.FindBone(b2Finder);
                            if (b2 != null)
                            {
                                //Console.WriteLine("Found! " + b2);
                                float tempE = b.getManualTranslation('Y');
                                float tempN = b2.getManualTranslation('Y');
                                b.setManualTranslation('Y', 0 - tempN);
                                b2.setManualTranslation('Y', 0 - tempE);
                                isRestrictedName = true;
                            }
                            else
                            {
                                isRestrictedName = false;
                            }
                        }
                        else if (b.Name.EndsWith("N"))
                        {
                            //Console.WriteLine("Found N Bone: " + b);
                            string b2Finder = b.Name.Remove(b.Name.Length - 1, 1) + "E";
                            //Console.WriteLine("Searching for " + b2Finder);
                            b2 = model.FindBone(b2Finder);
                            if (b2 != null)
                            {
                                //Console.WriteLine("Found! Will not regenerate as was set by " + b2);
                                isRestrictedName = true;
                            }
                            else
                            {
                                isRestrictedName = false;
                            }
                        }
                    }

                    if (!boundaryFixActive || !isRestrictedName)
                    {
                        b.setManualTranslation('Y', 0 - b.getManualTranslation('Y'));
                        b.setManualRotation('Z', 0 - b.getManualRotation('Z'));
                    }
                    b = model.FindBoneByIndex(j);
                    isRestrictedName = false;
                }
            }
        }
示例#16
0
        public void RenderBrawlStageData(ModelPanelViewport panel)
        {
            //If you ever make changes to GL attributes (enabled and disabled things)
            //and don't want to keep track of what you changed,
            //you can push all attributes and then pop them when you're done, like this.
            //This will make sure the GL state is back to how it was before you changed it.
            GL.PushAttrib(AttribMask.AllAttribBits);

            GL.Disable(EnableCap.DepthTest);

            if (RenderCollisions)
            {
                foreach (CollisionNode node in _collisions)
                {
                    node.Render();
                }
            }

            #region RenderOverlays

            List <MDL0BoneNode> ItemBones = new List <MDL0BoneNode>();

            MDL0Node stgPos = null;

            MDL0BoneNode CamBone0   = null,
                         CamBone1   = null,
                         DeathBone0 = null,
                         DeathBone1 = null;

            //Get bones and render spawns if checked
            if (_targetModel != null &&
                _targetModel is MDL0Node &&
                (((ResourceNode)_targetModel).Name.Contains("StgPosition") ||
                 ((ResourceNode)_targetModel).Name.Contains("stagePosition")))
            {
                stgPos = _targetModel as MDL0Node;
            }
            else if (_targetModels != null)
            {
                stgPos = _targetModels.Find(x => x is MDL0Node &&
                                            ((ResourceNode)x).Name.Contains("StgPosition") ||
                                            ((ResourceNode)x).Name.Contains("stagePosition")) as MDL0Node;
            }

            if (stgPos != null)
            {
                foreach (MDL0BoneNode bone in stgPos._linker.BoneCache)
                {
                    if (bone._name == "CamLimit0N")
                    {
                        CamBone0 = bone;
                    }
                    else if (bone.Name == "CamLimit1N")
                    {
                        CamBone1 = bone;
                    }
                    else if (bone.Name == "Dead0N")
                    {
                        DeathBone0 = bone;
                    }
                    else if (bone.Name == "Dead1N")
                    {
                        DeathBone1 = bone;
                    }
                    else if (bone._name.StartsWith("Player") && bone._name.Length == 8 && chkSpawns.Checked)
                    {
                        Vector3 position = bone._frameMatrix.GetPoint();
                        if (PointCollides(position))
                        {
                            GL.Color4(0.0f, 1.0f, 0.0f, 0.5f);
                        }
                        else
                        {
                            GL.Color4(1.0f, 0.0f, 0.0f, 0.5f);
                        }

                        TKContext.DrawSphere(position, 5.0f, 32);
                        if (int.TryParse(bone._name.Substring(6, 1), out int playernum))
                        {
                            panel.NoSettingsScreenText[playernum.ToString()] =
                                panel.Camera.Project(position) - new Vector3(8.0f, 8.0f, 0);
                        }
                    }
                    else if (bone._name.StartsWith("Rebirth") && bone._name.Length == 9 && chkSpawns.Checked)
                    {
                        GL.Color4(1.0f, 1.0f, 1.0f, 0.1f);
                        TKContext.DrawSphere(bone._frameMatrix.GetPoint(), 5.0f, 32);
                        if (int.TryParse(bone._name.Substring(7, 1), out int playernum))
                        {
                            panel.NoSettingsScreenText[playernum.ToString()] =
                                panel.Camera.Project(bone._frameMatrix.GetPoint()) - new Vector3(8.0f, 8.0f, 0);
                        }
                    }
                    else if (bone._name.StartsWith("Item"))
                    {
                        ItemBones.Add(bone);
                    }
                }
            }

            //Render item fields if checked
            if (ItemBones != null && chkItems.Checked)
            {
                GL.Color4(0.5f, 0.0f, 1.0f, 0.4f);
                for (int i = 0; i < ItemBones.Count; i += 2)
                {
                    Vector3 pos1, pos2;
                    if (ItemBones[i]._frameMatrix.GetPoint()._y == ItemBones[i + 1]._frameMatrix.GetPoint()._y)
                    {
                        pos1 = new Vector3(ItemBones[i]._frameMatrix.GetPoint()._x,
                                           ItemBones[i]._frameMatrix.GetPoint()._y + 1.5f, 1.0f);
                        pos2 = new Vector3(ItemBones[i + 1]._frameMatrix.GetPoint()._x,
                                           ItemBones[i + 1]._frameMatrix.GetPoint()._y - 1.5f, 1.0f);
                    }
                    else
                    {
                        pos1 = new Vector3(ItemBones[i]._frameMatrix.GetPoint()._x,
                                           ItemBones[i]._frameMatrix.GetPoint()._y, 1.0f);
                        pos2 = new Vector3(ItemBones[i + 1]._frameMatrix.GetPoint()._x,
                                           ItemBones[i + 1]._frameMatrix.GetPoint()._y, 1.0f);
                    }


                    if (pos1._x != pos2._x)
                    {
                        TKContext.DrawBox(pos1, pos2);
                    }
                    else
                    {
                        TKContext.DrawSphere(
                            new Vector3(ItemBones[i]._frameMatrix.GetPoint()._x,
                                        ItemBones[i]._frameMatrix.GetPoint()._y, pos1._z), 3.0f, 32);
                    }
                }
            }

            //Render boundaries if checked
            if (CamBone0 != null && CamBone1 != null && chkBoundaries.Checked)
            {
                //GL.Clear(ClearBufferMask.DepthBufferBit);
                GL.Disable(EnableCap.DepthTest);
                GL.Disable(EnableCap.Lighting);
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                GL.Enable(EnableCap.CullFace);
                GL.CullFace(CullFaceMode.Front);

                GL.Color4(Color.Blue);
                GL.Begin(BeginMode.LineLoop);
                GL.LineWidth(15.0f);

                Vector3
                    camBone0   = CamBone0._frameMatrix.GetPoint(),
                    camBone1   = CamBone1._frameMatrix.GetPoint(),
                    deathBone0 = DeathBone0._frameMatrix.GetPoint(),
                    deathBone1 = DeathBone1._frameMatrix.GetPoint();

                GL.Vertex2(camBone0._x, camBone0._y);
                GL.Vertex2(camBone1._x, camBone0._y);
                GL.Vertex2(camBone1._x, camBone1._y);
                GL.Vertex2(camBone0._x, camBone1._y);
                GL.End();
                GL.Begin(BeginMode.LineLoop);
                GL.Color4(Color.Red);
                GL.Vertex2(deathBone0._x, deathBone0._y);
                GL.Vertex2(deathBone1._x, deathBone0._y);
                GL.Vertex2(deathBone1._x, deathBone1._y);
                GL.Vertex2(deathBone0._x, deathBone1._y);
                GL.End();
                GL.Color4(0.0f, 0.5f, 1.0f, 0.3f);
                GL.Begin(BeginMode.TriangleFan);
                GL.Vertex2(camBone0._x, camBone0._y);
                GL.Vertex2(deathBone0._x, deathBone0._y);
                GL.Vertex2(deathBone1._x, deathBone0._y);
                GL.Vertex2(camBone1._x, camBone0._y);
                GL.End();
                GL.Begin(BeginMode.TriangleFan);
                GL.Vertex2(camBone1._x, camBone1._y);
                GL.Vertex2(deathBone1._x, deathBone1._y);
                GL.Vertex2(deathBone0._x, deathBone1._y);
                GL.Vertex2(camBone0._x, camBone1._y);
                GL.End();
                GL.Begin(BeginMode.TriangleFan);
                GL.Vertex2(camBone1._x, camBone0._y);
                GL.Vertex2(deathBone1._x, deathBone0._y);
                GL.Vertex2(deathBone1._x, deathBone1._y);
                GL.Vertex2(camBone1._x, camBone1._y);
                GL.End();
                GL.Begin(BeginMode.TriangleFan);
                GL.Vertex2(camBone0._x, camBone1._y);
                GL.Vertex2(deathBone0._x, deathBone1._y);
                GL.Vertex2(deathBone0._x, deathBone0._y);
                GL.Vertex2(camBone0._x, camBone0._y);
                GL.End();
            }

            #endregion

            GL.PopAttrib();
        }
示例#17
0
        static void Weight(PrimitiveManager manager, SkinEntry skin, DecoderShell shell, GeometryEntry geo, InfluenceManager iMan)
        {
            MDL0BoneNode[] boneList;
            MDL0BoneNode   bone = null;
            int            boneCount;

            string[]       jointStrings = null;
            byte *         pCmd         = stackalloc byte[4];
            int            cmdCount     = skin._weightInputs.Count;
            float          weight       = 0;
            float *        pWeights     = null;
            Vector3 *      pVert        = null;
            ushort *       pVInd        = (ushort *)manager._indices.Address;
            List <Vertex3> vertList     = new List <Vertex3>(skin._weightCount);

            manager._vertices = vertList;

            //Find vertex source
            foreach (SourceEntry s in geo._sources)
            {
                if (s._id == geo._verticesInput._source)
                {
                    pVert = (Vector3 *)((UnsafeBuffer)s._arrayData).Address;
                    break;
                }
            }

            //Find joint source
            foreach (InputEntry inp in skin._jointInputs)
            {
                if (inp._semantic == SemanticType.JOINT)
                {
                    foreach (SourceEntry src in skin._sources)
                    {
                        if (src._id == inp._source)
                        {
                            jointStrings = src._arrayData as string[];
                            break;
                        }
                    }
                    break;
                }
            }

            //Populate bone list
            boneCount = jointStrings.Length;
            boneList  = new MDL0BoneNode[boneCount];
            for (int i = 0; i < boneCount; i++)
            {
                boneList[i] = shell.FindNode(jointStrings[i])._node as MDL0BoneNode;
            }

            //Build command list
            foreach (InputEntry inp in skin._weightInputs)
            {
                switch (inp._semantic)
                {
                case SemanticType.JOINT:
                    pCmd[inp._offset] = 1;
                    break;

                case SemanticType.WEIGHT:
                    pCmd[inp._offset] = 2;

                    //Get weight source
                    foreach (SourceEntry src in skin._sources)
                    {
                        if (src._id == inp._source)
                        {
                            pWeights = (float *)((UnsafeBuffer)src._arrayData).Address;
                            break;
                        }
                    }

                    break;

                default:
                    pCmd[inp._offset] = 0;
                    break;
                }
            }

            //Construct Vertex from new weight
            for (int i = 0; i < skin._weightCount; i++)
            {
                //Create influence
                int       iCount = skin._weights.Length / cmdCount;
                Influence inf    = new Influence(iCount);
                fixed(int *p = skin._weights[i])
                {
                    int *iPtr = p;

                    for (int x = 0; x < iCount; x++)
                    {
                        for (int z = 0; z < cmdCount; z++, iPtr++)
                        {
                            if (pCmd[z] == 1)
                            {
                                bone = boneList[*iPtr];
                            }
                            else if (pCmd[z] == 2)
                            {
                                weight = pWeights[*iPtr];
                            }
                        }

                        inf._weights[x] = new BoneWeight(bone, weight);
                    }
                }

                //Match with manager
                inf = iMan.AddOrCreateInf(inf);

                //Create Vertex and look for match
                Vertex3 v     = new Vertex3(pVert[*pVInd], inf);
                int     index = 0;
                while (index < vertList.Count)
                {
                    if (v.Equals(vertList[i]))
                    {
                        break;
                    }
                    index++;
                }
                if (index == vertList.Count)
                {
                    vertList.Add(v);
                }

                //Assign new index
                *pVInd++ = (ushort)index;
            }
        }
示例#18
0
        private static unsafe void WriteControllers(MDL0Node model, XmlWriter writer)
        {
            if (model._polyList == null)
            {
                return;
            }

            writer.WriteStartElement("library_controllers");

            int g = 0;

            //List<MDL0BoneNode> boneSet = new List<MDL0BoneNode>();

            MDL0BoneNode[] bones = new MDL0BoneNode[model._linker.BoneCache.Length];
            model._linker.BoneCache.CopyTo(bones, 0);

            //foreach (MDL0BoneNode b in model._linker.BoneCache)
            //{
            //    b._nodeIndex = g++;
            //    boneSet.Add(b);
            //}

            List <float> weightSet = new List <float>();
            Matrix       m;
            bool         first;

            foreach (MDL0PolygonNode poly in model._polyList)
            {
                List <Vertex3> verts = poly._manager._vertices;

                writer.WriteStartElement("controller");
                writer.WriteAttributeString("id", poly.Name + "_Controller");
                writer.WriteStartElement("skin");
                writer.WriteAttributeString("source", "#" + poly.Name);

                writer.WriteStartElement("bind_shape_matrix");

                //Set bind pose matrix
                if (poly._singleBind != null)
                {
                    m = poly._singleBind.Matrix;
                }
                else
                {
                    m = Matrix.Identity;
                }

                float *fPtr = (float *)&m;

                first = true;
                for (int y = 0; y < 4; y++)
                {
                    for (int x = 0; x < 4; x++)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            writer.WriteString(" ");
                        }
                        writer.WriteValue(fPtr[(x << 2) + y]);
                    }
                }

                writer.WriteEndElement();

                //Get list of used bones and weights

                //int index = 0;
                if (poly._singleBind != null)
                {
                    foreach (BoneWeight w in poly._singleBind.Weights)
                    {
                        //if (!boneSet.Contains(w.Bone))
                        //{
                        //    boneSet.Add(w.Bone);
                        //    w.Bone._nodeIndex = index++;
                        //}
                        if (!weightSet.Contains(w.Weight))
                        {
                            weightSet.Add(w.Weight);
                        }
                    }
                }
                else
                {
                    foreach (Vertex3 v in verts)
                    {
                        foreach (BoneWeight w in v._influence.Weights)
                        {
                            //if (!boneSet.Contains(w.Bone))
                            //{
                            //    boneSet.Add(w.Bone);
                            //    w.Bone._nodeIndex = index++;
                            //}
                            if (!weightSet.Contains(w.Weight))
                            {
                                weightSet.Add(w.Weight);
                            }
                        }
                    }
                }

                //Write joint source
                writer.WriteStartElement("source");
                writer.WriteAttributeString("id", poly.Name + "_Joints");

                //Node array
                writer.WriteStartElement("Name_array");
                writer.WriteAttributeString("id", poly.Name + "_JointArr");
                //writer.WriteAttributeString("count", boneSet.Count.ToString());
                writer.WriteAttributeString("count", bones.Length.ToString());

                first = true;
                //foreach (MDL0BoneNode b in boneSet)
                foreach (MDL0BoneNode b in bones)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        writer.WriteString(" ");
                    }
                    writer.WriteString(b.Name);
                }
                writer.WriteEndElement(); //Name_array

                //Technique
                writer.WriteStartElement("technique_common");
                writer.WriteStartElement("accessor");
                writer.WriteAttributeString("source", String.Format("#{0}_JointArr", poly.Name));
                //writer.WriteAttributeString("count", boneSet.Count.ToString());
                writer.WriteAttributeString("count", bones.Length.ToString());
                writer.WriteStartElement("param");
                writer.WriteAttributeString("name", "JOINT");
                writer.WriteAttributeString("type", "Name");
                writer.WriteEndElement(); //param
                writer.WriteEndElement(); //accessor
                writer.WriteEndElement(); //technique

                writer.WriteEndElement(); //joint source

                //Inverse matrices source
                writer.WriteStartElement("source");
                writer.WriteAttributeString("id", poly.Name + "_Matrices");

                writer.WriteStartElement("float_array");
                writer.WriteAttributeString("id", poly.Name + "_MatArr");
                //writer.WriteAttributeString("count", (boneSet.Count * 16).ToString());
                writer.WriteAttributeString("count", (bones.Length * 16).ToString());
                first = true;
                //foreach (MDL0BoneNode b in boneSet)
                foreach (MDL0BoneNode b in bones)
                {
                    m    = b.InverseBindMatrix;
                    fPtr = (float *)&m;
                    for (int y = 0; y < 4; y++)
                    {
                        for (int x = 0; x < 4; x++)
                        {
                            if (first)
                            {
                                first = false;
                            }
                            else
                            {
                                writer.WriteString(" ");
                            }
                            writer.WriteValue(fPtr[(x << 2) + y]);
                        }
                    }
                }
                writer.WriteEndElement(); //float_array

                //Technique
                writer.WriteStartElement("technique_common");
                writer.WriteStartElement("accessor");
                writer.WriteAttributeString("source", String.Format("#{0}_MatArr", poly.Name));
                //writer.WriteAttributeString("count", boneSet.Count.ToString());
                writer.WriteAttributeString("count", bones.Length.ToString());
                writer.WriteAttributeString("stride", "16");
                writer.WriteStartElement("param");
                writer.WriteAttributeString("type", "float4x4");
                writer.WriteEndElement(); //param
                writer.WriteEndElement(); //accessor
                writer.WriteEndElement(); //technique

                writer.WriteEndElement(); //source

                //Weights source
                writer.WriteStartElement("source");
                writer.WriteAttributeString("id", poly.Name + "_Weights");

                writer.WriteStartElement("float_array");
                writer.WriteAttributeString("id", poly.Name + "_WeightArr");
                writer.WriteAttributeString("count", weightSet.Count.ToString());
                first = true;

                foreach (float f in weightSet)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        writer.WriteString(" ");
                    }
                    writer.WriteValue(f);
                }
                writer.WriteEndElement();

                //Technique
                writer.WriteStartElement("technique_common");
                writer.WriteStartElement("accessor");
                writer.WriteAttributeString("source", String.Format("#{0}_WeightArr", poly.Name));
                writer.WriteAttributeString("count", weightSet.Count.ToString());
                writer.WriteStartElement("param");
                writer.WriteAttributeString("type", "float");
                writer.WriteEndElement(); //param
                writer.WriteEndElement(); //accessor
                writer.WriteEndElement(); //technique

                writer.WriteEndElement(); //source

                //Joint bindings
                writer.WriteStartElement("joints");
                writer.WriteStartElement("input");
                writer.WriteAttributeString("semantic", "JOINT");
                writer.WriteAttributeString("source", String.Format("#{0}_Joints", poly.Name));
                writer.WriteEndElement(); //input
                writer.WriteStartElement("input");
                writer.WriteAttributeString("semantic", "INV_BIND_MATRIX");
                writer.WriteAttributeString("source", String.Format("#{0}_Matrices", poly.Name));
                writer.WriteEndElement(); //input
                writer.WriteEndElement(); //joints

                //Vertex weights, one for each vertex in geometry
                writer.WriteStartElement("vertex_weights");
                writer.WriteAttributeString("count", verts.Count.ToString());
                writer.WriteStartElement("input");
                writer.WriteAttributeString("semantic", "JOINT");
                writer.WriteAttributeString("offset", "0");
                writer.WriteAttributeString("source", String.Format("#{0}_Joints", poly.Name));
                writer.WriteEndElement(); //input
                writer.WriteStartElement("input");
                writer.WriteAttributeString("semantic", "WEIGHT");
                writer.WriteAttributeString("offset", "1");
                writer.WriteAttributeString("source", String.Format("#{0}_Weights", poly.Name));
                writer.WriteEndElement(); //input

                writer.WriteStartElement("vcount");
                first = true;
                if (poly._singleBind != null)
                {
                    for (int i = 0; i < verts.Count; i++)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            writer.WriteString(" ");
                        }
                        writer.WriteString(poly._singleBind.Weights.Length.ToString());
                    }
                }
                else
                {
                    foreach (Vertex3 v in verts)
                    {
                        if (first)
                        {
                            first = false;
                        }
                        else
                        {
                            writer.WriteString(" ");
                        }
                        writer.WriteString(v._influence.Weights.Length.ToString());
                    }
                }

                writer.WriteEndElement(); //vcount

                writer.WriteStartElement("v");

                first = true;
                if (poly._singleBind != null)
                {
                    for (int i = 0; i < verts.Count; i++)
                    {
                        foreach (BoneWeight w in poly._singleBind.Weights)
                        {
                            if (first)
                            {
                                first = false;
                            }
                            else
                            {
                                writer.WriteString(" ");
                            }
                            //writer.WriteString(w.Bone._nodeIndex.ToString());
                            writer.WriteString(Array.IndexOf(bones, w.Bone).ToString());
                            writer.WriteString(" ");
                            writer.WriteString(weightSet.IndexOf(w.Weight).ToString());
                        }
                    }
                }
                else
                {
                    foreach (Vertex3 v in verts)
                    {
                        foreach (BoneWeight w in v._influence.Weights)
                        {
                            if (first)
                            {
                                first = false;
                            }
                            else
                            {
                                writer.WriteString(" ");
                            }
                            //writer.WriteString(w.Bone._nodeIndex.ToString());
                            writer.WriteString(Array.IndexOf(bones, w.Bone).ToString());
                            writer.WriteString(" ");
                            writer.WriteString(weightSet.IndexOf(w.Weight).ToString());
                        }
                    }
                }

                writer.WriteEndElement(); //v

                writer.WriteEndElement(); //vertex_weights

                writer.WriteEndElement(); //skin
                writer.WriteEndElement(); //controller

                //boneSet.Clear();
                weightSet.Clear();
            }

            writer.WriteEndElement();
        }
示例#19
0
        static PrimitiveManager DecodePrimitivesWeighted(GeometryEntry geo, SkinEntry skin, SceneEntry scene, InfluenceManager infManager, ref string Error)
        {
            PrimitiveManager manager = DecodePrimitives(geo);

            MDL0BoneNode[] boneList;
            MDL0BoneNode   bone = null;
            int            boneCount;

            string[]       jointStrings = null;
            byte *         pCmd = stackalloc byte[4];
            int            cmdCount = skin._weightInputs.Count;
            float          weight = 0;
            float *        pWeights = null;
            Vector3 *      pVert = null, pNorms = null;
            ushort *       pVInd    = (ushort *)manager._indices.Address;
            List <Vertex3> vertList = new List <Vertex3>(skin._weightCount);
            Matrix *       pMatrix  = null;

            UnsafeBuffer remap  = new UnsafeBuffer(skin._weightCount * 2);
            ushort *     pRemap = (ushort *)remap.Address;

            pNorms = (Vector3 *)manager._faceData[1].Address;
            //List<int> FixedIndices = new List<int>();

            manager._vertices = vertList;

            //Find vertex source
            foreach (SourceEntry s in geo._sources)
            {
                if (s._id == geo._verticesInput._source)
                {
                    pVert = (Vector3 *)((UnsafeBuffer)s._arrayData).Address;
                    break;
                }
            }

            //Find joint source
            foreach (InputEntry inp in skin._jointInputs)
            {
                if (inp._semantic == SemanticType.JOINT)
                {
                    foreach (SourceEntry src in skin._sources)
                    {
                        if (src._id == inp._source)
                        {
                            jointStrings = src._arrayData as string[];
                            break;
                        }
                    }
                }
                else if (inp._semantic == SemanticType.INV_BIND_MATRIX)
                {
                    foreach (SourceEntry src in skin._sources)
                    {
                        if (src._id == inp._source)
                        {
                            pMatrix = (Matrix *)((UnsafeBuffer)src._arrayData).Address;
                            break;
                        }
                    }
                }
            }

            Error = "There was a problem creating the list of bones for geometry entry " + geo._name;

            //Populate bone list
            boneCount = jointStrings.Length;
            boneList  = new MDL0BoneNode[boneCount];
            for (int i = 0; i < boneCount; i++)
            {
                boneList[i] = scene.FindNode(jointStrings[i])._node as MDL0BoneNode;
            }

            //Build command list
            foreach (InputEntry inp in skin._weightInputs)
            {
                switch (inp._semantic)
                {
                case SemanticType.JOINT:
                    pCmd[inp._offset] = 1;
                    break;

                case SemanticType.WEIGHT:
                    pCmd[inp._offset] = 2;

                    //Get weight source
                    foreach (SourceEntry src in skin._sources)
                    {
                        if (src._id == inp._source)
                        {
                            pWeights = (float *)((UnsafeBuffer)src._arrayData).Address;
                            break;
                        }
                    }

                    break;

                default:
                    pCmd[inp._offset] = 0;
                    break;
                }
            }

            Error = "There was a problem creating vertex influences for geometry entry " + geo._name;

            //Build vertex list and remap table
            for (int i = 0; i < skin._weightCount; i++)
            {
                //Create influence
                int       iCount = skin._weights[i].Length / cmdCount;
                Influence inf    = new Influence(iCount);
                fixed(int *p = skin._weights[i])
                {
                    int *iPtr = p;

                    for (int x = 0; x < iCount; x++)
                    {
                        for (int z = 0; z < cmdCount; z++, iPtr++)
                        {
                            if (pCmd[z] == 1)
                            {
                                bone = boneList[*iPtr];
                            }
                            else if (pCmd[z] == 2)
                            {
                                weight = pWeights[*iPtr];
                            }
                        }
                        //if (bone != null)
                        //    if (bone.Name == "TopN" || bone.Name == "XRotN" || bone.Name == "YRotN" || bone.Name == "TransN" || bone.Name == "ThrowN" || bone.Name == "FacePattern")
                        //        Console.WriteLine(bone.Name);
                        //    else if (bone.Parent != null)
                        //        if (bone.Parent.Name == "FacePattern")
                        //            Console.WriteLine(bone.Name);
                        inf._weights[x] = new BoneWeight(bone, weight);
                    }
                }

                inf.CalcMatrix();

                Error = "There was a problem creating a vertex from the geometry entry " + geo._name + ".\nMake sure that all the vertices are weighted properly.";

                Vertex3 v;
                if (inf._weights.Length > 1)
                {
                    //Match with manager
                    inf = infManager.AddOrCreate(inf);
                    v   = new Vertex3(skin._bindMatrix * pVert[i], inf); //World position
                }
                else
                {
                    bone = inf._weights[0].Bone;
                    v    = new Vertex3(bone._inverseBindMatrix * skin._bindMatrix * pVert[i], bone); //Local position
                }

                ////Create Vertex, set to world position.
                //v = new Vertex3(skin._bindMatrix * pVert[i], inf);
                ////Fix single-bind vertices
                //v.Position = inf._weights[0].Bone._inverseBindMatrix * v.Position;

                ushort index = 0;
                while (index < vertList.Count)
                {
                    if (v.Equals(vertList[index]))
                    {
                        break;
                    }
                    index++;
                }
                if (index == vertList.Count)
                {
                    vertList.Add(v);
                }

                pRemap[i] = index;
            }

            Error = "There was a problem fixing normal rotations for geometry entry " + geo._name;

            //Remap vertex indices and fix normals
            for (int i = 0; i < manager._pointCount; i++, pVInd++)
            {
                *       pVInd = pRemap[*pVInd];
                Vertex3 v     = null;
                if (*pVInd < vertList.Count)
                {
                    v = vertList[*pVInd];
                }
                if (v != null && v._influence != null)
                {
                    if (v._influence.Weights.Length > 1)
                    {
                        pNorms[i] = skin._bindMatrix.GetRotationMatrix() * pNorms[i];
                    }
                    else
                    {
                        pNorms[i] = skin._bindMatrix.GetRotationMatrix() * v._influence.Weights[0].Bone._inverseBindMatrix.GetRotationMatrix() * pNorms[i];
                    }
                }
            }

            remap.Dispose();

            //manager.MergeTempData();
            return(manager);
        }
示例#20
0
        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);
            }
        }
示例#21
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());
        }
示例#22
0
 public Influence(MDL0BoneNode bone)
 {
     _weights = new BoneWeight[] { new BoneWeight(bone) };
 }
        public static void Serialize(CHR0Node node, bool bake, string output)
        {
            MDL0Node model;

            OpenFileDialog dlgOpen = new OpenFileDialog();

            dlgOpen.Filter = "MDL0 Model (*.mdl0)|*.mdl0";
            dlgOpen.Title  = "Select the model this animation is for...";

            if (dlgOpen.ShowDialog() != DialogResult.OK || (model = (MDL0Node)NodeFactory.FromFile(null, dlgOpen.FileName)) == null)
            {
                return;
            }

            using (StreamWriter file = new StreamWriter(output))
            {
                file.WriteLine("animVersion 1.1;");
                file.WriteLine("mayaVersion 2015;");
                file.WriteLine("timeUnit ntsc;");
                file.WriteLine("linearUnit cm;");
                file.WriteLine("angularUnit deg;");
                file.WriteLine("startTime 1;");
                file.WriteLine(String.Format("endTime {0};", node.FrameCount));
                foreach (CHR0EntryNode e in node.Children)
                {
                    MDL0BoneNode bone = model.FindChild("Bones/" + e.Name, true) as MDL0BoneNode;
                    if (bone == null)
                    {
                        continue;
                    }

                    KeyframeCollection c = e.Keyframes;
                    for (int index = 0; index < 9; index++)
                    {
                        KeyframeArray array = c._keyArrays[index];

                        if (array._keyCount <= 0)
                        {
                            continue;
                        }

                        file.WriteLine(String.Format("anim {0}.{0}{1} {0}{1} {2} {3} {4} {5}", types[index / 3], axes[index % 3], e.Name, 0, bone.Children.Count, index < 6 ? (index + 3) : index - 6));
                        file.WriteLine("animData {");
                        file.WriteLine("  input time;");
                        file.WriteLine(String.Format("  output {0};", index > 2 && index < 6 ? "angular" : "linear"));
                        file.WriteLine("  weighted 0;");
                        file.WriteLine("  preInfinity constant;");
                        file.WriteLine("  postInfinity constant;");
                        file.WriteLine("  keys {");
                        for (KeyframeEntry entry = array._keyRoot._next; (entry != array._keyRoot); entry = entry._next)
                        {
                            bool single = entry._next._index < 0 && entry._prev._index < 0;
                            //float angle = (float)Math.Atan(entry._tangent) * Maths._rad2degf;
                            //if (single)
                            {
                                file.WriteLine(String.Format("    {0} {1} {2} {2} {3} {4} {5};",
                                                             entry._index + 1,
                                                             entry._value.ToString(CultureInfo.InvariantCulture.NumberFormat),
                                                             "auto",//single ? "auto" : "fixed",
                                                             "1",
                                                             "1",
                                                             "0"));
                            }
                        }
                        file.WriteLine("  }");
                        file.WriteLine("}");
                    }
                }
            }
        }
示例#24
0
 public BoneWeight(MDL0BoneNode bone) : this(bone, 1.0f)
 {
 }
示例#25
0
        //Gets world-point of specified mouse point projected onto the selected bone's local space.
        //Intersects the projected ray with the appropriate plane using the snap flags.
        private bool GetOrbPoint(Vector2 mousePoint, out Vector3 point)
        {
            MDL0BoneNode bone = SelectedBone;

            if (bone == null)
            {
                point = new Vector3();
                return(false);
            }
            Vector3 lineStart = ModelPanel.UnProject(mousePoint._x, mousePoint._y, 0.0f);
            Vector3 lineEnd   = ModelPanel.UnProject(mousePoint._x, mousePoint._y, 1.0f);
            Vector3 center    = bone._frameMatrix.GetPoint();
            Vector3 camera    = ModelPanel._camera.GetPoint();
            Vector3 normal    = new Vector3();
            float   radius    = center.TrueDistance(camera) / _orbRadius * 0.1f;

            switch (_editType)
            {
            case TransformType.Rotation:

                if (_snapX)
                {
                    normal = (bone._frameMatrix * new Vector3(1.0f, 0.0f, 0.0f)).Normalize(center);
                }
                else if (_snapY)
                {
                    normal = (bone._frameMatrix * new Vector3(0.0f, 1.0f, 0.0f)).Normalize(center);
                }
                else if (_snapZ)
                {
                    normal = (bone._frameMatrix * new Vector3(0.0f, 0.0f, 1.0f)).Normalize(center);
                }
                else if (_snapCirc)
                {
                    radius *= _circOrbScale;
                    normal  = camera.Normalize(center);
                }
                else if (Maths.LineSphereIntersect(lineStart, lineEnd, center, radius, out point))
                {
                    return(true);
                }
                else
                {
                    normal = camera.Normalize(center);
                }

                if (Maths.LinePlaneIntersect(lineStart, lineEnd, center, normal, out point))
                {
                    point = Maths.PointAtLineDistance(center, point, radius);
                    return(true);
                }

                break;

            case TransformType.Translation:
            case TransformType.Scale:

                if (_snapX && _snapY)
                {
                    normal = new Vector3(0.0f, 0.0f, 1.0f);
                }
                else if (_snapX && _snapZ)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }
                else if (_snapY && _snapZ)
                {
                    normal = new Vector3(1.0f, 0.0f, 0.0f);
                }
                else if (_snapX)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }
                else if (_snapY)
                {
                    normal = new Vector3(1.0f, 0.0f, 0.0f);
                }
                else if (_snapZ)
                {
                    normal = new Vector3(0.0f, 1.0f, 0.0f);
                }
                else if (_editType == TransformType.Scale && _snapX && _snapY && _snapZ)
                {
                    normal = camera.Normalize(center);
                }

                break;
            }

            return(Maths.LinePlaneIntersect(lineStart, lineEnd, center, normal, out point));
        }
示例#26
0
 public BoneWeight(MDL0BoneNode bone, float weight)
 {
     Bone = bone; Weight = weight;
 }
示例#27
0
        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);
                        }
                    }
                }
            }
        }
示例#28
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));
        }
示例#29
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
                    }
                }
            }
        }
示例#30
0
        private static void WriteDefs(ModelLinker linker, ref byte *pGroup, ref byte *pData)
        {
            MDL0Node mdl = linker.Model;

            //This should never happen!
            if (!mdl._hasMix && !mdl._hasOpa && !mdl._hasTree && !mdl._hasXlu)
            {
                return;
            }

            ResourceNode[] polyList = null;
            if (mdl._objList != null)
            {
                polyList = new ResourceNode[mdl._objList.Count];
                Array.Copy(mdl._objList.ToArray(), polyList, mdl._objList.Count);
            }
            DrawCall drawCall;
            int      entryCount = 0;
            byte *   floor      = pData;
            int      dataLen;

            ResourceGroup *group = linker.Defs = (ResourceGroup *)pGroup;
            ResourceEntry *entry = &group->_first + 1;

            //NodeTree
            if (mdl._hasTree)
            {
                //Write group entry
                entry[entryCount++]._dataOffset = (int)(pData - pGroup);

                int bCount = linker.BoneCache.Length;
                for (int i = 0; i < bCount; i++)
                {
                    MDL0BoneNode bone = linker.BoneCache[i] as MDL0BoneNode;

                    *pData = 2; //Entry tag
                    *(bushort *)(pData + 1) = (ushort)bone._entryIndex;
                    *(bushort *)(pData + 3) = (ushort)(bone._parent is MDL0BoneNode ? ((MDL0BoneNode)bone._parent)._nodeIndex : 0);
                    pData += 5; //Advance
                }

                *pData++ = 1; //Terminate
            }

            //NodeMix
            //Only weight references go here.
            //First list bones used by weight groups, in bone order
            //Then list weight groups that use bones. Ordered by entry count.
            if (mdl._hasMix)
            {
                //Write group entry
                entry[entryCount++]._dataOffset = (int)(pData - pGroup);

                //Add bones first (using flat bone list)
                foreach (MDL0BoneNode b in linker.BoneCache)
                {
                    if (b._weightCount > 0)
                    {
                        *pData = 5; //Tag
                        *(bushort *)(pData + 1) = (ushort)b._nodeIndex;
                        *(bushort *)(pData + 3) = (ushort)b._entryIndex;
                        pData += 5; //Advance
                    }
                }

                //Add weight groups (using sorted influence list)
                foreach (Influence i in mdl._influences._influences)
                {
                    *pData++ = 3; //Tag
                    *(bushort *)pData = (ushort)i._index;
                    pData            += 2;

                    byte *countAddr = pData++;
                    byte  count     = 0;
                    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)
                        {
                            continue;
                        }

                        *(bushort *)pData      = (ushort)bone._nodeIndex;
                        *(bfloat *)(pData + 2) = w.Weight;
                        pData += 6; //Advance

                        if (linker.NodeCache[bone._nodeIndex] is MDL0BoneNode)
                        {
                            count++;
                        }
                    }
                    *countAddr = count;
                }

                *pData++ = 1; //Terminate
            }

            //DrawOpa
            if (mdl._hasOpa && polyList != null)
            {
                var objects = polyList.
                              SelectMany(x => ((MDL0ObjectNode)x)._drawCalls).
                              Where(x => x.DrawPass == DrawCall.DrawPassType.Opaque).
                              ToArray();

                Array.Sort(objects, DrawCall.DrawCompare);

                //Write group entry
                entry[entryCount++]._dataOffset = (int)(pData - pGroup);

                for (int i = 0; i < objects.Length; i++)
                {
                    drawCall = objects[i];

                    *pData = 4; //Tag
                    *(bushort *)(pData + 1) = (ushort)drawCall.MaterialNode._entryIndex;
                    *(bushort *)(pData + 3) = (ushort)drawCall._parentObject._entryIndex;
                    *(bushort *)(pData + 5) = (ushort)(drawCall.VisibilityBoneNode != null ? drawCall.VisibilityBoneNode.BoneIndex : 0);
                    pData[7] = drawCall.DrawPriority;
                    pData   += 8; //Advance
                }

                *pData++ = 1; //Terminate
            }

            //DrawXlu
            if (mdl._hasXlu && polyList != null)
            {
                var objects = polyList.
                              SelectMany(x => ((MDL0ObjectNode)x)._drawCalls).
                              Where(x => x.DrawPass == DrawCall.DrawPassType.Transparent).
                              ToArray();

                Array.Sort(objects, DrawCall.DrawCompare);

                //Write group entry
                entry[entryCount++]._dataOffset = (int)(pData - pGroup);

                for (int i = 0; i < objects.Length; i++)
                {
                    drawCall = objects[i];

                    *pData = 4; //Tag
                    *(bushort *)(pData + 1) = (ushort)drawCall.MaterialNode._entryIndex;
                    *(bushort *)(pData + 3) = (ushort)drawCall._parentObject._entryIndex;
                    *(bushort *)(pData + 5) = (ushort)(drawCall.VisibilityBoneNode != null ? drawCall.VisibilityBoneNode.BoneIndex : 0);
                    pData[7] = drawCall.DrawPriority;
                    pData   += 8; //Advance
                }

                *pData++ = 1; //Terminate
            }

            //Align data
            dataLen = (int)(pData - floor);
            while ((dataLen++ & 3) != 0)
            {
                *pData++ = 0;
            }

            //Set header
            *group = new ResourceGroup(entryCount);

            //Advance group poiner
            pGroup += group->_totalSize;
        }