| 278 | } |
| 279 | |
| 280 | bool PlanarShadowEffect::GetProjectionMatrix(size_t i, Matrix4x4<float>& projection) |
| 281 | { |
| 282 | // Compute the equation for the planeVisual in world coordinates. |
| 283 | auto const& wMatrix = mPlaneVisuals[i]->worldTransform.GetHMatrix(); |
| 284 | auto const& msTriangle = mModelSpaceTriangles[i]; |
| 285 | std::array<Vector4<float>, 3> wsTriangle{}; |
| 286 | for (size_t j = 0; j < 3; ++j) |
| 287 | { |
| 288 | wsTriangle[j] = DoTransform(wMatrix, msTriangle[j]); |
| 289 | } |
| 290 | CullingPlane<float> wPlane(wsTriangle[0], wsTriangle[1], wsTriangle[2]); |
| 291 | wPlane.Normalize(); |
| 292 | |
| 293 | // This is a conservative test to see whether a shadow should be cast. |
| 294 | // This can cause incorrect results if the caster is large and intersects |
| 295 | // the plane, but ordinarily we are not trying to cast shadows in such |
| 296 | // situations. |
| 297 | if (mShadowCaster->worldBound.WhichSide(wPlane) < 0) |
| 298 | { |
| 299 | // The shadow caster is on the far side of plane, so it cannot cast |
| 300 | // a shadow. |
| 301 | projection = Matrix4x4<float>::Identity(); |
| 302 | return false; |
| 303 | } |
| 304 | |
| 305 | // Compute the projection matrix for the light source. |
| 306 | auto normal = wPlane.GetNormal(); |
| 307 | if (mLightProjector->isPointLight) |
| 308 | { |
| 309 | float NdE = Dot(normal, mLightProjector->position); |
| 310 | if (NdE <= 0.0f) |
| 311 | { |
| 312 | // The projection must be onto the positive side of the plane. |
| 313 | projection = Matrix4x4<float>::Identity(); |
| 314 | return false; |
| 315 | } |
| 316 | |
| 317 | projection = MakePerspectiveProjection(wsTriangle[0], normal, |
| 318 | mLightProjector->position); |
| 319 | } |
| 320 | else |
| 321 | { |
| 322 | float NdD = Dot(normal, mLightProjector->direction); |
| 323 | if (NdD >= 0.0f) |
| 324 | { |
| 325 | // The projection must be onto the positive side of the plane. |
| 326 | projection = Matrix4x4<float>::Identity(); |
| 327 | return false; |
| 328 | } |
| 329 | |
| 330 | projection = MakeObliqueProjection(wsTriangle[0], normal, |
| 331 | mLightProjector->direction); |
| 332 | } |
| 333 | |
| 334 | return true; |
| 335 | } |
| 336 | |
| 337 |
no test coverage detected