示例#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);
            }
        }
示例#2
0
        //---------------------

        public override bool preciseIntersect(ref SSRay localRay, out float nearestLocalRayContact)
        {
            nearestLocalRayContact = float.PositiveInfinity;

            if (useBVHForIntersections)
            {
                if (_bvh == null && _vbo != null && _ibo != null)
                {
                    // rebuilding BVH
                    // TODO try updating instead of rebuilding?
                    _bvh = new SSIndexedMeshTrianglesBVH(_vbo, _ibo);
                    for (UInt16 triIdx = 0; triIdx < _ibo.numIndices / 3; ++triIdx)
                    {
                        _bvh.addObject(triIdx);
                    }
                }

                if (_bvh != null)
                {
                    List <ssBVHNode <UInt16> > nodesHit = _bvh.traverseRay(localRay);
                    foreach (var node in nodesHit)
                    {
                        if (!node.IsLeaf)
                        {
                            continue;
                        }

                        foreach (UInt16 triIdx in node.gobjects)
                        {
                            Vector3 v0, v1, v2;
                            _readTriangleVertices(triIdx, out v0, out v1, out v2);

                            float contact;
                            if (OpenTKHelper.TriangleRayIntersectionTest(
                                    ref v0, ref v1, ref v2, ref localRay.pos, ref localRay.dir, out contact))
                            {
                                if (contact < nearestLocalRayContact)
                                {
                                    nearestLocalRayContact = contact;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                _bvh = null;
                // slow, tedious intersection test
                int numTri = lastAssignedIndices.Length / 3;
                for (UInt16 triIdx = 0; triIdx < numTri; ++triIdx)
                {
                    Vector3 v0, v1, v2;
                    _readTriangleVertices(triIdx, out v0, out v1, out v2);
                    float contact;
                    if (OpenTKHelper.TriangleRayIntersectionTest(
                            ref v0, ref v1, ref v2, ref localRay.pos, ref localRay.dir, out contact))
                    {
                        if (contact < nearestLocalRayContact)
                        {
                            nearestLocalRayContact = contact;
                        }
                    }
                }
            }
            return(nearestLocalRayContact < float.PositiveInfinity);
        }