Esempio n. 1
0
        public override bool PreciseIntersect(ref SSRay worldSpaceRay, ref float distanceAlongRay)
        {
            SSRay          localRay            = worldSpaceRay.Transformed(this.worldMat.Inverted());
            SSAbstractMesh mesh                = this._mesh;
            bool           hit                 = false;
            float          localNearestContact = float.MaxValue;

            if (mesh == null)
            {
                return(true);                // no mesh to test
            }
            else
            {
                // precise meshIntersect
                bool global_hit = mesh.TraverseTriangles((state, V1, V2, V3) => {
                    float contact;
                    if (OpenTKHelper.TriangleRayIntersectionTest(V1, V2, V3, localRay.pos, localRay.dir, out contact))
                    {
                        hit = true;
                        localNearestContact = Math.Min(localNearestContact, contact);
                        Console.WriteLine("Triangle Hit @ {0} : Object {1}", contact, Name);
                    }
                    return(false);                    // don't short circuit
                });
                if (hit)
                {
                    float worldSpaceContactDistance = -localNearestContact * this.Scale.LengthFast;
                    Console.WriteLine("Nearest Triangle Hit @ {0} vs Sphere {1} : Object {2}", worldSpaceContactDistance, distanceAlongRay, Name);
                    distanceAlongRay = worldSpaceContactDistance;
                }
                return(global_hit || hit);
            }
        }
Esempio n. 2
0
        public override bool Intersect(ref SSRay worldSpaceRay, out float distanceAlongRay)
        {
            // transform the ray into object space
            float localDistanceAlongRay;

            SSRay localRay = worldSpaceRay.Transformed(this.worldMat.Inverted());

            float distanceToSphereOrigin = OpenTKHelper.DistanceToLine(localRay, Vector3.Zero, out localDistanceAlongRay);

            distanceAlongRay = localDistanceAlongRay * this.Scale.LengthFast;
            bool result = distanceToSphereOrigin <= this.radius;

#if false
            Console.WriteLine("_____________________________");
            Console.WriteLine("sphere intersect test {0}   vs radius {1}", distanceToSphereOrigin, radius);
            Console.WriteLine("worldray {0}", worldSpaceRay);
            Console.WriteLine("localray {0}", localRay);
            Console.WriteLine("objectPos {0}", this.Pos);

            if (result)
            {
                Console.WriteLine("     ----> hit <-----");
                Console.WriteLine("----------------------------");
            }
            else
            {
                Console.WriteLine("          miss");
                Console.WriteLine("----------------------------");
            }
#endif

            return(result);
        }
        protected bool _perInstanceIntersectionTest(SSAbstractMesh abstrMesh, int i,
                                                    ref SSRay localRay, out float localContact)
        {
            var pos         = instanceData.readPosition(i);
            var masterScale = instanceData.readMasterScale(i);
            var scale       = instanceData.readComponentScale(i) * masterScale;

            if (abstrMesh == null)
            {
                // no way to be any more precise except hitting a generic sphere
                float radius = Math.Max(scale.Z, Math.Max(scale.X, scale.Y));
                var   sphere = new SSSphere(pos, radius);
                return(sphere.IntersectsRay(ref localRay, out localContact));
            }
            else
            {
                // When using SSAbstractMesh we can invoke its preciseIntersect()
                Matrix4 instanceMat = Matrix4.CreateScale(scale) * Matrix4.CreateTranslation(pos);

                SSRay instanceRay = localRay.Transformed(instanceMat.Inverted());
                float instanceContact;
                if (abstrMesh.preciseIntersect(ref instanceRay, out instanceContact))
                {
                    Vector3 instanceContactPt = instanceRay.pos + instanceContact * instanceRay.dir;
                    Vector3 localContactPt    = Vector3.Transform(instanceContactPt, instanceMat);
                    localContact = (localContactPt - localRay.pos).Length;
                    return(true);
                }
                else
                {
                    localContact = float.PositiveInfinity;
                    return(false);
                }
            }
        }
        public override bool Intersect(ref SSRay worldSpaceRay)
        {
            // transform the ray into object space

            SSRay localRay = worldSpaceRay.Transformed(this.worldMat.Inverted());

            float distanceToSphereOrigin = OpenTKHelper.DistanceToLine(localRay,Vector3.Zero);
            bool result = distanceToSphereOrigin <= this.radius;
            #if false
            Console.WriteLine("_____________________________");
            Console.WriteLine("sphere intersect test {0}   vs radius {1}",distanceToSphereOrigin,radius);
            Console.WriteLine("worldray {0}",worldSpaceRay);
            Console.WriteLine("localray {0}",localRay);
            Console.WriteLine("objectPos {0}",this.Pos);

            if (result) {
                Console.WriteLine("     ----> hit <-----");
                Console.WriteLine("----------------------------");
            } else {
                Console.WriteLine("          miss");
                Console.WriteLine("----------------------------");
            }
            #endif

            return result;
        }
Esempio n. 5
0
        public override bool PreciseIntersect(ref SSRay worldSpaceRay, ref float distanceAlongWorldRay)
        {
            SSRay localRay = worldSpaceRay.Transformed(this.worldMat.Inverted());

            if (this.Mesh != null)
            {
                float localNearestContact;
                bool  ret = this.Mesh.preciseIntersect(ref localRay, out localNearestContact);
                if (ret)
                {
                    Vector3 localContactPt = localRay.pos + localNearestContact * localRay.dir;
                    Vector3 worldContactPt = Vector3.Transform(localContactPt, this.worldMat);
                    distanceAlongWorldRay = (worldContactPt - worldSpaceRay.pos).Length;
                    //Console.WriteLine ("Nearest Triangle Hit @ {0} vs Sphere {1} : Object {2}", worldSpaceContactDistance, distanceAlongRay, Name);
                }
                else
                {
                    distanceAlongWorldRay = float.PositiveInfinity;
                }
                return(ret);
            }
            else
            {
                distanceAlongWorldRay = float.PositiveInfinity;
                return(false);
            }
        }
Esempio n. 6
0
 public override bool PreciseIntersect(ref SSRay worldSpaceRay, ref float distanceAlongRay)
 {
     SSRay localRay = worldSpaceRay.Transformed (this.worldMat.Inverted ());
     SSAbstractMesh mesh = this._mesh;
     bool hit = false;
     float localNearestContact = float.MaxValue;
     if (mesh == null) {
         return true; // no mesh to test
     } else {
         // precise meshIntersect
         bool global_hit = mesh.traverseTriangles ((state, V1, V2, V3) => {
             float contact;
             if (OpenTKHelper.TriangleRayIntersectionTest (V1, V2, V3, localRay.pos, localRay.dir, out contact)) {
                 hit = true;
                 localNearestContact = Math.Min (localNearestContact, contact);
                 Console.WriteLine ("Triangle Hit @ {0} : Object {1}", contact, Name);
             }
             return false; // don't short circuit
         });
         if (hit) {
             float worldSpaceContactDistance = -localNearestContact * this.Scale.LengthFast;
             Console.WriteLine ("Nearest Triangle Hit @ {0} vs Sphere {1} : Object {2}", worldSpaceContactDistance, distanceAlongRay, Name);
             distanceAlongRay = worldSpaceContactDistance;
         }
         return global_hit || hit;
     }
 }
Esempio n. 7
0
 public override bool PreciseIntersect(ref SSRay worldSpaceRay, ref float distanceAlongWorldRay)
 {
     SSRay localRay = worldSpaceRay.Transformed (this.worldMat.Inverted ());
     if (this.Mesh != null) {
         float localNearestContact;
         bool ret = this.Mesh.preciseIntersect(ref localRay, out localNearestContact);
         if (ret) {
             Vector3 localContactPt = localRay.pos + localNearestContact * localRay.dir;
             Vector3 worldContactPt = Vector3.Transform(localContactPt, this.worldMat);
             distanceAlongWorldRay = (worldContactPt - worldSpaceRay.pos).Length;
             //Console.WriteLine ("Nearest Triangle Hit @ {0} vs Sphere {1} : Object {2}", worldSpaceContactDistance, distanceAlongRay, Name);
         } else {
             distanceAlongWorldRay = float.PositiveInfinity;
         }
         return ret;
     } else {
         distanceAlongWorldRay = float.PositiveInfinity;
         return false;
     }
 }
        public override bool PreciseIntersect(ref SSRay worldSpaceRay, ref float distanceAlongRay)
        {
            SSRay          localRay  = worldSpaceRay.Transformed(this.worldMat.Inverted());
            SSAbstractMesh abstrMesh = this.mesh as SSAbstractMesh;

            float nearestLocalRayContact = float.PositiveInfinity;

            if (useBVHForIntersections)
            {
                if (_bvh == null)
                {
                    _bvh = new SSInstanceBVH(this.instanceData);
                    for (int i = 0; i < instanceData.activeBlockLength; ++i)
                    {
                        if (instanceData.isValid(i))
                        {
                            _bvh.addObject(i);
                        }
                    }
                }

                List <ssBVHNode <int> > nodesHit = _bvh.traverseRay(localRay);
                foreach (var node in nodesHit)
                {
                    if (!node.IsLeaf)
                    {
                        continue;
                    }
                    foreach (int i in node.gobjects)
                    {
                        if (!instanceData.isValid(i))
                        {
                            continue;
                        }

                        float localContact;
                        if (_perInstanceIntersectionTest(abstrMesh, i, ref localRay, out localContact))
                        {
                            if (localContact < nearestLocalRayContact)
                            {
                                nearestLocalRayContact = localContact;
                            }
                        }
                    }
                }
            }
            else
            {
                // no BVH is used
                for (int i = 0; i < instanceData.activeBlockLength; ++i)
                {
                    if (!instanceData.isValid(i))
                    {
                        continue;
                    }

                    float localContact;
                    if (_perInstanceIntersectionTest(abstrMesh, i, ref localRay, out localContact))
                    {
                        if (localContact < nearestLocalRayContact)
                        {
                            nearestLocalRayContact = localContact;
                        }
                    }
                }
            }

            if (nearestLocalRayContact < float.PositiveInfinity)
            {
                Vector3 localContactPt = localRay.pos + nearestLocalRayContact * localRay.dir;
                Vector3 worldContactPt = Vector3.Transform(localContactPt, this.worldMat);
                distanceAlongRay = (worldContactPt - worldSpaceRay.pos).Length;
                return(true);
            }
            else
            {
                distanceAlongRay = float.PositiveInfinity;
                return(false);
            }
        }