///======================================================================== /// Method : AddBump /// /// <summary> /// Add a new Bump, returning the size of the added Bump in bytes /// </summary> /// <param name="xiBump"></param> /// <returns></returns> ///======================================================================== public int AddBump(BumpImageChunk xiBump) { Chunk[] lNewBumpArray = new Chunk[BumpImages.mChildren.Length + 1]; Array.Copy(BumpImages.mChildren, lNewBumpArray, BumpImages.mChildren.Length); lNewBumpArray[BumpImages.mChildren.Length] = xiBump; BumpImages.mChildren = lNewBumpArray; return(xiBump.Data.Length); }
private void FindUnusedBumps() { //======================================================================= // Get a list of all bumps to start with. //======================================================================= for (int i = 0; i < BumpImages.mChildren.Length; i++) { if (!(BumpImages.mChildren[i] is BumpImageChunk)) { continue; } BumpImageChunk lBump = (BumpImageChunk)BumpImages.mChildren[i]; mUnusedBumps[i] = lBump; } //======================================================================= // Now remove all used bumps. //======================================================================= foreach (FlatChunk lFlat in Flats) { if (lFlat.TexMetaData == null) { continue; } for (int x = 0; x < lFlat.Width; x++) { for (int y = 0; y < lFlat.Height; y++) { int lBumpId = lFlat.TexMetaData[x][y][(byte)eTexMetaDataEntries.Bumpmap]; if (mUnusedBumps.ContainsKey(lBumpId)) { mUnusedBumps.Remove(lBumpId); } } } } }
public void Deserialise(Stream inStr, BinaryReader bin) { //header HeaderString1 = StreamUtils.ReadASCIINullTermString(inStr); HeaderString2 = StreamUtils.ReadASCIINullTermString(inStr); HeaderShort1 = bin.ReadInt16(); HeaderShort2 = bin.ReadInt16(); HeaderByte = bin.ReadByte(); int lSheetCount = bin.ReadInt16(); Flats = new FlatChunk[lSheetCount]; for (int i = 0; i < lSheetCount; i++) { Flats[i] = new FlatChunk(bin); } //key waypoints KeyWaypoints = new KeyWaypointsChunk(bin); //now the first set of images. I don't really know //what these do. They might be referred to by TexMetaData[7] short steeringImgCount = bin.ReadInt16(); SteeringImageChunk[] steeringImages = new SteeringImageChunk[steeringImgCount]; for (int i = 0; i < steeringImgCount; i++) { steeringImages[i] = new SteeringImageChunk(i, inStr); } this.SteeringImages = new GroupingChunk("SteeringImages", steeringImages); //now some camera positions: short cameraPositionCount = bin.ReadInt16(); CameraPosChunk[] cameraPositions = new CameraPosChunk[cameraPositionCount]; for (int i = 0; i < cameraPositionCount; i++) { cameraPositions[i] = new CameraPosChunk(i, bin); } this.CameraPositions = new GroupingChunk("CameraPositions", cameraPositions); //now the bump map prototypes. These are referred to by TexMetaData[6] short bumpImgCount = bin.ReadInt16(); BumpImageChunk[] bumpImages = new BumpImageChunk[bumpImgCount]; for (int i = 0; i < bumpImgCount; i++) { bumpImages[i] = new BumpImageChunk(i, inStr); } this.BumpImages = new GroupingChunk("BumpImages", bumpImages); //now trailing zeroes: int lNextByte; while (-1 != (lNextByte = inStr.ReadByte())) { if (lNextByte != 0) { throw new DeserialisationException(string.Format("Expecting SHET to be followed by a block of zeroes. Found {0}", lNextByte), inStr.Position); } TrailingZeroByteCount++; } }
public void CopyFrom(BumpImageChunk xiFrom) { Array.Copy(xiFrom.Data, this.Data, Data.Length); }
public override void SetSubject(Chunk xiChunk) { if (!(xiChunk is BumpImageChunk)) { mChunk = null; } else { mChunk = (BumpImageChunk)xiChunk; } if (mLastSubject == mChunk) { return; } if (mChunk == null) { mMainForm.BumpEditPictureBox.Image = null; } else { byte lType = mChunk.GetPixelType(mX, mY); mMainForm.BumpTypeLabel.Text = GetBumpTypeName(lType); SetUpDropDown(lType); RefreshView(); } mLastSubject = xiChunk; }
///======================================================================== /// Method : UpdateBumpPixel /// /// <summary> /// Update an individual pixel in the bump maps /// </summary> /// <param name="xiTexX"></param> /// <param name="xiTexY"></param> /// <param name="xiBumpPxX"></param> /// <param name="xiBumpPxY"></param> /// <param name="xiNewVal"></param> ///======================================================================== private void UpdateBumpPixel( int xiTexX, //the x-offset of the tex square in the grid int xiTexY, int xiBumpPxX, //the x-offset of the bump pixel in the square int xiBumpPxY, byte xiNewVal) { byte lBumpImageIdx = mSubject.TexMetaData[xiTexX][xiTexY][(int)eTexMetaDataEntries.Bumpmap]; if (lBumpImageIdx >= mBumpImageUsageCountArray.Length) { MessageBox.Show("Cannot edit that bump square: it indexes a non-existant bump. Please edit it numerically first"); return; } //how to update the bump pix depends on how many tex squares //use that bump pix switch (mBumpImageUsageCountArray[lBumpImageIdx]) { case 0: throw new Exception("Interal error: unreachable statement!"); case 1: BumpImageChunk bic = mMainForm.CurrentLevel.GetBumpById(lBumpImageIdx); bic.SetPixelType(xiBumpPxX, xiBumpPxY, xiNewVal); break; default: // i.e. > 1 SHETChunk lShet = mMainForm.CurrentLevel.SHET; BumpImageChunk lNewBump = null; int lNewBumpId = -1; if (lShet.UnusedBumps.Count == 0) { //================================================================= // Create a new bump //================================================================= lNewBumpId = lShet.BumpImages.mChildren.Length; lNewBump = new BumpImageChunk(lNewBumpId); int lSizeIncrease = lShet.AddBump(lNewBump); lShet.TrailingZeroByteCount -= lSizeIncrease; if (lShet.TrailingZeroByteCount < 0) { MessageBox.Show(string.Format( "WARNING: You have just run out of space in your level file - you will need to free up {0} bytes before you can save your changes.", -lShet.TrailingZeroByteCount)); } //================================================================= // Update our usage count array to include the new bump //================================================================= int[] lNewBumpImageUsageCountArray = new int[lNewBumpId + 1]; Array.Copy(mBumpImageUsageCountArray, lNewBumpImageUsageCountArray, mBumpImageUsageCountArray.Length); mBumpImageUsageCountArray = lNewBumpImageUsageCountArray; } else { //================================================================= // Find the first unused bump and use that //================================================================= foreach (DictionaryEntry lEntry in lShet.UnusedBumps) { lNewBumpId = (int)lEntry.Key; lNewBump = (BumpImageChunk)lEntry.Value; break; } lShet.UnusedBumps.Remove(lNewBumpId); } //=================================================================== // Update the bump with the desired contents, and update the terrain // square to use it //=================================================================== BumpImageChunk lOldBump = mMainForm.CurrentLevel.GetBumpById(lBumpImageIdx); lNewBump.CopyFrom(lOldBump); lNewBump.SetPixelType(xiBumpPxX, xiBumpPxY, xiNewVal); mSubject.TexMetaData[xiTexX][xiTexY][(int)eTexMetaDataEntries.Bumpmap] = (byte)lNewBumpId; mBumpImageUsageCountArray[lBumpImageIdx]--; mBumpImageUsageCountArray[lNewBumpId]++; break; } }
public void Deserialise(Stream inStr, BinaryReader bin) { //header HeaderString1 = StreamUtils.ReadASCIINullTermString(inStr); HeaderString2 = StreamUtils.ReadASCIINullTermString(inStr); HeaderShort1 = bin.ReadInt16(); HeaderShort2 = bin.ReadInt16(); HeaderByte = bin.ReadByte(); int lSheetCount = bin.ReadInt16(); Flats = new FlatChunk[lSheetCount]; for (int i = 0; i < lSheetCount; i++) { Flats[i] = new FlatChunk(bin); } //key waypoints KeyWaypoints = new KeyWaypointsChunk(bin); //now the first set of images. I don't really know //what these do. They might be referred to by TexMetaData[7] short steeringImgCount = bin.ReadInt16(); SteeringImageChunk[] steeringImages = new SteeringImageChunk[steeringImgCount]; for (int i = 0; i < steeringImgCount; i++) { steeringImages[i] = new SteeringImageChunk(i, inStr); } this.SteeringImages = new GroupingChunk("SteeringImages", steeringImages); //now some camera positions: short cameraPositionCount = bin.ReadInt16(); CameraPosChunk[] cameraPositions = new CameraPosChunk[cameraPositionCount]; for (int i = 0; i < cameraPositionCount; i++) { cameraPositions[i] = new CameraPosChunk(i, bin); } this.CameraPositions = new GroupingChunk("CameraPositions", cameraPositions); //now the bump map prototypes. These are referred to by TexMetaData[6] short bumpImgCount = bin.ReadInt16(); BumpImageChunk[] bumpImages = new BumpImageChunk[bumpImgCount]; for (int i = 0; i < bumpImgCount; i++) { bumpImages[i] = new BumpImageChunk(i, inStr); } this.BumpImages = new GroupingChunk("BumpImages", bumpImages); //now trailing zeroes: int lNextByte; while (-1 != (lNextByte = inStr.ReadByte())) { if (lNextByte != 0) throw new DeserialisationException(string.Format("Expecting SHET to be followed by a block of zeroes. Found {0}", lNextByte), inStr.Position); TrailingZeroByteCount++; } }
///======================================================================== /// Method : AddBump /// /// <summary> /// Add a new Bump, returning the size of the added Bump in bytes /// </summary> /// <param name="xiBump"></param> /// <returns></returns> ///======================================================================== public int AddBump(BumpImageChunk xiBump) { Chunk[] lNewBumpArray = new Chunk[BumpImages.mChildren.Length + 1]; Array.Copy(BumpImages.mChildren, lNewBumpArray, BumpImages.mChildren.Length); lNewBumpArray[BumpImages.mChildren.Length] = xiBump; BumpImages.mChildren = lNewBumpArray; return xiBump.Data.Length; }
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); }