| 2166 | } |
| 2167 | |
| 2168 | float Landscape::IntersectWithGround(Vector3* ret, Vector3Par from, Vector3Par dir, float minDist, float maxDist) const |
| 2169 | { |
| 2170 | float maxDist0 = maxDist * 1.1f; |
| 2171 | saturateMin(maxDist, ENGINE_CONFIG.horizontZ); |
| 2172 | Vector3 pos = from; |
| 2173 | |
| 2174 | Vector3 dNorm = dir.Normalized(); |
| 2175 | float deltaX = dNorm.X(); |
| 2176 | float deltaZ = dNorm.Z(); |
| 2177 | |
| 2178 | int xInt = toIntFloor(pos.X() * _invTerrainGrid); |
| 2179 | int zInt = toIntFloor(pos.Z() * _invTerrainGrid); |
| 2180 | |
| 2181 | float invDeltaX = fabs(deltaX) < 1e-10 ? FloatSign(deltaX) * 1e10 : 1 / deltaX; |
| 2182 | float invDeltaZ = fabs(deltaZ) < 1e-10 ? FloatSign(deltaZ) * 1e10 : 1 / deltaZ; |
| 2183 | int ddx = deltaX >= 0 ? 1 : -1; |
| 2184 | int ddz = deltaZ >= 0 ? 1 : -1; |
| 2185 | float dnx = deltaX >= 0 ? _terrainGrid : 0; |
| 2186 | float dnz = deltaZ >= 0 ? _terrainGrid : 0; |
| 2187 | |
| 2188 | float tRest = maxDist; |
| 2189 | int maxIter = toInt(ENGINE_CONFIG.horizontZ * _invTerrainGrid * 15); |
| 2190 | while (tRest > 0) |
| 2191 | { |
| 2192 | if (--maxIter < 0) |
| 2193 | { |
| 2194 | LOG_DEBUG(Physics, "IntersectWithGround: Max iters failed (dist {:.1f})", maxDist); |
| 2195 | break; |
| 2196 | } |
| 2197 | Vector3 beg = pos; |
| 2198 | |
| 2199 | int xio = xInt, zio = zInt; |
| 2200 | float tx = (xInt * _terrainGrid + dnx - pos.X()) * invDeltaX; |
| 2201 | float tz = (zInt * _terrainGrid + dnz - pos.Z()) * invDeltaZ; |
| 2202 | // Clamp to 0: when direction component is near-zero, floating-point |
| 2203 | // imprecision in (gridEdge - pos) * hugeInvDelta can produce small negatives |
| 2204 | if (tx < 0) |
| 2205 | tx = 0; |
| 2206 | if (tz < 0) |
| 2207 | tz = 0; |
| 2208 | if (tx <= tz) |
| 2209 | { |
| 2210 | saturateMin(tx, tRest); |
| 2211 | xInt += ddx; |
| 2212 | tRest -= tx; |
| 2213 | pos += dNorm * tx; |
| 2214 | } |
| 2215 | else |
| 2216 | { |
| 2217 | saturateMin(tz, tRest); |
| 2218 | zInt += ddz; |
| 2219 | tRest -= tz; |
| 2220 | pos += dNorm * tz; |
| 2221 | } |
| 2222 | |
| 2223 | float t; |
| 2224 | bool col = CheckIntersection(beg, pos, xio, zio, t); |
| 2225 | if (col) |
no test coverage detected