public static void Freeze(Model model, Matrix4 matrix) { foreach (ModelMesh mesh in model.Meshes) { Matrix4 o = mesh.Parent.Transform; Vector3 p = Vector3.Transform(o.ExtractTranslation(), matrix); Vector3 e = o.ExtractRotation().ToEuler(RotationOrder.OrderXYZ); o = Matrix4.CreateFromQuaternion( Quaternion.FromAxisAngle(OpenTK.Vector3.UnitX, MathHelper.DegreesToRadians(e.X)) * Quaternion.FromAxisAngle(OpenTK.Vector3.UnitZ, MathHelper.DegreesToRadians(-e.Y)) * Quaternion.FromAxisAngle(OpenTK.Vector3.UnitY, MathHelper.DegreesToRadians(-e.Z)) ); o.M41 = p.X; o.M42 = p.Y; o.M43 = p.Z; mesh.Parent.Transform = matrix; ModelManipulator.Freeze(mesh, FreezeComponents.Rotation); mesh.Parent.Transform = o; } }
public SceneManager(bool bUseVertexBuffer = true) { Current = this; content = new ContentManager(); bVertexBuffer = bUseVertexBuffer; node = new Entity { Name = "node", EntityType = EntityType.Bone, AssetType = AssetType.Model, Asset = new Model() }; var sphere = new Sphere(0.125f, 7, 7); ModelManipulator.SetVertexColour(sphere, 0, 255, 0, 255); ((Model)node.Asset).AddMesh(sphere); ((Model)node.Asset).SetRenderStyle(RenderStyle.Wireframe); entities.Add(node); InputManager.Current.RegisterBinding('d', KeyBinding.KeysClearSelection, ClearBoundingBox); InputManager.Current.RegisterBinding('w', KeyBinding.KeysRenderMode, CycleRenderMode); InputManager.Current.RegisterBinding('p', KeyBinding.KeysCoordinateSystem, ToggleCoordinateSystem); }
private void applyTransforms() { var bones = (chkHierarchy.Checked ? SceneManager.Current.Models[modelIndex].Bones[boneIndex].AllChildren() : new ModelBoneCollection { SceneManager.Current.Models[modelIndex].Bones[boneIndex] }); if (rdoScaling.Checked) { OpenTK.Matrix4 scaleMatrix = OpenTK.Matrix4.Identity; if (rdoScaleWholeModel.Checked) { scaleMatrix = OpenTK.Matrix4.CreateScale( txtScaleWholeModel.Text.ToSingle(), txtScaleWholeModel.Text.ToSingle(), txtScaleWholeModel.Text.ToSingle() ); } else if (rdoScaleByAxis.Checked) { scaleMatrix = OpenTK.Matrix4.CreateScale( txtScaleAxisX.Text.ToSingle(), txtScaleAxisY.Text.ToSingle(), txtScaleAxisZ.Text.ToSingle() ); } ModelManipulator.Scale(bones, scaleMatrix, chkHierarchy.Checked); } else if (rdoMunging.Checked) { if (rdoInvert.Checked) { ModelManipulator.FlipAxis(SceneManager.Current.Models[modelIndex].Bones[boneIndex].Mesh, cboInvertAxis.SelectedItem.ToString().ToEnum <Axis>(), chkHierarchy.Checked); } else if (rdoMeshBoneSwap.Checked) { ModelManipulator.MungeMeshWithBone(bones); } else if (rdoFlipWindingOrder.Checked) { ModelManipulator.FlipFaces(bones, chkHierarchy.Checked); } } }
private void menuCarmageddon2Click(object sender, EventArgs e) { ToolStripMenuItem mi = (ToolStripMenuItem)sender; SceneManager.Current.SetCoordinateSystem(SceneManager.CoordinateSystem.RightHanded); switch (mi.Text) { case "Actor": ofdBrowse.Filter = "Carmageddon 2 ACTOR (*.act)|*.act"; if (ofdBrowse.ShowDialog() == DialogResult.OK && File.Exists(ofdBrowse.FileName)) { SceneManager.Current.Content.Load <Model, ACTImporter>(Path.GetFileNameWithoutExtension(ofdBrowse.FileName), Path.GetDirectoryName(ofdBrowse.FileName), true); } break; case "Race": ofdBrowse.Filter = "Carmageddon 2 Race (*.act)|*.act"; if (ofdBrowse.ShowDialog() == DialogResult.OK && File.Exists(ofdBrowse.FileName)) { string txtFile = Path.Combine(Path.GetDirectoryName(ofdBrowse.FileName), Path.GetFileNameWithoutExtension(ofdBrowse.FileName) + ".txt"); Model race = SceneManager.Current.Content.Load <Model, ACTImporter>(Path.GetFileNameWithoutExtension(ofdBrowse.FileName), Path.GetDirectoryName(ofdBrowse.FileName), true); //if (File.Exists(txtFile)) { race.SupportingDocuments["TXT"] = ToxicRagers.Carmageddon2.Formats.Map.Load(txtFile); } SceneManager.Current.SetContext(ContextGame.Carmageddon_2, ContextMode.Level); } break; case "Process Level for Carmageddon Reincarnation": { if (SceneManager.Current.Models.Count == 0) { return; } var bones = SceneManager.Current.Models[0].Bones[0].AllChildren(); SceneManager.Current.UpdateProgress("Applying Carmageddon Reincarnation scale"); ModelManipulator.Scale(bones, Matrix4.CreateScale(6.9f, 6.9f, -6.9f), true); ModelManipulator.FlipFaces(bones, true); SceneManager.Current.UpdateProgress("Fixing material names"); foreach (var material in SceneManager.Current.Materials) { if (material.Name.Contains(".")) { material.Name = material.Name.Substring(0, material.Name.IndexOf(".")); } material.Name = material.Name.Replace("\\", ""); MATMaterial m = (material.SupportingDocuments["Source"] as MATMaterial); if (!m.HasTexture) { using (Bitmap bmp = new Bitmap(16, 16)) using (Graphics g = Graphics.FromImage(bmp)) { g.FillRectangle(new SolidBrush(Color.FromArgb(m.DiffuseColour[3], m.DiffuseColour[0], m.DiffuseColour[1], m.DiffuseColour[2])), 0, 0, 16, 16); Texture t = new Texture(); t.CreateFromBitmap(bmp, string.Format("{4}_R{0:x2}G{1:x2}B{2:x2}A{3:x2}", m.DiffuseColour[0], m.DiffuseColour[1], m.DiffuseColour[2], m.DiffuseColour[3], material.Name)); material.Texture = t; } } } SceneManager.Current.UpdateProgress("Processing powerups and accessories"); for (int i = bones.Count - 1; i >= 0; i--) { var bone = bones[i]; if (bone.Name.StartsWith("&")) { var entity = new Entity(); if (bone.Name.StartsWith("&£")) { string key = bone.Name.Substring(2, 2); entity.UniqueIdentifier = "errol_B00BIE" + key + "_" + i.ToString("000"); entity.EntityType = EntityType.Powerup; var pup = ToxicRagers.Carmageddon2.Powerups.LookupID(int.Parse(key)); if (pup.InCR) { entity.Name = "pup_" + pup.Name; entity.Tag = pup.Model; } else { entity.Name = "pup_Credits"; entity.Tag = pup.Model; } } else { // accessory entity.UniqueIdentifier = "errol_HEAD00" + bone.Name.Substring(1, 2) + "_" + i.ToString("000"); entity.EntityType = EntityType.Accessory; entity.Name = "C2_" + bone.Mesh.Name.Substring(3); } entity.Transform = bone.CombinedTransform; entity.AssetType = AssetType.Sprite; SceneManager.Current.Entities.Add(entity); SceneManager.Current.Models[0].RemoveBone(bone.Index); } } SceneManager.Current.UpdateProgress("Processing complete!"); SceneManager.Current.SetCoordinateSystem(SceneManager.CoordinateSystem.LeftHanded); SceneManager.Current.Change(ChangeType.Munge, -1); SceneManager.Current.SetContext(ContextGame.Carmageddon_Reincarnation, ContextMode.Level); } break; case "Process Car for Carmageddon Reincarnation": { if (SceneManager.Current.Models.Count == 0) { return; } var model = SceneManager.Current.Models[0]; var bones = SceneManager.Current.Models[0].Bones[0].AllChildren(); SceneManager.Current.UpdateProgress("Applying Carmageddon Reincarnation scale"); ModelManipulator.Scale(bones, Matrix4.CreateScale(6.9f, 6.9f, -6.9f), true); ModelManipulator.FlipFaces(bones, true); SceneManager.Current.UpdateProgress("Fixing material names"); foreach (var material in SceneManager.Current.Materials) { if (material.Name.Contains(".")) { material.Name = material.Name.Substring(0, material.Name.IndexOf(".")); } material.Name = material.Name.Replace("\\", ""); } SceneManager.Current.UpdateProgress("Munging parts and fixing wheels"); Single scale; for (int i = 0; i < bones.Count; i++) { var bone = bones[i]; if (i == 0) { bone.Name = "c_Body"; bone.Mesh.Name = "c_Body"; } else { bone.Name = Path.GetFileNameWithoutExtension(bone.Name); } switch (bone.Name.ToUpper()) { case "C_BODY": break; case "FLPIVOT": case "FRPIVOT": bone.Name = "Hub_" + bone.Name.ToUpper().Substring(0, 2); if (bone.Transform.Position() == Vector3.Zero) { ModelManipulator.MungeMeshWithBone(bone.Children[0].Mesh, false); var m = bone.Transform; m.Row3 = bone.Children[0].Transform.Row3; bone.Transform = m; model.SetTransform(Matrix4.Identity, bone.Children[0].Index); } break; case "FLWHEEL": scale = bone.CombinedTransform.ExtractTranslation().Y / 0.35f; bone.Name = "Wheel_FL"; model.ClearMesh(bone.Index); model.SetTransform(Matrix4.CreateScale(scale) * Matrix4.CreateRotationY(MathHelper.DegreesToRadians(180)), bone.Index); break; case "FRWHEEL": scale = bone.CombinedTransform.ExtractTranslation().Y / 0.35f; bone.Name = "Wheel_FR"; model.ClearMesh(bone.Index); model.SetTransform(Matrix4.CreateScale(scale), bone.Index); break; case "RLWHEEL": case "RRWHEEL": string suffix = bone.Name.ToUpper().Substring(0, 2); bone.Name = "Hub_" + suffix; if (bone.Transform.Position() == Vector3.Zero) { ModelManipulator.MungeMeshWithBone(bone.Mesh, false); } model.ClearMesh(bone.Index); scale = bone.CombinedTransform.ExtractTranslation().Y / 0.35f; int newBone = model.AddMesh(null, bone.Index); model.SetName("Wheel_" + suffix, newBone); model.SetTransform(Matrix4.CreateScale(scale) * (suffix == "RL" ? Matrix4.CreateRotationY(MathHelper.DegreesToRadians(180)) : Matrix4.Identity), newBone); break; case "DRIVER": bone.Name = "Dryver"; goto default; default: if (bone.Type == BoneType.Mesh) { ModelManipulator.MungeMeshWithBone(bone.Mesh, false); } break; } } SceneManager.Current.UpdateProgress("Processing complete!"); SceneManager.Current.SetCoordinateSystem(SceneManager.CoordinateSystem.LeftHanded); SceneManager.Current.Change(ChangeType.Munge, -1); SceneManager.Current.SetContext(ContextGame.Carmageddon_Reincarnation, ContextMode.Car); } break; } }
private void menuObjectClick(object sender, EventArgs e) { ToolStripMenuItem mi = (ToolStripMenuItem)sender; int boneIndex = SceneManager.Current.SelectedBoneIndex; int modelIndex = SceneManager.Current.SelectedModelIndex; int modelBoneKey = ModelBone.GetModelBoneKey(modelIndex, boneIndex); switch (mi.Text) { case "New...": var addNew = new frmNewObject(); addNew.SetParentNode(modelIndex, boneIndex); if (addNew.ShowDialog(this) == DialogResult.OK) { SceneManager.Current.Change(ChangeType.Add, addNew.NewBoneKey, modelBoneKey); } break; case "Remove...": var removeObject = new frmRemoveObject(); removeObject.SetParentNode(modelIndex, boneIndex); if (removeObject.ShowDialog(this) == DialogResult.OK) { SceneManager.Current.Change(ChangeType.Delete, modelBoneKey, removeObject.RemovedBone); } break; case "Modify geometry...": var geometry = new frmModifyModel(); geometry.SetParentNode(modelIndex, boneIndex); if (geometry.ShowDialog(this) == DialogResult.OK) { SceneManager.Current.Change(ChangeType.Transform, modelBoneKey); } break; case "Modify actor...": var transform = new frmModifyActor(); transform.SetParentNode(modelIndex, boneIndex); if (transform.ShowDialog(this) == DialogResult.OK) { SceneManager.Current.Change(ChangeType.Transform, modelBoneKey); } break; case "Rename": var rename = new frmRename(); rename.SetParentNode(modelIndex, boneIndex); if (rename.ShowDialog(this) == DialogResult.OK) { SceneManager.Current.Change(ChangeType.Rename, modelBoneKey, rename.NewName); } break; case "Add/Change Type...": var changeType = new frmChangeNodeType(); changeType.SetParentNode(modelIndex, boneIndex); if (changeType.ShowDialog(this) == DialogResult.OK) { SceneManager.Current.Change(ChangeType.ChangeType, modelBoneKey); } break; case "Remove": break; case "Optimise": foreach (ModelMesh mesh in SceneManager.Current.SelectedModel.Meshes) { foreach (ModelMeshPart part in mesh.MeshParts) { part.Optimise(); } } break; case "Flatten hierarchy...": SceneManager.Current.UpdateProgress("TODO: Code \"Flatten hierarchy...\""); break; case "Invert texture 'v' coordinates": ModelManipulator.FlipUVs(SceneManager.Current.SelectedModel.Bones[SceneManager.Current.SelectedBoneIndex].Mesh); break; } }