bool CastRay(Ray ray, ref BouncyRay raycast) { bool result = false; if (raycast.Bounces < 5) { RaycastHit hit; if (Physics.Raycast(ray, out hit)) { //Rr = Ri - 2 N(Ri.N) Vector3 Ri = (hit.point - ray.origin).normalized; Vector3 reflection = Ri - 2 * hit.normal * (Vector3.Dot(Ri, hit.normal)); float distance2 = Vector3.Distance(ray.origin, hit.point); // TODO: remplace with layers if (hit.transform.gameObject.GetComponent <ProjectionTarget>() != null) { //length += distance2; raycast.AddHit(new Ray(ray.origin, hit.point - ray.origin), distance2); result = true; } // TODO: remplace with layers else if (hit.transform.gameObject.GetComponent <Mirror>() != null) { raycast.AddBounce(new Ray(ray.origin, hit.point - ray.origin), distance2); result = CastRay(new Ray(hit.point, reflection), ref raycast); } else { raycast.AddBounce(new Ray(ray.origin, hit.point - ray.origin), distance2); } } } return(result); }
void Compute() { Awake(); float delta = 1.0f / size; int lastCount = count; count = (size) * (size); if (rays == null || rays.Length != lastCount) { uv = new Vector2[count]; xyz = new Vector3[count]; rays = new BouncyRay[count]; } int current = 0; Vector3 origin = this.transform.position; for (int x = 0; x < size; ++x) { for (int y = 0; y < size; ++y) { Vector2 uv = new Vector2(x, y) / (size - 1); Ray ray = _camera.ViewportPointToRay(new Vector3(uv.x, uv.y, 1)); rays[current] = new BouncyRay(ray) { uv = uv }; bool hit = CastRay(ray, ref rays[current]); ++current; } } // Sîmple stats idxRayOpticalCenter = (size - 1) / 2 + size * (size - 1) / 2; int hits = 0; lengthAvg = 0; foreach (BouncyRay r in rays) { if (r.Hit) { ++hits; lengthAvg += r.Length; } } coverture = ((float)hits) / count; lengthAvg = lengthAvg / hits; lengthDev = 0; foreach (BouncyRay r in rays) { lengthDev += Mathf.Abs(r.Length - lengthAvg); } // find the intersections intersectionCount = 0; Vector3 centroidIntersection = Vector3.zero; Vector3 avgCentroid = Vector3.zero; for (int r1 = 0; r1 < rays.Length; ++r1) { BouncyRay raycast1 = rays[r1]; if (raycast1.Hit) { Ray ray1 = raycast1.Unfolded; for (int r2 = r1 + 1; r2 < rays.Length; ++r2) { BouncyRay raycast2 = rays[r2]; if (raycast2.Hit) { Ray ray2 = raycast2.Unfolded; Vector3 intersection; if (Math3d.LineLineIntersection(out intersection, ray1.origin, ray1.direction, ray2.origin, ray2.direction)) { centroidIntersection += intersection; ++intersectionCount; } } } avgCentroid += ray1.origin; } } if (compute && intersectionCount > 0) { centroidIntersection /= intersectionCount; if (otherCamera != null) { Ray physicalCenterRay = new Ray(this.transform.position, this.transform.forward); physicalCenterBounce = new BouncyRay(physicalCenterRay); bool hit = CastRay(physicalCenterRay, ref physicalCenterBounce); Ray TheCenterRay = physicalCenterBounce.Unfolded;// rays[idxRayOpticalCenter].Unfolded; otherCamera.CopyFrom(_camera); otherCamera.transform.position = centroidIntersection; Debug.Log("" + idxRayOpticalCenter + ": " + TheCenterRay.origin); otherCamera.transform.rotation = Quaternion.LookRotation(TheCenterRay.origin - centroidIntersection, Vector3.down); Gizmos.DrawLine(TheCenterRay.origin, centroidIntersection); } } lengthDev /= hits; }
private void OnDrawGizmos() { if (compute) { Compute(); } if (drawRays || drawHits || drawUnfold) { foreach (BouncyRay ray in rays) { Vector2 uv = ray.uv; Gizmos.color = ray.Hit ? new Color(uv.x, uv.y, 0, 0.25f) : new Color(1, 1, 1, 0.25f); if (drawRays || drawHits) { Vector3[] hits = ray.GetPoints(); for (int p = 1; p < hits.Length; ++p) { if (drawRays) { Gizmos.DrawLine(hits[p - 1], hits[p]); } if (drawHits) { Gizmos.DrawSphere(hits[p], 0.25f); } } } if (drawUnfold) { Ray unfolded = ray.Unfolded; Gizmos.DrawLine(unfolded.origin, unfolded.origin + unfolded.direction * ray.Length); } } } //this is the optical center { idxRayOpticalCenter = (size - 1) / 2 + size * (size - 1) / 2; BouncyRay ray = rays[idxRayOpticalCenter]; Vector3[] hits = ray.GetPoints(); Vector2 uv = ray.uv; Gizmos.color = Color.blue; for (int p = 1; p < hits.Length; ++p) { Gizmos.DrawLine(hits[p - 1], hits[p]); Gizmos.DrawSphere(hits[p], 0.25f); } Ray unfolded = ray.Unfolded; Gizmos.DrawLine(unfolded.origin, unfolded.origin + unfolded.direction * ray.Length); } { BouncyRay ray = physicalCenterBounce; Vector3[] hits = ray.GetPoints(); Vector2 uv = ray.uv; Gizmos.color = Color.white; for (int p = 1; p < hits.Length; ++p) { Gizmos.DrawLine(hits[p - 1], hits[p]); Gizmos.DrawSphere(hits[p], 0.25f); } Ray unfolded = ray.Unfolded; Gizmos.DrawLine(unfolded.origin, unfolded.origin + unfolded.direction * ray.Length); } Gizmos.color = Color.red; Vector3 center = Vector3.zero; int intersections = 0; for (int r1 = 0; r1 < rays.Length; ++r1) { BouncyRay raycast1 = rays[r1]; if (raycast1.Hit) { Ray ray1 = raycast1.Unfolded; for (int r2 = r1 + 1; r2 < rays.Length; ++r2) { BouncyRay raycast2 = rays[r2]; if (raycast2.Hit) { Ray ray2 = raycast2.Unfolded; Vector3 p1; Vector3 p2; if (Math3d.ClosestPointsOnTwoLines(out p1, out p2, ray1.origin, ray1.direction, ray2.origin, ray2.direction)) { Gizmos.DrawLine(p1, p2); center += (p1 + p2) / 2; ++intersections; } } } } } Gizmos.DrawWireSphere(center / intersections, 0.1f); }