public AntiIntersection AntiIntersect(Ray ray, SphereBase parentSphere) { Vector3 l = GetPosition() - ray.GetStart(); //Vector to sphere center (and direction) float tc = Vector3.Dot(l, ray.GetDirection()); //Length to ray hit-center float els = Vector3.Dot(l, l); float radiusSquared = _radius * _radius; if (tc < 0 && els > radiusSquared) { return(AntiIntersection.CreateNullAntiIntersection()); } float dSquared = els - tc * tc; //Squared perpendicular distance from spherecenter to ray (vinkelrätt) if (dSquared > radiusSquared) { return(AntiIntersection.CreateNullAntiIntersection()); } float t1c = (float)Math.Sqrt(radiusSquared - dSquared); float tNear, tFar; tNear = tc - t1c; tFar = tc + t1c; Vector3 pNear = ray.GetStart() + Vector3.Multiply(ray.GetDirection(), tNear); Vector3 pFar = ray.GetStart() + Vector3.Multiply(ray.GetDirection(), tFar); var normNearTexture = Vector3.Normalize(Vector3.Divide(GetPosition() - pNear, _radius)); var normFarTexture = Vector3.Normalize(Vector3.Divide(GetPosition() - pFar, _radius)); return(new AntiIntersection(pNear, pFar, normNearTexture, normFarTexture, tNear, tFar, this)); }
protected void insertAntiIntersectionSortedToArray(AntiIntersection[] array, int maxPosition, AntiIntersection item) { if (maxPosition == 0) { array[0] = item; return; } //Sort at insert for (int i = maxPosition - 1; i >= 0; i--) { if (item.GetTNear() > array[i].GetTNear() | item.IsNull()) { array[i + 1] = item; break; } else { array[i + 1] = array[i]; if (i == 0) { array[0] = item; } } } }
private AntiIntersection getFarthestAntiIntersection(float tMin, float tMax, AntiIntersection[] antiSphereIntersectionList) { AntiIntersection farthestAntiIntersection = AntiIntersection.CreateNullAntiIntersection(); tMin = (tMin < 0) ? 0 : tMin; float tCurrent = tMin; //compare the hits in the antilist foreach (AntiIntersection antiIntersection in antiSphereIntersectionList) { //Break here, because the sorting places all the missed intersections in the end if (!antiIntersection.IsHit()) { break; } if (antiIntersection.isDistanceInside(tCurrent)) { //Move away the nearest hit to the other side of the AntiSphere tCurrent = antiIntersection.GetTFar(); farthestAntiIntersection = antiIntersection; } if (tCurrent >= tMax) { //It went through farthestAntiIntersection = AntiIntersection.CreateInfiniteAntiIntersection(); break; } } return(farthestAntiIntersection); }
protected void calculateAntiSphereIntersections(Ray ray, out AntiIntersection[] antiSphereIntersectionList, out bool antiSphereIntersectionListIsHit) { //Local array will help about thread issues antiSphereIntersectionList = new AntiIntersection[_antiSphereList.Count]; antiSphereIntersectionListIsHit = false; for (int i = 0; i < _antiSphereList.Count; i++) { var intersection = _antiSphereList[i].AntiIntersect(ray, this); antiSphereIntersectionListIsHit = antiSphereIntersectionListIsHit | intersection.IsHit(); insertAntiIntersectionSortedToArray(antiSphereIntersectionList, i, intersection); } }
protected Intersection getClosestIntersectionFromAntiSpheres(Intersection sphereIntersection, Ray ray) { bool insideSphere = sphereIntersection.GetTFirstHit() == sphereIntersection.GetTFar(); AntiIntersection[] antiSphereIntersectionList; bool antiSphereIntersectionListIsHit; calculateAntiSphereIntersections(ray, out antiSphereIntersectionList, out antiSphereIntersectionListIsHit); if (antiSphereIntersectionListIsHit) { AntiIntersection farthestAntiIntersection = getFarthestAntiIntersection(sphereIntersection.GetTNear(), sphereIntersection.GetTFar(), antiSphereIntersectionList); if (farthestAntiIntersection.IsHit()) { var intersection = this.Intersect(farthestAntiIntersection.GetPositionFar(), farthestAntiIntersection.GetNormalFarTexture()); sphereIntersection = farthestAntiIntersection.CreateIntersection(intersection.GetNormalFirstHitTexture()); } else if (farthestAntiIntersection.IsInfinite()) { sphereIntersection = new Intersection(true); } } return(sphereIntersection); }
public void SetAntiIntersection(AntiIntersection antiIntersection) { _antiIntersection = antiIntersection; }
public AntiSphereAntiIntersection(AntiSphere antiSphere) { _antiSphere = antiSphere; _antiIntersection = AntiIntersection.CreateNullAntiIntersection(); }