/*
* 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;
}
}
}