public bool isGridBlock(VoxelHitInfo hitInfo) { return(hitInfo.voxelCenter.y == 0.5f); }
/// <summary> /// Perform ray cast against all terrain /// </summary> /// <param name="R">Ray in unit space</param> /// <param name="MaxDistance"></param> /// <param name="Hit">Information of the hit, if hit successfully</param> /// <param name="IgnoreTransparent">Should voxels with transparent type just be ignoreed in this check</param> /// <param name="TypeMask">Bit mask to determine what voxel types to check against</param> /// <returns>Does the ray hit</returns> public bool PerformRayCast(Ray R, out VoxelHitInfo Hit, float MaxDistance = 32.0f, bool IgnoreTransparent = false, int TypeMask = int.MaxValue) { Point lastCheck = new Point(); bool started = false; for (float i = 0; i < MaxDistance; i += 0.5f) { Point check = new Point((R.origin + R.direction * i) * WorldManager.UnitToVoxelScale); // Don't repeat checks if (started && lastCheck == check) { continue; } // Ignore invalid height if (check.y < 0 || check.y >= VoxelChunk.ChunkHeight) { // If we were in bounds exit out, as we've left if (started) { break; } // Ignore invalid height until we get in bounds else { continue; } } lastCheck = check; started = true; VoxelInstance voxel = GetVoxel(check.x, check.y, check.z); // Ignore invalid checks if (voxel == null || voxel.mType == VoxelType.None || ((1 << (int)voxel.mType) & TypeMask) == 0 || (IgnoreTransparent && voxel.bIsTransparent)) { continue; } // Intersect ray against bounding box and see if it hits Bounds bounds = new Bounds(new Vector3(check.x, check.y, check.z) * WorldManager.VoxelToUnitScale, new Vector3(1, 1, 1) * WorldManager.VoxelToUnitScale); float d; if (bounds.IntersectRay(R, out d)) { Vector3 c = bounds.ClosestPoint(R.origin + R.direction * (d - 0.0001f)); Vector3 normal = new Vector3(0, 0, 0); // Work out normal based on closest point if (c.y == bounds.min.y) { normal.y = -1; } if (c.y == bounds.max.y) { normal.y = 1; } if (c.x == bounds.min.x) { normal.x = -1; } if (c.x == bounds.max.x) { normal.x = 1; } if (c.z == bounds.min.z) { normal.z = -1; } if (c.z == bounds.max.z) { normal.z = 1; } Hit = new VoxelHitInfo(check.x, check.y, check.z, voxel, normal.normalized); return(true); } } Hit = new VoxelHitInfo(); return(false); }