internal static MapDrawableBatch FromReducedLayer(TMXGlueLib.DataTypes.ReducedLayerInfo reducedLayerInfo, string contentManagerName, int tileDimensionWidth, int tileDimensionHeight, float quadWidth, float quadHeight) { string textureName = reducedLayerInfo.Texture; Texture2D texture = FlatRedBallServices.Load <Texture2D>(textureName, contentManagerName); #if DEBUG if (!MathFunctions.IsPowerOfTwo(texture.Width) || !MathFunctions.IsPowerOfTwo(texture.Height)) { throw new Exception("The dimensions of the texture file " + texture.Name + " are not power of 2!"); } #endif MapDrawableBatch toReturn = new MapDrawableBatch(reducedLayerInfo.Quads.Count, tileDimensionWidth, tileDimensionHeight, texture); toReturn.Name = reducedLayerInfo.Name; Vector3 position = new Vector3(); Vector2 tileDimensions = new Vector2(quadWidth, quadHeight); foreach (var quad in reducedLayerInfo.Quads) { position.X = quad.LeftQuadCoordinate; position.Y = quad.BottomQuadCorodinate; position.Z = reducedLayerInfo.Z; var textureValues = new Vector4(); textureValues.X = (float)quad.LeftTexturePixel / (float)texture.Width; // Left textureValues.Y = (float)(quad.LeftTexturePixel + tileDimensionWidth) / (float)texture.Width; // Right textureValues.Z = (float)quad.TopTexturePixel / (float)texture.Height; // Top textureValues.W = (float)(quad.TopTexturePixel + tileDimensionHeight) / (float)texture.Height; // Bottom const bool pad = true; if (pad) { const float amountToAdd = .0000001f; textureValues.X += amountToAdd; // Left textureValues.Y -= amountToAdd; // Right textureValues.Z += amountToAdd; // Top textureValues.W -= amountToAdd; // Bottom } int tileIndex = toReturn.AddTile(position, tileDimensions, //quad.LeftTexturePixel, quad.TopTexturePixel, quad.LeftTexturePixel + tileDimensionWidth, quad.TopTexturePixel + tileDimensionHeight); textureValues); toReturn.RegisterName(quad.Name, tileIndex); } return(toReturn); }
/* This creates a MapDrawableBatch (MDB) from the list of sprites provided to us by the FlatRedBall (FRB) Scene XML (scnx) file. */ public static MapDrawableBatch FromSpriteSaves(List<SpriteSave> spriteSaveList, int startingIndex, int count, string contentManagerName, bool verifySameTexturesPerLayer) { #if DEBUG if (verifySameTexturesPerLayer) { VerifySingleTexture(spriteSaveList, startingIndex, count); } #endif // We got it! We are going to make some assumptions: // First we need the texture. We'll assume all Sprites // use the same texture: // TODO: I (Bryan) really HATE this assumption. But it will work for now. SpriteSave firstSprite = spriteSaveList[startingIndex]; // This is the file name of the texture, but the file name is relative to the .scnx location string textureRelativeToScene = firstSprite.Texture; // so we load the texture Texture2D texture = FlatRedBallServices.Load<Texture2D>(textureRelativeToScene, contentManagerName); if (!MathFunctions.IsPowerOfTwo(texture.Width) || !MathFunctions.IsPowerOfTwo(texture.Height)) { throw new Exception("The dimensions of the texture file " + texture.Name + " are not power of 2!"); } // Assume all the dimensions of the textures are the same. I.e. all tiles use the same texture width and height. // This assumption is safe for Iso and Ortho tile maps. int tileFileDimensionsWidth = 0; int tileFileDimensionsHeight = 0; if (spriteSaveList.Count > startingIndex) { SpriteSave s = spriteSaveList[startingIndex]; // deduce the dimensionality of the tile from the texture coordinates tileFileDimensionsWidth = (int)System.Math.Round((double)((s.RightTextureCoordinate - s.LeftTextureCoordinate) * texture.Width)); tileFileDimensionsHeight = (int)System.Math.Round((double)((s.BottomTextureCoordinate - s.TopTextureCoordinate) * texture.Height)); } // alas, we create the MDB MapDrawableBatch mMapBatch = new MapDrawableBatch(count, tileFileDimensionsWidth, tileFileDimensionsHeight, texture); int lastIndexExclusive = startingIndex + count; for (int i = startingIndex; i < lastIndexExclusive; i++) { SpriteSave spriteSave = spriteSaveList[i]; // here we have the Sprite's X and Y in absolute coords as well as its texture coords // NOTE: I appended the Z coordinate for the sake of iso maps. This SHOULDN'T have an effect on the ortho maps since I believe the // TMX->SCNX tool sets all z to zero. // The AddTile method expects the bottom-left corner float x = spriteSave.X - spriteSave.ScaleX; float y = spriteSave.Y - spriteSave.ScaleY; float z = spriteSave.Z; float width = 2f * spriteSave.ScaleX; // w float height = 2f * spriteSave.ScaleY; // z float topTextureCoordinate = spriteSave.TopTextureCoordinate; float bottomTextureCoordinate = spriteSave.BottomTextureCoordinate; float leftTextureCoordinate = spriteSave.LeftTextureCoordinate; float rightTextureCoordinate = spriteSave.RightTextureCoordinate; int tileIndex = mMapBatch.mCurrentNumberOfTiles; mMapBatch.RegisterName(spriteSave.Name, tileIndex); // add the textured tile to our map so that we may draw it. mMapBatch.AddTile(new Vector3(x, y, z), new Vector2(width, height), new Vector4(leftTextureCoordinate, rightTextureCoordinate, topTextureCoordinate, bottomTextureCoordinate)); } return mMapBatch; }
internal static MapDrawableBatch FromReducedLayer(TMXGlueLib.DataTypes.ReducedLayerInfo reducedLayerInfo, string contentManagerName, int tileDimensionWidth, int tileDimensionHeight, float quadWidth, float quadHeight) { string textureName = reducedLayerInfo.Texture; Texture2D texture = FlatRedBallServices.Load<Texture2D>(textureName, contentManagerName); #if DEBUG if (!MathFunctions.IsPowerOfTwo(texture.Width) || !MathFunctions.IsPowerOfTwo(texture.Height)) { throw new Exception("The dimensions of the texture file " + texture.Name + " are not power of 2!"); } #endif MapDrawableBatch toReturn = new MapDrawableBatch(reducedLayerInfo.Quads.Count, tileDimensionWidth, tileDimensionHeight, texture); Vector3 position = new Vector3(); Vector2 tileDimensions = new Vector2(quadWidth, quadHeight); foreach (var quad in reducedLayerInfo.Quads) { position.X = quad.LeftQuadCoordinate; position.Y = quad.BottomQuadCorodinate; var textureValues = new Vector4(); textureValues.X = (float)quad.LeftTexturePixel / (float)texture.Width; // Left textureValues.Y = (float)(quad.LeftTexturePixel + tileDimensionWidth) / (float)texture.Width; // Right textureValues.Z = (float)quad.TopTexturePixel / (float)texture.Height; // Top textureValues.W = (float)(quad.TopTexturePixel + tileDimensionHeight) / (float)texture.Height; // Bottom const bool pad = true; if (pad) { const float amountToAdd = .0000001f; textureValues.X += amountToAdd; // Left textureValues.Y -= amountToAdd; // Right textureValues.Z += amountToAdd; // Top textureValues.W -= amountToAdd; // Bottom } int tileIndex = toReturn.AddTile(position, tileDimensions, //quad.LeftTexturePixel, quad.TopTexturePixel, quad.LeftTexturePixel + tileDimensionWidth, quad.TopTexturePixel + tileDimensionHeight); textureValues); toReturn.RegisterName(quad.Name, tileIndex); } return toReturn; }
internal static MapDrawableBatch FromReducedLayer(TMXGlueLib.DataTypes.ReducedLayerInfo reducedLayerInfo, TMXGlueLib.DataTypes.ReducedTileMapInfo rtmi, string contentManagerName) { int tileDimensionWidth = rtmi.CellWidthInPixels; int tileDimensionHeight = rtmi.CellHeightInPixels; float quadWidth = rtmi.QuadWidth; float quadHeight = rtmi.QuadHeight; string textureName = reducedLayerInfo.Texture; #if IOS || ANDROID textureName = textureName.ToLowerInvariant(); #endif Texture2D texture = FlatRedBallServices.Load<Texture2D>(textureName, contentManagerName); #if DEBUG if (!MathFunctions.IsPowerOfTwo(texture.Width) || !MathFunctions.IsPowerOfTwo(texture.Height)) { throw new Exception("The dimensions of the texture file " + texture.Name + " are not power of 2!"); } #endif MapDrawableBatch toReturn = new MapDrawableBatch(reducedLayerInfo.Quads.Count, tileDimensionWidth, tileDimensionHeight, texture); toReturn.Name = reducedLayerInfo.Name; Vector3 position = new Vector3(); Vector2 tileDimensions = new Vector2(quadWidth, quadHeight); IEnumerable<TMXGlueLib.DataTypes.ReducedQuadInfo> quads = null; if (rtmi.NumberCellsWide > rtmi.NumberCellsTall) { quads = reducedLayerInfo.Quads.OrderBy(item => item.LeftQuadCoordinate); toReturn.mSortAxis = SortAxis.X; } else { quads = reducedLayerInfo.Quads.OrderBy(item => item.BottomQuadCoordinate); toReturn.mSortAxis = SortAxis.Y; } foreach (var quad in quads) { position.X = quad.LeftQuadCoordinate; position.Y = quad.BottomQuadCoordinate; // The Z of the quad should be relative to this layer, not absolute Z values. // A multi-layer map will offset the individual layer Z values, the quads should have a Z of 0. // position.Z = reducedLayerInfo.Z; var textureValues = new Vector4(); textureValues.X = (float)quad.LeftTexturePixel / (float)texture.Width; // Left textureValues.Y = (float)(quad.LeftTexturePixel + tileDimensionWidth) / (float)texture.Width; // Right textureValues.Z = (float)quad.TopTexturePixel / (float)texture.Height; // Top textureValues.W = (float)(quad.TopTexturePixel + tileDimensionHeight) / (float)texture.Height; // Bottom // pad before doing any rotations/flipping const bool pad = true; if (pad) { const float amountToAdd = .0000001f; textureValues.X += amountToAdd; // Left textureValues.Y -= amountToAdd; // Right textureValues.Z += amountToAdd; // Top textureValues.W -= amountToAdd; // Bottom } if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedHorizontallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedHorizontallyFlag) { var temp = textureValues.Y; textureValues.Y = textureValues.X; textureValues.X = temp; } if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedVerticallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedVerticallyFlag) { var temp = textureValues.Z; textureValues.Z = textureValues.W; textureValues.W = temp; } int tileIndex = toReturn.AddTile(position, tileDimensions, //quad.LeftTexturePixel, quad.TopTexturePixel, quad.LeftTexturePixel + tileDimensionWidth, quad.TopTexturePixel + tileDimensionHeight); textureValues); if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedDiagonallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedDiagonallyFlag) { toReturn.ApplyDiagonalFlip(tileIndex); } toReturn.RegisterName(quad.Name, tileIndex); } return toReturn; }
internal static MapDrawableBatch FromReducedLayer(TMXGlueLib.DataTypes.ReducedLayerInfo reducedLayerInfo, LayeredTileMap owner, TMXGlueLib.DataTypes.ReducedTileMapInfo rtmi, string contentManagerName) { int tileDimensionWidth = reducedLayerInfo.TileWidth; int tileDimensionHeight = reducedLayerInfo.TileHeight; float quadWidth = reducedLayerInfo.TileWidth; float quadHeight = reducedLayerInfo.TileHeight; string textureName = reducedLayerInfo.Texture; #if IOS || ANDROID textureName = textureName.ToLowerInvariant(); #endif Texture2D texture = FlatRedBallServices.Load <Texture2D>(textureName, contentManagerName); MapDrawableBatch toReturn = new MapDrawableBatch(reducedLayerInfo.Quads.Count, tileDimensionWidth, tileDimensionHeight, texture); toReturn.Name = reducedLayerInfo.Name; Vector3 position = new Vector3(); Vector2 tileDimensions = new Vector2(quadWidth, quadHeight); IEnumerable <TMXGlueLib.DataTypes.ReducedQuadInfo> quads = null; if (rtmi.NumberCellsWide > rtmi.NumberCellsTall) { quads = reducedLayerInfo.Quads.OrderBy(item => item.LeftQuadCoordinate).ToList(); toReturn.mSortAxis = SortAxis.X; } else { quads = reducedLayerInfo.Quads.OrderBy(item => item.BottomQuadCoordinate).ToList(); toReturn.mSortAxis = SortAxis.Y; } foreach (var quad in quads) { position.X = quad.LeftQuadCoordinate; position.Y = quad.BottomQuadCoordinate; // The Z of the quad should be relative to this layer, not absolute Z values. // A multi-layer map will offset the individual layer Z values, the quads should have a Z of 0. // position.Z = reducedLayerInfo.Z; var textureValues = new Vector4(); // The purpose of CoordinateAdjustment is to bring the texture values "in", to reduce the chance of adjacent // tiles drawing on a given tile quad. If we don't do this, we can get slivers of adjacent colors appearing, causing // lines or grid patterns. // To bring the values "in" we have to consider rotated quads. textureValues.X = CoordinateAdjustment + (float)quad.LeftTexturePixel / (float)texture.Width; // Left textureValues.Y = -CoordinateAdjustment + (float)(quad.LeftTexturePixel + tileDimensionWidth) / (float)texture.Width; // Right textureValues.Z = CoordinateAdjustment + (float)quad.TopTexturePixel / (float)texture.Height; // Top textureValues.W = -CoordinateAdjustment + (float)(quad.TopTexturePixel + tileDimensionHeight) / (float)texture.Height; // Bottom // pad before doing any rotations/flipping const bool pad = true; if (pad) { const float amountToAdd = .0000001f; textureValues.X += amountToAdd; // Left textureValues.Y -= amountToAdd; // Right textureValues.Z += amountToAdd; // Top textureValues.W -= amountToAdd; // Bottom } if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedHorizontallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedHorizontallyFlag) { var temp = textureValues.Y; textureValues.Y = textureValues.X; textureValues.X = temp; } if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedVerticallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedVerticallyFlag) { var temp = textureValues.Z; textureValues.Z = textureValues.W; textureValues.W = temp; } int tileIndex = toReturn.AddTile(position, tileDimensions, //quad.LeftTexturePixel, quad.TopTexturePixel, quad.LeftTexturePixel + tileDimensionWidth, quad.TopTexturePixel + tileDimensionHeight); textureValues); if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedDiagonallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedDiagonallyFlag) { toReturn.ApplyDiagonalFlip(tileIndex); } // This was moved to outside of this conversion, to support shaps //if (quad.QuadSpecificProperties != null) //{ // var listToAdd = quad.QuadSpecificProperties.ToList(); // listToAdd.Add(new NamedValue { Name = "Name", Value = quad.Name }); // owner.Properties.Add(quad.Name, listToAdd); //} if (quad.RotationDegrees != 0) { // Tiled rotates clockwise :( var rotationRadians = -MathHelper.ToRadians(quad.RotationDegrees); Vector3 bottomLeftPos = toReturn.Vertices[tileIndex * 4].Position; Vector3 vertPos = toReturn.Vertices[tileIndex * 4 + 1].Position; MathFunctions.RotatePointAroundPoint(bottomLeftPos, ref vertPos, rotationRadians); toReturn.Vertices[tileIndex * 4 + 1].Position = vertPos; vertPos = toReturn.Vertices[tileIndex * 4 + 2].Position; MathFunctions.RotatePointAroundPoint(bottomLeftPos, ref vertPos, rotationRadians); toReturn.Vertices[tileIndex * 4 + 2].Position = vertPos; vertPos = toReturn.Vertices[tileIndex * 4 + 3].Position; MathFunctions.RotatePointAroundPoint(bottomLeftPos, ref vertPos, rotationRadians); toReturn.Vertices[tileIndex * 4 + 3].Position = vertPos; } toReturn.RegisterName(quad.Name, tileIndex); } return(toReturn); }
/* This creates a MapDrawableBatch (MDB) from the list of sprites provided to us by the FlatRedBall (FRB) Scene XML (scnx) file. */ public static MapDrawableBatch FromSpriteSaves(List <SpriteSave> spriteSaveList, int startingIndex, int count, string contentManagerName, bool verifySameTexturesPerLayer) { #if DEBUG if (verifySameTexturesPerLayer) { VerifySingleTexture(spriteSaveList, startingIndex, count); } #endif // We got it! We are going to make some assumptions: // First we need the texture. We'll assume all Sprites // use the same texture: // TODO: I (Bryan) really HATE this assumption. But it will work for now. SpriteSave firstSprite = spriteSaveList[startingIndex]; // This is the file name of the texture, but the file name is relative to the .scnx location string textureRelativeToScene = firstSprite.Texture; // so we load the texture Texture2D texture = FlatRedBallServices.Load <Texture2D>(textureRelativeToScene, contentManagerName); if (!MathFunctions.IsPowerOfTwo(texture.Width) || !MathFunctions.IsPowerOfTwo(texture.Height)) { throw new Exception("The dimensions of the texture file " + texture.Name + " are not power of 2!"); } // Assume all the dimensions of the textures are the same. I.e. all tiles use the same texture width and height. // This assumption is safe for Iso and Ortho tile maps. int tileFileDimensionsWidth = 0; int tileFileDimensionsHeight = 0; if (spriteSaveList.Count > startingIndex) { SpriteSave s = spriteSaveList[startingIndex]; // deduce the dimensionality of the tile from the texture coordinates tileFileDimensionsWidth = (int)System.Math.Round((double)((s.RightTextureCoordinate - s.LeftTextureCoordinate) * texture.Width)); tileFileDimensionsHeight = (int)System.Math.Round((double)((s.BottomTextureCoordinate - s.TopTextureCoordinate) * texture.Height)); } // alas, we create the MDB MapDrawableBatch mMapBatch = new MapDrawableBatch(count, tileFileDimensionsWidth, tileFileDimensionsHeight, texture); int lastIndexExclusive = startingIndex + count; for (int i = startingIndex; i < lastIndexExclusive; i++) { SpriteSave spriteSave = spriteSaveList[i]; // here we have the Sprite's X and Y in absolute coords as well as its texture coords // NOTE: I appended the Z coordinate for the sake of iso maps. This SHOULDN'T have an effect on the ortho maps since I believe the // TMX->SCNX tool sets all z to zero. // The AddTile method expects the bottom-left corner float x = spriteSave.X - spriteSave.ScaleX; float y = spriteSave.Y - spriteSave.ScaleY; float z = spriteSave.Z; float width = 2f * spriteSave.ScaleX; // w float height = 2f * spriteSave.ScaleY; // z float topTextureCoordinate = spriteSave.TopTextureCoordinate; float bottomTextureCoordinate = spriteSave.BottomTextureCoordinate; float leftTextureCoordinate = spriteSave.LeftTextureCoordinate; float rightTextureCoordinate = spriteSave.RightTextureCoordinate; int tileIndex = mMapBatch.mCurrentNumberOfTiles; mMapBatch.RegisterName(spriteSave.Name, tileIndex); // add the textured tile to our map so that we may draw it. mMapBatch.AddTile(new Vector3(x, y, z), new Vector2(width, height), new Vector4(leftTextureCoordinate, rightTextureCoordinate, topTextureCoordinate, bottomTextureCoordinate)); } return(mMapBatch); }
internal static MapDrawableBatch FromReducedLayer(TMXGlueLib.DataTypes.ReducedLayerInfo reducedLayerInfo, TMXGlueLib.DataTypes.ReducedTileMapInfo rtmi, string contentManagerName) { int tileDimensionWidth = rtmi.CellWidthInPixels; int tileDimensionHeight = rtmi.CellHeightInPixels; float quadWidth = rtmi.QuadWidth; float quadHeight = rtmi.QuadHeight; string textureName = reducedLayerInfo.Texture; #if IOS || ANDROID textureName = textureName.ToLowerInvariant(); #endif Texture2D texture = FlatRedBallServices.Load <Texture2D>(textureName, contentManagerName); #if DEBUG if (!MathFunctions.IsPowerOfTwo(texture.Width) || !MathFunctions.IsPowerOfTwo(texture.Height)) { throw new Exception("The dimensions of the texture file " + texture.Name + " are not power of 2!"); } #endif MapDrawableBatch toReturn = new MapDrawableBatch(reducedLayerInfo.Quads.Count, tileDimensionWidth, tileDimensionHeight, texture); toReturn.Name = reducedLayerInfo.Name; Vector3 position = new Vector3(); Vector2 tileDimensions = new Vector2(quadWidth, quadHeight); IEnumerable <TMXGlueLib.DataTypes.ReducedQuadInfo> quads = null; if (rtmi.NumberCellsWide > rtmi.NumberCellsTall) { quads = reducedLayerInfo.Quads.OrderBy(item => item.LeftQuadCoordinate); toReturn.mSortAxis = SortAxis.X; } else { quads = reducedLayerInfo.Quads.OrderBy(item => item.BottomQuadCoordinate); toReturn.mSortAxis = SortAxis.Y; } foreach (var quad in quads) { position.X = quad.LeftQuadCoordinate; position.Y = quad.BottomQuadCoordinate; // The Z of the quad should be relative to this layer, not absolute Z values. // A multi-layer map will offset the individual layer Z values, the quads should have a Z of 0. // position.Z = reducedLayerInfo.Z; var textureValues = new Vector4(); textureValues.X = (float)quad.LeftTexturePixel / (float)texture.Width; // Left textureValues.Y = (float)(quad.LeftTexturePixel + tileDimensionWidth) / (float)texture.Width; // Right textureValues.Z = (float)quad.TopTexturePixel / (float)texture.Height; // Top textureValues.W = (float)(quad.TopTexturePixel + tileDimensionHeight) / (float)texture.Height; // Bottom // pad before doing any rotations/flipping const bool pad = true; if (pad) { const float amountToAdd = .0000001f; textureValues.X += amountToAdd; // Left textureValues.Y -= amountToAdd; // Right textureValues.Z += amountToAdd; // Top textureValues.W -= amountToAdd; // Bottom } if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedHorizontallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedHorizontallyFlag) { var temp = textureValues.Y; textureValues.Y = textureValues.X; textureValues.X = temp; } if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedVerticallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedVerticallyFlag) { var temp = textureValues.Z; textureValues.Z = textureValues.W; textureValues.W = temp; } int tileIndex = toReturn.AddTile(position, tileDimensions, //quad.LeftTexturePixel, quad.TopTexturePixel, quad.LeftTexturePixel + tileDimensionWidth, quad.TopTexturePixel + tileDimensionHeight); textureValues); if ((quad.FlipFlags & TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedDiagonallyFlag) == TMXGlueLib.DataTypes.ReducedQuadInfo.FlippedDiagonallyFlag) { toReturn.RotateTextureCoordinatesCounterclockwise(tileIndex); } toReturn.RegisterName(quad.Name, tileIndex); } return(toReturn); }