private static bool PathHitsTerrain(NativeArray <TerrainSystem.AABB> blockBoxes, int2 terrainSize, float3 start, float3 end, float paraA, float paraB, float paraC) { float distance = math.distance(end.xz, start.xz); int steps = math.max(2, (int)math.ceil(distance / TerrainSystem.BOX_SPACING) + 1); steps = (int)math.ceil(steps * COLLISION_STEP_MULTIPLIER); for (int i = 0; i < steps; i++) { float t = i / (steps - 1f); float3 pos = GetSimulatedPosition(start, end, paraA, paraB, paraC, t); TerrainSystem.AABB box = new TerrainSystem.AABB { Min = pos - CANNONBALL_RADIUS, Max = pos + CANNONBALL_RADIUS, }; if (BoxHitsTerrain(blockBoxes, terrainSize, box)) { return(true); } } return(false); }
static private bool BoxHitsTerrain(NativeArray <TerrainSystem.AABB> blockBoxes, int2 terrainSize, TerrainSystem.AABB box) { // check nearby boxes -- TODO bias by half a box int xMin = (int)math.floor((box.Min.x + 0.5f) / TerrainSystem.BOX_SPACING); int xMax = (int)math.floor((box.Max.x + 0.5f) / TerrainSystem.BOX_SPACING); int zMin = (int)math.floor((box.Min.z + 0.5f) / TerrainSystem.BOX_SPACING); int zMax = (int)math.floor((box.Max.z + 0.5f) / TerrainSystem.BOX_SPACING); xMin = math.max(0, xMin); xMax = math.min(terrainSize.x - 1, xMax); zMin = math.max(0, zMin); zMax = math.min(terrainSize.y - 1, zMax); for (int z = zMin; z <= zMax; z++) { for (int x = xMin; x <= xMax; x++) { int blockIndex = TerrainSystem.BlockCoordsToIndex(new int2(x, z), terrainSize); TerrainSystem.AABB blockBox = blockBoxes[blockIndex]; bool intersects = !(box.Max.x <blockBox.Min.x || box.Min.x> blockBox.Max.x || box.Max.y <blockBox.Min.y || box.Min.y> blockBox.Max.y || box.Max.z <blockBox.Min.z || box.Min.z> blockBox.Max.z); if (intersects) { return(true); } } } // TODO: check tanks return(false); }