/* * ColonyLevel.cs * Authors: August Zinsser * * Copyright Matthew Belmonte 2007 */ using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; using tAC_Engine; using Pina3D; namespace Astropolis.ColonySimulator { /// /// A tile in the map /// public class ColonyTile { protected float mHeight; public float Height { get { return mHeight; } } /// /// Create a new colony tile /// public ColonyTile(float height) { mHeight = height; } } /// /// A level in the colony simulator /// public class ColonyLevel { protected ColonyTile[,] mGrid; protected float mResolution = 500f; // How many grid points per heightmap points protected Terrain mTerrain; protected PinaModel mTempConsole; /// /// Create a new level /// public ColonyLevel() { } /// /// Sets values for the level /// /// /// public void Initialize(int rows, int cols) { mGrid = new ColonyTile[rows, cols]; int seed = 777; if (mTerrain != null) Pina.RemoveRenderable(mTerrain); mTerrain = new Terrain(PinaState.Default, new PerlinNoise(seed), rows, cols, mResolution, 40f); for (int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) { mGrid[i, j] = new ColonyTile(mTerrain.LookUp(i, j)); } mTerrain.Material = new Material(null, null, null, TextureManager.Load(@"Content\ColonySimulator\sand"), null); mTerrain.Material.DiffuseMap1 = TextureManager.Load(@"Content\ColonySimulator\grass"); mTerrain.Material.DiffuseMap2 = TextureManager.Load(@"Content\ColonySimulator\rock"); mTerrain.Material.DiffuseMap3 = TextureManager.Load(@"Content\ColonySimulator\snow"); Pina.AddRenderable(mTerrain); // Hardcode some buildings PinaState spawnState = PinaState.Default; ColladaFile consoleSource = new ColladaFile(@"Content\Models\10mBox"); spawnState.Matrix *= Matrix.CreateTranslation(new Vector3(30f, 30f, 24f)); mTempConsole = new PinaModel(spawnState, consoleSource); mTempConsole.Material = consoleSource.DefaultMaterial; //mTempConsole.Material.AmbientColor = new Color(100, 255, 100); mTempConsole.Material.DiffuseMap = TextureManager.Load(@"Content\Models\Cement01"); Pina.AddRenderable(mTempConsole); spawnState.Matrix = Matrix.CreateTranslation(new Vector3(50f, 25f, 26f)); spawnState.Matrix *= Matrix.CreateRotationZ(1f); PinaModel anotherBuilding = new PinaModel(spawnState, consoleSource); Pina.AddRenderable(anotherBuilding); spawnState.Matrix = Matrix.CreateTranslation(new Vector3(40f, 45f, 26f)); anotherBuilding = new PinaModel(spawnState, consoleSource); Pina.AddRenderable(anotherBuilding); spawnState.Matrix = Matrix.CreateTranslation(new Vector3(60f, 40f, 31f)); anotherBuilding = new PinaModel(spawnState, new ColladaFile(@"Content\Models\Dude")); Pina.AddRenderable(anotherBuilding); spawnState.Matrix = Matrix.CreateScale(10f) * Matrix.CreateTranslation(70f, 50f, 30f); anotherBuilding = new PinaModel(spawnState, new ColladaFile(@"Content\Models\Dude")); Pina.AddRenderable(anotherBuilding); } public void Update(float dT) { } /// /// Retrieves the height of the ground mesh at the specified x and y position or 0 if the grid does not include the specified point /// public float GetGroundHeight(Vector2 samplePoint) { // Get the 4 nearest grid points int x0 = (int)samplePoint.X; int x1 = x0 + 1; int y0 = (int)samplePoint.Y; int y1 = y0 + 1; // Validate those points if (x0 < 0 || x0 >= mGrid.GetLength(0)) x0 = -1; if (x1 < 1 || x1 >= mGrid.GetLength(0)) x1 = -1; if (y0 < 0 || y0 >= mGrid.GetLength(1)) y0 = -1; if (y1 < 0 || y1 >= mGrid.GetLength(1)) y1 = -1; // Get the values at those points float v00 = 0; float v01 = 0; float v10 = 0; float v11 = 0; if (x0 != -1 && y0 != -1) v00 = mTerrain.LookUp(x0, y0); if (x0 != -1 && y1 != -1) v01 = mTerrain.LookUp(x0, y1); if (x1 != -1 && y0 != -1) v10 = mTerrain.LookUp(x1, y0); if (x1 != -1 && y1 != -1) v11 = mTerrain.LookUp(x1, y1); // Get the x-distances float d0 = 0; float d1 = 0; float dTotal; if (x0 != -1) d0 = samplePoint.X - x0; if (x1 != -1) d1 = x1 - samplePoint.X; dTotal = d0 + d1; // Get the x-weights float w0 = 0; float w1 = 0; if (dTotal > 0) { if (x0 != -1) w0 = (dTotal - d0) / dTotal; if (x1 != -1) w1 = (dTotal - d1) / dTotal; } // Get the frontX and backX values float vfx = 0; float vbx = 0; vfx = w0 * v00 + w1 * v01; vbx = w0 * v10 + w1 * v11; // Get the y-distances d0 = 0; d1 = 0; if (y0 != -1) d0 = samplePoint.Y - y0; if (y1 != -1) d1 = y1 - samplePoint.Y; dTotal = d0 + d1; // Get the y-weights w0 = 0; w1 = 0; if (dTotal > 0) { if (y0 != -1) w0 = (dTotal - d0) / dTotal; if (y1 != -1) w1 = (dTotal - d1) / dTotal; } // Get the weighted average of all values return w0 * vfx + w1 * vbx; } } }