public Entity GetEntity(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata, object xiMeshOwner) { MMEdEntity lAcc = new MMEdEntity(xiMeshOwner); Mesh lColouredMesh = null; Dictionary <int, Mesh> lPageIdToTexturedMeshMap = new Dictionary <int, Mesh>(); List <Mesh> lTranslucentMeshes = new List <Mesh>(); //qq move all this into Face class? //qq add quad mode meshes (needs separate meshes currently...) Vertex[] lVBuff = new Vertex[4]; foreach (Face f in Faces) { if (!f.IsUnknownType()) { for (int v = 0; v < f.mVertexIds.Length; v++) { lVBuff[v] = new Vertex(ThreeDeeViewer.Short3CoordToPoint(Vertices[f.mVertexIds[v]])); //normal if (v < f.mNormalIds.Length) { lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[v]]).GetPositionVector().Normalise(); } else { lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[0]]).GetPositionVector().Normalise(); } //color: if (f.mColors != null && v < f.mColors.Length) { lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[v]); } else if (f.mColors != null) { lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[0]); } //tex coords if (f.mTexCoords != null && v < f.mTexCoords.Length) { lVBuff[v].TexCoordX = f.mTexCoords[v].X / (double)VRAMViewer.TEX_PAGE_WIDTH; lVBuff[v].TexCoordY = f.mTexCoords[v].Y / (double)VRAMViewer.TEX_PAGE_HEIGHT; } } // Create a new mesh if appropriate, or add this face to an existing mesh // First check if it's tex or solid? Mesh lMesh; if (f.mTexCoords != null) { if (!lPageIdToTexturedMeshMap.ContainsKey(f.mTexPage)) { lMesh = new OwnedMesh(xiMeshOwner); lPageIdToTexturedMeshMap[f.mTexPage] = lMesh; if (xiTextureMode == eTextureMode.NormalTextures || xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lMesh.RenderMode = RenderMode.Textured; lMesh.Texture = AbstractRenderer.ImageToTextureId( VRAMViewer.GetInstance().GetTexturePage(xiRootChunk, f.mTexPage)); } else { lMesh.RenderMode = RenderMode.Wireframe; } } else { lMesh = lPageIdToTexturedMeshMap[f.mTexPage]; } } else { if (f.IsTranslucent()) { lMesh = new OwnedMesh(xiMeshOwner); if (xiTextureMode == eTextureMode.NormalTextures || xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lMesh.RenderMode = RenderMode.TranslucentFilled; } else { lMesh.RenderMode = RenderMode.Wireframe; } lTranslucentMeshes.Add(lMesh); } else { if (lColouredMesh == null) { lColouredMesh = new OwnedMesh(xiMeshOwner); if (xiTextureMode == eTextureMode.NormalTextures || xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lColouredMesh.RenderMode = RenderMode.Filled; } else { lColouredMesh.RenderMode = RenderMode.Wireframe; } } lMesh = lColouredMesh; } } if (f.mVertexIds.Length == 3) { lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]); } else //4 { lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]); lMesh.AddFace(lVBuff[0], lVBuff[2], lVBuff[3]); } } } foreach (Mesh lTexturedMesh in lPageIdToTexturedMeshMap.Values) { lAcc.Meshes.Add(lTexturedMesh); } if (lColouredMesh != null) { lAcc.Meshes.Add(lColouredMesh); } lAcc.Meshes.AddRange(lTranslucentMeshes); lAcc.Scale(1, 1, -1); return(lAcc); }
public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { return(SHET.GetEntities(xiRootChunk, xiTextureMode, xiSelectedMetadata)); }
public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { return(new Entity[] { GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this) }); }
public IEnumerable<GLTK.Entity> GetEntities(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { List<Entity> lAcc = new List<Entity>(); //a bit hacky: if (!this.TreeNode.Checked) { lAcc.Add(GetSurfaceEntity(xiLevel, xiTextureMode, xiSelectedMetadata)); } ///////////////////////////////////////////////////// // The child weapons if (Weapons != null) { foreach (WeaponEntry lWeapon in Weapons) { lAcc.AddRange(lWeapon.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata)); } } ///////////////////////////////////////////////////// // The child objects if (Objects != null) { foreach (ObjectEntry oe in Objects) { lAcc.AddRange(oe.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata)); } } return lAcc; }
private GLTK.Entity GetSurfaceEntity(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { // notes: // invert the textures along the y-axis // use level co-ords, so z is down ///////////////////////////////////////////////////// // The surface Entity lSurface = new MMEdEntity(this); Font lNumberFont = null; Brush lNumberFGBrush = null, lNumberBGBrush = null; Pen lWaypointPen = null, lKeyWaypointPen = null; if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lNumberFont = new Font(FontFamily.GenericMonospace, 10); lNumberFGBrush = new SolidBrush(Color.Black); lNumberBGBrush = new SolidBrush(Color.White); lWaypointPen = new Pen(Color.Black, 1f); lKeyWaypointPen = new Pen(Color.Red, 2f); } for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { Mesh lSquare = new OwnedMesh(this, PolygonMode.Quads); lSquare.AddFace( new Vertex(new Point(x, y, -GetTerrainHeightSafe(x, y)), 0, 0), new Vertex(new Point(x + 1, y, -GetTerrainHeightSafe(x + 1, y)), 1, 0), new Vertex(new Point(x + 1, y + 1, -GetTerrainHeightSafe(x + 1, y + 1)), 1, 1), new Vertex(new Point(x, y + 1, -GetTerrainHeightSafe(x, y + 1)), 0, 1)); switch (xiTextureMode) { case eTextureMode.WireFrame: lSquare.RenderMode = RenderMode.Wireframe; break; // normal textures, optionally with metadata drawn on case eTextureMode.NormalTextures: case eTextureMode.NormalTexturesWithMetadata: TIMChunk lTIM = xiLevel.GetTileById(TextureIds[x][y]); if (lTIM != null) { //some TIMs can't be loaded yet: they're null Bitmap lTexture = lTIM.ToBitmap(); if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata && TexMetaData != null) { byte lVal = TexMetaData[x][y][(int)xiSelectedMetadata]; if (lVal != 0) { // we create a new bitmap based on the given texture // a) so that we can modify it freely // and b) to change it from indexed to full colour mode, to allow us // to draw on it (otherwise we'll get an exception) lTexture = new Bitmap(lTexture); Graphics g = Graphics.FromImage(lTexture); string lText = lVal.ToString(); SizeF size = g.MeasureString(lText, lNumberFont); float xf = lTexture.Width / 2.0f - size.Width / 2.0f; float yf = lTexture.Height / 2.0f - size.Height / 2.0f; g.FillRectangle(lNumberBGBrush, xf, yf, size.Width, size.Height); g.DrawString( lText, lNumberFont, lNumberFGBrush, xf, yf); if (xiSelectedMetadata == eTexMetaDataEntries.Waypoint) { Pen lPen = xiLevel.WaypointIsKeyWaypoint(lVal) ? lKeyWaypointPen : lWaypointPen; g.DrawRectangle( lPen, 0, 0, lTexture.Width - 1, lTexture.Height - 1); } } } lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture); } break; //draw the bumpmap textures on: case eTextureMode.BumpmapTextures: if (TexMetaData != null) { BumpImageChunk lBIC = xiLevel.GetBumpById(TexMetaData[x][y][(int)eTexMetaDataEntries.Bumpmap]); if (lBIC != null) { Bitmap lTexture = lBIC.ToBitmap(); lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture); } } break; default: throw new Exception("Unexpected case"); } //end switch lSurface.Meshes.Add(lSquare); } } lSurface.Scale(ScaleX, ScaleY, 1.0); if (RotationVector.Norm() != 0) { //the rotation is z-y-x lSurface.RotateAboutWorldOrigin(RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis); lSurface.RotateAboutWorldOrigin(-RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis); lSurface.RotateAboutWorldOrigin(-RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis); } Point lNewPos = ThreeDeeViewer.Short3CoordToPoint(OriginPosition); lSurface.Position = new Point(lNewPos.x, lNewPos.y, -lNewPos.z); return lSurface; }
public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { return SHET.GetEntities(xiRootChunk, xiTextureMode, xiSelectedMetadata); }
public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { //a bit hacky: if (this.TreeNode.Checked) { return(new Entity[0]); } Entity lWeaponEntity = ((Level)xiRootChunk).GetObjtById(TMDChunk.OBJT_ID_FOR_WEAPONS_BOX) .GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this); // Set the position. Point lWeaponPosition = ThreeDeeViewer.Short3CoordToPoint(this.OriginPosition); lWeaponEntity.Position = new Point(lWeaponPosition.x, lWeaponPosition.y, -lWeaponPosition.z); List <GLTK.Entity> lRet = new List <Entity>(); lRet.Add(lWeaponEntity); return(lRet); }
public Entity GetEntity(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata, object xiMeshOwner) { MMEdEntity lAcc = new MMEdEntity(xiMeshOwner); Mesh lColouredMesh = null; Dictionary<int, Mesh> lPageIdToTexturedMeshMap = new Dictionary<int, Mesh>(); List<Mesh> lTranslucentMeshes = new List<Mesh>(); //qq move all this into Face class? //qq add quad mode meshes (needs separate meshes currently...) Vertex[] lVBuff = new Vertex[4]; foreach (Face f in Faces) { if (!f.IsUnknownType()) { for (int v = 0; v < f.mVertexIds.Length; v++) { lVBuff[v] = new Vertex(ThreeDeeViewer.Short3CoordToPoint(Vertices[f.mVertexIds[v]])); //normal if (v < f.mNormalIds.Length) lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[v]]).GetPositionVector().Normalise(); else lVBuff[v].Normal = ThreeDeeViewer.Short3CoordToPoint(Normals[f.mNormalIds[0]]).GetPositionVector().Normalise(); //color: if (f.mColors != null && v < f.mColors.Length) lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[v]); else if (f.mColors != null) lVBuff[v].Color = Utils.PSRGBColorToColor(f.mColors[0]); //tex coords if (f.mTexCoords != null && v < f.mTexCoords.Length) { lVBuff[v].TexCoordX = f.mTexCoords[v].X / (double)VRAMViewer.TEX_PAGE_WIDTH; lVBuff[v].TexCoordY = f.mTexCoords[v].Y / (double)VRAMViewer.TEX_PAGE_HEIGHT; } } // Create a new mesh if appropriate, or add this face to an existing mesh // First check if it's tex or solid? Mesh lMesh; if (f.mTexCoords != null) { if (!lPageIdToTexturedMeshMap.ContainsKey(f.mTexPage)) { lMesh = new OwnedMesh(xiMeshOwner); lPageIdToTexturedMeshMap[f.mTexPage] = lMesh; if (xiTextureMode == eTextureMode.NormalTextures || xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lMesh.RenderMode = RenderMode.Textured; lMesh.Texture = AbstractRenderer.ImageToTextureId( VRAMViewer.GetInstance().GetTexturePage(xiRootChunk, f.mTexPage)); } else { lMesh.RenderMode = RenderMode.Wireframe; } } else { lMesh = lPageIdToTexturedMeshMap[f.mTexPage]; } } else { if (f.IsTranslucent()) { lMesh = new OwnedMesh(xiMeshOwner); if (xiTextureMode == eTextureMode.NormalTextures || xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lMesh.RenderMode = RenderMode.TranslucentFilled; } else { lMesh.RenderMode = RenderMode.Wireframe; } lTranslucentMeshes.Add(lMesh); } else { if (lColouredMesh == null) { lColouredMesh = new OwnedMesh(xiMeshOwner); if (xiTextureMode == eTextureMode.NormalTextures || xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lColouredMesh.RenderMode = RenderMode.Filled; } else { lColouredMesh.RenderMode = RenderMode.Wireframe; } } lMesh = lColouredMesh; } } if (f.mVertexIds.Length == 3) { lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]); } else //4 { lMesh.AddFace(lVBuff[0], lVBuff[1], lVBuff[2]); lMesh.AddFace(lVBuff[0], lVBuff[2], lVBuff[3]); } } } foreach (Mesh lTexturedMesh in lPageIdToTexturedMeshMap.Values) { lAcc.Meshes.Add(lTexturedMesh); } if (lColouredMesh != null) lAcc.Meshes.Add(lColouredMesh); lAcc.Meshes.AddRange(lTranslucentMeshes); lAcc.Scale(1, 1, -1); return lAcc; }
public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { //a bit hacky: if (this.TreeNode.Checked) { return new Entity[0]; } List<GLTK.Entity> lRet = new List<Entity>(); TMDChunk lObjt = ((Level)xiRootChunk).GetObjtById(this.ObjtType); if (lObjt != null) { Entity lE = lObjt.GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this); //nasty, but required because the PS 3D world coords are left-handed, //and the OpenGl 3D coords are right handed lE.Scale(1, 1, -1); if (this.RotationVector.Norm() != 0) { //the rotation is z-y-x lE.RotateAboutWorldOrigin(-this.RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis); lE.RotateAboutWorldOrigin(-this.RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis); lE.RotateAboutWorldOrigin(-this.RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis); } lE.Position = ThreeDeeViewer.Short3CoordToPoint(this.OriginPosition); //return to right handed coords lE.Scale(1, 1, -1); lRet.Add(lE); } return lRet; }
public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { if (!(xiRootChunk is Level)) { throw new Exception("xiRootChunk must be Level for SHETChunk.GetEntities"); } List<Entity> lAcc = new List<Entity>(); foreach (FlatChunk fl in Flats) { lAcc.AddRange(fl.GetEntities((Level)xiRootChunk, xiTextureMode, xiSelectedMetadata)); } return lAcc; }
public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { return new Entity[] { GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this) }; }
private GLTK.Entity GetSurfaceEntity(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { // notes: // invert the textures along the y-axis // use level co-ords, so z is down ///////////////////////////////////////////////////// // The surface Entity lSurface = new MMEdEntity(this); Font lNumberFont = null; Brush lNumberFGBrush = null, lNumberBGBrush = null; Pen lWaypointPen = null, lKeyWaypointPen = null; if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata) { lNumberFont = new Font(FontFamily.GenericMonospace, 10); lNumberFGBrush = new SolidBrush(Color.Black); lNumberBGBrush = new SolidBrush(Color.White); lWaypointPen = new Pen(Color.Black, 1f); lKeyWaypointPen = new Pen(Color.Red, 2f); } for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { Mesh lSquare = new OwnedMesh(this, PolygonMode.Quads); lSquare.AddFace( new Vertex(new Point(x, y, -GetTerrainHeightSafe(x, y)), 0, 0), new Vertex(new Point(x + 1, y, -GetTerrainHeightSafe(x + 1, y)), 1, 0), new Vertex(new Point(x + 1, y + 1, -GetTerrainHeightSafe(x + 1, y + 1)), 1, 1), new Vertex(new Point(x, y + 1, -GetTerrainHeightSafe(x, y + 1)), 0, 1)); switch (xiTextureMode) { case eTextureMode.WireFrame: lSquare.RenderMode = RenderMode.Wireframe; break; // normal textures, optionally with metadata drawn on case eTextureMode.NormalTextures: case eTextureMode.NormalTexturesWithMetadata: TIMChunk lTIM = xiLevel.GetTileById(TextureIds[x][y]); if (lTIM != null) { //some TIMs can't be loaded yet: they're null Bitmap lTexture = lTIM.ToBitmap(); if (xiTextureMode == eTextureMode.NormalTexturesWithMetadata && TexMetaData != null) { byte lVal = TexMetaData[x][y][(int)xiSelectedMetadata]; if (lVal != 0) { // we create a new bitmap based on the given texture // a) so that we can modify it freely // and b) to change it from indexed to full colour mode, to allow us // to draw on it (otherwise we'll get an exception) lTexture = new Bitmap(lTexture); Graphics g = Graphics.FromImage(lTexture); string lText = lVal.ToString(); SizeF size = g.MeasureString(lText, lNumberFont); float xf = lTexture.Width / 2.0f - size.Width / 2.0f; float yf = lTexture.Height / 2.0f - size.Height / 2.0f; g.FillRectangle(lNumberBGBrush, xf, yf, size.Width, size.Height); g.DrawString( lText, lNumberFont, lNumberFGBrush, xf, yf); if (xiSelectedMetadata == eTexMetaDataEntries.Waypoint) { Pen lPen = xiLevel.WaypointIsKeyWaypoint(lVal) ? lKeyWaypointPen : lWaypointPen; g.DrawRectangle( lPen, 0, 0, lTexture.Width - 1, lTexture.Height - 1); } } } lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture); } break; //draw the bumpmap textures on: case eTextureMode.BumpmapTextures: if (TexMetaData != null) { BumpImageChunk lBIC = xiLevel.GetBumpById(TexMetaData[x][y][(int)eTexMetaDataEntries.Bumpmap]); if (lBIC != null) { Bitmap lTexture = lBIC.ToBitmap(); lSquare.Texture = AbstractRenderer.ImageToTextureId(lTexture); } } break; default: throw new Exception("Unexpected case"); } //end switch lSurface.Meshes.Add(lSquare); } } lSurface.Scale(ScaleX, ScaleY, 1.0); if (RotationVector.Norm() != 0) { //the rotation is z-y-x lSurface.RotateAboutWorldOrigin(RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis); lSurface.RotateAboutWorldOrigin(-RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis); lSurface.RotateAboutWorldOrigin(-RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis); } Point lNewPos = ThreeDeeViewer.Short3CoordToPoint(OriginPosition); lSurface.Position = new Point(lNewPos.x, lNewPos.y, -lNewPos.z); return(lSurface); }
public IEnumerable <GLTK.Entity> GetEntities(Level xiLevel, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { List <Entity> lAcc = new List <Entity>(); //a bit hacky: if (!this.TreeNode.Checked) { lAcc.Add(GetSurfaceEntity(xiLevel, xiTextureMode, xiSelectedMetadata)); } ///////////////////////////////////////////////////// // The child weapons if (Weapons != null) { foreach (WeaponEntry lWeapon in Weapons) { lAcc.AddRange(lWeapon.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata)); } } ///////////////////////////////////////////////////// // The child objects if (Objects != null) { foreach (ObjectEntry oe in Objects) { lAcc.AddRange(oe.GetEntities(xiLevel, xiTextureMode, xiSelectedMetadata)); } } return(lAcc); }
public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { if (!(xiRootChunk is Level)) { throw new Exception("xiRootChunk must be Level for Level.GetEntities"); } return(GetEntities((Level)xiRootChunk, xiTextureMode, xiSelectedMetadata)); }
///======================================================================== /// Method : CompactImages /// /// <summary> /// Compact images fo the given type - remove any unused images from the /// end of the array. /// </summary> /// <param name="xiImageType"></param> /// <remarks> /// Note that no attempt is made to deduplicate - it is assumed that /// duplicates will be removed via ReindexImages if required. /// </remarks> ///======================================================================== public void CompactImages(eTexMetaDataEntries xiImageType) { Level lLevel = mMainForm.CurrentLevel; if (lLevel == null) { MessageBox.Show("Must have a level open for this action"); return; } //======================================================================= // Work out which array of images to work with //======================================================================= Chunk[] lChunkArray; if (xiImageType == eTexMetaDataEntries.Bumpmap) { lChunkArray = lLevel.SHET.BumpImages.mChildren; } else if (xiImageType == eTexMetaDataEntries.Steering) { lChunkArray = lLevel.SHET.SteeringImages.mChildren; } else if (xiImageType == eTexMetaDataEntries.CameraPos) { lChunkArray = lLevel.SHET.CameraPositions.mChildren; } else { throw new Exception("Internal error: Cannot reindex images of type " + xiImageType.ToString()); } //======================================================================= // Find the highest numbered image that's in use - we'll remove all // higher-numbered images //======================================================================= int lMaxUsedIndex = -1; int lTexMetaIndex = (int)xiImageType; foreach (FlatChunk lFlat in lLevel.SHET.Flats) { if (lFlat.TexMetaData != null) { foreach (byte[][] lRow in lFlat.TexMetaData) { foreach (byte[] lEntry in lRow) { if (lMaxUsedIndex < lEntry[lTexMetaIndex]) { lMaxUsedIndex = lEntry[lTexMetaIndex]; } } } } } if (lMaxUsedIndex == -1) { MessageBox.Show(string.Format("No compaction required - there are no {0} tiles!", xiImageType.ToString().ToLower())); return; } //======================================================================= // Create a new image array and adjust zero padding //======================================================================= Chunk[] lNewChunkArray = new Chunk[lMaxUsedIndex + 1]; Array.Copy(lChunkArray, lNewChunkArray, lMaxUsedIndex + 1); lLevel.SHET.TrailingZeroByteCount += (lChunkArray.Length - (lMaxUsedIndex + 1)) * ((IReindexableChunk)lChunkArray[0]).Data.Length; if (xiImageType == eTexMetaDataEntries.Bumpmap) { lLevel.SHET.BumpImages.mChildren = lNewChunkArray; } else if (xiImageType == eTexMetaDataEntries.Steering) { lLevel.SHET.SteeringImages.mChildren = lNewChunkArray; } else if (xiImageType == eTexMetaDataEntries.CameraPos) { lLevel.SHET.CameraPositions.mChildren = lNewChunkArray; } MessageBox.Show(string.Format("Successfully compacted. There are {0} {1} tiles remaining", lMaxUsedIndex + 1, xiImageType.ToString().ToLower())); }
public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { //a bit hacky: if (this.TreeNode.Checked) { return new Entity[0]; } Entity lWeaponEntity = ((Level)xiRootChunk).GetObjtById(TMDChunk.OBJT_ID_FOR_WEAPONS_BOX) .GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this); // Set the position. Point lWeaponPosition = ThreeDeeViewer.Short3CoordToPoint(this.OriginPosition); lWeaponEntity.Position = new Point(lWeaponPosition.x, lWeaponPosition.y, -lWeaponPosition.z); List<GLTK.Entity> lRet = new List<Entity>(); lRet.Add(lWeaponEntity); return lRet; }
///======================================================================== /// Method : ReindexImages /// /// <summary> /// Reindex images of the given type - remove duplicates and renumber /// to the top of the image array. /// </summary> /// <param name="xiImageType"></param> ///======================================================================== public void ReindexImages(eTexMetaDataEntries xiImageType) { Level lLevel = mMainForm.CurrentLevel; if (lLevel == null) { MessageBox.Show("Must have a level open for this action"); return; } Chunk[] lChunkArray; if (xiImageType == eTexMetaDataEntries.Bumpmap) { lChunkArray = lLevel.SHET.BumpImages.mChildren; } else if (xiImageType == eTexMetaDataEntries.Steering) { lChunkArray = lLevel.SHET.SteeringImages.mChildren; } else if (xiImageType == eTexMetaDataEntries.CameraPos) { lChunkArray = lLevel.SHET.CameraPositions.mChildren; } else { throw new Exception("Internal error: Cannot reindex images of type " + xiImageType.ToString()); } // count how many times each image is currently in use int[] lUseCount = new int[lChunkArray.Length]; int lTexMetaIndex = (int)xiImageType; foreach (FlatChunk flat in lLevel.SHET.Flats) { if (flat.TexMetaData != null) { foreach (byte[][] row in flat.TexMetaData) { foreach (byte[] entry in row) { lUseCount[entry[lTexMetaIndex]]++; } } } } //get a mapping from each equivalence class of chunks to the lowest index in that class SortedDictionary <IReindexableChunk, int> lImagesToCanonicalId = new SortedDictionary <IReindexableChunk, int>(new ReindexableChunkComparer()); for (int i = lChunkArray.Length - 1; i >= 0; i--) { if (lUseCount[i] == 0) { // Ignore any unused images - otherwise we might try to remap used images // to unused ones, which would cause errors when we remove all the unused // images later on. continue; } lImagesToCanonicalId[(IReindexableChunk)lChunkArray[i]] = i; } int[] lOldToNewIndexMap = new int[lUseCount.Length]; //determine where each image should map to: int lNextUnusedId = 0; for (int lOldIdx = 0; lOldIdx < lOldToNewIndexMap.Length; lOldIdx++) { if (lUseCount[lOldIdx] > 0) { //we need to map this to somewhere. //can it be coalesced with other, identical bumps? int lCanonicalId = (int)lImagesToCanonicalId[(IReindexableChunk)lChunkArray[lOldIdx]]; if (lCanonicalId < lOldIdx) { lOldToNewIndexMap[lOldIdx] = lOldToNewIndexMap[lCanonicalId]; } else if (lCanonicalId == lOldIdx) { lOldToNewIndexMap[lOldIdx] = lNextUnusedId; lNextUnusedId++; } else { throw new Exception("Internal error: lCanonicalId can't be greater than lOldIdx"); } } else { lOldToNewIndexMap[lOldIdx] = -1; } } //take a copy of each canonical image, so we don't lose any information Dictionary <int, byte[]> lCanonicalImages = new Dictionary <int, byte[]>(); foreach (KeyValuePair <IReindexableChunk, int> lEntry in lImagesToCanonicalId) { lCanonicalImages.Add(lEntry.Value, (byte[])lEntry.Key.Data.Clone()); } //fill in all the bump images with their new values: int lHighestUsed = -1; for (int lOldIdx = 0; lOldIdx < lOldToNewIndexMap.Length; lOldIdx++) { int lNew = lOldToNewIndexMap[lOldIdx]; if (lNew != -1) { if (lCanonicalImages.ContainsKey(lOldIdx)) { lHighestUsed = lNew; ((IReindexableChunk)lChunkArray[lNew]).Data = lCanonicalImages[lOldIdx]; } } } for (int i = lHighestUsed + 1; i < lChunkArray.Length; i++) { ((IReindexableChunk)lChunkArray[i]).Clear(); } //now update all the bumps in the Flats foreach (FlatChunk flat in lLevel.SHET.Flats) { if (flat.TexMetaData != null) { foreach (byte[][] row in flat.TexMetaData) { foreach (byte[] entry in row) { int lOldIdx = entry[lTexMetaIndex]; int lNewIdx = lOldToNewIndexMap[lOldIdx]; if (lNewIdx < 0) { throw new Exception("Internal error: this image should be unused"); } entry[lTexMetaIndex] = (byte)lNewIdx; } } } } MessageBox.Show(string.Format( "Successfully reindexed. There are {0} {2} tiles in use, and {1} free", lCanonicalImages.Count, lChunkArray.Length - lCanonicalImages.Count, xiImageType.ToString().ToLower())); }
public IEnumerable<GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { if (!(xiRootChunk is Level)) { throw new Exception("xiRootChunk must be Level for Level.GetEntities"); } return GetEntities((Level)xiRootChunk, xiTextureMode, xiSelectedMetadata); }
public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { if (!(xiRootChunk is Level)) { throw new Exception("xiRootChunk must be Level for SHETChunk.GetEntities"); } List <Entity> lAcc = new List <Entity>(); foreach (FlatChunk fl in Flats) { lAcc.AddRange(fl.GetEntities((Level)xiRootChunk, xiTextureMode, xiSelectedMetadata)); } return(lAcc); }
public IEnumerable <GLTK.Entity> GetEntities(Chunk xiRootChunk, eTextureMode xiTextureMode, eTexMetaDataEntries xiSelectedMetadata) { //a bit hacky: if (this.TreeNode.Checked) { return(new Entity[0]); } List <GLTK.Entity> lRet = new List <Entity>(); TMDChunk lObjt = ((Level)xiRootChunk).GetObjtById(this.ObjtType); if (lObjt != null) { Entity lE = lObjt.GetEntity(xiRootChunk, xiTextureMode, xiSelectedMetadata, this); //nasty, but required because the PS 3D world coords are left-handed, //and the OpenGl 3D coords are right handed lE.Scale(1, 1, -1); if (this.RotationVector.Norm() != 0) { //the rotation is z-y-x lE.RotateAboutWorldOrigin(-this.RotationVector.Z / 1024.0 * Math.PI / 2.0, Vector.ZAxis); lE.RotateAboutWorldOrigin(-this.RotationVector.Y / 1024.0 * Math.PI / 2.0, Vector.YAxis); lE.RotateAboutWorldOrigin(-this.RotationVector.X / 1024.0 * Math.PI / 2.0, Vector.XAxis); } lE.Position = ThreeDeeViewer.Short3CoordToPoint(this.OriginPosition); //return to right handed coords lE.Scale(1, 1, -1); lRet.Add(lE); } return(lRet); }