Example #1
0
        public static void ReadInList(List <IntersectInfo> listToPopulate, StreamReader reader)
        {
            int count;

            int.TryParse(reader.ReadLine(), NumberStyles.Number, null, out count);
            for (int i = 0; i < count; i++)
            {
                IntersectInfo info    = new IntersectInfo();
                string        line    = reader.ReadLine();
                string[]      strings = line.Split(',');
                if (strings[0] == IntersectionType.FrontFace.ToString())
                {
                    info.hitType = IntersectionType.FrontFace;
                }
                else
                {
                    if (strings[0] != IntersectionType.BackFace.ToString())
                    {
                        throw new Exception("Has to be back or front.");
                    }
                    info.hitType = IntersectionType.BackFace;
                }
                double.TryParse(strings[1], NumberStyles.Number, null, out info.distanceToHit);
                listToPopulate.Add(info);
            }
        }
Example #2
0
 public IntersectInfo(IntersectInfo copyInfo)
 {
     this.hitType          = copyInfo.hitType;
     this.closestHitObject = copyInfo.closestHitObject;
     this.hitPosition      = copyInfo.hitPosition;
     this.normalAtHit      = copyInfo.normalAtHit;
     this.distanceToHit    = copyInfo.distanceToHit;
 }
Example #3
0
        public IntersectInfo GetClosestIntersection(Ray ray)
        {
            if (ray.Intersection(Aabb))
            {
                IPrimitive checkFirst  = nodeA;
                IPrimitive checkSecond = nodeB;
                if (ray.directionNormal[splitingPlane] < 0)
                {
                    checkFirst  = nodeB;
                    checkSecond = nodeA;
                }

                IntersectInfo infoFirst = checkFirst.GetClosestIntersection(ray);
                if (infoFirst != null && infoFirst.hitType != IntersectionType.None)
                {
                    if (ray.isShadowRay)
                    {
                        return(infoFirst);
                    }
                    else
                    {
                        ray.maxDistanceToConsider = infoFirst.distanceToHit;
                    }
                }
                if (checkSecond != null)
                {
                    IntersectInfo infoSecond = checkSecond.GetClosestIntersection(ray);
                    if (infoSecond != null && infoSecond.hitType != IntersectionType.None)
                    {
                        if (ray.isShadowRay)
                        {
                            return(infoSecond);
                        }
                        else
                        {
                            ray.maxDistanceToConsider = infoSecond.distanceToHit;
                        }
                    }
                    if (infoFirst != null && infoFirst.hitType != IntersectionType.None && infoFirst.distanceToHit >= 0)
                    {
                        if (infoSecond != null && infoSecond.hitType != IntersectionType.None && infoSecond.distanceToHit < infoFirst.distanceToHit && infoSecond.distanceToHit >= 0)
                        {
                            return(infoSecond);
                        }
                        else
                        {
                            return(infoFirst);
                        }
                    }

                    return(infoSecond);                    // we don't have to test it because it didn't hit.
                }
                return(infoFirst);
            }

            return(null);
        }
Example #4
0
        private static bool GetRemoveRegion(List <IntersectInfo> subtractList, int startIndex, out int regionStartIndex, out int regionEndIndex)
        {
            regionStartIndex = startIndex;
            regionEndIndex   = startIndex;
            double insideCount   = 0;
            int    subtractCount = subtractList.Count;

            for (int subtractIndex = startIndex; subtractIndex < subtractCount; subtractIndex++)
            {
                IntersectInfo subtractInfo = subtractList[subtractIndex];
                if (subtractInfo.hitType == IntersectionType.FrontFace)
                {
                    if (insideCount == 0)
                    {
                        regionStartIndex = subtractIndex;
                    }
                    insideCount++;
                }
                else if (subtractInfo.hitType == IntersectionType.BackFace)
                {
                    if (insideCount == 0)
                    {
                        throw new Exception("You should not have a back face without a matching front face.");
                    }
                    insideCount--;
                    if (insideCount == 0)
                    {
                        // let's check that there is not another entry aligned exactly with this exit
                        int nextIndex = subtractIndex + 1;
                        if (nextIndex >= subtractCount || subtractList[subtractIndex].distanceToHit + Ray.sameSurfaceOffset < subtractList[nextIndex].distanceToHit)
                        {
                            // we have our subtract region
                            regionEndIndex = subtractIndex;
                            return(true);
                        }
                    }
                }
                else
                {
                    throw new Exception("There should be no 'none's in the hit types.");
                }
            }

            return(false);
        }
Example #5
0
        public IntersectInfo GetClosestIntersection(Ray ray)
        {
            IntersectInfo bestInfo = null;

            foreach (IPrimitive item in items)
            {
                IntersectInfo info = item.GetClosestIntersection(ray);
                if (info != null && info.hitType != IntersectionType.None && info.distanceToHit >= 0)
                {
                    if (bestInfo == null || info.distanceToHit < bestInfo.distanceToHit)
                    {
                        bestInfo = info;
                    }
                }
            }

            return(bestInfo);
        }
Example #6
0
        private static bool IsInside(List <IntersectInfo> listToCheck, double distance)
        {
            int insideCount = 0;
            int conut       = listToCheck.Count;

            for (int index = 0; index < conut; index++)
            {
                IntersectInfo info = listToCheck[index];
                if (info.hitType == HitType.FrontFace)
                {
                    if (insideCount == 0)
                    {
                        startSubtract = info.distanceToHit;
                        // add all the elements from the last end to the new start
                    }
                    insideCount++;
                }
                else if (info.hitType == HitType.BackFace)
                {
                    insideCount--;
                    if (insideCount == 0)
                    {
                        if (IsInside(allPrimary, info.distanceToHit))
                        {
                            result.Add(info);
                        }
                        lastSubtractEnd = info.distanceToHit;
                        // add all the front face points between lastSubtractEnd and startSubtract
                    }
                }
                else
                {
                    throw new Exception("There should be no 'none's in the hit types.");
                }
            }

            return(false);
        }
Example #7
0
        private static void SubtractRemoveRegion(List <IntersectInfo> removeFrom, IntersectInfo startRemoveInfo, IntersectInfo endRemoveInfo)
        {
            if (startRemoveInfo.hitType != IntersectionType.FrontFace || endRemoveInfo.hitType != IntersectionType.BackFace)
            {
                throw new Exception("These should always be set right.");
            }

            double insideCount = 0;

            for (int primaryIndex = 0; primaryIndex < removeFrom.Count; primaryIndex++)
            {
                IntersectInfo primaryInfo = removeFrom[primaryIndex];
                if (primaryInfo.hitType == IntersectionType.FrontFace)
                {
                    insideCount++;

                    if (primaryInfo.distanceToHit < (startRemoveInfo.distanceToHit - Ray.sameSurfaceOffset))
                    {
                        // We are in front of the remove start. If the next backface is behind the remove start, add a back face at the remove start.
                        // there should always be a back face so it should be safe to + 1 this index.  I will let the bounds checker get it because it will throw an assert.  If not I would throw one instead.
                        if (removeFrom[primaryIndex + 1].distanceToHit > (startRemoveInfo.distanceToHit - Ray.sameSurfaceOffset))
                        {
                            IntersectInfo newBackFace = new IntersectInfo(startRemoveInfo);
                            newBackFace.hitType = IntersectionType.BackFace;
                            removeFrom.Insert(primaryIndex + 1, newBackFace);                             // it goes after the current index
                            primaryIndex++;
                        }
                    }
                    else if (primaryInfo.distanceToHit >= (startRemoveInfo.distanceToHit - Ray.sameSurfaceOffset) && primaryInfo.distanceToHit < (endRemoveInfo.distanceToHit + Ray.sameSurfaceOffset))
                    {
                        // the front face is within the remove so remove it.
                        removeFrom.Remove(primaryInfo);
                        // need to check the same index again.
                        primaryIndex--;
                    }
                    else if (primaryInfo.distanceToHit >= (endRemoveInfo.distanceToHit + Ray.sameSurfaceOffset))
                    {
                        // we have gone past the remove region just return.
                        return;
                    }
                }
                else if (primaryInfo.hitType == IntersectionType.BackFace)
                {
                    if (insideCount == 0)
                    {
                        throw new Exception("You should not have a back face without a matching front face.");
                    }
                    insideCount--;
                    if (insideCount == 0)
                    {
                        if (primaryInfo.distanceToHit > (startRemoveInfo.distanceToHit - Ray.sameSurfaceOffset) && primaryInfo.distanceToHit < (endRemoveInfo.distanceToHit + Ray.sameSurfaceOffset))
                        {
                            // the back face is within the remove so remove it.
                            removeFrom.Remove(primaryInfo);
                            // need to check the same index again.
                            primaryIndex--;
                        }
                        else if (primaryInfo.distanceToHit >= (endRemoveInfo.distanceToHit + Ray.sameSurfaceOffset))
                        {
                            // the back face is past the remove distance.
                            // Add the remove back face as a front face to the primary
                            // We should be guaranteed that the front face is within the remove distance because if it was we should have returned above.
                            IntersectInfo newFrontFace = new IntersectInfo(endRemoveInfo);
                            newFrontFace.hitType = IntersectionType.FrontFace;
                            removeFrom.Insert(primaryIndex, newFrontFace);
                            primaryIndex++;
                        }
                    }
                    else
                    {
                        if (primaryInfo.distanceToHit > (startRemoveInfo.distanceToHit - Ray.sameSurfaceOffset) && primaryInfo.distanceToHit < (endRemoveInfo.distanceToHit + Ray.sameSurfaceOffset))
                        {
                            // the back face is within the remove so remove it.
                            removeFrom.Remove(primaryInfo);
                            // need to check the same index again.
                            primaryIndex--;
                        }
                    }
                }
                else
                {
                    throw new Exception("There should be no 'none's in the hit types.");
                }
            }
        }