/** * Tests whether this light affects the given primitive. This checks both the primitive and light settings for light relevance * and also calls AffectsBounds. * * @param CompactPrimitiveSceneInfo - The primitive to test. * @return True if the light affects the primitive. */ bool FLightSceneInfoCompact::AffectsPrimitive(const FPrimitiveSceneInfoCompact& CompactPrimitiveSceneInfo) const { // Check if the light's bounds intersect the primitive's bounds. if(AreSpheresNotIntersecting( BoundingSphereVector, VectorReplicate(BoundingSphereVector,3), VectorLoadFloat3(&CompactPrimitiveSceneInfo.Bounds.Origin), VectorLoadFloat1(&CompactPrimitiveSceneInfo.Bounds.SphereRadius) )) { return false; } // Cull based on information in the full scene infos. if(!LightSceneInfo->Proxy->AffectsBounds(CompactPrimitiveSceneInfo.Bounds)) { return false; } if (LightSceneInfo->Proxy->CastsShadowsFromCinematicObjectsOnly() && !CompactPrimitiveSceneInfo.Proxy->CastsCinematicShadow()) { return false; } if (!(LightSceneInfo->Proxy->GetLightingChannelMask() & CompactPrimitiveSceneInfo.Proxy->GetLightingChannelMask())) { return false; } return true; }
bool FConvexVolume::IntersectSphere(const FVector& Origin,const float& Radius, bool& bOutFullyContained) const { bool Result = true; //Assume fully contained bOutFullyContained = true; checkSlow(PermutedPlanes.Num() % 4 == 0); // Load the origin & radius VectorRegister Orig = VectorLoadFloat3(&Origin); VectorRegister VRadius = VectorLoadFloat1(&Radius); VectorRegister NegativeVRadius = VectorNegate(VRadius); // Splat origin into 3 vectors VectorRegister OrigX = VectorReplicate(Orig, 0); VectorRegister OrigY = VectorReplicate(Orig, 1); VectorRegister OrigZ = VectorReplicate(Orig, 2); // Since we are moving straight through get a pointer to the data const FPlane* RESTRICT PermutedPlanePtr = (FPlane*)PermutedPlanes.GetData(); // Process four planes at a time until we have < 4 left for (int32 Count = 0; Count < PermutedPlanes.Num(); Count += 4) { // Load 4 planes that are already all Xs, Ys, ... VectorRegister PlanesX = VectorLoadAligned(PermutedPlanePtr); PermutedPlanePtr++; VectorRegister PlanesY = VectorLoadAligned(PermutedPlanePtr); PermutedPlanePtr++; VectorRegister PlanesZ = VectorLoadAligned(PermutedPlanePtr); PermutedPlanePtr++; VectorRegister PlanesW = VectorLoadAligned(PermutedPlanePtr); PermutedPlanePtr++; // Calculate the distance (x * x) + (y * y) + (z * z) - w VectorRegister DistX = VectorMultiply(OrigX,PlanesX); VectorRegister DistY = VectorMultiplyAdd(OrigY,PlanesY,DistX); VectorRegister DistZ = VectorMultiplyAdd(OrigZ,PlanesZ,DistY); VectorRegister Distance = VectorSubtract(DistZ,PlanesW); // Check for completely outside int32 Mask = VectorAnyGreaterThan(Distance,VRadius); if (Mask) { Result = false; bOutFullyContained = false; break; } //the sphere is definitely inside the frustums, but let's check if it's FULLY contained by checking the NEGATIVE radius (on the inside of each frustum plane) Mask = VectorAnyGreaterThan(Distance,NegativeVRadius); if (Mask) { bOutFullyContained = false; } } return Result; }
bool FConvexVolume::IntersectSphere(const FVector& Origin,const float& Radius) const { bool Result = true; checkSlow(PermutedPlanes.Num() % 4 == 0); // Load the origin & radius VectorRegister Orig = VectorLoadFloat3(&Origin); VectorRegister VRadius = VectorLoadFloat1(&Radius); // Splat origin into 3 vectors VectorRegister OrigX = VectorReplicate(Orig, 0); VectorRegister OrigY = VectorReplicate(Orig, 1); VectorRegister OrigZ = VectorReplicate(Orig, 2); // Since we are moving straight through get a pointer to the data const FPlane* RESTRICT PermutedPlanePtr = (FPlane*)PermutedPlanes.GetData(); // Process four planes at a time until we have < 4 left for (int32 Count = 0; Count < PermutedPlanes.Num(); Count += 4) { // Load 4 planes that are already all Xs, Ys, ... VectorRegister PlanesX = VectorLoadAligned(PermutedPlanePtr); PermutedPlanePtr++; VectorRegister PlanesY = VectorLoadAligned(PermutedPlanePtr); PermutedPlanePtr++; VectorRegister PlanesZ = VectorLoadAligned(PermutedPlanePtr); PermutedPlanePtr++; VectorRegister PlanesW = VectorLoadAligned(PermutedPlanePtr); PermutedPlanePtr++; // Calculate the distance (x * x) + (y * y) + (z * z) - w VectorRegister DistX = VectorMultiply(OrigX,PlanesX); VectorRegister DistY = VectorMultiplyAdd(OrigY,PlanesY,DistX); VectorRegister DistZ = VectorMultiplyAdd(OrigZ,PlanesZ,DistY); VectorRegister Distance = VectorSubtract(DistZ,PlanesW); // Check for completely outside if (VectorAnyGreaterThan(Distance,VRadius)) { Result = false; break; } } return Result; }