/// <summary> /// Initializes a new instance of the <see cref="ModelViewer"/> class. /// </summary> /// <param name="temppm">The temppm.</param> /// <remarks></remarks> public ModelViewer(ParsedModel temppm) { // Set the initial size of our form this.ClientSize = new Size(400, 300); // And its caption this.Text = "Model Viewer"; pm = temppm; this.MouseDown += ModelViewer_MouseDown; this.MouseMove += this.ModelViewer_MouseDownx; this.MouseUp += this.ModelViewer_MouseUp; Main(); }
/// <summary> /// The create index buffers. /// </summary> /// <param name="device">The device.</param> /// <param name="pm">The pm.</param> /// <remarks></remarks> private static void CreateIndexBuffers(ref Device device, ref ParsedModel pm) { // Pool pool=; // if (device.DeviceCaps.. pm.Display.indexBuffer = new IndexBuffer[pm.RawDataMetaChunks.Length]; for (int rawindex = 0; rawindex < pm.Display.Chunk.Count; rawindex++) { int x = pm.Display.Chunk[rawindex]; pm.Display.indexBuffer[x] = new IndexBuffer( typeof(short), pm.RawDataMetaChunks[x].IndiceCount, device, Usage.WriteOnly, Pool.Managed); IndexBuffer ib = pm.Display.indexBuffer[x]; ib.SetData(pm.RawDataMetaChunks[x].Indices, 0, LockFlags.None); ib.Unlock(); } }
/// <summary> /// The make meshes. /// </summary> /// <param name="device">The device.</param> /// <param name="pm">The pm.</param> /// <remarks></remarks> public static void MakeMeshes(ref Device device, ref ParsedModel pm) { pm.Display.meshes = new Mesh[pm.Display.Chunk.Count]; for (int t = 0; t < pm.Display.Chunk.Count; t++) { int rawindex = pm.Display.Chunk[t]; pm.Display.meshes[t] = Renderer.MakeMesh(ref pm, rawindex, ref device); } }
/// <summary> /// The load direct x textures and buffers. /// </summary> /// <param name="device">The device.</param> /// <param name="pm">The pm.</param> /// <remarks></remarks> public static void LoadDirectXTexturesAndBuffers(ref Device device, ref ParsedModel pm) { if (pm == null) { return; } CreateVertexBuffers(ref device, ref pm); CreateIndexBuffers(ref device, ref pm); LoadShaderTextures(ref device, ref pm); MakeMeshes(ref device, ref pm); }
/// <summary> /// The find displayed pieces. /// </summary> /// <param name="lodlevel">The lodlevel.</param> /// <param name="pm">The pm.</param> /// <returns></returns> /// <remarks></remarks> public static DisplayedInfo FindDisplayedPieces(int lodlevel, ParsedModel pm) { DisplayedInfo di = new DisplayedInfo(); if (pm.hlmt == null || pm.hlmt.Permutations.Piece.Length == 0) { for (int x = 0; x < pm.LOD.Piece.Length; x++) { for (int y = 0; y < pm.LOD.Piece[x].Permutation.Length; y++) { if (pm.LOD.Piece[x].Permutation[y].name == pm.LOD.PermutationStrings[0]) { if (di.Chunk.IndexOf(pm.LOD.Piece[x].Permutation[y].pieceNumber[lodlevel]) == -1) { di.Chunk.Add(pm.LOD.Piece[x].Permutation[y].pieceNumber[lodlevel]); } } } } goto shadeshit; } int tempid = pm.hlmt.FindPermutation(pm.PermutationString); LODInfo.LODPieceInfo.LODPermutationInfo lodinfo = new LODInfo.LODPieceInfo.LODPermutationInfo(); for (int x = 0; x < pm.hlmt.Permutations.Piece.Length; x++) { string name1 = pm.hlmt.Permutations.Piece[x].PieceName; // if (pm.hlmt.Permutations[tempid].Piece[x].Permutation.Length for (int xx = 0; xx < pm.hlmt.Permutations.Piece[x].Permutation.Length; xx++) { string name2 = pm.hlmt.Permutations.Piece[x].Permutation[xx].PermutationNameX; lodinfo = pm.LOD.FindPermutationInfo(name1, name2); if (di.Chunk.IndexOf(lodinfo.pieceNumber[lodlevel]) == -1) { di.Chunk.Add(lodinfo.pieceNumber[lodlevel]); } } } shadeshit: int[] tempshade = new int[200]; int tempshadecount = 1; for (int x = 0; x < di.Chunk.Count; x++) { for (int y = 0; y < pm.RawDataMetaChunks[di.Chunk[x]].SubMeshInfo.Length; y++) { int r = pm.RawDataMetaChunks[di.Chunk[x]].SubMeshInfo[y].ShaderNumber; if (Array.IndexOf(tempshade, r) == -1) { tempshade[tempshadecount] = r; tempshadecount++; } } } di.ShaderIndex = new int[tempshadecount]; Array.Copy(tempshade, 0, di.ShaderIndex, 0, tempshadecount); return di; }
/// <summary> /// The draw meshes. /// </summary> /// <param name="device">The device.</param> /// <param name="pm">The pm.</param> /// <remarks></remarks> public static void DrawMeshes(ref Device device, ParsedModel pm) { for (int x = 0; x < pm.Display.Chunk.Count; x++) { int rawindex = pm.Display.Chunk[x]; VertexBuffer vb = pm.Display.meshes[x].VertexBuffer; IndexBuffer ib = pm.Display.meshes[x].IndexBuffer; device.SetStreamSource(0, vb, 0); device.VertexFormat = HaloVertex.FVF; device.Indices = ib; for (int xx = 0; xx < pm.RawDataMetaChunks[rawindex].SubMeshInfo.Length; xx++) { int tempshade = pm.RawDataMetaChunks[rawindex].SubMeshInfo[xx].ShaderNumber; Renderer.SetAlphaBlending(pm.Shaders.Shader[tempshade].Alpha, ref device); device.SetTexture(0, pm.Shaders.Shader[tempshade].MainTexture); device.TextureState[0].ColorOperation = TextureOperation.Modulate; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorArgument2 = TextureArgument.Current; device.RenderState.FillMode = FillMode.Solid; pm.Display.meshes[x].DrawSubset(xx); } } }
/// <summary> /// The draw. /// </summary> /// <param name="device">The device.</param> /// <param name="pm">The pm.</param> /// <remarks></remarks> public static void Draw(ref Device device, ParsedModel pm) { for (int i = 0; i < 5; i++) { device.SetTexture(i, null); } for (int x = 0; x < pm.Display.Chunk.Count; x++) { int rawindex = pm.Display.Chunk[x]; device.SetStreamSource(0, pm.Display.vertexBuffer[rawindex], 0); // device.VertexFormat = HaloVertex.FVF; device.VertexFormat = pm.Display.vertexBuffer[rawindex].Description.VertexFormat; // This makes the sky look a little more correct... // device.VertexFormat = VertexFormats.Texture0 | VertexFormats.PositionNormal | VertexFormats.Specular; device.Indices = pm.Display.indexBuffer[rawindex]; for (int xx = 0; xx < pm.RawDataMetaChunks[rawindex].SubMeshInfo.Length; xx++) { device.RenderState.AlphaBlendEnable = false; device.RenderState.SpecularEnable = false; int tempshade = pm.RawDataMetaChunks[rawindex].SubMeshInfo[xx].ShaderNumber; ShaderInfo shad = pm.Shaders.Shader[tempshade]; Renderer.SetAlphaBlending(shad.Alpha, ref device); device.SetTexture(0, shad.MainTexture); if (shad.Alpha == ShaderInfo.AlphaType.None) { device.TextureState[0].ColorOperation = TextureOperation.SelectArg1; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; if (shad.BitmapNames.Count > 0 && shad.BitmapNames[0].ToLower().Contains("specular")) { device.RenderState.SpecularEnable = true; device.RenderState.SpecularMaterialSource = ColorSource.Material; device.TextureState[0].ColorOperation = TextureOperation.Modulate; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorArgument2 = TextureArgument.Specular; } } else { device.RenderState.AlphaBlendEnable = true; device.RenderState.AlphaTestEnable = true; device.RenderState.ReferenceAlpha = 180; device.RenderState.AlphaFunction = Compare.Greater; device.RenderState.SourceBlend = Blend.SourceAlpha; device.RenderState.DestinationBlend = Blend.One; // was Blend.InvSourceAlpha; device.TextureState[0].ColorOperation = TextureOperation.SelectArg1; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse; /* device.TextureState[0].AlphaOperation = TextureOperation.Modulate; // BlendTextureAlpha; device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor; device.TextureState[0].AlphaArgument2 = TextureArgument.Current; */ } if (shad.BitmapTextures != null) { for (int xxx = 1; xxx <= shad.BitmapTextures.Length; xxx++) { device.SetTexture(xxx, shad.BitmapTextures[xxx - 1]); if (shad.Alpha == ShaderInfo.AlphaType.None) { // device.RenderState.AlphaBlendEnable = false; device.TextureState[xxx].AlphaOperation = TextureOperation.Disable; device.TextureState[xxx].AlphaArgument1 = TextureArgument.TextureColor; device.TextureState[xxx].AlphaArgument2 = TextureArgument.Current; device.TextureState[xxx].ColorOperation = TextureOperation.Disable; device.TextureState[xxx].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[xxx].ColorArgument2 = TextureArgument.Current; } else { // device.RenderState.AlphaBlendEnable = true; device.RenderState.SourceBlend = Blend.SourceColor; device.RenderState.DestinationBlend = Blend.InvSourceColor; /* device.TextureState[xxx].ColorOperation = TextureOperation.SelectArg1; device.TextureState[xxx].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[xxx].ColorArgument2 = TextureArgument.Diffuse; */ device.TextureState[xxx].AlphaOperation = TextureOperation.Modulate; device.TextureState[xxx].AlphaArgument1 = TextureArgument.TextureColor; device.TextureState[xxx].AlphaArgument2 = TextureArgument.Current; } } } PrimitiveType pt; if (pm.RawDataMetaChunks[rawindex].FaceCount * 3 != pm.RawDataMetaChunks[rawindex].IndiceCount) { pt = PrimitiveType.TriangleStrip; // The -2 is because it's a Triangle Strip, which has three vertices for trianlge 1 and one for // each following traingle. // So the total # of triangles are IndiceCount-2 (for the first two points) // Thanks to Prey for pointing this out try { device.DrawIndexedPrimitives( pt, 0, 0, pm.RawDataMetaChunks[rawindex].VerticeCount, pm.RawDataMetaChunks[rawindex].SubMeshInfo[xx].IndiceStart, pm.RawDataMetaChunks[rawindex].SubMeshInfo[xx].IndiceCount - 2); } catch { } } else { pt = PrimitiveType.TriangleList; device.DrawIndexedPrimitives( pt, 0, 0, pm.RawDataMetaChunks[rawindex].VerticeCount, pm.RawDataMetaChunks[rawindex].SubMeshInfo[xx].IndiceStart, pm.RawDataMetaChunks[rawindex].SubMeshInfo[xx].IndiceCount / 3); } } } }
/// <summary> /// The view model tool strip menu item_ click. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <remarks></remarks> private void viewModelToolStripMenuItem_Click(object sender, EventArgs e) { ParsedModel pm = new ParsedModel(ref map.SelectedMeta); ModelViewer mv = new ModelViewer(pm); pm.Dispose(); pm = null; mv.Dispose(); mv = null; }
/// <summary> /// The load sky. /// </summary> /// <param name="meta">The meta.</param> /// <remarks></remarks> public void LoadSky(ref Meta meta) { map.OpenMap(MapTypes.Internal); map.BR.BaseStream.Position = map.MetaInfo.Offset[3] + 8; int tempc = map.BR.ReadInt32(); int tempr = map.BR.ReadInt32() - map.SecondaryMagic; if (tempc == 0) { return; } map.BR.BaseStream.Position = tempr + 4; int tempident = map.Functions.ForMeta.FindMetaByID(map.BR.ReadInt32()); if (tempident != -1) { sky = new Sky(tempident, map); map.BR.BaseStream.Position = map.MetaInfo.Offset[tempident] + 4; tempident = map.Functions.ForMeta.FindMetaByID(map.BR.ReadInt32()); if (tempident != -1) { Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempident, false); SkyBox = new ParsedModel(ref tempmeta); } } map.CloseMap(); }
/// <summary> /// The to x tool strip menu item_ click. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <remarks></remarks> private void toXToolStripMenuItem_Click(object sender, EventArgs e) { if (folderBrowserDialog.ShowDialog() == DialogResult.Cancel) { return; } ParsedModel pm = new ParsedModel(ref map.SelectedMeta); pm.ExtractMeshesToX(folderBrowserDialog.SelectedPath); MessageBox.Show("Done"); }
/// <summary> /// The tree view 1_ key press. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <remarks></remarks> private void treeView1_KeyPress(object sender, KeyPressEventArgs e) { if ((byte)e.KeyChar == 22) { // Ctrl + v if (map.SelectedMeta == null) { return; } if (map.SelectedMeta.type == "PRTM") { // PRTM Viewer PRTMModel pm = new PRTMModel(ref map.SelectedMeta); ModelViewer mv = new ModelViewer(pm); } else if (map.SelectedMeta.type == "mod2" || map.SelectedMeta.type == "mode") { // MODE Viewer ParsedModel pm = new ParsedModel(ref map.SelectedMeta); ModelViewer mv = new ModelViewer(pm); pm.Dispose(); pm = null; mv.Dispose(); mv = null; } else if (map.SelectedMeta.type == "coll") { collisonViewerToolStripMenuItem_Click(this, null); } else if (map.SelectedMeta.type == "sbsp") { loadBSP(map.SelectedMeta.TagIndex); } } }
/// <summary> /// The inject obj tool strip menu item_ click. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The e.</param> /// <remarks></remarks> private void injectOBJToolStripMenuItem_Click(object sender, EventArgs e) { if (folderBrowserDialog.ShowDialog() == DialogResult.Cancel) { return; } ParsedModel pm = new ParsedModel(ref map.SelectedMeta); Meta addme = pm.InjectModel(folderBrowserDialog.SelectedPath, map.SelectedMeta); addme.name += "(new)"; addme.name = GetNameDialog.Show("Choose injection name", "Meta Name:", addme.name, "OK"); ArrayList oi = new ArrayList(); oi.Add(addme); MapAnalyzer analyze = new MapAnalyzer(); MapLayout layout = analyze.ScanMapForLayOut(map, false); layout.ReadChunks(map); Builder build = new Builder(); build.MapBuilder(oi, ref layout, map, false); map = Map.Refresh(map); formFuncs.AddMetasToTreeView(map, treeView1, metaView, false); this.Enabled = true; MessageBox.Show("Done"); }
/// <summary> /// The load spawns. /// </summary> /// <remarks></remarks> public void LoadSpawns() { spawns = new SpawnLoads(map, bsp, render.device); SpawnModel = new List<ParsedModel>(); spawnmodelindex = new int[bsp.Spawns.Spawn.Count]; BoundingBoxModel = new Mesh[bsp.Spawns.Spawn.Count]; map.OpenMap(MapTypes.Internal); int blockCount = 0; int scenCount = 0; for (int x = 0; x < bsp.Spawns.Spawn.Count; x++) { // Display loading information if (x % 7 == 0) { this.label3.Text = ".:Loading Spawns [" + x.ToString() + "/" + bsp.Spawns.Spawn.Count.ToString() + "]:."; // Every 5 updates, refresh whole window, otherwise just update the label if (x % 35 == 0) Application.DoEvents(); else this.label3.Refresh(); } // This is the only way I could think of doing it right now... // Used for saving Obstacle & Scenery to their original places if (bsp.Spawns.Spawn[x] is SpawnInfo.ObstacleSpawn) { ((SpawnInfo.ObstacleSpawn)bsp.Spawns.Spawn[x]).BlocNumber = blockCount++; } else if (bsp.Spawns.Spawn[x] is SpawnInfo.ScenerySpawn) { ((SpawnInfo.ScenerySpawn)bsp.Spawns.Spawn[x]).ScenNumber = scenCount++; } if (bsp.Spawns.Spawn[x] is SpawnInfo.BoundingBoxSpawn) { BoundingBoxModel[x] = loadBoundingBoxSpawn(bsp.Spawns.Spawn[x]); continue; } #region CameraSpawn if (bsp.Spawns.Spawn[x] is SpawnInfo.CameraSpawn) { BoundingBoxModel[x] = loadCameraSpawn(bsp.Spawns.Spawn[x]); continue; } #endregion #region LightSpawn if (bsp.Spawns.Spawn[x] is SpawnInfo.LightSpawn) { SpawnInfo.LightSpawn tempbox; tempbox = bsp.Spawns.Spawn[x] as SpawnInfo.LightSpawn; tempbox.LightInfo = new HaloLight(tempbox.ModelTagNumber, map); bsp.Spawns.Spawn[x] = tempbox; BoundingBoxModel[x] = Mesh.Cylinder(render.device, 0.5f, 0.0f, 1f, 10, 10); if (render.lighting) { render.device.Lights[HaloLightCount].Type = LightType.Point; render.device.Lights[HaloLightCount].Position = new Vector3(tempbox.X, tempbox.Y, tempbox.Z); render.device.Lights[HaloLightCount].Direction = new Vector3( -tempbox.Yaw, -tempbox.Pitch, -tempbox.Roll); render.device.Lights[HaloLightCount].Range = 10f; // render.device.Lights[HaloLightCount].=0.5f; // render.device.Lights[HaloLightCount].p = 1.0f; render.device.Lights[HaloLightCount].Falloff = 1.0f; render.device.Lights[HaloLightCount].Attenuation0 = 1.0f; render.device.Lights[HaloLightCount].Diffuse = Color.FromArgb( tempbox.LightInfo.r, tempbox.LightInfo.g, tempbox.LightInfo.b); render.device.Lights[HaloLightCount].Update(); render.device.Lights[HaloLightCount].Enabled = true; } HaloLightCount++; continue; } #endregion #region SoundSpawn if (bsp.Spawns.Spawn[x] is SpawnInfo.SoundSpawn) { BoundingBoxModel[x] = loadSoundSpawn(bsp.Spawns.Spawn[x]); continue; } #endregion #region SpawnZone if (bsp.Spawns.Spawn[x] is SpawnInfo.SpawnZone) { BoundingBoxModel[x] = loadSpawnZone(bsp.Spawns.Spawn[x]); continue; } #endregion SpawnInfo.RotationSpawn tempspawn = bsp.Spawns.Spawn[x] as SpawnInfo.RotationSpawn; #region ScanForExistingModels bool found = false; for (int xx = 0; xx < x; xx++) { SpawnInfo.RotationSpawn tempspawn2 = bsp.Spawns.Spawn[xx] as SpawnInfo.RotationSpawn; if (bsp.Spawns.Spawn[xx] is SpawnInfo.BoundingBoxSpawn) { continue; } if (tempspawn.ModelTagNumber == tempspawn2.ModelTagNumber) { BoundingBoxModel[x] = BoundingBoxModel[xx]; spawnmodelindex[x] = spawnmodelindex[xx]; bsp.Spawns.Spawn[x].bbXDiff = bsp.Spawns.Spawn[xx].bbXDiff; bsp.Spawns.Spawn[x].bbYDiff = bsp.Spawns.Spawn[xx].bbYDiff; bsp.Spawns.Spawn[x].bbZDiff = bsp.Spawns.Spawn[xx].bbZDiff; found = true; break; } } if (found) { continue; } #endregion #region ReadSpawnMeta Meta m = new Meta(map); if (tempspawn.ModelTagNumber == -1) { MessageBox.Show("Test"); } m.ReadMetaFromMap(tempspawn.ModelTagNumber, false); #endregion #region DirectXModel ParsedModel pm = new ParsedModel(ref m); // pm.PermutationString=pm.hlmt.Permutations[pm.hlmt.FindPermutationByBaseClass, ParsedModel.DisplayedInfo.LoadDirectXTexturesAndBuffers(ref render.device, ref pm); SpawnModel.Add(pm); spawnmodelindex[x] = SpawnModel.Count - 1; m.Dispose(); #endregion #region BoundingBox float boxwidth = pm.BoundingBox.MaxX - pm.BoundingBox.MinX; float boxheight = pm.BoundingBox.MaxY - pm.BoundingBox.MinY; float boxdepth = pm.BoundingBox.MaxZ - pm.BoundingBox.MinZ; try { BoundingBoxModel[x] = Mesh.Box(render.device, boxwidth, boxheight, boxdepth); } catch (Exception ex) { Global.ShowErrorMsg("Failure to create Bounding Box Mesh for " + pm.name + "\nWidth : " + boxwidth.ToString() + "\nHeight: " + boxheight.ToString() + "\nLength: " + boxdepth.ToString(), ex); } // Used for fixing position of bounding boxes bsp.Spawns.Spawn[x].bbXDiff = pm.BoundingBox.MaxX + pm.BoundingBox.MinX; bsp.Spawns.Spawn[x].bbYDiff = pm.BoundingBox.MaxY + pm.BoundingBox.MinY; bsp.Spawns.Spawn[x].bbZDiff = pm.BoundingBox.MaxZ + pm.BoundingBox.MinZ; #endregion } if (render.device.DeviceCaps.RasterCaps.SupportsFogTable && bsp.sky.fogenabled && bsp.sky.fog.FogThickness != 0) { int a = (int)(bsp.sky.fog.A * 255); int r = (int)(bsp.sky.fog.R * 255); int g = (int)(bsp.sky.fog.G * 255); int b = (int)(bsp.sky.fog.B * 255); render.device.RenderState.FogColor = Color.FromArgb(a, r, g, b); render.device.RenderState.FogStart = bsp.sky.fog.Start; render.device.RenderState.FogEnd = bsp.sky.fog.End; render.device.RenderState.FogDensity = bsp.sky.fog.FogThickness; // bsp.sky.fog.FogThickness; render.device.RenderState.FogTableMode = FogMode.Linear; render.device.RenderState.FogEnable = true; } // render.device.RenderState.FogVertexMode = FogMode.Linear; /* this.label3.Text = ".:Loading Weapons Collection:."; this.ResumeLayout(); this.SuspendLayout(); #region LoadAllWeaponsForCollectionChangeBox WeaponsList.Clear(); // Lists all weapons for (int i = 0; i < map.MetaInfo.TagType.Length; i++) if ((map.MetaInfo.TagType[i] == "itmc") || (map.MetaInfo.TagType[i] == "vehc")) { CollectionInfo Weapon = new CollectionInfo(); Meta m = new Meta(map); m.ReadMetaFromMap(i, map, false); Weapon.ItmcTagNumber = i; // Base address of ITMC tag, offset of WEAP pointer (+20) map.BR.BaseStream.Position = map.MetaInfo.Offset[Weapon.ItmcTagNumber] + 20; Weapon.WeapTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); if (Weapon.WeapTagNumber == -1) { continue; } // Base address of WEAP tag, offset of HLMT pointer (+56) map.BR.BaseStream.Position = map.MetaInfo.Offset[Weapon.WeapTagNumber] + 56; Weapon.HlmtTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); if (Weapon.HlmtTagNumber != -1) { // Base address of HLMT tag, offset of MODE pointer (+4) map.BR.BaseStream.Position = map.MetaInfo.Offset[Weapon.HlmtTagNumber] + 4; Weapon.ModelTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); m.ReadMetaFromMap(Weapon.ModelTagNumber, map, false); Weapon.Model = new ParsedModel(ref m, map); Raw.ParsedModel.DisplayedInfo.LoadDirectXTexturesAndBuffers(ref render.device, ref Weapon.Model); // Store names into Weapon Weapon.TagPath = map.FileNames.Name[i]; Weapon.TagType = map.MetaInfo.TagType[i]; int xx = map.Functions.Meta.FindByNameAndTagType(Weapon.TagType, Weapon.TagPath, map); string[] NameSplit = map.FileNames.Name[xx].Split('\\'); Weapon.Name = NameSplit[NameSplit.Length - 1]; Weapon.Name = Weapon.Name.Replace('_', ' '); WeaponsList.Add(Weapon); } } #endregion #region LoadAllObjectsForObstacleAndSceneryChangeBox SceneryList.Clear(); ObstacleList.Clear(); // Lists all Scenery & Obstacles for (int i = 0; i < map.MapHeader.fileCount; i++) { if ((map.MetaInfo.TagType[i] == "scnr")) { Meta m = new Meta(map); //m.ReadMetaFromMap(i, map, false); // Base address of SCNR tag, offset of Scenery Palette pointer (+88) map.BR.BaseStream.Position = map.MetaInfo.Offset[i] + 88; int chunkCount = map.BR.ReadInt32(); int chunkOffset = map.BR.ReadInt32() - map.SecondaryMagic; #region Scenery Palette Objects // Scenery Palette Objects for (int a = 0; a < chunkCount; a++) { SceneryInfo Scenery = new SceneryInfo(); // The Palette Chunk # Scenery.ScenPalNumber = a; // Each chunk is 40 bytes apart map.BR.BaseStream.Position = chunkOffset + a * 40; char[] tagName = map.BR.ReadChars(4); Scenery.ScenTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); try { // Retrieve the Model HLMT tag from the Scenery tag (+56) map.BR.BaseStream.Position = map.MetaInfo.Offset[Scenery.ScenTagNumber] + 56; Scenery.HlmtTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); // Base address of HLMT tag, offset of MODE pointer (+4) map.BR.BaseStream.Position = map.MetaInfo.Offset[Scenery.HlmtTagNumber] + 4; Scenery.ModelTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); if (Scenery.ModelTagNumber != -1) { m.ReadMetaFromMap(Scenery.ModelTagNumber, map, false); Scenery.Model = new ParsedModel(ref m, map); } else Scenery.Model = null; Raw.ParsedModel.DisplayedInfo.LoadDirectXTexturesAndBuffers(ref render.device, ref Scenery.Model); string[] s = map.FileNames.Name[Scenery.ScenTagNumber].Split('\\'); Scenery.Name = s[s.Length - 1]; Scenery.TagPath = map.FileNames.Name[Scenery.ScenTagNumber]; Scenery.TagType = map.MetaInfo.TagType[Scenery.ScenTagNumber]; SceneryList.Add(Scenery); } catch { } } #endregion // Base address of SCNR tag, offset of Sound Scenery Palette pointer (+224) map.BR.BaseStream.Position = map.MetaInfo.Offset[i] + 224; chunkCount = map.BR.ReadInt32(); chunkOffset = map.BR.ReadInt32() - map.SecondaryMagic; #region Sound Scenery Palette Objects // Scenery Palette Objects for (int a = 0; a < chunkCount; a++) { SceneryInfo Sound = new SceneryInfo(); // The Palette Chunk # Sound.ScenPalNumber = a; // Each chunk is 40 bytes apart map.BR.BaseStream.Position = chunkOffset + a * 40; char[] tagName = map.BR.ReadChars(4); Sound.ScenTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); if (Sound.ScenTagNumber != -1) { string[] s = map.FileNames.Name[Sound.ScenTagNumber].Split('\\'); Sound.Name = s[s.Length - 1]; Sound.TagPath = map.FileNames.Name[Sound.ScenTagNumber]; Sound.TagType = map.MetaInfo.TagType[Sound.ScenTagNumber]; SoundsList.Add(Sound); } } #endregion // Base address of SCNR tag, offset of Crate Palette pointer (+816) map.BR.BaseStream.Position = map.MetaInfo.Offset[i] + 816; chunkCount = map.BR.ReadInt32(); chunkOffset = map.BR.ReadInt32() - map.SecondaryMagic; #region Crate Palette Objects // Crate (Obstacle) Palette Objects for (int a = 0; a < chunkCount; a++) { SceneryInfo Obstacle = new SceneryInfo(); // The Palette Chunk # Obstacle.ScenPalNumber = a; // Each chunk is 40 bytes apart map.BR.BaseStream.Position = chunkOffset + a * 40; char[] tagName = map.BR.ReadChars(4); Obstacle.ScenTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); if (Obstacle.ScenTagNumber != -1) { // Retrieve the Model HLMT tag from the Scenery tag (+56) map.BR.BaseStream.Position = map.MetaInfo.Offset[Obstacle.ScenTagNumber] + 56; Obstacle.HlmtTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); // Base address of HLMT tag, offset of MODE pointer (+4) map.BR.BaseStream.Position = map.MetaInfo.Offset[Obstacle.HlmtTagNumber] + 4; Obstacle.ModelTagNumber = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); m.ReadMetaFromMap(Obstacle.ModelTagNumber, map, false); Obstacle.Model = new ParsedModel(ref m, map); Raw.ParsedModel.DisplayedInfo.LoadDirectXTexturesAndBuffers(ref render.device, ref Obstacle.Model); string[] s = map.FileNames.Name[Obstacle.ScenTagNumber].Split('\\'); Obstacle.Name = s[s.Length - 1]; Obstacle.TagPath = map.FileNames.Name[Obstacle.ScenTagNumber]; Obstacle.TagType = map.MetaInfo.TagType[Obstacle.ScenTagNumber]; ObstacleList.Add(Obstacle); } } #endregion break; } } #endregion */ map.CloseMap(); }
/// <summary> /// The draw skybox. /// </summary> /// <param name="pm">The pm.</param> /// <remarks></remarks> private void DrawSkybox(ParsedModel pm) { if (pm == null) { return; } for (int x = 0; x < pm.Display.Chunk.Count; x++) { if (x != 0 && x != 0) continue; int rawindex = pm.Display.Chunk[x]; for (int xx = 0; xx < pm.RawDataMetaChunks[rawindex].SubMeshInfo.Length; xx++) { // device.Material = meshmaterials[i]; int tempshade = pm.RawDataMetaChunks[rawindex].SubMeshInfo[xx].ShaderNumber; //Renderer.SetAlphaBlending(ShaderInfo.AlphaType.AlphaBlend, ref render.device); Renderer.SetAlphaBlending(pm.Shaders.Shader[tempshade].Alpha, ref render.device); switch (pm.Shaders.Shader[tempshade].Alpha) { case ShaderInfo.AlphaType.AlphaBlend: render.device.RenderState.SourceBlend = Blend.BothSourceAlpha; render.device.RenderState.DestinationBlend = Blend.Zero; break; case ShaderInfo.AlphaType.None: render.device.RenderState.SourceBlend = Blend.One; render.device.RenderState.DestinationBlend = Blend.One; break; } render.device.SetTexture(0, pm.Shaders.Shader[tempshade].MainTexture); // Skybox textures render.device.TextureState[0].ColorOperation = TextureOperation.SelectArg1; render.device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; render.device.TextureState[0].ColorArgument2 = TextureArgument.Current; render.device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1; // render.device.TextureState[0].AlphaOperation = TextureOperation.ModulateAlphaAddColor; render.device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor; render.device.TextureState[0].AlphaArgument2 = TextureArgument.Current; // Skybox Lighting /* if (bsp.LightMapTexture[x] != null && bsp.BSPRawDataMetaChunks[x].LightMapUVs.Count != 0) { render.device.SetTexture(1, bsp.LightMapTexture[x]); render.device.TextureState[1].ColorOperation = TextureOperation.Disable; render.device.TextureState[1].AlphaOperation = TextureOperation.Disable; render.device.TextureState[1].TextureCoordinateIndex = 2; } */ render.device.RenderState.FillMode = FillMode.WireFrame; // render.device.SetTexture(0, meshtextures[i]); pm.Display.meshes[x].DrawSubset(xx); } } }
/// <summary> /// The create vertex buffers. /// </summary> /// <param name="device">The device.</param> /// <param name="pm">The pm.</param> /// <remarks></remarks> private static void CreateVertexBuffers(ref Device device, ref ParsedModel pm) { pm.Display.vertexBuffer = new VertexBuffer[pm.RawDataMetaChunks.Length]; for (int x = 0; x < pm.Display.Chunk.Count; x++) { int rawindex = pm.Display.Chunk[x]; pm.Display.vertexBuffer[rawindex] = new VertexBuffer( typeof(HaloVertex), pm.RawDataMetaChunks[rawindex].VerticeCount, device, Usage.WriteOnly, HaloVertex.FVF, Pool.Managed); HaloVertex[] verts = (HaloVertex[])pm.Display.vertexBuffer[rawindex].Lock(0, 0); // Lock the buffer (which will return our structs) for (int i = 0; i < pm.RawDataMetaChunks[rawindex].VerticeCount; i++) { verts[i].Position = new Vector3( pm.RawDataMetaChunks[rawindex].Vertices[i].X, pm.RawDataMetaChunks[rawindex].Vertices[i].Y, pm.RawDataMetaChunks[rawindex].Vertices[i].Z); verts[i].Tu0 = pm.RawDataMetaChunks[rawindex].UVs[i].X; verts[i].Tv0 = pm.RawDataMetaChunks[rawindex].UVs[i].Y; verts[i].Normal = new Vector3( pm.RawDataMetaChunks[rawindex].Vertices[i].X, pm.RawDataMetaChunks[rawindex].Vertices[i].Y, pm.RawDataMetaChunks[rawindex].Vertices[i].Z); verts[i].specular = 1; verts[i].diffuse = 1; } // Unlock (and copy) the data pm.Display.vertexBuffer[rawindex].Unlock(); } }
/// <summary> /// The dispose. /// </summary> /// <remarks></remarks> public void Dispose() { foreach (IntPtr ip in bitmPtrs) { Marshal.FreeHGlobal(ip); } bitmPtrs.Clear(); for (int i = 0; i < this.LightMapBitmap.Length; i++) { if (this.LightMapBitmap[i] != null) { this.LightMapBitmap[i].Dispose(); this.LightMapBitmap[i] = null; } } for (int i = 0; i < this.SceneryLightMapBitmap.Length; i++) { if (this.SceneryLightMapBitmap[i] != null) { this.SceneryLightMapBitmap[i].Dispose(); } } this.BSPPermutationRawDataMetaChunks = null; this.PermutationInfo = null; this.BSPRawDataMetaChunks = null; this.Display = null; this.Shaders = null; this.SkyBox = null; this.Spawns = null; GC.SuppressFinalize(this); }
/// <summary> /// The load shader textures. /// </summary> /// <param name="device">The device.</param> /// <param name="pm">The pm.</param> /// <remarks></remarks> private static void LoadShaderTextures(ref Device device, ref ParsedModel pm) { for (int x = 0; x < pm.Display.ShaderIndex.Length; x++) { try { pm.Shaders.Shader[pm.Display.ShaderIndex[x]].MakeTextures(ref device); } catch { } } // MessageBox.Show("test"); }
/// <summary> /// The make mesh. /// </summary> /// <param name="pm">The pm.</param> /// <param name="chunknumber">The chunknumber.</param> /// <param name="device">The device.</param> /// <returns></returns> /// <remarks></remarks> public static Mesh MakeMesh(ref ParsedModel pm, int chunknumber, ref Device device) { short[] indices; int[] facecount = new int[pm.RawDataMetaChunks[chunknumber].SubMeshInfo.Length]; int[] facestart = new int[pm.RawDataMetaChunks[chunknumber].SubMeshInfo.Length]; if (pm.RawDataMetaChunks[chunknumber].FaceCount * 3 != pm.RawDataMetaChunks[chunknumber].Indices.Length) { short[] tempindicesx = new short[pm.RawDataMetaChunks[chunknumber].FaceCount * 3]; int tempc = 0; for (int x = 0; x < pm.RawDataMetaChunks[chunknumber].SubMeshInfo.Length; x++) { short[] tempindices = DecompressIndices( pm.RawDataMetaChunks[chunknumber].Indices, pm.RawDataMetaChunks[chunknumber].SubMeshInfo[x].IndiceStart, pm.RawDataMetaChunks[chunknumber].SubMeshInfo[x].IndiceCount); Array.ConstrainedCopy(tempindices, 0, tempindicesx, tempc, tempindices.Length); facecount[x] = tempindices.Length / 3; facestart[x] = tempc; tempc += tempindices.Length; } indices = new short[tempindicesx.Length]; Array.Copy(tempindicesx, indices, tempindicesx.Length); } else { indices = pm.RawDataMetaChunks[chunknumber].Indices; for (int x = 0; x < pm.RawDataMetaChunks[chunknumber].SubMeshInfo.Length; x++) { facecount[x] = pm.RawDataMetaChunks[chunknumber].SubMeshInfo[x].IndiceCount / 3; facestart[x] = pm.RawDataMetaChunks[chunknumber].SubMeshInfo[x].IndiceStart / 3; } } Mesh m = new Mesh( indices.Length / 3, pm.RawDataMetaChunks[chunknumber].Vertices.Count, MeshFlags.Managed, HaloVertex.FVF, device); VertexBuffer vb = m.VertexBuffer; HaloVertex[] tempv = new HaloVertex[pm.RawDataMetaChunks[chunknumber].Vertices.Count]; for (int x = 0; x < pm.RawDataMetaChunks[chunknumber].Vertices.Count; x++) { tempv[x].Position = pm.RawDataMetaChunks[chunknumber].Vertices[x]; tempv[x].Normal = pm.RawDataMetaChunks[chunknumber].Normals[x]; tempv[x].Tu0 = pm.RawDataMetaChunks[chunknumber].UVs[x].X; tempv[x].Tv0 = pm.RawDataMetaChunks[chunknumber].UVs[x].Y; } vb.SetData(tempv, 0, LockFlags.None); vb.Unlock(); IndexBuffer ibx = m.IndexBuffer; ibx.SetData(indices, 0, LockFlags.None); return m; }