示例#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);
            }
        }
        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);
                }
            }
        }
示例#3
0
 public SSObjectMesh(SSAbstractMesh mesh) : this()
 {
     this.Mesh = mesh;
     this.renderState.castsShadow     = true; // SSObjectMesh casts shadow by default
     this.renderState.receivesShadows = true; // SSObjectMesh receives shadow by default
     _setupMesh();
 }
示例#4
0
 public SSObjectMesh(SSAbstractMesh mesh)
     : this()
 {
     this.Mesh = mesh;
     this.renderState.castsShadow = true;    // SSObjectMesh casts shadow by default
     this.renderState.receivesShadows = true; // SSObjectMesh receives shadow by default
     _setupMesh ();
 }
示例#5
0
 public SSObjectBillboard(SSAbstractMesh mesh, bool enableOcclusionTest = false)
 {
     Mesh = mesh;
     isOcclusionQueueryEnabled = enableOcclusionTest;
     if (isOcclusionQueueryEnabled) {
         GL_query_id = GL.GenQuery();
     }
 }
示例#6
0
 public SSObjectBillboard(SSAbstractMesh mesh, bool enableOcclusionTest = false)
 {
     Mesh = mesh;
     isOcclusionQueueryEnabled = enableOcclusionTest;
     if (isOcclusionQueueryEnabled)
     {
         GL_query_id = GL.GenQuery();
     }
 }
示例#7
0
 public SSObjectMesh(SSAbstractMesh mesh) : this()
 {
     this.Mesh = mesh;
     this.renderState.castsShadow = true; // SSObjectMesh casts shadow by default
 }
        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);
            }
        }
示例#9
0
 public SSObjectMeshSky(SSAbstractMesh mesh) : base(mesh)
 {
 }
 public SSObjectMeshSky(SSAbstractMesh mesh)
     : base(mesh)
 {
 }
 public SSObjectOcclusionQueuery(SSAbstractMesh mesh)
 {
     Mesh = mesh;
     _gl_query_id = GL.GenQuery();
 }
 public SSObjectOcclusionQueuery(SSAbstractMesh mesh)
 {
     Mesh         = mesh;
     _gl_query_id = GL.GenQuery();
 }