private static Vector4 MaxDotProductPlaneAABB(ref BoxMinMaxSoA Box, Vector4 Plane) { return(Vector4.Max(Box.MinX * Plane.x, Box.MaxX * Plane.x) + Vector4.Max(Box.MinY * Plane.y, Box.MaxY * Plane.y) + Vector4.Max(Box.MinZ * Plane.z, Box.MaxZ * Plane.z) + new Vector4(Plane.w, Plane.w, Plane.w, Plane.w)); }
private static Vector4 FrustumOutsideAABB(ref BoxMinMaxSoA Box, Vector3 FrustumAABBMin, Vector3 FrustumAABBMax) { var r0 = new Vector4(FrustumAABBMax.x, FrustumAABBMax.x, FrustumAABBMax.x, FrustumAABBMax.x) - Box.MinX; var r1 = new Vector4(FrustumAABBMax.y, FrustumAABBMax.y, FrustumAABBMax.y, FrustumAABBMax.y) - Box.MinY; var r2 = new Vector4(FrustumAABBMax.z, FrustumAABBMax.z, FrustumAABBMax.z, FrustumAABBMax.z) - Box.MinZ; var r3 = Box.MaxX - new Vector4(FrustumAABBMin.x, FrustumAABBMin.x, FrustumAABBMin.x, FrustumAABBMin.x); var r4 = Box.MaxY - new Vector4(FrustumAABBMin.y, FrustumAABBMin.y, FrustumAABBMin.y, FrustumAABBMin.y); var r5 = Box.MaxZ - new Vector4(FrustumAABBMin.z, FrustumAABBMin.z, FrustumAABBMin.z, FrustumAABBMin.z); return(Vector4.Min(Vector4.Min(Vector4.Min(r0, r1), Vector4.Min(r2, r3)), Vector4.Min(r4, r5))); }
static private void CullBoxesAoSoA_Default( ref byte[] OutVisibilityMask, ref Vector4[] InBoxesMinMaxAoSoA, ref Vector4[] InFrustumData, Vector3 FrustumAABBMax, Vector3 FrustumAABBMin, bool TestFrustumCorners) { int NumSoAPackets = InBoxesMinMaxAoSoA.Length / 6; for (int i = 0; i < NumSoAPackets; ++i) { var BoxMinMax = new BoxMinMaxSoA(ref InBoxesMinMaxAoSoA, i); var DotsL = MaxDotProductPlaneAABB(ref BoxMinMax, InFrustumData[0]); var DotsR = MaxDotProductPlaneAABB(ref BoxMinMax, InFrustumData[1]); var DotsT = MaxDotProductPlaneAABB(ref BoxMinMax, InFrustumData[2]); var DotsB = MaxDotProductPlaneAABB(ref BoxMinMax, InFrustumData[3]); var DotsN = MaxDotProductPlaneAABB(ref BoxMinMax, InFrustumData[4]); var DotsF = MaxDotProductPlaneAABB(ref BoxMinMax, InFrustumData[5]); var R = Vector4.Min(Vector4.Min(DotsL, DotsR), Vector4.Min(Vector4.Min(DotsT, DotsB), Vector4.Min(DotsF, DotsN))); if (TestFrustumCorners) { R = Vector4.Min(R, FrustumOutsideAABB(ref BoxMinMax, FrustumAABBMin, FrustumAABBMax)); } int Mask = (R.w < 0.0f ? 0x8 : 0x0) | (R.z < 0.0f ? 0x4 : 0x0) | (R.y < 0.0f ? 0x2 : 0x0) | (R.x < 0.0f ? 0x1 : 0x0); // init mask when index is even, update mask when it's odd if ((i & 0x1) == 0) { OutVisibilityMask[i >> 1] = (byte)Mask; } else { OutVisibilityMask[i >> 1] |= (byte)(Mask << 4); } } }