public static void Update(GameWindow window, WorldServer world) { _blockRaytrace = world.BlockRaytrace(PlayerEntity.Position, PlayerEntity.Forward, 8); if (!window.Focused) { return; } var ks = Keyboard.GetState(); var a = Vector3.Zero; if (ks.IsKeyDown(Key.A)) { a.X -= 1; } if (ks.IsKeyDown(Key.D)) { a.X += 1; } if (ks.IsKeyDown(Key.ShiftLeft)) { a.Y -= 1; } if (ks.IsKeyDown(Key.Space)) { a.Y += 1; } if (ks.IsKeyDown(Key.S)) { a.Z -= 1; } if (ks.IsKeyDown(Key.W)) { a.Z += 1; } if (Math.Abs(a.LengthSquared) > 0.0001f) { PlayerEntity.Move(a.Normalized() * 0.08f); } foreach (var keybinding in ClientResources.Keybindings) { if (ks.IsKeyDown(keybinding.Key)) { _currentBlock = keybinding.Value; } } var ms = Mouse.GetState(); if (_oldMouseState != null) { var pitch = _oldMouseState.Value.Y - ms.Y; var yaw = _oldMouseState.Value.X - ms.X; PlayerEntity.Rotate(pitch * 0.008f, yaw * 0.008f); if (_oldMouseState.Value.LeftButton == ButtonState.Released && ms.LeftButton == ButtonState.Pressed) { BreakBlock(world); } if (_oldMouseState.Value.RightButton == ButtonState.Released && ms.RightButton == ButtonState.Pressed) { PlaceBlock(world); } } _oldMouseState = ms; Mouse.SetPosition(window.X + window.Width / 2, window.Y + window.Height / 2); Camera.Update(); }
public BlockRaytraceResult BlockRaytrace(Vector3 position, Vector3 direction, float range) { const float epsilon = -1e-6f; direction.Normalize(); var start = (position - direction * 0.5f).ToVector3i(); var end = (position + direction * (range + 0.5f)).ToVector3i(); var minX = Math.Min(start.X, end.X) - 1; var minY = Math.Min(start.Y, end.Y) - 1; var minZ = Math.Min(start.Z, end.Z) - 1; var maxX = Math.Max(start.X, end.X) + 1; var maxY = Math.Max(start.Y, end.Y) + 1; var maxZ = Math.Max(start.Z, end.Z) + 1; BlockRaytraceResult result = null; for (var x = minX; x <= maxX; x++) { for (var y = minY; y <= maxY; y++) { for (var z = minZ; z <= maxZ; z++) { var block = GetBlock(x, y, z); var blockPosi = new Vector3i(x, y, z); var bb = block.GetBoundingBox(this, blockPosi); if (bb == null || !block.CanTarget(this, blockPosi)) { continue; } var translation = bb.Min + (bb.Max - bb.Min) * 0.5f; var scale = bb.Max - bb.Min; foreach (var face in BlockFaceHelper.Faces) { var normal = face.GetNormal(); var divisor = Vector3.Dot(normal, direction); //ignore back faces if (divisor >= epsilon) { continue; } var planeNormal = normal * normal; var blockPos = new Vector3(x, y, z) + translation; var blockSize = new Vector3(0.5f) * scale; var d = -(Vector3.Dot(blockPos, planeNormal) + Vector3.Dot(blockSize, normal)); var numerator = Vector3.Dot(planeNormal, position) + d; var distance = Math.Abs(-numerator / divisor); var point = position + distance * direction; if (point.X < x + translation.X - blockSize.X + epsilon || point.X > x + translation.X + blockSize.X - epsilon || point.Y < y + translation.Y - blockSize.Y + epsilon || point.Y > y + translation.Y + blockSize.Y - epsilon || point.Z < z + translation.Z - blockSize.Z + epsilon || point.Z > z + translation.Z + blockSize.Z - epsilon) { continue; } if (distance <= range && (result == null || result.Distance > distance)) { result = new BlockRaytraceResult(block, face, new Vector3i(x, y, z), distance, point, bb); } } } } } return(result); }