public void SetTexture(float x, float z, ITexture texture, float rotation) { int tx = (int)(x / Constants.terrainPieceSize); int tz = (int)(z / Constants.terrainPieceSize); int cx = tx / Constants.terrainHeightsPerChunk; if (tx < 0 && tx % Constants.terrainHeightsPerChunk != 0) { cx--; } int cz = tz / Constants.terrainHeightsPerChunk; if (tz < 0 && tz % Constants.terrainHeightsPerChunk != 0) { cz--; } Vector2D loc = new Vector2D(cx, cz); ITerrainChunk tc = terrainChunks[loc] as ITerrainChunk; if (tc == null) { tc = TerrainChunk.CreateTerrainChunk(cx * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, cz * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, Constants.terrainPieceSize, Constants.terrainHeightsPerChunk); terrainChunks.Add(loc, tc); } tc.DrawTexture(texture, x, z, rotation); }
public void SetHeight(float x, float z, float altitude) { int tx = (int)(x / Constants.terrainPieceSize); int tz = (int)(z / Constants.terrainPieceSize); Vector2D loc = new Vector2D(tx, tz); if (terrainHeights.Contains(loc)) { //Strive.Logging.Log.WarningMessage( "Replacing terrain peice " + tpexists.instance_id + " with " + tp.instance_id ); terrainHeights.Remove(loc); } terrainHeights.Add(loc, altitude); int cx = tx / Constants.terrainHeightsPerChunk; if (tx < 0 && tx % Constants.terrainHeightsPerChunk != 0) { cx--; } int cz = tz / Constants.terrainHeightsPerChunk; if (tz < 0 && tz % Constants.terrainHeightsPerChunk != 0) { cz--; } loc.Set(cx, cz); ITerrainChunk tc = terrainChunks[loc] as ITerrainChunk; if (tc == null) { tc = TerrainChunk.CreateTerrainChunk(cx * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, cz * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, Constants.terrainPieceSize, Constants.terrainHeightsPerChunk); terrainChunks.Add(loc, tc); } tc.SetHeight(x, z, altitude); if (tx % Constants.terrainHeightsPerChunk == 0) { loc.Set(cx - 1, cz); tc = terrainChunks[loc] as ITerrainChunk; if (tc == null) { tc = TerrainChunk.CreateTerrainChunk((cx - 1) * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, cz * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, Constants.terrainPieceSize, Constants.terrainHeightsPerChunk); terrainChunks.Add(loc, tc); } tc.SetHeight(x, z, altitude); } if (tz % Constants.terrainHeightsPerChunk == 0) { loc.Set(cx, cz - 1); tc = terrainChunks[loc] as ITerrainChunk; if (tc == null) { tc = TerrainChunk.CreateTerrainChunk(cx * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, (cz - 1) * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, Constants.terrainPieceSize, Constants.terrainHeightsPerChunk); terrainChunks.Add(loc, tc); } tc.SetHeight(x, z, altitude); } if (tx % Constants.terrainHeightsPerChunk == 0 && tz % Constants.terrainHeightsPerChunk == 0) { loc.Set(cx - 1, cz - 1); tc = terrainChunks[loc] as ITerrainChunk; if (tc == null) { tc = TerrainChunk.CreateTerrainChunk((cx - 1) * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, (cz - 1) * Constants.terrainHeightsPerChunk * Constants.terrainPieceSize, Constants.terrainPieceSize, Constants.terrainHeightsPerChunk); terrainChunks.Add(loc, tc); } tc.SetHeight(x, z, altitude); } }
public void Recenter(float x, float z) { int i, j, k, cs, cx, cz; int xdiff, zdiff; float tcx, tcz, px, pz, altitude; int l, m; Vector2D loc = new Vector2D(0, 0); Terrain t1, t2; // drop all terrain data that is now out of scope ArrayList arrayList = new ArrayList(terrainPiecesXYIndex.Keys); foreach (Vector2D key in arrayList) { for (k = 0; k < Constants.terrainZoomOrder; k++) { if ( key.X > x + Constants.xRadius[k] * ts || key.Y > z + Constants.zRadius[k] * ts || key.X < x - Constants.xRadius[k] * ts || key.Y < z - Constants.zRadius[k] * ts ) { if ( // there is no higher zoom order k == (Constants.terrainZoomOrder - 1) // this is not a higher order point || (key.X % (ts * Constants.scale[k + 1])) != 0 || (key.Y % (ts * Constants.scale[k + 1])) != 0 ) { // TODO: why doesn't this wurk??? umg //terrainPiecesXYIndex.Remove( key ); break; } } else { break; } } } // loop through all chunks to see if any can be reused for (k = (zoomorder - 1); k >= 0; k--) { cs = (int)(ts * Math.Pow(hpc, k + 1)); cx = Helper.DivTruncate((int)x, cs); cz = Helper.DivTruncate((int)z, cs); if (x - (cx * cs) < (cx + 1) * cs - x) { cx--; } if (z - (cz * cs) < (cz + 1) * cs - z) { cz--; } cx -= (xorder / 2 - 1); cz -= (zorder / 2 - 1); xdiff = cx - CX[k]; zdiff = cz - CZ[k]; // no difference, keep all the chunks if (xdiff == 0 && zdiff == 0) { continue; } for (i = (xdiff < 0?xorder - 1:0); (xdiff < 0?i >= 0:i < xorder);) { for (j = (zdiff < 0?zorder - 1:0); (zdiff < 0?j >= 0:j < zorder);) { // see if we can replace it with an existing chunk tcx = cx * cs + i * cs; tcz = cz * cs + j * cs; if ( i + xdiff >= 0 && i + xdiff < xorder && j + zdiff >= 0 && j + zdiff < zorder ) { // Keep the data in TC[i+xdiff,j+zdiff,k] // but move it to TC[i,j,k] ITerrainChunk tc = TC[i, j, k]; TC[i, j, k] = TC[i + xdiff, j + zdiff, k]; TC[i + xdiff, j + zdiff, k] = tc; // update edges with real values // this is 'unseaming' from the higher order if ((i + xdiff) == 0) { for (m = 0; m < hpc; m++) { px = TC[i, j, k].Position.X; pz = TC[i, j, k].Position.Z + m * cs / hpc; loc.Set(px, pz); altitude = 0; t1 = (Terrain)terrainPiecesXYIndex[loc]; if (t1 != null) { altitude = t1.Position.Y; } TC[i, j, k].SetHeight(px, pz, altitude); } } else if ((i + xdiff) == (xorder - 1)) { for (m = 0; m < hpc; m++) { px = TC[i, j, k].Position.X + cs; pz = TC[i, j, k].Position.Z + m * cs / hpc; loc.Set(px, pz); altitude = 0; t1 = (Terrain)terrainPiecesXYIndex[loc]; if (t1 != null) { altitude = t1.Position.Y; } TC[i, j, k].SetHeight(px, pz, altitude); } } if ((j + zdiff) == 0) { for (l = 0; l < hpc; l++) { px = TC[i, j, k].Position.X + l * cs / hpc; pz = TC[i, j, k].Position.Z; loc.Set(px, pz); altitude = 0; t1 = (Terrain)terrainPiecesXYIndex[loc]; if (t1 != null) { altitude = t1.Position.Y; } TC[i, j, k].SetHeight(px, pz, altitude); } } else if ((j + zdiff) == (zorder - 1)) { for (l = 0; l < hpc; l++) { px = TC[i, j, k].Position.X + l * cs / hpc; pz = TC[i, j, k].Position.Z + cs; loc.Set(px, pz); altitude = 0; t1 = (Terrain)terrainPiecesXYIndex[loc]; if (t1 != null) { altitude = t1.Position.Y; } TC[i, j, k].SetHeight(px, pz, altitude); } } } else { // TC[i,j,k] is dirty and ready for // reuse... this means that its higher order peice // is going to become visible again (if it exists). if (k < zoomorder - 1) { MakeVisible(k + 1, TC[i, j, k].Position.X, TC[i, j, k].Position.Z); } // NB: TODO in order to make sure invis and seaming works, // we need to remove Set() and replace it with this // refresh process, or put the extra checking into Set // The new location needs to be made invisible TC[i, j, k].Position = new Vector3D(tcx, 0, tcz); if (k < zoomorder - 1) { MakeInvisible(k + 1, TC[i, j, k].Position.X, TC[i, j, k].Position.Z); } // update it with any known heights // Refresh( TC[i,j,k] ); for (l = 0; l <= hpc; l++) { for (m = 0; m <= hpc; m++) { px = tcx + l * cs / hpc; pz = tcz + m * cs / hpc; altitude = 0; if (l == 0 && i == 0 || l == (hpc - 1) && i == (xorder - 1)) { // edges need to be seamed with higher order edges loc.Set(tcx, tcz); t1 = (Terrain)terrainPiecesXYIndex[loc]; loc.Set(tcx, tcz + cs); t2 = (Terrain)terrainPiecesXYIndex[loc]; if (t1 != null && t2 != null) { altitude = t1.Position.Y + (t2.Position.Y - t1.Position.Y) * m / hpc; } } else if (m == 0 && j == 0 || m == (hpc - 1) && j == (zorder - 1)) { // edges need to be seamed with higher order edges loc.Set(tcx, tcz); t1 = (Terrain)terrainPiecesXYIndex[loc]; loc.Set(tcx + cs, tcz); t2 = (Terrain)terrainPiecesXYIndex[loc]; if (t1 != null && t2 != null) { altitude = t1.Position.Y + (t2.Position.Y - t1.Position.Y) * m / hpc; } } else { loc.Set(px, pz); t1 = (Terrain)terrainPiecesXYIndex[loc]; if (t1 != null) { altitude = t1.Position.Y; } } TC[i, j, k].SetHeight(px, pz, altitude); // regardless of altitude, always use the right loc.Set(px, pz); t1 = (Terrain)terrainPiecesXYIndex[loc]; if (t1 != null) { //if ( k==0 ) TC[i, j, k].DrawTexture(_resource_manager.GetTexture(t1.ResourceID), px, pz, t1.Rotation.Y); } } } } if (zdiff < 0) { j--; } else { j++; } } if (xdiff < 0) { i--; } else { i++; } } CX[k] = cx; CZ[k] = cz; } }