internal static PositionChunk CreateFrom(Vector3 pos) { PositionChunk newChunk = new PositionChunk( MathLibrary.FloorToWorldGrid(pos.X / 16f), MathLibrary.FloorToWorldGrid(pos.Y / 16f), MathLibrary.FloorToWorldGrid(pos.Z / 16f)); return(newChunk); }
public Vector3 Resolve(CrossCutting.Entities.EntityPlayer entity) { World theWorld = World.Instance; Vector3 pos = entity.Position; // already collided? - then bubble up int x = MathLibrary.FloorToWorldGrid(pos.X); int y = MathLibrary.FloorToWorldGrid(pos.Y); int z = MathLibrary.FloorToWorldGrid(pos.Z); if (Block.FromId(theWorld.GetBlock(x, y, z)).IsOpaque) { // allready collided entity.Velocity = new Vector3(); if (!Block.FromId(theWorld.GetBlock(x - 1, y, z)).IsOpaque) { return(pos + new Vector3(-1, 0, 0)); } if (!Block.FromId(theWorld.GetBlock(x + 1, y, z)).IsOpaque) { return(pos + new Vector3(1, 0, 0)); } if (!Block.FromId(theWorld.GetBlock(x, y, z - 1)).IsOpaque) { return(pos + new Vector3(0, 0, -1)); } if (!Block.FromId(theWorld.GetBlock(x, y, z + 1)).IsOpaque) { return(pos + new Vector3(0, 0, 1)); } if (!Block.FromId(theWorld.GetBlock(x, y + 1, z)).IsOpaque) { return(pos + new Vector3(0, 1, 0)); } if (!Block.FromId(theWorld.GetBlock(x, y - 1, z)).IsOpaque) { return(pos + new Vector3(0, -1, 0)); } // could not be resolved .. entity should be killed! throw new NotImplementedException("Kill entity in this case!"); } Vector3 v = entity.Velocity; Vector3 destpos = pos + v; x = MathLibrary.FloorToWorldGrid(destpos.X); y = MathLibrary.FloorToWorldGrid(destpos.Y); z = MathLibrary.FloorToWorldGrid(destpos.Z); Block block = Block.FromId(theWorld.GetBlock(x, y, z)); if (block.IsOpaque) { entity.Velocity = -entity.Velocity / 2f; v = new Vector3(); } return(pos + v); }
internal override void Render(float partialStep) { t.ResetTransformation(); Vector3 position = Interpolate.Vector(entity.PrevPosition, entity.Position, partialStep); Player p = World.Instance.Player; Vector3 pos = position + p.EyePosition; int blockId = World.Instance.GetBlock((int)MathLibrary.FloorToWorldGrid(pos.X), (int)MathLibrary.FloorToWorldGrid(pos.Y), (int)MathLibrary.FloorToWorldGrid(pos.Z)); if (blockId == BlockRepository.Water.Id) { t.StartDrawingColoredQuads(); Camera.Instance.World = Matrix.Identity; Camera.Instance.World = Matrix.Multiply(Camera.Instance.World, Matrix.Translation(new Vector3(-0.5f, -0.5f, -1.2f))); Camera.Instance.World = Matrix.Multiply(Camera.Instance.World, Matrix.RotationYawPitchRoll(p.Yaw - (float)Math.PI, -p.Pitch, 0)); Camera.Instance.World = Matrix.Multiply(Camera.Instance.World, Matrix.Translation(pos)); Vector3 normal = new Vector3(0, 0, 1); Vector4 c1 = new Vector4(0.2f, 0.2f, 0.4f, 0.5f); t.AddVertexWithColor(new Vector4(0f, 0f, 1f, 1.0f), c1, normal); t.AddVertexWithColor(new Vector4(0f, 1f, 1f, 1.0f), c1, normal); t.AddVertexWithColor(new Vector4(1f, 1f, 1f, 1.0f), c1, normal); t.AddVertexWithColor(new Vector4(1f, 0f, 1f, 1.0f), c1, normal); t.Draw(); } if (World.Instance.Player.DestroyProgress > 0) { t.StartDrawingTiledQuads2(); t.Translate.X = World.Instance.Player.BlockAttackPosition.X + 0.5f; t.Translate.Y = World.Instance.Player.BlockAttackPosition.Y + 0.5f; t.Translate.Z = World.Instance.Player.BlockAttackPosition.Z + 0.5f; float s = 1.005f; t.Scale = new Vector3(s, s, s); t.Draw(TileTextures.Instance.GetDestroyBlockVertexBuffer(World.Instance.Player.DestroyProgress)); } }
internal void Update(Vector3 centerPos) { float chunkRadius = (int)((GameSettings.CachingRadius) / 16f); float chunkRadiusSquared = chunkRadius * chunkRadius; Vector3 centerBlockPos = new Vector3( MathLibrary.FloorToWorldGrid(centerPos.X), MathLibrary.FloorToWorldGrid(centerPos.Y), MathLibrary.FloorToWorldGrid(centerPos.Z)); if (centerBlockPos.Y > Chunk.MaxSizeY - 1) { centerBlockPos.Y = Chunk.MaxSizeY - 1; } else if (centerBlockPos.Y < 0) { centerBlockPos.Y = 0; } PositionChunk centerChunk = PositionChunk.CreateFrom(centerBlockPos); PositionChunk minChunk = new PositionChunk(centerChunk.X - (int)chunkRadius, 0, centerChunk.Z - (int)chunkRadius); PositionChunk maxChunk = new PositionChunk(centerChunk.X + (int)chunkRadius, Chunk.MaxSizeY / 16 - 1, centerChunk.Z + (int)chunkRadius); // add all chunks within blockradius if (!centerChunk.SameAs(LastCenterChunk)) { // update the cache for (int x = minChunk.X; x <= maxChunk.X; x++) { for (int z = minChunk.Z; z <= maxChunk.Z; z++) { int dx = x - centerChunk.X; int dz = z - centerChunk.Z; double chunkCurrentDistSquared = dx * dx + dz * dz; if (chunkCurrentDistSquared > chunkRadiusSquared) { continue; } for (int y = minChunk.Y; y <= maxChunk.Y; y++) { Chunk chunk = World.Instance.GetChunk(new PositionChunk(x, y, z)); if (!cachedChunks.ContainsKey(chunk.Position.Key)) { cachedChunks.Add(chunk.Position.Key, chunk); } } } } OrderedChunks = cachedChunks.Values.Where(c => { float dx = c.Position.X - centerChunk.X; float dz = c.Position.Z - centerChunk.Z; return(dx * dx + dz * dz <= chunkRadiusSquared); }).OrderBy(c => { float dx = c.Position.X - centerChunk.X; float dz = c.Position.Z - centerChunk.Z; return(dx * dx + dz * dz); }).ThenBy(c => { float dy = c.Position.Y - centerChunk.Y; return(dy * dy); }).ToList(); IsDirty = true; } // update chunks... bool allowHeavyTask = true; foreach (var column in ChunkColumns.Values) { column.Active = false; } foreach (Chunk chunk in OrderedChunks) { chunk.Column = GetChunkColumn(chunk.Position); chunk.HeavyTaskAllowed = allowHeavyTask; chunk.Update(); if (chunk.HeavyTaskExecuted) { allowHeavyTask = false; } // relocate entities foreach (EntityStack stack in chunk.StackEntities.ToArray()) { PositionChunk destChunk = PositionChunk.CreateFrom(stack.Position); if (!chunk.Position.SameAs(destChunk)) { // relocate chunk.RemoveEntity(stack); if (cachedChunks.ContainsKey(destChunk.Key)) { cachedChunks[destChunk.Key].AddEntity(stack); } } } } // dispose and remove expired chunks var expiredChunks = cachedChunks.Where(pair => pair.Value.Expired).ToList(); expiredChunks.ForEach(pair => { pair.Value.Dipose(); cachedChunks.Remove(pair.Key); }); // remove unused columnds var columnsToRemove = ChunkColumns.Where(pair => pair.Value.Active == false).ToList(); columnsToRemove.ForEach(pair => { ChunkColumns.Remove(pair.Key); }); LastCenterChunk = centerChunk; }