Пример #1
0
        private void ModelComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (isLocked)
            {
                return;
            }
            if (datafile.replacedModels.Count == 0)
            {
                return;
            }
            Polymodel model    = datafile.replacedModels[ElementNumber];
            ComboBox  comboBox = (ComboBox)sender;

            switch (comboBox.Tag)
            {
            case "1":
                model.SimplerModels = (byte)comboBox.SelectedIndex;
                break;

            case "2":
                model.DyingModelnum = comboBox.SelectedIndex - 1;
                break;

            case "3":
                model.DeadModelnum = comboBox.SelectedIndex - 1;
                break;
            }
        }
Пример #2
0
        private void FindPackButton_Click(object sender, EventArgs e)
        {
            if (datafile.replacedModels.Count == 0)
            {
                return;
            }
            Polymodel model = datafile.replacedModels[ElementNumber];
            //Okay, the logic here is that we can pack new object bitmaps past 422.
            //So long as you aren't using more than 178 entirely new textures, this
            //should work fairly well.
            //TODO: Needs to consider additional ObjBitmaps introduced by a V-HAM, perhaps
            int bestFit = VHAMFile.N_D2_OBJBITMAPS;
            int testTextures;

            foreach (Polymodel testModel in datafile.replacedModels)
            {
                testTextures = testModel.BaseTexture + datafile.CountUniqueObjBitmaps(testModel);
                if (bestFit < testTextures)
                {
                    bestFit = testTextures;
                }
            }
            if (bestFit >= 600)
            {
                bestFit = 0;
                MessageBox.Show("Cannot find a open slot beyond 422.");
            }
            model.BaseTexture             = bestFit;
            isLocked                      = true;
            ModelBaseTextureSpinner.Value = bestFit;
            isLocked                      = false;
        }
Пример #3
0
        private void ImportModel(Polymodel original)
        {
            int oldNumTextures = original.NumTextures;

            List <string> newTextureNames = new List <string>();

            openFileDialog1.Filter = "Parallax Object Files|*.pof";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string traceto = "";
                if (bool.Parse(StandardUI.options.GetOption("TraceModels", bool.FalseString)))
                {
                    string bareFilename = Path.GetFileName(openFileDialog1.FileName);
                    traceto = StandardUI.options.GetOption("TraceDir", ".") + Path.DirectorySeparatorChar + Path.ChangeExtension(bareFilename, "txt");
                }

                Polymodel model = POFReader.ReadPOFFile(openFileDialog1.FileName, traceto);
                model.ExpandSubmodels();
                //int numTextures = model.n_textures;
                //datafile.ReplaceModel(ElementNumber, model);
                datafile.replacedModels[ElementNumber] = model;
                model.replacementID = ReplacedElementComboBox.SelectedIndex;
                UpdateModelPanel(ElementNumber);
            }
        }
Пример #4
0
        private void UpdateModelPanel(int num)
        {
            Polymodel model = datafile.Models[num];

            txtModelNumModels.Text          = model.NumSubmodels.ToString();
            txtModelDataSize.Text           = model.ModelIDTASize.ToString();
            txtModelRadius.Text             = model.Radius.ToString();
            txtModelTextureCount.Text       = model.NumTextures.ToString();
            cbModelLowDetail.SelectedIndex  = model.SimplerModels;
            cbModelDyingModel.SelectedIndex = model.DyingModelnum + 1;
            cbModelDeadModel.SelectedIndex  = model.DeadModelnum + 1;

            txtModelMinX.Text = model.Mins.x.ToString();
            txtModelMinY.Text = model.Mins.y.ToString();
            txtModelMinZ.Text = model.Mins.z.ToString();
            txtModelMaxX.Text = model.Maxs.x.ToString();
            txtModelMaxY.Text = model.Maxs.y.ToString();
            txtModelMaxZ.Text = model.Maxs.z.ToString();

            txtElemName.Text = datafile.ModelNames[num];
            if (!noPMView)
            {
                Polymodel mainmodel = datafile.Models[(int)ElementSpinner.Value];
                modelRenderer.SetModel(mainmodel);
                glControl1.Invalidate();
            }
        }
Пример #5
0
        private void UpdateModelPanel(int num)
        {
            Polymodel model = datafile.replacedModels[(int)nudElementNum.Value];

            //Polymodel model = datafile.PolygonModels[num];
            txtModelNumModels.Text          = model.NumSubmodels.ToString();
            txtModelDataSize.Text           = model.ModelIDTASize.ToString();
            txtModelRadius.Text             = model.Radius.ToString();
            txtModelTextureCount.Text       = model.NumTextures.ToString();
            cbModelLowDetail.SelectedIndex  = model.SimplerModels;
            cbModelDyingModel.SelectedIndex = model.DyingModelnum + 1;
            cbModelDeadModel.SelectedIndex  = model.DeadModelnum + 1;

            /*txtModelMinX.Text = model.mins.x.ToString();
            *  txtModelMinY.Text = model.mins.y.ToString();
            *  txtModelMinZ.Text = model.mins.z.ToString();
            *  txtModelMaxX.Text = model.maxs.x.ToString();
            *  txtModelMaxY.Text = model.maxs.y.ToString();
            *  txtModelMaxZ.Text = model.maxs.z.ToString();
            *
            *  txtElemName.Text = datafile.ModelNames[num];*/
            //if (!noPMView)
            {
                modelRenderer.SetModel(model);
                glControl1.Invalidate();
            }

            UpdateModelTexturePanel(model);
        }
Пример #6
0
        public PolymodelPreviewer(Polymodel model, StandardUI host)
        {
            InitializeComponent();
            //moo
            this.glControl1           = new GLControl();
            this.glControl1.BackColor = System.Drawing.Color.Black;
            this.glControl1.Location  = new System.Drawing.Point(63, 12);
            this.glControl1.Name      = "glControl1";
            this.glControl1.Size      = new System.Drawing.Size(384, 384);
            this.glControl1.TabIndex  = 3;
            this.glControl1.VSync     = false;
            this.glControl1.Load     += new System.EventHandler(this.glControl1_Load);
            this.glControl1.Paint    += new System.Windows.Forms.PaintEventHandler(this.glControl1_Paint);
            glControl1.Anchor         = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;

            this.Controls.Add(glControl1);
            this.PerformLayout();

            this.model = model;
            if (this.model.IsAnimated)
            {
                numericUpDown1.Minimum = 0;
                numericUpDown1.Maximum = Robot.NumAnimationStates - 1;
            }
            else
            {
                numericUpDown1.Enabled = false;
                chkAnimation.Enabled   = false;
            }
            this.host     = host;
            this.renderer = new ModelRenderer(host.DefaultPigFile, host.DefaultPalette);
        }
Пример #7
0
        //---------------------------------------------------------------------
        // GENERIC FUNCTIONS
        //---------------------------------------------------------------------
        private void ReplacedElementComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (isLocked)
            {
                return;
            }
            switch (EditorTabs.SelectedIndex)
            {
            case 0:
            {
                if (datafile.ReplacedRobots.Count == 0)
                {
                    return;
                }
                Robot robot = datafile.ReplacedRobots[ElementNumber];
                robot.replacementID = ReplacedElementComboBox.SelectedIndex;
            }
            break;

            case 1:
            {
                if (datafile.ReplacedModels.Count == 0)
                {
                    return;
                }
                Polymodel model = datafile.ReplacedModels[ElementNumber];
                model.ReplacementID = ReplacedElementComboBox.SelectedIndex;
            }
            break;
            }
        }
Пример #8
0
        private void LoadAnimations(Robot robot, Polymodel model)
        {
            robot.NumGuns = (sbyte)model.NumGuns;
            for (int i = 0; i < 8; i++)
            {
                robot.GunPoints[i]    = model.GunPoints[i];
                robot.GunSubmodels[i] = (byte)model.GunSubmodels[i];
            }
            for (int m = 0; m < 9; m++)
            {
                for (int f = 0; f < 5; f++)
                {
                    robot.AnimStates[m, f].NumJoints = 0;
                    robot.AnimStates[m, f].Offset    = 0;
                }
            }
            if (!model.IsAnimated)
            {
                return;
            }
            int[] gunNums = new int[10];

            for (int i = 1; i < model.NumSubmodels; i++)
            {
                gunNums[i] = robot.NumGuns;
            }
            gunNums[0] = -1;

            for (int g = 0; g < robot.NumGuns; g++)
            {
                int m = robot.GunSubmodels[g];

                while (m != 0)
                {
                    gunNums[m] = g;
                    m          = model.Submodels[m].Parent;
                }
            }

            for (int g = 0; g < robot.NumGuns + 1; g++)
            {
                for (int state = 0; state < 5; state++)
                {
                    robot.AnimStates[g, state].NumJoints = 0;
                    robot.AnimStates[g, state].Offset    = (short)(Joints.Count + VHAMFile.NumDescent2Joints);

                    for (int m = 0; m < model.NumSubmodels; m++)
                    {
                        if (gunNums[m] == g)
                        {
                            JointPos joint = new JointPos();
                            joint.JointNum = (short)m;
                            joint.Angles   = model.AnimationMatrix[m, state];
                            Joints.Add(joint);
                            robot.AnimStates[g, state].NumJoints++;
                        }
                    }
                }
            }
        }
        public override bool Apply()
        {
            Polymodel changeModel = (Polymodel)target;

            changeModel.PartialCopy(model);
            return(true);
        }
Пример #10
0
        private void UpdateModelPanel(int num)
        {
            Polymodel model = datafile.Models[num];

            txtElemName.Text = model.Name;

            polymodelPanel.Update(model, num);
        }
Пример #11
0
        private void LoadShipGuns(Ship ship)
        {
            Polymodel models = Models[ship.ModelNum];

            for (int i = 0; i < 8; i++)
            {
                ship.GunPoints[i] = models.GunPoints[i];
            }
        }
Пример #12
0
        /// <summary>
        /// Transfers the gun information from a robot to a Polymodel instance.
        /// </summary>
        /// <param name="robot">The robot to read the guns from.</param>
        private void BuildModelAnimation(Robot robot)
        {
            if (robot.ModelNum == -1)
            {
                return;
            }
            Polymodel        model     = Models[robot.ModelNum];
            List <FixAngles> jointlist = new List <FixAngles>();

            model.NumGuns = robot.NumGuns;
            for (int i = 0; i < Polymodel.MaxGuns; i++)
            {
                model.GunPoints[i]    = robot.GunPoints[i];
                model.GunDirs[i]      = FixVector.FromRawValues(65536, 0, 0);
                model.GunSubmodels[i] = robot.GunSubmodels[i];
            }
            int[,] jointmapping = new int[10, 5];
            for (int m = 0; m < Polymodel.MaxSubmodels; m++)
            {
                for (int f = 0; f < Robot.NumAnimationStates; f++)
                {
                    jointmapping[m, f] = -1;
                }
            }
            int basejoint = 0;

            for (int m = 0; m < Polymodel.MaxGuns + 1; m++)
            {
                for (int f = 0; f < Robot.NumAnimationStates; f++)
                {
                    Robot.JointList robotjointlist = robot.AnimStates[m, f];
                    basejoint = robotjointlist.Offset;
                    for (int j = 0; j < robotjointlist.NumJoints; j++)
                    {
                        JointPos joint = Joints[basejoint];
                        jointmapping[joint.JointNum, f] = basejoint;
                        model.IsAnimated = true;
                        basejoint++;
                    }
                }
            }

            for (int m = 1; m < Polymodel.MaxSubmodels; m++)
            {
                for (int f = 0; f < Robot.NumAnimationStates; f++)
                {
                    int jointnum = jointmapping[m, f];
                    if (jointnum != -1)
                    {
                        JointPos joint = Joints[jointnum];
                        model.AnimationMatrix[m, f].P = joint.Angles.P;
                        model.AnimationMatrix[m, f].B = joint.Angles.B;
                        model.AnimationMatrix[m, f].H = joint.Angles.H;
                    }
                }
            }
        }
Пример #13
0
        private void LoadReactorGuns(Reactor reactor)
        {
            Polymodel model = Models[reactor.ModelNum];

            reactor.NumGuns = (byte)model.NumGuns;
            for (int i = 0; i < reactor.NumGuns; i++)
            {
                reactor.GunPoints[i] = model.GunPoints[i];
                reactor.GunDirs[i]   = model.GunDirs[i];
            }
        }
Пример #14
0
 private void RobotAnimationCheckbox_CheckedChanged(object sender, EventArgs e)
 {
     if (isLocked)
     {
         return;
     }
     if (robot.ModelNum < hxmFile.GetNumModels())
     {
         Polymodel model = hxmFile.GetModel(robot.ModelNum);
         model.isAnimated = RobotAnimationCheckbox.Checked;
     }
 }
Пример #15
0
        /// <summary>
        /// Transfers the gun information from the player ship to a Polymodel instance.
        /// </summary>
        /// <param name="ship">The ship to read the guns from.</param>
        private void BuildModelGunsFromShip(Ship ship)
        {
            Polymodel model = Models[ship.ModelNum];

            model.NumGuns = 8;
            for (int i = 0; i < 8; i++)
            {
                model.GunPoints[i]    = ship.GunPoints[i];
                model.GunDirs[i]      = FixVector.FromRawValues(65536, 0, 0);
                model.GunSubmodels[i] = 0;
            }
        }
        public List <int> LoadPolymodelTextures(Polymodel model, Palette palette, PIGFile pigFile)
        {
            List <int> textureIDs = new List <int>();
            Bitmap     image;

            foreach (string textureName in model.TextureList)
            {
                image = PiggyBitmapUtilities.GetBitmap(pigFile, palette, textureName);
                textureIDs.Add(LoadTexture(image));
            }

            return(textureIDs);
        }
Пример #17
0
        //---------------------------------------------------------------------
        // UTILITY FUNCTIONS
        //---------------------------------------------------------------------

        /// <summary>
        /// Counts the amount of textures present in a model that aren't present in the parent file.
        /// </summary>
        /// <param name="model">The model to count the textures of.</param>
        /// <returns>The number of unique textures not found in the parent file.</returns>
        public int CountUniqueObjBitmaps(Polymodel model)
        {
            int num = 0;

            foreach (string tex in model.TextureList)
            {
                if (!BaseHAM.ObjBitmapMapping.ContainsKey(tex))
                {
                    num++;
                }
            }
            return(num);
        }
Пример #18
0
        public void Update(Polymodel model, int id)
        {
            isLocked = true;
            txtModelNumModels.Text    = model.NumSubmodels.ToString();
            txtModelDataSize.Text     = model.ModelIDTASize.ToString();
            txtModelRadius.Text       = model.Radius.ToString();
            txtModelTextureCount.Text = model.NumTextures.ToString();
            UIUtil.SafeFillComboBox(cbModelLowDetail, model.SimplerModels);
            UIUtil.SafeFillComboBox(cbModelDyingModel, model.DyingModelnum + 1);
            UIUtil.SafeFillComboBox(cbModelDeadModel, model.DeadModelnum + 1);
            ModelNumSpinner.Minimum = -1;
            ModelNumSpinner.Value   = -1;
            ModelNumSpinner.Maximum = model.NumSubmodels - 1;

            txtModelMinX.Text = model.Mins.X.ToString();
            txtModelMinY.Text = model.Mins.Y.ToString();
            txtModelMinZ.Text = model.Mins.Z.ToString();
            txtModelMaxX.Text = model.Maxs.X.ToString();
            txtModelMaxY.Text = model.Maxs.Y.ToString();
            txtModelMaxZ.Text = model.Maxs.Z.ToString();

            if (hxmFile != null)
            {
                int numNewTextures = hxmFile.CountUniqueObjBitmaps(model);
                ModelNumTextures.Text         = numNewTextures.ToString();
                ModelNumPointers.Text         = model.NumTextures.ToString();
                ModelBasePointerSpinner.Value = model.FirstTexture;
                ModelBaseTextureSpinner.Value = model.BaseTexture;

                for (int i = 0; i < numNewTextures; i++)
                {
                    ushort index = hxmFile.GetObjBitmap(i + model.BaseTexture);
                    if (hxmFile.BaseHAM.piggyFile.Bitmaps[index].IsAnimated)
                    {
                        AnimatedWarningLabel.Visible = true;
                    }
                    else
                    {
                        AnimatedWarningLabel.Visible = false;
                    }
                }
            }

            modelRenderer.SetModel(model);
            ModelViewControl.Invalidate();

            modelID    = id;
            this.model = model;
            isLocked   = false;
        }
Пример #19
0
        private void ModelBasePointerSpinner_ValueChanged(object sender, EventArgs e)
        {
            if (isLocked)
            {
                return;
            }
            if (datafile.replacedModels.Count == 0)
            {
                return;
            }
            Polymodel model = datafile.replacedModels[ElementNumber];

            model.FirstTexture = (ushort)ModelBasePointerSpinner.Value;
        }
        public List <int> LoadPolymodelTexturesHack(Polymodel model, PIGFile pigFile)
        {
            List <int> textureIDs = new List <int>();
            Bitmap     image;

            image = (Bitmap)Image.FromFile("c:/dev/d2test/tex0.png");
            textureIDs.Add(LoadTexture(image));
            image.Dispose();
            image = (Bitmap)Image.FromFile("c:/dev/d2test/tex1.png");
            textureIDs.Add(LoadTexture(image));
            image.Dispose();

            return(textureIDs);
        }
Пример #21
0
        /// <summary>
        /// Transfers the gun information from a reactor to a Polymodel instance.
        /// </summary>
        /// <param name="reactor">The reactor to read the guns from.</param>
        private void BuildModelGunsFromReactor(Reactor reactor)
        {
            if (reactor.ModelNum == -1)
            {
                return;
            }
            Polymodel model = Models[reactor.ModelNum];

            model.NumGuns = reactor.NumGuns;
            for (int i = 0; i < 8; i++)
            {
                model.GunPoints[i]    = reactor.GunPoints[i];
                model.GunDirs[i]      = reactor.GunDirs[i];
                model.GunSubmodels[i] = 0;
            }
        }
Пример #22
0
        public void GenerateBSPTest() //note: this mostly just tests ATM that the code executes without error.
        //Proper results currently need to be visually validated with a tool like Descent 2 Workshop
        {
            Polymodel model = LibDescent.Data.POFReader.ReadPOFFile(TestUtils.GetResourceStream("NewConcussion.pof"));

            model.ExpandSubmodels();

            //Build the BSP tree
            PolymodelBuilder polymodelBuilder = new PolymodelBuilder();

            polymodelBuilder.RebuildModel(model);

            BinaryWriter bw = new BinaryWriter(File.Open("NewConcussionBSP.pof", FileMode.Create));

            //the POFWriter API needs some changes...
            POFWriter.SerializePolymodel(bw, model, 8);
            bw.Flush();
            bw.Close();
            bw.Dispose();
        }
Пример #23
0
        /// <summary>
        /// Looks through a model's textures, and finds the first ObjBitmap not present in the parent file.
        /// </summary>
        /// <param name="model">The model to check the textures of.</param>
        /// <returns>The index of the first new texture, or 0 if there are no new textures.</returns>
        public int FindFirstObjBitmap(Polymodel model)
        {
            int    num = int.MaxValue;
            string tex;

            for (int i = 0; i < model.NumTextures; i++)
            {
                tex = model.TextureList[i];
                if (!BaseHAM.ObjBitmapMapping.ContainsKey(tex))
                {
                    //This texture isn't present in the base file, so it's new. Figure out where it is
                    num = GetObjBitmapPointer(model.FirstTexture + i);
                }
            }
            if (num == int.MaxValue)
            {
                return(0);
            }
            return(num);
        }
Пример #24
0
        private void PartitionButton_Click(object sender, EventArgs e)
        {
            //Do in a copy to allow undo
            Polymodel        newModel = new Polymodel(model);
            PolymodelBuilder builder  = new PolymodelBuilder();

            try
            {
                builder.RebuildModel(newModel);
            }
            catch (ArgumentException exc)
            {
                MessageBox.Show(exc.Message, "Error partitioning model");
                return;
            }

            ModelReplaceTransaction transaction = new ModelReplaceTransaction("Load model", (object)model, newModel, modelID, tabPage);

            transactionManager.ApplyTransaction(transaction);
            Update(newModel, modelID);
        }
        public List <int> LoadPolymodelTextures(Polymodel model, PIGFile pigFile, Palette palette, EditorHAMFile hamFile)
        {
            List <int> textureIDs = new List <int>();
            Bitmap     image; EClip clip;

            foreach (string textureName in model.TextureList)
            {
                if (hamFile.EClipNameMapping.ContainsKey(textureName.ToLower()))
                {
                    clip  = hamFile.EClipNameMapping[textureName.ToLower()];
                    image = PiggyBitmapUtilities.GetBitmap(pigFile, palette, clip.Clip.Frames[0]);
                }
                else
                {
                    image = PiggyBitmapUtilities.GetBitmap(pigFile, palette, textureName);
                }
                textureIDs.Add(LoadTexture(image));
            }

            return(textureIDs);
        }
Пример #26
0
        private void btnImportModel_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string traceto = "";
                if (bool.Parse(StandardUI.options.GetOption("TraceModels", bool.FalseString)))
                {
                    string bareFilename = Path.GetFileName(openFileDialog1.FileName);
                    traceto = StandardUI.options.GetOption("TraceDir", ".") + Path.DirectorySeparatorChar + Path.ChangeExtension(bareFilename, "txt");
                }

                Stream    stream   = File.OpenRead(openFileDialog1.FileName);
                Polymodel newmodel = POFReader.ReadPOFFile(stream);
                stream.Close();
                stream.Dispose();
                newmodel.ExpandSubmodels();
                //datafile.ReplaceModel(ElementNumber, model);
                ModelReplaceTransaction transaction = new ModelReplaceTransaction("Load model", (object)model, newmodel, modelID, tabPage);
                transactionManager.ApplyTransaction(transaction);
                Update(model, modelID);
            }
        }
Пример #27
0
        private void UpdateModelTexturePanel(Polymodel model)
        {
            int numNewTextures = datafile.CountUniqueObjBitmaps(model);

            ModelNumTextures.Text         = numNewTextures.ToString();
            ModelNumPointers.Text         = model.NumTextures.ToString();
            ModelBasePointerSpinner.Value = model.FirstTexture;
            ModelBaseTextureSpinner.Value = model.BaseTexture;

            for (int i = 0; i < numNewTextures; i++)
            {
                ushort index = datafile.GetObjBitmap(i + model.BaseTexture);
                if (datafile.BaseHAM.piggyFile.Bitmaps[index].IsAnimated)
                {
                    AnimatedWarningLabel.Visible = true;
                }
                else
                {
                    AnimatedWarningLabel.Visible = false;
                }
            }
        }
 public ModelReplaceTransaction(string label, object target, Polymodel newModel, int page, int tab) : base(label, target, null, page, tab)
 {
     model = newModel;
     //Keep a backup of the old model, for undo purposes
     oldModel = new Polymodel((Polymodel)target);
 }
Пример #29
0
        private void BuildModelAnimation(Robot robot)
        {
            //this shouldn't happen?
            if (robot.ModelNum == -1)
            {
                return;
            }
            //If the robot is referring to a base HAM file model, reject it
            if (robot.ModelNum < VHAMFile.NumDescent2Polymodels)
            {
                return;
            }
            Polymodel        model     = Models[robot.ModelNum - VHAMFile.NumDescent2Polymodels];
            List <FixAngles> jointlist = new List <FixAngles>();

            model.NumGuns = robot.NumGuns;
            for (int i = 0; i < Polymodel.MaxGuns; i++)
            {
                model.GunPoints[i]    = robot.GunPoints[i];
                model.GunDirs[i]      = FixVector.FromRawValues(65536, 0, 0);
                model.GunSubmodels[i] = robot.GunSubmodels[i];
            }
            int[,] jointmapping = new int[10, 5];
            for (int m = 0; m < Polymodel.MaxSubmodels; m++)
            {
                for (int f = 0; f < Robot.NumAnimationStates; f++)
                {
                    jointmapping[m, f] = -1;
                }
            }
            int basejoint = 0;

            for (int m = 0; m < Polymodel.MaxGuns + 1; m++)
            {
                for (int f = 0; f < Robot.NumAnimationStates; f++)
                {
                    Robot.JointList robotjointlist = robot.AnimStates[m, f];
                    basejoint = robotjointlist.Offset;
                    for (int j = 0; j < robotjointlist.NumJoints; j++)
                    {
                        JointPos joint = GetJoint(basejoint);
                        jointmapping[joint.JointNum, f] = basejoint;
                        model.IsAnimated = true;
                        basejoint++;
                    }
                }
            }

            for (int m = 1; m < Polymodel.MaxSubmodels; m++)
            {
                for (int f = 0; f < Robot.NumAnimationStates; f++)
                {
                    int jointnum = jointmapping[m, f];
                    if (jointnum != -1)
                    {
                        JointPos joint = GetJoint(jointnum);
                        model.AnimationMatrix[m, f].P = joint.Angles.P;
                        model.AnimationMatrix[m, f].B = joint.Angles.B;
                        model.AnimationMatrix[m, f].H = joint.Angles.H;
                    }
                }
            }
        }
        public override void Revert()
        {
            Polymodel changeModel = (Polymodel)target;

            changeModel.PartialCopy(oldModel);
        }