private static bool HasCollisionHelper(ref VoxelRay centerRay, Pipliz.Vector3Int pos, RayCastType type, ref RayHit.VoxelHit hit) { ushort hitType = default(ushort); if (!World.TryGetTypeAt(pos, out hitType)) { return(true); } if (hitType == 0) { return(false); } if (hitType == BuiltinBlocks.Indices.water) { return(false); } if ((type & RayCastType.HitBoxesSelection) != 0) { ItemTypes.ItemType itemType = ItemTypes.GetType(hitType); if (itemType.BoxColliders != null && itemType.CollideSelection) { Vector3 vector = pos.Vector; List <BoundsPip> boxes = itemType.BoxColliders; for (int i = 0; i < boxes.Count; i++) { BoundsPip bounds2 = boxes[i]; bounds2.Shift(pos.Vector); if (centerRay.Intersects(bounds2, out float hitDist2, out VoxelSide hitSides2) && hitDist2 < hit.Distance) { hit.TypeHit = hitType; hit.Distance = hitDist2; hit.VoxelPositionHit = pos; hit.VoxelSideHit = hitSides2; hit.BoundsHit = new RotatedBounds(boxes[i], Quaternion.identity); hit.BoundsCenter = pos.Vector; } } return(false); } } if ((type & RayCastType.HitNonSolidAsSolid) == 0 && !ItemTypes.Solids[hitType]) { return(false); } BoundsPip bounds = default(BoundsPip); bounds.SetCenterSize(pos.Vector, Vector3.one); if (centerRay.Intersects(bounds, out float hitDist, out VoxelSide hitSides) && hitDist < hit.Distance) { hit.TypeHit = hitType; hit.Distance = hitDist; hit.VoxelPositionHit = pos; hit.VoxelSideHit = hitSides; hit.BoundsHit = new RotatedBounds(Vector3.zero, Vector3.one, Quaternion.identity); hit.BoundsCenter = pos.Vector; } return(false); }
public static bool RayCastVoxel(Vector3 center, Vector3 direction, float maxDistance, RayCastType type, out RayHit.VoxelHit hit) { hit = default(RayHit.VoxelHit); VoxelRay ray = new VoxelRay(center, direction); hit.Distance = float.MaxValue; while (ray.Distance - 2f < Pipliz.Math.Min(hit.Distance, maxDistance) && !HasCollisionHelper(ref ray, ray.NextVoxel, type, ref hit) && ray.WalkNextVoxel(maxDistance)) { } return(hit.Distance < float.MaxValue); }