public EntityPlacement(EntityPos pos, EntityOrientation orientation) { Pos = pos; Orientation = orientation; }
public RayCastResult CastRay(EntityPos entityPos, EntityOffset direction, double max) { long x = entityPos.X, y = entityPos.Y, z = entityPos.Z; double dx = direction.X, dy = direction.Y, dz = direction.Z; int sdx = (int)Math.Sign(dx); int sdy = (int)Math.Sign(dy); int sdz = (int)Math.Sign(dz); if (sdx == 0 && sdy == 0 && sdz == 0) { return null; } const long edgeLength = 1L << 32; const double oneOverEdge = 1.0 / edgeLength; var blockPos = (BlockPos)entityPos; if (this[blockPos] != 0) { return new RayCastResult { EntityPos = entityPos, BlockPos = blockPos }; } while (max > 0 && IsNumber(max)) { /* Check which edge of the current block is hit first */ long edgeX; if (sdx > 0) { edgeX = (x + edgeLength) & _upperMask; } else { edgeX = (x - 1) & _upperMask; } double tx = (edgeX - x) * oneOverEdge / dx; long edgeY; if (sdy > 0) { edgeY = (y + edgeLength) & _upperMask; } else { edgeY = (y - 1) & _upperMask; } double ty = (edgeY - y) * oneOverEdge / dy; long edgeZ; if (sdz > 0) { edgeZ = (z + edgeLength) & _upperMask; } else { edgeZ = (z - 1) & _upperMask; } double tz = (edgeZ - z) * oneOverEdge / dz; if (Math.Abs(edgeX - x) > edgeLength || Math.Abs(edgeY - y) > edgeLength || Math.Abs(edgeZ - z) > edgeLength) { // Shouldn't happen. throw new Exception(); } if (IsNumber(tx) && (tx <= ty || !IsNumber(ty)) && (tx <= tz || !IsNumber(tz))) { x = edgeX; y += (long)(tx * dy * edgeLength); z += (long)(tx * dz * edgeLength); max -= tx; blockPos.X += sdx; if (max >= 0 && this[blockPos] != 0) { return new RayCastResult { EntityPos = new EntityPos(x, y, z), BlockPos = blockPos, Normal = new BlockOffset(-sdx, 0, 0) }; } } else if (IsNumber(ty) && (ty <= tz || !IsNumber(tz))) { x += (long)(ty * dx * edgeLength); y = edgeY; z += (long)(ty * dz * edgeLength); max -= ty; blockPos.Y += sdy; if (max >= 0 && this[blockPos] != 0) { return new RayCastResult { EntityPos = new EntityPos(x, y, z), BlockPos = blockPos, Normal = new BlockOffset(0, -sdy, 0) }; } } else if (IsNumber(tz)) { x += (long)(tz * dx * edgeLength); y += (long)(tz * dy * edgeLength); z = edgeZ; max -= tz; blockPos.Z += sdz; if (max >= 0 && this[blockPos] != 0) { return new RayCastResult { EntityPos = new EntityPos(x, y, z), BlockPos = blockPos, Normal = new BlockOffset(0, 0, -sdz) }; } } else { // Shouldn't happen. throw new Exception(); } } return null; }
public EntityPlacement(EntityPos pos, EntityOrientation orientation) { Pos = pos; Orientation = orientation; }