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; } }
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; }
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); } }
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(); } }
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); }
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); }
//--------------------------------------------------------------------- // 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; } }
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); }
private void UpdateModelPanel(int num) { Polymodel model = datafile.Models[num]; txtElemName.Text = model.Name; polymodelPanel.Update(model, num); }
private void LoadShipGuns(Ship ship) { Polymodel models = Models[ship.ModelNum]; for (int i = 0; i < 8; i++) { ship.GunPoints[i] = models.GunPoints[i]; } }
/// <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; } } } }
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]; } }
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; } }
/// <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); }
//--------------------------------------------------------------------- // 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); }
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; }
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); }
/// <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; } }
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(); }
/// <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); }
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); }
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); } }
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); }
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); }