// Cast a line from A to B, checking for collisions with other entities. public IEnumerable <LineCastResult> LineCastAll(DVector3 start, DVector3 end, int ignoreTeam = -1) { var start2d = new DVector2(start.x, start.z); var end2d = new DVector2(end.x, end.z); foreach (Collider c in colliders) { if (c.entity.team == ignoreTeam) { continue; } var position2d = new DVector2(c.entity.position.x, c.entity.position.z); DVector2 result; // FIXME: Need to adjust positions to correct for wrap. // FIXME: Some cases still not handled properly. // // _______________ // | / | // ---X----------- // / // / // O // / // / // Circle intersects at O, which is a miss, but a real intersect happens at X. if (Utility.IntersectLineCircle(position2d, c.radius, start2d, end2d, out result)) { // Possible hit, work out the correct 3D position at the intersect. var result3d = new DVector3(result.x, start.y, result.y); var a = result3d - start; var bhat = (end - start).normalized; var ab = DVector3.Dot(a, bhat); var intersectPoint = start + bhat * ab; var height = intersectPoint.y; var bottom = c.entity.position.y; var top = bottom + c.height; Logger.Log("result3d: {0} a: {1} bhat: {2} ab: {3} height: {4} bottom: {5} top:{6}", result3d, a, bhat, ab, height, bottom, top); DebugExtension.DebugPoint((UnityEngine.Vector3)intersectPoint, UnityEngine.Color.blue, 10, 10); UnityEngine.Debug.DrawLine((UnityEngine.Vector3)start, (UnityEngine.Vector3)end, UnityEngine.Color.green, 10); UnityEngine.Debug.DrawLine((UnityEngine.Vector3)start, (UnityEngine.Vector3)result3d, UnityEngine.Color.green, 10); if (bottom <= height && height <= top) { var r = new LineCastResult(); r.entity = c.entity; r.position = intersectPoint; yield return(r); } } } }
// Directly examine the map to determine if a tile is passible. bool MapPassable(int x, int z) { for (int xoff = 0; xoff < granularity; xoff += 1) { for (int zoff = 0; zoff < granularity; zoff += 1) { var pos = new DVector3(x + xoff + DReal.Half, 0, z + zoff + DReal.Half); var normal = map.Normal(pos); var up = new DVector3(0, 1, 0); var slope = DVector3.Dot(normal, up); if (slope < slopeLimit) { // Too sloped. return(false); } if (map.Height(pos) < 0) { // Underwater. return(false); } } } return(true); }