Beispiel #1
0
        // Determines which triangles of the surface are facing towards the light origin.
        // The facing array should be allocated with one extra index than the number of surface triangles, which will be used to handle dangling edge silhouettes.
        static void R_CalcInteractionFacing(IRenderEntity ent, SrfTriangles tri, IRenderLight light, ref SrfCullInfo cullInfo)
        {
            if (cullInfo.facing != null)
            {
                return;
            }

            Vector3 localLightOrigin;

            R_GlobalPointToLocal(ent.modelMatrix, light.globalLightOrigin, out localLightOrigin);

            var numFaces = tri.numIndexes / 3;

            if (tri.facePlanes == null || !tri.facePlanesCalculated)
            {
                R_DeriveFacePlanes(tri);
            }

            cullInfo.facing = (byte *)R_StaticAlloc((numFaces + 1) * sizeof(byte));

            // calculate back face culling
            var planeSide = stackalloc float[numFaces + floatX.ALLOC16]; planeSide = (float *)_alloca16(planeSide);

            // exact geometric cull against face
            fixed(Plane *facePlanesP = tri.facePlanes) Simd.Dotcp(planeSide, localLightOrigin, facePlanesP, numFaces);

            Simd.CmpGE(cullInfo.facing, planeSide, 0f, numFaces);

            cullInfo.facing[numFaces] = 1;  // for dangling edges to reference
        }
Beispiel #2
0
        // We want to cull a little on the sloppy side, because the pre-clipping of geometry to the lights in dmap will give many cases that are right
        // at the border we throw things out on the border, because if any one vertex is clearly inside, the entire triangle will be accepted.
        static void R_CalcInteractionCullBits(IRenderEntity ent, SrfTriangles tri, IRenderLight light, ref SrfCullInfo cullInfo)
        {
            int i, frontBits;

            if (cullInfo.cullBits != null)
            {
                return;
            }

            frontBits = 0;

            // cull the triangle surface bounding box
            for (i = 0; i < 6; i++)
            {
                R_GlobalPlaneToLocal(ent.modelMatrix, -light.frustum[i], out cullInfo.localClipPlanes[i]);

                // get front bits for the whole surface
                if (tri.bounds.PlaneDistance(cullInfo.localClipPlanes[i]) >= IInteraction.LIGHT_CLIP_EPSILON)
                {
                    frontBits |= 1 << i;
                }
            }

            // if the surface is completely inside the light frustum
            if (frontBits == ((1 << 6) - 1))
            {
                cullInfo.cullBits = IInteraction.LIGHT_CULL_ALL_FRONT; return;
            }

            cullInfo.cullBits = (byte *)R_StaticAlloc(tri.numVerts * sizeof(byte));
            Simd.Memset(cullInfo.cullBits, 0, tri.numVerts * sizeof(byte));

            var planeSide = stackalloc float[tri.numVerts + floatX.ALLOC16]; planeSide = (float *)_alloca16(planeSide);

            for (i = 0; i < 6; i++)
            {
                // if completely infront of this clipping plane
                if ((frontBits & (1 << i)) != 0)
                {
                    continue;
                    fixed(DrawVert *vertsD = tri.verts) Simd.Dotpd(planeSide, cullInfo.localClipPlanes[i], vertsD, tri.numVerts);

                    Simd.CmpLTb(cullInfo.cullBits, (byte)i, planeSide, IInteraction.LIGHT_CLIP_EPSILON, tri.numVerts);
            }
        }