public Terrain( Game game, IHeightMap heightMap, ICamera camera ) : base( game ) { mGame = game; mHeightMap = heightMap; mCamera = camera; mTerrainCells = new List<TerrainCell>(); }
public GeoMipmap(IHeightMap map, int patchsize, float scale,float heightscale) { int count; if (map.Size.X != map.Size.Y) throw new Exception("map.Size.X!=map.Size.Y"); if (IsPowerOf2(map.Size.X - 1)) { count = (map.Size.X - 1) / (patchsize - 1); } else if (IsPowerOf2(map.Size.X)) { count = map.Size.X / (patchsize - 1); } else throw new Exception("!IsPowerOf2(map.Size.X-1)"); if (map.Size.X < patchsize) throw new Exception("map.Size.X<patchvertexsize"); int levels = (int)(Math.Log((double)(patchsize - 1)) / Math.Log(2.0)) + 1; Levels = GenerateLevels(levels,patchsize); Patches = GeneratePatches(map, patchsize, count, scale,heightscale); Size = scale * count; Lod = new int[count, count]; System.Console.WriteLine("terrain: " + map.Size.X + "x" + map.Size.X + "+size=" + Size.ToString() + " patchcount=" + count.ToString()); }
/// <summary> /// Build a terrain patch. /// </summary> /// <param name="heightmap"></param> /// <param name="worldMatrix"></param> /// <param name="width"></param> /// <param name="depth"></param> /// <param name="offsetX"></param> /// <param name="offsetZ"></param> public void BuildPatch(IHeightMap heightmap, Matrix worldMatrix, int width, int length, int offsetX, int offsetZ) { mWidth = width; mLength = length; mOffsetX = offsetX; mOffsetZ = offsetZ; mBoundingBox.Min = new Vector3(mOffsetX, float.MaxValue, mOffsetZ); mBoundingBox.Max = new Vector3(mOffsetX + mWidth, float.MinValue, mOffsetZ + mLength); BuildBoundingBox(heightmap); //BuildVertexBuffer( heightmap ); /* * mVertexBuffer = new VertexBuffer( mGame.GraphicsDevice, VertexPositionNormalTexture.SizeInBytes * mVertexPosition.Length, BufferUsage.WriteOnly ); * mVertexBuffer.SetData<VertexPositionNormalTexture>( mVertexPosition ); * * BuildIndexBuffer(); * * mIndexBuffer = new IndexBuffer( mGame.GraphicsDevice, sizeof( short ) * mIndices.Length, BufferUsage.WriteOnly, IndexElementSize.SixteenBits ); * mIndexBuffer.SetData<short>( mIndices ); */ // Apply the world matrix transformation to the bounding box. mBoundingBox.Min = Vector3.Transform(mBoundingBox.Min, worldMatrix); mBoundingBox.Max = Vector3.Transform(mBoundingBox.Max, worldMatrix); }
void GenerateIsometric(WallGrid grid, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap) { ceilingMesh = MeshBuilder.BuildCeiling(grid, ceilingHeightMap); outlines = OutlineGenerator.Generate(ceilingMesh); wallMesh = MeshBuilder.BuildWalls(outlines, floorHeightMap, ceilingHeightMap); floorMesh = MeshBuilder.BuildFloor(grid, floorHeightMap); }
/// <summary> /// Build a terrain patch. /// </summary> /// <param name="heightmap"></param> /// <param name="worldMatrix"></param> /// <param name="width"></param> /// <param name="depth"></param> /// <param name="offsetX"></param> /// <param name="offsetZ"></param> public void BuildPatch( IHeightMap heightmap, Matrix worldMatrix, int width, int length, int offsetX, int offsetZ ) { mWidth = width; mLength = length; mOffsetX = offsetX; mOffsetZ = offsetZ; mBoundingBox.Min = new Vector3( mOffsetX, float.MaxValue, mOffsetZ ); mBoundingBox.Max = new Vector3( mOffsetX + mWidth, float.MinValue, mOffsetZ + mLength ); BuildBoundingBox( heightmap ); BuildVertexBuffer( heightmap ); BuildIndexBuffer( heightmap ); BuildNormals(); BuildTerrainTexWeights( heightmap ); mVertexBuffer = new VertexBuffer( mGame.GraphicsDevice, VertexMultiTextured.SizeInBytes * mPatchVertices.Length, BufferUsage.WriteOnly ); mVertexBuffer.SetData( mPatchVertices ); mIndexBuffer = new IndexBuffer( mGame.GraphicsDevice, sizeof( int ) * mPatchIndices.Length, BufferUsage.WriteOnly, IndexElementSize.SixteenBits ); mIndexBuffer.SetData( mPatchIndices ); mTerrainVertexDeclaration = new VertexDeclaration( mGame.GraphicsDevice, VertexMultiTextured.VertexElements ); // Apply the world matrix transformation to the bounding box. mBoundingBox.Min = Vector3.Transform( mBoundingBox.Min, worldMatrix ); mBoundingBox.Max = Vector3.Transform( mBoundingBox.Max, worldMatrix ); }
/// <summary> /// Generates meshes for a cave. /// </summary> /// <exception cref="System.ArgumentException"></exception> /// <exception cref="System.ArgumentNullException"></exception> public static CaveMeshes GenerateCaveMeshes(WallGrid grid, CaveType type, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap) { var generator = new MeshGenerator(); generator.Generate(grid, type, floorHeightMap, ceilingHeightMap); return(generator.ExtractMeshes()); }
public GameObject Generate(ThreeTierCaveConfiguration config, bool randomizeSeeds) { if (config == null) { throw new ArgumentNullException("config"); } string message = config.Validate(); if (message.Length > 0) { throw new ArgumentException(message, "config"); } if (randomizeSeeds) { config.SetSeed(GetRandomSeed()); } Map map = config.MapGenerator.Generate(); IHeightMap floor = config.FloorHeightMapModule.GetHeightMap(); IHeightMap ceiling = config.CeilingHeightMapModule.GetHeightMap(); Map[,] mapChunks = MapSplitter.Subdivide(map); CaveMeshes[,] caveChunks = GenerateCaveChunks(mapChunks, config.CaveType, config.Scale, floor, ceiling); ThreeTierCave cave = new ThreeTierCave(caveChunks); AssignMaterials(cave, config.FloorMaterial, config.WallMaterial, config.CeilingMaterial); return(cave.GameObject); }
public override void Initialise(ref IHeightMap heightMap) { mHeightCenter = heightMap[mCenter.X, mCenter.Y] - mRadiusRim; float maxH = float.MinValue; float minH = float.MinValue; for (int x = 0; x < heightMap.Width; x++) { for (int y = 0; y < heightMap.Height; y++) { float distanceFromCenter = new Point(x, y).DistanceTo(mCenter); bool inInnerCircle = distanceFromCenter <= mRadiusRim; bool inOuterCircle = !inInnerCircle && (distanceFromCenter < mRadiusOuter); if (inOuterCircle && heightMap[x, y] > maxH) { maxH = heightMap[x, y]; } if (inOuterCircle && heightMap[x, y] < minH) { minH = heightMap[x, y]; } } } mHeightRim = maxH + mRadiusOuter * 0.10f; mHeightOuter = (maxH - minH) / 2.0f; base.Initialise(ref heightMap); }
public IPhysicsObject CreateHeightmap(IHeightMap heightMapInfo, float scale, float shiftx, float shifty, float heightscale) { CollisionSkin collision = new CollisionSkin(null); Body _body = new Body(); Array2D field = new Array2D(heightMapInfo.Size.X, heightMapInfo.Size.Y); for (int x = 0; x < field.Nx; x++) { for (int z = 0; z < field.Nz; z++) { field.SetAt(x, z, heightscale * heightMapInfo.GetHeight(x, z)); } } // move the body. The body (because its not connected to the collision // skin) is just a dummy. But the base class shoudl know where to // draw the model. _body.MoveTo(new Vector3(shiftx, 0, shifty), Matrix4.Identity); //collision.AddPrimitive(new Heightmap(field, shift.X, shift.Y, heightMapInfo.terrainScale, heightMapInfo.terrainScale), new MaterialProperties(0.7f, 0.7f, 0.6f)); collision.AddPrimitive(new Heightmap(field, shiftx, shifty, scale, scale), new MaterialProperties(0.7f, 0.7f, 0.6f)); _body.CollisionSkin = collision; _body.Immovable = true; _body.EnableBody(); return(new JigLibObject(_body)); }
/// <summary> /// Build the vertex buffer as well as the bounding box. /// </summary> /// <param name="heightmap"></param> private void BuildVertexBuffer(IHeightMap heightmap) { int index = 0; float height = 0f; Vector3 position, normal; mVertexPosition = new VertexPositionNormalTexture[mWidth * mLength]; for (int z = mOffsetZ; z < mOffsetZ + mLength; z++) { for (int x = mOffsetX; x < mOffsetX + mWidth; x++, index++) { height = heightmap[x, z]; position = new Vector3((float)x, height, (float)z); mBoundingBox.Min.Y = Math.Min(height, mBoundingBox.Min.Y); mBoundingBox.Max.Y = Math.Max(height, mBoundingBox.Max.Y); ComputeVertexNormal(heightmap, x, z, out normal); mVertexPosition[index] = new VertexPositionNormalTexture(position, normal, new Vector2(x, z)); } } }
public MeshData BuildWalls(WallGrid grid, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap, CaveWallModule caveWall) { var outlines = BuildOutlines(grid); var wallBuilder = new WallBuilder(outlines, floorHeightMap, ceilingHeightMap, caveWall); return(wallBuilder.Build()); }
public bool load(Variant conf, Action onFin) { this.m_conf = conf; bool flag = conf == null; bool result; if (flag) { result = false; } else { bool flag2 = this.m_conf.ContainsKey("asset"); if (flag2) { Variant variant = this.m_conf["asset"]; for (int i = 0; i < variant.Count; i++) { Variant variant2 = variant[i]; bool flag3 = variant2.ContainsKey("file"); if (flag3) { bool flag4 = variant2["cls"]._str == "htmap"; if (flag4) { this.m_heightmap = os.physics.createScene3D().createHeightMap(); this.m_heightmap.asset = os.asset.getAsset <IAssetHeightMap>(variant2["file"]._str); } } } } result = true; } return(result); }
public override GameObject Generate() { int scale = configuration.Scale; Map map = configuration.MapGenerator.Generate(); Material floorMaterial = configuration.Material; IHeightMap heightMap = configuration.HeightMapModule.GetHeightMap(); OutlineModule outlinePrefabber = configuration.OutlineModule; GameObject cave = new GameObject("Cave"); Map[,] mapChunks = MapSplitter.Subdivide(map); mapChunks.ForEach((x, y) => { Coord index = new Coord(x, y); WallGrid grid = MapConverter.MapToWallGrid(mapChunks[x, y], scale, index); List <Vector3[]> outlines = meshGenerator.BuildOutlines(grid); CaveMeshes caveMeshes = BuildCaveMesh(grid, heightMap); Sector sector = BuildSector(caveMeshes, index, cave, floorMaterial); GameObject rockAnchor = BuildRockAnchor(sector.GameObject, index); BuildOutline(outlines, outlinePrefabber, rockAnchor.transform); }); return(cave); }
private void BuildTerrainTexWeights(IHeightMap mHeightMap) { int index = 0; for (int x = 0; x < mWidth; x++) { for (int y = 0; y < mLength; y++) { index = x + y * mWidth; if (mPatchVertices[index].Normal.Y > 0.6f) { mPatchVertices[index].TexWeights.X = GetTexWeight(mHeightMap, x, y, 0f, 8f); mPatchVertices[index].TexWeights.Y = GetTexWeight(mHeightMap, x, y, 12f, 6f); mPatchVertices[index].TexWeights.Z = 1.0f - mPatchVertices[index].Normal.Y; mPatchVertices[index].TexWeights.W = GetTexWeight(mHeightMap, x, y, 30f, 6f); } else { mPatchVertices[index].TexWeights.Z = 1.0f; mPatchVertices[index].TexWeights.W = GetTexWeight(mHeightMap, x, y, 30f, 6f); } // normalise fuzzy weights -- to sum up to one float total = mPatchVertices[index].TexWeights.X + mPatchVertices[index].TexWeights.Y + mPatchVertices[index].TexWeights.Z + mPatchVertices[index].TexWeights.W; mPatchVertices[index].TexWeights.X /= total; mPatchVertices[index].TexWeights.Y /= total; mPatchVertices[index].TexWeights.Z /= total; mPatchVertices[index].TexWeights.W /= total; } } }
/// <summary> /// Build a terrain patch. /// </summary> /// <param name="heightmap"></param> /// <param name="worldMatrix"></param> /// <param name="width"></param> /// <param name="depth"></param> /// <param name="offsetX"></param> /// <param name="offsetZ"></param> public void BuildPatch(IHeightMap heightmap, Matrix worldMatrix, int width, int length, int offsetX, int offsetZ) { mWidth = width; mLength = length; mOffsetX = offsetX; mOffsetZ = offsetZ; mBoundingBox.Min = new Vector3(mOffsetX, float.MaxValue, mOffsetZ); mBoundingBox.Max = new Vector3(mOffsetX + mWidth, float.MinValue, mOffsetZ + mLength); BuildBoundingBox(heightmap); BuildVertexBuffer(heightmap); BuildIndexBuffer(heightmap); BuildNormals(); BuildTerrainTexWeights(heightmap); mVertexBuffer = new VertexBuffer(mGame.GraphicsDevice, VertexMultiTextured.SizeInBytes * mPatchVertices.Length, BufferUsage.WriteOnly); mVertexBuffer.SetData(mPatchVertices); mIndexBuffer = new IndexBuffer(mGame.GraphicsDevice, sizeof(int) * mPatchIndices.Length, BufferUsage.WriteOnly, IndexElementSize.SixteenBits); mIndexBuffer.SetData(mPatchIndices); mTerrainVertexDeclaration = new VertexDeclaration(mGame.GraphicsDevice, VertexMultiTextured.VertexElements); // Apply the world matrix transformation to the bounding box. mBoundingBox.Min = Vector3.Transform(mBoundingBox.Min, worldMatrix); mBoundingBox.Max = Vector3.Transform(mBoundingBox.Max, worldMatrix); }
public GeoMipmap(IHeightMap map, int patchsize, float scale, float heightscale) { int count; if (map.Size.X != map.Size.Y) { throw new Exception("map.Size.X!=map.Size.Y"); } if (IsPowerOf2(map.Size.X - 1)) { count = (map.Size.X - 1) / (patchsize - 1); } else if (IsPowerOf2(map.Size.X)) { count = map.Size.X / (patchsize - 1); } else { throw new Exception("!IsPowerOf2(map.Size.X-1)"); } if (map.Size.X < patchsize) { throw new Exception("map.Size.X<patchvertexsize"); } int levels = (int)(Math.Log((double)(patchsize - 1)) / Math.Log(2.0)) + 1; Levels = GenerateLevels(levels, patchsize); Patches = GeneratePatches(map, patchsize, count, scale, heightscale); Size = scale * count; Lod = new int[count, count]; System.Console.WriteLine("terrain: " + map.Size.X + "x" + map.Size.X + "+size=" + Size.ToString() + " patchcount=" + count.ToString()); }
CaveMeshes BuildCaveMesh(WallGrid grid, IHeightMap heightMap) { MeshData floorPreMesh = MeshGenerator.BuildFloor(grid, heightMap); Mesh floorMesh = floorPreMesh.CreateMesh(); return(new CaveMeshes(floorMesh)); }
public CollisionSphere(Game game, IHeightMap floor, Vector3 startingPosition, int mapScale) { this.Position = startingPosition; this.model = game.Content.Load <Model>("sphere"); this.boneTransforms = new Matrix[this.model.Bones.Count]; this.mapScale = mapScale; this.Position = this.OffsetToFloorHeight(Game1.heightMap); }
protected override bool IsInFloorBounds(IHeightMap floor, Vector3 position) { return (position.X + this.radius < floor.Width * this.mapScale && position.X - this.radius > 0 && position.Z - this.radius >= 0 && position.Z + this.radius < floor.Height * this.mapScale); }
static void ApplyHeightMap(Vector3[] vertices, IHeightMap heightMap) { for (int i = 0; i < vertices.Length; i++) { Vector3 vertex = vertices[i]; vertices[i].y = heightMap.GetHeight(vertex.x, vertex.z); } }
static MeshData BuildFlatMesh(WallGrid grid, IHeightMap heightMap) { MeshData mesh = MapTriangulator.Triangulate(grid); mesh.uv = ComputeFlatUVArray(mesh.vertices); ApplyHeightMap(mesh.vertices, heightMap); return(mesh); }
public static MeshData BuildEnclosure(MeshData floor, IHeightMap heightMap) { MeshData mesh = floor.Clone(); ApplyHeightMap(mesh.vertices, heightMap); FlipVisibility(mesh); return(mesh); }
void CreateMesh() { var wallGrid = new WallGrid(new byte[size, size], Vector3.zero); IHeightMap heightMap = parameters.ToHeightMap(); CaveMeshes meshes = MeshGenerator.GenerateCaveMeshes(wallGrid, CaveType.Isometric, heightMap, heightMap); mesh = meshes.Floor; }
public MeshData BuildEnclosure(WallGrid grid, IHeightMap heightMap) { WallGrid invertedGrid = grid.Invert(); MeshData mesh = BuildFlatMesh(invertedGrid, heightMap); FlipVisibility(mesh); return(mesh); }
public CollisionSphere(Game game, IHeightMap floor, Vector3 startingPosition, int mapScale) { this.Position = startingPosition; this.model = game.Content.Load<Model>("sphere"); this.boneTransforms = new Matrix[this.model.Bones.Count]; this.mapScale = mapScale; this.Position = this.OffsetToFloorHeight(Game1.heightMap); }
/// <summary> /// Generate the data necessary to produce meshes for isometric type cave. Generates ceiling, wall and floor meshes. /// </summary> public void GenerateIsometric(Map map, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap) { index = map.index; GenerateCeiling(map, ceilingHeightMap); ComputeMeshOutlines(ceilingMesh); GenerateWallsFromCeiling(); GenerateFloor(map, floorHeightMap); }
void GenerateEnclosed(WallGrid grid, IHeightMap floorHeightMap, IHeightMap enclosureHeightMap) { floorMesh = MeshBuilder.BuildFloor(grid, floorHeightMap); outlines = OutlineGenerator.Generate(floorMesh, reverseOutlines: true); ceilingMesh = MeshBuilder.BuildEnclosure(floorMesh, enclosureHeightMap); wallMesh = MeshBuilder.BuildWalls(outlines, floorHeightMap, enclosureHeightMap); PruneWallsAtGlobalSeams(grid.Scale); }
public NodeIndicator(IHeightMap heightMapProvider, Vector3 mins, Vector3 maxs) { _status = NodeStatus.OutOfRange; InLastVisibleSet = InCurVisibleSet = false; _heightMapProvider = heightMapProvider; _mins = mins; _maxs = maxs; }
public Terrain(Game game, IHeightMap heightMap, ICamera camera) : base(game) { mGame = game; mHeightMap = heightMap; mCamera = camera; mTerrainCells = new List <TerrainCell>(); }
Mesh CreateMesh() { var wallGrid = new WallGrid(new byte[size, size], Vector3.zero, scale); IHeightMap heightMap = heightMapModule.GetHeightMap(); MeshData preMesh = MeshGenerator.BuildFloor(wallGrid, heightMap); return(preMesh.CreateMesh()); }
/// <summary> /// /// </summary> /// <param name="source"></param> /// <param name="shoreLength">the distance from the start of the beach to the water</param> /// <param name="waterLevel"></param> /// <param name="shoreHeight">the height as measured from the water level</param> /// <param name="type"></param> /// <param name="method"></param> public HeightMapIslandTrim(IHeightMap source, float shoreLength, float waterLevel, float shoreHeight, IslandShape type, IslandTrimMethod method) { mSource = source; mWaterLevel = waterLevel; mShoreHeight = shoreHeight; mShoreLength = shoreLength; mType = type; mMethod = method; }
public WallBuilder(List <Vector3[]> outlines, IHeightMap floor, IHeightMap ceiling, CaveWallModule walls) { this.outlines = outlines; floorHeightMap = floor; ceilingHeightMap = ceiling; wallModule = walls; extraVertsPerCorner = wallModule.ExtraVerticesPerCorner; totalVertsPerCorner = extraVertsPerCorner + 2; }
public static MeshData Build(Outline[] outlines, IHeightMap floorHeightMap, IHeightMap ceilingHeightMap) { MeshData mesh = new MeshData(); mesh.vertices = GetVertices(outlines, floorHeightMap, ceilingHeightMap); mesh.triangles = GetTriangles(outlines); mesh.uv = GetUVs(outlines, mesh.vertices); return(mesh); }
public virtual void Initialise() { IHeightMap hm = this; foreach (var form in Landformations) { form.Initialise(ref hm); } Landformations = null; }
/// <summary> /// Registers the height map with this manager. /// </summary> /// <param name="heightMap">The height map.</param> public void RegisterMap(IHeightMap heightMap) { if (heightMap.isGridBound) { _onGridHeightMaps.AddUnique(heightMap); } else { _offGridHeightMaps.AddUnique(heightMap); } }
/// <summary> /// Unregisters the height map with this manager. /// </summary> /// <param name="heightMap">The height map.</param> public void UnregisterMap(IHeightMap heightMap) { if (heightMap.isGridBound) { _onGridHeightMaps.Remove(heightMap); } else { _offGridHeightMaps.Remove(heightMap); } }
private void BuildVertices(IHeightMap heightMap) { this.Vertices = new VertexMultitextured[this.vertexCount]; float[] heightData = Utilities.Utilities.Flatten(heightMap.Data); float x = this.position.X, y = this.position.Y, z = this.position.Z, limX = x + this.topSize; float minSandHeight = 0, minGrassHeight = 0.3f * heightMap.HighestPeak, minRockHeight = (2 / 3f) * heightMap.HighestPeak, minSnowHeight = heightMap.HighestPeak, sandBracket = (0.2f) * heightMap.HighestPeak, grassBracket = 0.2f * heightMap.HighestPeak, rockBracket = 0.2f * heightMap.HighestPeak, snowBracket = 0.2f * heightMap.HighestPeak; for (int ndx = 0; ndx < this.vertexCount; ++ndx) { float height = heightData[ndx]; if (x > limX) { x = this.position.X; ++z; } this.Vertices[ndx].Position = new Vector3(x * this.scale, (height) * this.scale - heightMap.HeightOffset, z * this.scale); this.Vertices[ndx].Normal = new Vector3(0, 0, 0); this.Vertices[ndx].TextureCoordinate.X = (this.Vertices[ndx].Position.X - this.position.X) / this.topSize; this.Vertices[ndx].TextureCoordinate.Y = (this.Vertices[ndx].Position.Z - this.position.Z) / this.topSize; #region Texture weight calculation this.Vertices[ndx].TextureWeights.X = MathHelper.Clamp(1f - Math.Abs(height - minSandHeight) / sandBracket, 0, 1); this.Vertices[ndx].TextureWeights.Y = MathHelper.Clamp(1f - Math.Abs(height - minGrassHeight) / grassBracket, 0, 1); this.Vertices[ndx].TextureWeights.Z = MathHelper.Clamp(1f - Math.Abs(height - minRockHeight) / rockBracket, 0, 1); this.Vertices[ndx].TextureWeights.W = MathHelper.Clamp(1f - Math.Abs(height - minSnowHeight) / snowBracket, 0, 1); float totalWeight = this.Vertices[ndx].TextureWeights.X + this.Vertices[ndx].TextureWeights.Y + this.Vertices[ndx].TextureWeights.Z + this.Vertices[ndx].TextureWeights.W; this.Vertices[ndx].TextureWeights.X /= totalWeight; this.Vertices[ndx].TextureWeights.Y /= totalWeight; this.Vertices[ndx].TextureWeights.Z /= totalWeight; this.Vertices[ndx].TextureWeights.W /= totalWeight; #endregion ++x; } }
/// <summary> /// Initializes a new instance of the <see cref="TreeVertexCollection" /> class. /// </summary> /// <param name="position">The position of the top-left terrain corner in the 3D space.</param> /// <param name="heightMap">The height map.</param> /// <param name="scale">The scale.</param> public TreeVertexCollection( Vector3 position, IHeightMap heightMap, int scale) { this.position = position; this.scale = scale; this.topSize = heightMap.Width - 1; this.halfSize = this.topSize / 2; this.vertexCount = heightMap.Width * heightMap.Height; this.BuildVertices(heightMap); this.CalculateAllNormals(); }
/// <summary> /// Initializes a new instance of the <see cref="ColoredTerrain" /> class. /// </summary> /// <param name="heightMap">The height map.</param> /// <param name="coloringMethod">The coloring method.</param> public ColoredTerrain(GraphicsDevice device, IHeightMap heightMap, IHeightToColorTranslationMethod coloringMethod) { this.effect = new BasicEffect(device); this.effect.VertexColorEnabled = true; Vector3 lightDir = new Vector3(1, -1, -1); lightDir.Normalize(); this.effect.LightingEnabled = true; this.effect.PreferPerPixelLighting = true; this.effect.DirectionalLight0.Direction = lightDir; this.Width = heightMap.Width; this.Height = heightMap.Height; this.heightMap = heightMap; this.coloringMethod = coloringMethod; this.SetUpVertices(); this.SetUpIndices(); this.CalculateNormals(); }
/// <summary> /// Initializes a new instance of the <see cref="ColoredTerrain" /> class. /// </summary> /// <param name="heightMap">The height map.</param> /// <param name="coloringMethod">The coloring method.</param> public MultiTexturedTerrain(GraphicsDevice device, ContentManager content, IHeightMap heightMap, int scale = 1) { this.effect = content.Load<Effect>("Multitexture"); this.sand = content.Load<Texture>("sand"); this.grass = content.Load<Texture>("grass"); this.rock = content.Load<Texture>("rock"); this.snow = content.Load<Texture>("snow"); this.InitializeEffect(); this.Width = heightMap.Width; this.Height = heightMap.Height; this.heightMap = heightMap; this.scale = scale; this.SetUpVertices(); this.SetUpIndices(); this.CalculateNormals(); this.BufferVertexData(device); this.BufferIndexData(device); }
protected abstract bool IsInFloorBounds(IHeightMap floor);
/// <summary> /// /// </summary> /// <param name="source"></param> /// <param name="shoreLength">the distance from the start of the beach to the water</param> /// <param name="waterLevel"></param> /// <param name="shoreHeight">the height as measured from the water level</param> /// <param name="type"></param> /// <param name="method"></param> public HeightMapIslandTrim( IHeightMap source, float shoreLength, float waterLevel, float shoreHeight, IslandShape type, IslandTrimMethod method ) { mSource = source; mWaterLevel = waterLevel; mShoreHeight = shoreHeight; mShoreLength = shoreLength; mType = type; mMethod = method; }
public override void Initialise() { mSource.Initialise(); mWidth = mSource.Width; mLength = mSource.Length; mHeightMap = new float[ mWidth * mLength ]; for( int x = 0; x < mWidth; x++ ) for( int y = 0; y < mLength; y++ ) SetHeight( x, y ); // release to allow collection via GC mSource = null; base.Initialise(); }
/// <summary> /// Build the index buffer. /// </summary> private void BuildIndexBuffer( IHeightMap mHeightMap ) { mPatchIndices = new int[ ( mWidth - 1 ) * ( mLength - 1 ) * 6 ]; int counter = 0; for( int x = 0; x < mWidth - 1; x++ ) { for( int y = 0; y < mLength - 1; y++ ) { int lowerLeft = x + y * mWidth; int lowerRight = ( x + 1 ) + y * mWidth; int topLeft = x + ( y + 1 ) * mWidth; int topRight = ( x + 1 ) + ( y + 1 ) * mWidth; mPatchIndices[ counter++ ] = topLeft; mPatchIndices[ counter++ ] = lowerRight; mPatchIndices[ counter++ ] = lowerLeft; mPatchIndices[ counter++ ] = topLeft; mPatchIndices[ counter++ ] = topRight; mPatchIndices[ counter++ ] = lowerRight; } } }
/// <summary> /// Build the vertex buffer as well as the bounding box. /// </summary> /// <param name="heightmap"></param> private void BuildVertexBuffer( IHeightMap heightmap ) { int index = 0; float height = 0f; mPatchVertices = new VertexMultiTextured[ mWidth * mLength ]; for( int x = mOffsetX; x < mOffsetX + mWidth; x++ ) { for( int y = mOffsetZ; y < mOffsetZ + mLength; y++, index++ ) { height = heightmap[ x, y ]; mBoundingBox.Min.Y = Math.Min( height, mBoundingBox.Min.Y ); mBoundingBox.Max.Y = Math.Max( height, mBoundingBox.Max.Y ); //ComputeVertexNormal( heightmap, x, y, out normal ); mPatchVertices[ index ].Position = new Vector3( (float)x, heightmap[ x, y ], (float)-y ); mPatchVertices[ index ].TextureCoordinate.X = (float)x / 30.0f; mPatchVertices[ index ].TextureCoordinate.Y = (float)y / 30.0f; } } }
protected abstract Vector3 OffsetToFloorHeight(IHeightMap floor);
public static Patch[,] GeneratePatches(IHeightMap map,int patchsize, int count, float scale, float heightscale) { Patch[,] patches = new Patch[count, count]; for (int y = 0; y < count; ++y) { for (int x = 0; x < count; ++x) { patches[x, y] = new Patch(map, patchsize, x, y, count,scale,heightscale); } } return patches; }
/// <summary> /// The source is used once and then discarded /// </summary> /// <param name="source"></param> public HeightMapMirror( IHeightMap source ) { mSource = source; }
public void Initialize(IHeightMap heightMap) { Thread t = new Thread(() => { topNodeSize = heightMap.Width - 1; vertices = new TreeVertexCollection(this.position, heightMap, Game1.GameParameters.MapScale); buffers = new BufferManager(vertices.Vertices, GraphicsDevice); root = new QuadNode(NodeType.FullNode, topNodeSize, 1, null, this, 0); Indices = new int[(heightMap.Width + 1) * (heightMap.Height + 1) * 3]; this.FireReady(this); }); t.Start(); }
public Terrain(IHeightMap heightmap, Texture color, Texture detail,float size,float heightscale,int patchsize) { PatchSize = patchsize; PatchCount = (heightmap.Size.X) / (PatchSize - 1); HeightScale = heightscale; //PatchCount*PatchScale=size PatchScale = size / PatchCount; Init(heightmap, color, detail); }
public Patch(IHeightMap map, int patchsize, int gridx, int gridy, int patchcount,float scale,float heightscale) { int c = patchsize; float s = scale; VertexP3T2[] vtx = new VertexP3T2[c * c]; int i = 0; for (int y = 0; y < c; ++y) { for (int x = 0; x < c; ++x) { //x and y position float px = (float)gridx * s + ((float)x / (float)(c - 1)) * s; float py = (float)gridy * s + ((float)y / (float)(c - 1)) * s; px -= s * patchcount / 2; py -= s * patchcount / 2; //z position (height) float h = ((float)map.GetHeight( gridx * (patchsize - 1) + x, gridy * (patchsize - 1) + y)) * heightscale; //add the vertex vtx[i].position=new Vector3(px, h, py); vtx[i++].texture0=new Vector2( (float)(gridx * (c - 1) + x) / (float)(patchcount * (c - 1)), (float)(gridy * (c - 1) + y) / (float)(patchcount * (c - 1)) ); } } Vertices = Root.Instance.UserInterface.Renderer.CreateStaticVertexBuffer(vtx, Format.Size * vtx.Length); Vertices.Format = Format; }
private float GetTexWeight( IHeightMap heightMap, int x, int y, float i, float j ) { return MathHelper.Clamp( 1.0f - Math.Abs( heightMap[ x, y ] - i ) / j, 0.0f, 1.0f ); }
public Terrain(IHeightMap heightmap,Texture color,Texture detail) { Init(heightmap,color,detail); }
/// <summary> /// Compute vertex normal at the given x,z coordinate. /// </summary> /// <param name="heightmap"></param> /// <param name="x"></param> /// <param name="z"></param> /// <param name="normal"></param> private void ComputeVertexNormal( IHeightMap heightmap, int x, int z, out Vector3 normal ) { int width = heightmap.Width; int depth = heightmap.Length; Vector3 center; Vector3 p1; Vector3 p2; Vector3 avgNormal = Vector3.Zero; int avgCount = 0; bool spaceAbove = false; bool spaceBelow = false; bool spaceLeft = false; bool spaceRight = false; Vector3 tmpNormal; Vector3 v1; Vector3 v2; center = new Vector3( (float)x, heightmap[ x, z ], (float)z ); if( x > 0 ) spaceLeft = true; if( x < width - 1 ) spaceRight = true; if( z > 0 ) spaceAbove = true; if( z < depth - 1 ) spaceBelow = true; if( spaceAbove && spaceLeft ) { p1 = new Vector3( x - 1, heightmap[ x - 1, z ], z ); p2 = new Vector3( x - 1, heightmap[ x - 1, z - 1 ], z - 1 ); v1 = p1 - center; v2 = p2 - p1; tmpNormal = Vector3.Cross( v1, v2 ); avgNormal += tmpNormal; ++avgCount; } if( spaceAbove && spaceRight ) { p1 = new Vector3( x, heightmap[ x, z - 1 ], z - 1 ); p2 = new Vector3( x + 1, heightmap[ x + 1, z - 1 ], z - 1 ); v1 = p1 - center; v2 = p2 - p1; tmpNormal = Vector3.Cross( v1, v2 ); avgNormal += tmpNormal; ++avgCount; } if( spaceBelow && spaceRight ) { p1 = new Vector3( x + 1, heightmap[ x + 1, z ], z ); p2 = new Vector3( x + 1, heightmap[ x + 1, z + 1 ], z + 1 ); v1 = p1 - center; v2 = p2 - p1; tmpNormal = Vector3.Cross( v1, v2 ); avgNormal += tmpNormal; ++avgCount; } if( spaceBelow && spaceLeft ) { p1 = new Vector3( x, heightmap[ x, z + 1 ], z + 1 ); p2 = new Vector3( x - 1, heightmap[ x - 1, z + 1 ], z + 1 ); v1 = p1 - center; v2 = p2 - p1; tmpNormal = Vector3.Cross( v1, v2 ); avgNormal += tmpNormal; ++avgCount; } normal = avgNormal / avgCount; }
protected void Init(IHeightMap heightmap,Texture color,Texture detail) { Height=heightmap; if(Height.Size.X!=Height.Size.Y) throw new Exception("map.Size.X!=map.Size.Y"); if(IsPowerOf2(Height.Size.X-1)) { PatchCount=(Height.Size.X-1)/(PatchSize-1); } else if(IsPowerOf2(Height.Size.X)) { PatchCount=(Height.Size.X)/(PatchSize-1); } else throw new Exception("!IsPowerOf2(map.Size.X-1)"); if(Height.Size.X<PatchSize) throw new Exception("map.Size.X<patchvertexsize"); Levels=(int)Math.Log(PatchSize-1,2)+1; Patches=new Patch[PatchCount][]; for(int x=0;x<PatchCount;++x) { Patches[x]=new Patch[PatchCount]; for(int y=0;y<PatchCount;++y) { Patch p=new Patch(this,x,y); Patches[x][y]=p; } } for(int x=0;x<PatchCount;++x) { for(int y=0;y<PatchCount;++y) { Patches[y][x].SetNeighbors(x>0 ? Patches[y][x-1] : null, x<PatchCount-1 ? Patches[y][x+1] : null, y>0 ? Patches[y-1][x] : null, y<PatchCount-1 ? Patches[y+1][x] : null); Patches[y][x].Generate(); } } /*for(int x=0;x<PatchCount;++x) { for(int y=0;y<PatchCount;++y) { Patches[y][x].Generate(); } }*/ Material=new Material(); Material.diffusemap=color; Material.DetailMap=detail; HighDetail = 1 * PatchScale; LowDetail = HighDetail + Levels * PatchScale * 1.2f; //Color=color; //Detail=detail; Tree=new QuadTree(new Vector3(0,HeightScale/2,0),new Vector3(PatchScale*(float)PatchCount,HeightScale,PatchScale*(float)PatchCount),(int)Math.Log(PatchCount,2)+1,new Point(PatchCount,PatchCount)); //collision /*Ode.dVector3[] verts=new Ode.dVector3[heightmap.Size.X*heightmap.Size.Y]; int[] inds=new int[(heightmap.Size.X-1)*(heightmap.Size.Y-1)*2*3]; int i=0; int j=0; for(int y=0;y<heightmap.Size.Y;++y) { for(int x=0;x<heightmap.Size.X;++x) { float h=((float)Height.GetHeight(x,y)/255)*HeightScale; verts[i].X = (float)(x - heightmap.Size.X / 2) * PatchScale; verts[i].Y = h; verts[i].Z = (float)(y - heightmap.Size.Y / 2) * PatchScale; if (x < heightmap.Size.X - 1 && y < heightmap.Size.Y - 1) { inds[j++] = y * heightmap.Size.X + x; inds[j++] = y * heightmap.Size.X + x +1; inds[j++] = (y+1) * heightmap.Size.X + x; inds[j++] = (y + 1) * heightmap.Size.X + x; inds[j++] = y * heightmap.Size.X + x + 1; inds[j++] = (y + 1) * heightmap.Size.X + x +1; } i++; } } CollisionMesh = new OdeTriMeshData(verts,inds);*/ //CollisionMesh. }
private void BuildTerrainTexWeights( IHeightMap mHeightMap ) { int index = 0; for( int x = 0; x < mWidth; x++ ) { for( int y = 0; y < mLength; y++ ) { index = x + y * mWidth; if( mPatchVertices[ index ].Normal.Y > 0.6f ) { mPatchVertices[ index ].TexWeights.X = GetTexWeight( mHeightMap, x, y, 0f, 8f ); mPatchVertices[ index ].TexWeights.Y = GetTexWeight( mHeightMap, x, y, 12f, 6f ); mPatchVertices[ index ].TexWeights.Z = 1.0f - mPatchVertices[ index ].Normal.Y; mPatchVertices[ index ].TexWeights.W = GetTexWeight( mHeightMap, x, y, 30f, 6f ); } else { mPatchVertices[ index ].TexWeights.Z = 1.0f; mPatchVertices[ index ].TexWeights.W = GetTexWeight( mHeightMap, x, y, 30f, 6f ); } // normalise fuzzy weights -- to sum up to one float total = mPatchVertices[ index ].TexWeights.X + mPatchVertices[ index ].TexWeights.Y + mPatchVertices[ index ].TexWeights.Z + mPatchVertices[ index ].TexWeights.W; mPatchVertices[ index ].TexWeights.X /= total; mPatchVertices[ index ].TexWeights.Y /= total; mPatchVertices[ index ].TexWeights.Z /= total; mPatchVertices[ index ].TexWeights.W /= total; } } }
protected abstract bool IsInFloorBounds(IHeightMap floor, Vector3 position);
public override void Initialise() { mSource.Initialise(); mWidth = mSource.Width * 2; mLength = mSource.Length * 2; mHeightMap = new float[ mWidth * mLength ]; for( int x = 0; x < mWidth; x++ ) for( int y = 0; y < mLength; y++ ) { int sx = x < mSource.Width ? x : ( mWidth - 1 - x ); int sy = y < mSource.Length ? y : ( mLength - 1 - y ); mHeightMap[ x + y * mWidth ] = mSource[ sx, sy ]; } // release reference to source so that it can be collect by GC mSource = null; base.Initialise(); }
protected abstract Vector3 OffsetToFloorHeight(IHeightMap floor, Vector3 position);
public static Mesh3V3N CreateFromHeightMap(int columns, int rows, IHeightMap heightMap) { var vertices = new List<Vertex3V3N>(); for (var x = 0; x <= columns; x++) { for (var y = 0; y <= rows; y++) { var height = heightMap.GetHeight(x, y); vertices.Add(new Vertex3V3N { Position = new Vector3(x, (float)height, y), Normal = (Vector3)heightMap.GetNormal(x, y) }); } } var faces = new List<Face3>(); for (var x = 0; x < columns; x++) { for (var y = 0; y < rows; y++) { var verticesInColumn = rows + 1; var v0 = x * verticesInColumn + y; var v1 = (x + 1) * verticesInColumn + y; var v2 = (x + 1) * verticesInColumn + y + 1; var v3 = x * verticesInColumn + y + 1; Face3 f0; Face3 f1; if (y % 2 == 0) { if (x % 2 == 0) { f0 = new Face3 { V0 = v0, V1 = v1, V2 = v2 }; f1 = new Face3 { V0 = v0, V1 = v2, V2 = v3 }; } else { f0 = new Face3 { V0 = v0, V1 = v1, V2 = v3 }; f1 = new Face3 { V0 = v1, V1 = v2, V2 = v3 }; } } else { if (x % 2 == 0) { f0 = new Face3 { V0 = v0, V1 = v1, V2 = v3 }; f1 = new Face3 { V0 = v1, V1 = v2, V2 = v3 }; } else { f0 = new Face3 { V0 = v0, V1 = v1, V2 = v2 }; f1 = new Face3 { V0 = v0, V1 = v2, V2 = v3 }; } } faces.Add(f0); faces.Add(f1); } } return new Mesh3V3N(vertices, faces).Transformed(Matrix4.CreateTranslation(-columns / 2, 0, -rows / 2) * Matrix4.CreateScale((float)(1.0 / columns), 1, (float)(1.0 / rows))); }