From 7b4fce8deb45430d2c880c1c8ddd06fafda5dfe6 Mon Sep 17 00:00:00 2001 From: "Eunki, Hong" Date: Tue, 21 Feb 2023 18:37:26 +0900 Subject: [PATCH] Revert "[Tizen] Revert "Optimize some matrix multiply for projection matrix + Orthographic reflection"" This reverts commit dab53484581bc2e32970b312276443dde54d1bdb. --- automated-tests/src/dali/utc-Dali-CameraActor.cpp | 33 ++- dali/internal/common/matrix-utils.cpp | 10 +- dali/internal/common/matrix-utils.h | 5 +- dali/internal/event/actors/actor-coords.cpp | 14 +- dali/internal/event/actors/camera-actor-impl.cpp | 4 +- dali/internal/event/common/projection.cpp | 6 +- dali/internal/render/renderers/render-renderer.cpp | 4 +- .../update/render-tasks/scene-graph-camera.cpp | 227 +++++++++++++++++---- .../update/render-tasks/scene-graph-camera.h | 9 +- 9 files changed, 241 insertions(+), 71 deletions(-) diff --git a/automated-tests/src/dali/utc-Dali-CameraActor.cpp b/automated-tests/src/dali/utc-Dali-CameraActor.cpp index 9f3e6e7..6c8af27 100644 --- a/automated-tests/src/dali/utc-Dali-CameraActor.cpp +++ b/automated-tests/src/dali/utc-Dali-CameraActor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -2324,6 +2324,37 @@ int UtcDaliCameraActorReflectionByPlane(void) matrixAfter.GetTransformComponents(position, rotation, scale); DALI_TEST_EQUALS(reflected, rotation, 0.01f, TEST_LOCATION); + // Test Orthographic camera + freeLookCameraActor.SetProjectionMode(Dali::Camera::ProjectionMode::ORTHOGRAPHIC_PROJECTION); + + // Make sure the recalculation will take place + freeLookCameraActor.SetProperty(Dali::DevelCameraActor::Property::REFLECTION_PLANE, Vector4(0.0f, 1.0f, 0.0f, 0.0f)); + + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + + // Nothing should change despite of different camera type + matrixAfter.GetTransformComponents(position, rotation, scale); + DALI_TEST_EQUALS(reflected, rotation, 0.01f, TEST_LOCATION); + + // Test Orthographic camera + Look at target + freeLookCameraActor.SetType(Camera::LOOK_AT_TARGET); + freeLookCameraActor.SetTargetPosition(targetPosition); + + // Make sure the recalculation will take place + freeLookCameraActor.SetProperty(Dali::DevelCameraActor::Property::REFLECTION_PLANE, Vector4(0.0f, 1.0f, 0.0f, 0.0f)); + + application.SendNotification(); + application.Render(); + application.SendNotification(); + application.Render(); + + // Nothing should change despite of different camera type + matrixAfter.GetTransformComponents(position, rotation, scale); + DALI_TEST_EQUALS(reflected, rotation, 0.01f, TEST_LOCATION); + END_TEST; } diff --git a/dali/internal/common/matrix-utils.cpp b/dali/internal/common/matrix-utils.cpp index ce2eb1f..e5c7566 100644 --- a/dali/internal/common/matrix-utils.cpp +++ b/dali/internal/common/matrix-utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -256,7 +256,7 @@ void MultiplyProjectionMatrix(Dali::Matrix& result, const Dali::Matrix& lhs, con // Current NEON code is copy of Multiply. MATH_INCREASE_COUNTER(PerformanceMonitor::MATRIX_MULTIPLYS); - MATH_INCREASE_BY(PerformanceMonitor::FLOAT_POINT_MULTIPLY, 32); // 32 = 8*4 + MATH_INCREASE_BY(PerformanceMonitor::FLOAT_POINT_MULTIPLY, 40); // 40 = 10*4 float* temp = result.AsFloat(); const float* rhsPtr = projection.AsFloat(); @@ -264,11 +264,13 @@ void MultiplyProjectionMatrix(Dali::Matrix& result, const Dali::Matrix& lhs, con #ifndef __ARM_NEON__ - // We only use rhsPtr's 0, 1, 4, 5, 10, 11, 14, 15 index. + // We only use rhsPtr's 0, 1, 2, 4, 5, 6, 10, 11, 14, 15 index. const float rhs0 = rhsPtr[0]; const float rhs1 = rhsPtr[1]; + const float rhs2 = rhsPtr[2]; const float rhs4 = rhsPtr[4]; const float rhs5 = rhsPtr[5]; + const float rhs6 = rhsPtr[6]; const float rhs10 = rhsPtr[10]; const float rhs11 = rhsPtr[11]; const float rhs14 = rhsPtr[14]; @@ -289,7 +291,7 @@ void MultiplyProjectionMatrix(Dali::Matrix& result, const Dali::Matrix& lhs, con temp[loc0] = (value0 * rhs0) + (value1 * rhs4); temp[loc1] = (value0 * rhs1) + (value1 * rhs5); - temp[loc2] = (value2 * rhs10) + (value3 * rhs14); + temp[loc2] = (value0 * rhs2) + (value1 * rhs6) + (value2 * rhs10) + (value3 * rhs14); temp[loc3] = (value2 * rhs11) + (value3 * rhs15); } diff --git a/dali/internal/common/matrix-utils.h b/dali/internal/common/matrix-utils.h index f65687c..9852f97 100644 --- a/dali/internal/common/matrix-utils.h +++ b/dali/internal/common/matrix-utils.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_MATRIX_UTILS_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,7 +59,8 @@ void Multiply(Dali::Matrix& result, const Dali::Matrix& lhs, const Dali::Quatern * Perspective matrix only has 0, 5, 10, 11, 14 (14 is const value, 1.0f). * Orthographic matrix only has 0, 5, 10, 14, 15 (15 is const value, 1.0f). * If window rotated, we use 1, 4 index instead of 0, 5. - * So we only need 8 values to multiplication. + * If reflect plane used, we use 2, 6 index. + * So we only need 10 values to multiplication. * * Use this method in time critical path as it does not require temporaries. * diff --git a/dali/internal/event/actors/actor-coords.cpp b/dali/internal/event/actors/actor-coords.cpp index 9f1fefe..9fa1983 100644 --- a/dali/internal/event/actors/actor-coords.cpp +++ b/dali/internal/event/actors/actor-coords.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,7 +83,7 @@ bool ConvertScreenToLocal( // Calculate the inverted ModelViewProjection matrix; this will be used for 2 unprojects Matrix invertedMvp(false /*don't init*/); - MatrixUtils::Multiply(invertedMvp, modelView, projectionMatrix); + MatrixUtils::MultiplyProjectionMatrix(invertedMvp, modelView, projectionMatrix); bool success = invertedMvp.Invert(); // Convert to GL coordinates @@ -540,17 +540,17 @@ Matrix CalculateActorWorldTransform(const Actor& actor) parentMatrix.GetTransformComponents(parentPosition, parentOrientation, parentScale); // Compute intermediate Local information - centerPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, localScale, localOrientation); + centerPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, localScale, localOrientation); Vector3 intermediateLocalPosition = actorPosition + centerPosition + (parentOrigin - Vector3(0.5f, 0.5f, 0.5f)) * parentSize; - Matrix intermediateLocalMatrix; + Matrix intermediateLocalMatrix; intermediateLocalMatrix.SetTransformComponents(localScale, localOrientation, intermediateLocalPosition); // Compute intermediate world information Matrix intermediateWorldMatrix; MatrixUtils::Multiply(intermediateWorldMatrix, intermediateLocalMatrix, parentMatrix); - Vector3 intermediateWorldPosition, intermediateWorldScale; - Quaternion intermediateWorldOrientation; + Vector3 intermediateWorldPosition, intermediateWorldScale; + Quaternion intermediateWorldOrientation; intermediateWorldMatrix.GetTransformComponents(intermediateWorldPosition, intermediateWorldOrientation, intermediateWorldScale); // Compute final world information @@ -576,7 +576,7 @@ Matrix CalculateActorWorldTransform(const Actor& actor) // parent origin position in world space and relative position of center from parent origin. // If this node doesn't inherit its parent position, simply use the relative position as a final world position. Vector3 localCenterPosition = CalculateCenterPosition(anchorPoint, positionUsesAnchorPoint, size, finalWorldScale, finalWorldOrientation); - finalWorldPosition = actorPosition * finalWorldScale; + finalWorldPosition = actorPosition * finalWorldScale; finalWorldPosition *= finalWorldOrientation; finalWorldPosition += localCenterPosition; if((inheritanceModeList[i] & INHERIT_POSITION) != 0) diff --git a/dali/internal/event/actors/camera-actor-impl.cpp b/dali/internal/event/actors/camera-actor-impl.cpp index 1c6bb33..f714d74 100644 --- a/dali/internal/event/actors/camera-actor-impl.cpp +++ b/dali/internal/event/actors/camera-actor-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -107,7 +107,7 @@ void BuildOrthoPickingRay(const Matrix& viewMatrix, // Transforms the touch point from the screen reference system to the world reference system. Matrix invViewProjection(false); // Don't initialize. - MatrixUtils::Multiply(invViewProjection, viewMatrix, projectionMatrix); + MatrixUtils::MultiplyProjectionMatrix(invViewProjection, viewMatrix, projectionMatrix); if(!invViewProjection.Invert()) { DALI_ASSERT_DEBUG(false); diff --git a/dali/internal/event/common/projection.cpp b/dali/internal/event/common/projection.cpp index e6cae8d..d662f2f 100644 --- a/dali/internal/event/common/projection.cpp +++ b/dali/internal/event/common/projection.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,7 +73,7 @@ bool UnprojectFull(const Vector4& windowPos, Vector4& objectPos) { Matrix invertedMvp(false); // Don't initialize. - MatrixUtils::Multiply(invertedMvp, modelView, projection); + MatrixUtils::MultiplyProjectionMatrix(invertedMvp, modelView, projection); if(invertedMvp.Invert()) { @@ -124,7 +124,7 @@ bool ProjectFull(const Vector4& position, bool ok = false; Matrix Mvp(false); // Don't initialize. - MatrixUtils::Multiply(Mvp, modelView, projection); + MatrixUtils::MultiplyProjectionMatrix(Mvp, modelView, projection); Vector4 p = Mvp * position; diff --git a/dali/internal/render/renderers/render-renderer.cpp b/dali/internal/render/renderers/render-renderer.cpp index 3bea0e5..9b8c2c9 100644 --- a/dali/internal/render/renderers/render-renderer.cpp +++ b/dali/internal/render/renderers/render-renderer.cpp @@ -487,7 +487,7 @@ bool Renderer::Render(Graphics::CommandBuffer& comma mRenderCallbackInput->size = size; mRenderCallbackInput->projection = projectionMatrix; - MatrixUtils::Multiply(mRenderCallbackInput->mvp, modelViewMatrix, projectionMatrix); + MatrixUtils::MultiplyProjectionMatrix(mRenderCallbackInput->mvp, modelViewMatrix, projectionMatrix); // submit draw commandBuffer.DrawNative(&info); @@ -739,7 +739,7 @@ void Renderer::WriteUniformBuffer( if(mvpUniformInfo && !mvpUniformInfo->name.empty()) { Matrix modelViewProjectionMatrix(false); - MatrixUtils::Multiply(modelViewProjectionMatrix, modelViewMatrix, projectionMatrix); + MatrixUtils::MultiplyProjectionMatrix(modelViewProjectionMatrix, modelViewMatrix, projectionMatrix); WriteDefaultUniform(mvpUniformInfo, *uboView, modelViewProjectionMatrix); } diff --git a/dali/internal/update/render-tasks/scene-graph-camera.cpp b/dali/internal/update/render-tasks/scene-graph-camera.cpp index 586d7cc..450c990 100644 --- a/dali/internal/update/render-tasks/scene-graph-camera.cpp +++ b/dali/internal/update/render-tasks/scene-graph-camera.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -166,6 +166,154 @@ void Orthographic(Matrix& result, Dali::DevelCameraActor::ProjectionDirection or m[15] = 1.0f; } +/** + * Adjust near plane for reflection + * @param[in] perspective Perspective matrix + * @param[in] clipPlane Clipping plane + * @param[in] far Far plane distance of original projection matrix + */ +void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane, float far) +{ + // Make third row of perspective projection matrix as clipPlane. + // If me let third row vector as v = (v[2], v[6], v[10], v[14]), + // z_n = v * (x, y, z, 1) / z + + // For example, standard case : -1 for near, 1 for far. + // v.z * n + v.w = -n + // v.z * f + v.w = f + // This formular makes v.z = (f + n) / (f - n), v.w = -2fn / (f - n) + + // Now, we should make like this : -1 for clipPlane, 1 for farPlane. + // Let we think some point p : c.x * p.x + c.y * p.y + c.z * p.z + c.w = 0. + // v.x * p.x + v.y * p.y + v.z * p.z + v.w = -p.z; + + // Since point p doesn't have any special rule, we can think that + // (v.x, v.y, v.z + 1, v.w) = scale * (c.x, c.y, c.z, c.w). + // --> + // v.z = scale * c.z - 1.0, + // v.w = scale * c.w. + + // Now we have to determine scale value. + + // Reference of Far plane fomular : https://ubm-twvideo01.s3.amazonaws.com/o1/vault/gdc07/slides/S3730i1.pdf page 38 + // Let we pick 'one of any edge' point Q which position on original projection frustum's far plane and... + // c.x * Q.x + c.y * Q.y + c.z * Q.z + c.w is maximum. + + // To make Q far far away, Below fomular should be applied. (We can assume that Q.z is bigger than 0) + // || (v[0], 0, v[8], 0) * Q / Q.z || = 1 --> || v[0] * Q.x + v[8] * Q.z || = Q.z + // || (0, v[5], v[9], 0) * Q / Q.z || = 1 --> || v[5] * Q.y + v[9] * Q.z || = Q.z + + // And the far plane case + // v * Q = Q.z + // --> (c * scale + (0, 0, -1, 0)) * Q = Q.z + // --> c * scale * Q = 2.0 * Q.z + // --> scale = 2.0 * Q.z / (c * Q) + + float* v = perspective.AsFloat(); + + float maximalCDotQ = Math::MACHINE_EPSILON_0; // We should find CDotQ is positive. + + float inverseV0 = 1.0f / v[0]; + float inverseV5 = 1.0f / v[5]; + + // There are 4 case of solution. Choose one of them and check whether clipPlane * Q is maxium. + for(int testCase = 0; testCase != 4; ++testCase) + { + Vector4 Q(0.0f, 0.0f, far, 1.0f); + + // Check for Q.x + // v[0] * Q.x = (+-1.0f - v[8]) * Q.z + Q.x = (((testCase & 1) ? 1.0f : -1.0f) - v[8]) * Q.z * inverseV0; + // v[5] * Q.y = (+-1.0f - v[9]) * Q.z + Q.y = (((testCase & 2) ? 1.0f : -1.0f) - v[9]) * Q.z * inverseV5; + + maximalCDotQ = std::max(maximalCDotQ, clipPlane.Dot(Q)); + } + + float scale = 2.0f * far / maximalCDotQ; + + Vector4 scaledPlaneVector = clipPlane * scale; + + v[2] = scaledPlaneVector.x; + v[6] = scaledPlaneVector.y; + v[10] = scaledPlaneVector.z - 1.0f; + v[14] = scaledPlaneVector.w; +} + +/** + * Adjust near plane for reflection + * @param[in] orthographic Orthographic matrix + * @param[in] clipPlane Clipping plane + * @param[in] far Far plane distance of original projection matrix + */ +void AdjustNearPlaneForOrthographic(Matrix& orthographic, const Vector4& clipPlane, float far) +{ + // Make third row of orthographic projection matrix as clipPlane. + // If me let third row vector as v = (v[2], v[6], v[10], v[14]), + // z_n = v * (x, y, z, 1) + + // For example, standard case : -1 for near, 1 for far. + // v.z * n + v.w = -1 + // v.z * f + v.w = 1 + // This formular makes v.z = 2 / (f - n), v.w = -(f + n) / (f - n) + + // Now, we should make like this : -1 for clipPlane, 1 for farPlane. + // Let we think some point p : c.x * p.x + c.y * p.y + c.z * p.z + c.w = 0. + // v.x * p.x + v.y * p.y + v.z * p.z + v.w = -1; + + // Since point p doesn't have any special rule, we can think that + // (v.x, v.y, v.z, v.w + 1) = scale * (c.x, c.y, c.z, c.w). + // --> + // v.z = scale * c.z, + // v.w = scale * c.w - 1.0. + + // Now we have to determine scale value. + + // Reference of Far plane fomular : https://ubm-twvideo01.s3.amazonaws.com/o1/vault/gdc07/slides/S3730i1.pdf page 38 + // Let we pick 'one of any edge' point Q which position on original projection frustum's far plane and... + // c.x * Q.x + c.y * Q.y + c.z * Q.z + c.w is maximum. + + // To make Q far far away, Below fomular should be applied. (We can assume that Q.z is bigger than 0) + // || (v[0], 0, 0, v[12]) * Q || = 1 --> || v[0] * Q.x + v[12] || = 1 + // || (0, v[5], 0, v[13]) * Q || = 1 --> || v[5] * Q.y + v[13] || = 1 + + // And the far plane case + // v * Q = 1 + // --> (c * scale + (0, 0, 0, 1)) * Q = 1 + // --> c * scale * Q = 2.0 + // --> scale = 2.0 / (c * Q) + + float* v = orthographic.AsFloat(); + + float maximalCDotQ = Math::MACHINE_EPSILON_0; // We should find CDotQ is positive. + + float inverseV0 = 1.0f / v[0]; + float inverseV5 = 1.0f / v[5]; + + // There are 4 case of solution. Choose one of them and check whether clipPlane * Q is maxium. + for(int testCase = 0; testCase != 4; ++testCase) + { + Vector4 Q(0.0f, 0.0f, far, 1.0f); + + // Check for Q.x + // v[0] * Q.x = (+-1.0f - v[12]) + Q.x = (((testCase & 1) ? 1.0f : -1.0f) - v[12]) * inverseV0; + // v[5] * Q.y = (+-1.0f - v[13]) + Q.y = (((testCase & 2) ? 1.0f : -1.0f) - v[13]) * inverseV5; + + maximalCDotQ = std::max(maximalCDotQ, clipPlane.Dot(Q)); + } + + float scale = 2.0f / maximalCDotQ; + + Vector4 scaledPlaneVector = clipPlane * scale; + + v[2] = scaledPlaneVector.x; + v[6] = scaledPlaneVector.y; + v[10] = scaledPlaneVector.z; + v[14] = scaledPlaneVector.w - 1.0f; +} + } // unnamed namespace const Dali::Camera::Type Camera::DEFAULT_TYPE(Dali::Camera::FREE_LOOK); @@ -283,28 +431,10 @@ void VectorReflectedByPlane(Vector4& out, Vector4& in, Vector4& plane) out.w = static_cast(in.w - plane.w * d); } -void Camera::AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane) -{ - Vector4 q; - float* v = perspective.AsFloat(); - - q.x = (Sign(clipPlane.x) + v[8]) / v[0]; - q.y = (Sign(clipPlane.y) + v[9]) / v[5]; - q.z = -1.0f; - q.w = (1.0f + v[10]) / v[14]; - - // Calculate the scaled plane vector - Vector4 c = clipPlane * (REFLECTION_NORMALIZED_DEVICE_COORDINATE_PARAMETER_A / q.Dot(clipPlane)); - - // Replace the third row of the projection v - v[2] = c.x; - v[6] = c.y; - v[10] = c.z + REFLECTION_NORMALIZED_DEVICE_COORDINATE_PARAMETER_D; - v[14] = c.w; -} - void Camera::SetReflectByPlane(const Vector4& plane) { + // Note : we assume that plane.xyz is normal vector. + float* v = mReflectionMtx.AsFloat(); float _2ab = -2.0f * plane.x * plane.y; float _2ac = -2.0f * plane.x * plane.z; @@ -416,7 +546,7 @@ void Camera::Update(BufferIndex updateBufferIndex) if(viewUpdateCount > COPY_PREVIOUS_MATRIX || projectionUpdateCount > COPY_PREVIOUS_MATRIX) { // either has actually changed so recalculate - MatrixUtils::Multiply(mInverseViewProjection[updateBufferIndex], mViewMatrix[updateBufferIndex], mProjectionMatrix[updateBufferIndex]); + MatrixUtils::MultiplyProjectionMatrix(mInverseViewProjection[updateBufferIndex], mViewMatrix[updateBufferIndex], mProjectionMatrix[updateBufferIndex]); UpdateFrustum(updateBufferIndex); // ignore the error, if the view projection is incorrect (non inversible) then you will have tough times anyways @@ -514,10 +644,12 @@ uint32_t Camera::UpdateViewMatrix(BufferIndex updateBufferIndex) upNew3 = Vector3(upNew); LookAt(viewMatrix, positionNew3, targetNewVector3, upNew3); - Matrix oldViewMatrix(viewMatrix); - Matrix tmp; - tmp.SetIdentityAndScale(Vector3(-1.0, 1.0, 1.0)); - MatrixUtils::Multiply(viewMatrix, oldViewMatrix, tmp); + // Invert X + float* vZ = viewMatrix.AsFloat(); + vZ[0] = -vZ[0]; + vZ[4] = -vZ[4]; + vZ[8] = -vZ[8]; + vZ[12] = -vZ[12]; mReflectionEye = positionNew; mUseReflectionClip = true; @@ -539,8 +671,8 @@ uint32_t Camera::UpdateViewMatrix(BufferIndex updateBufferIndex) void Camera::UpdateFrustum(BufferIndex updateBufferIndex, bool normalize) { // Extract the clip matrix planes - Matrix clipMatrix; - MatrixUtils::Multiply(clipMatrix, mViewMatrix[updateBufferIndex], mProjectionMatrix[updateBufferIndex]); + Matrix clipMatrix(false); // Don't initialize. + MatrixUtils::MultiplyProjectionMatrix(clipMatrix, mViewMatrix[updateBufferIndex], mProjectionMatrix[updateBufferIndex]); const float* cm = clipMatrix.AsFloat(); FrustumPlanes& planes = mFrustum[updateBufferIndex]; @@ -685,18 +817,12 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex) float d = mReflectionPlane.Dot(mReflectionEye); if(d < 0) { - adjReflectPlane.w = -adjReflectPlane.w; + // Original eyesight was behind of mReflectionPlane. Reverse the plane. + adjReflectPlane = -adjReflectPlane; } Vector4 customClipping = viewInv * adjReflectPlane; - AdjustNearPlaneForPerspective(projectionMatrix, customClipping); - - // Invert Z - Matrix matZ; - matZ.SetIdentity(); - float* vZ = matZ.AsFloat(); - vZ[10] = -vZ[10]; - MatrixUtils::Multiply(projectionMatrix, projectionMatrix, matZ); + AdjustNearPlaneForPerspective(projectionMatrix, customClipping, mFarClippingPlane); } break; } @@ -710,6 +836,26 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex) mNearClippingPlane, mFarClippingPlane, mInvertYAxis); + + //need to apply custom clipping plane + if(mUseReflectionClip) + { + Matrix& viewMatrix = mViewMatrix.Get(updateBufferIndex); + Matrix viewInv = viewMatrix; + viewInv.Invert(); + viewInv.Transpose(); + + Dali::Vector4 adjReflectPlane = mReflectionPlane; + float d = mReflectionPlane.Dot(mReflectionEye); + if(d < 0) + { + // Original eyesight was behind of mReflectionPlane. Reverse the plane. + adjReflectPlane = -adjReflectPlane; + } + + Vector4 customClipping = viewInv * adjReflectPlane; + AdjustNearPlaneForOrthographic(projectionMatrix, customClipping, mFarClippingPlane); + } break; } } @@ -739,11 +885,8 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex) break; } - Matrix rotation; - rotation.SetIdentity(); - rotation.SetTransformComponents(Vector3(1.0f, 1.0f, 1.0f), rotationAngle, Vector3(0.0f, 0.0f, 0.0f)); - - MatrixUtils::Multiply(finalProjection, mProjectionMatrix.Get(updateBufferIndex), rotation); + // TODO : Can't we make finalProjection without matrix multiply? + MatrixUtils::Multiply(finalProjection, mProjectionMatrix.Get(updateBufferIndex), rotationAngle); } --mUpdateProjectionFlag; } diff --git a/dali/internal/update/render-tasks/scene-graph-camera.h b/dali/internal/update/render-tasks/scene-graph-camera.h index 6604fb9..278d765 100644 --- a/dali/internal/update/render-tasks/scene-graph-camera.h +++ b/dali/internal/update/render-tasks/scene-graph-camera.h @@ -2,7 +2,7 @@ #define DALI_INTERNAL_SCENE_GRAPH_CAMERA_H /* - * Copyright (c) 2022 Samsung Electronics Co., Ltd. + * Copyright (c) 2023 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -384,13 +384,6 @@ private: */ void UpdateFrustum(BufferIndex updateBufferIndex, bool normalize = true); - /** - * Adjust near plane for reflection - * @param perspective Perspective matrix - * @param clipPlane Clipping plane - */ - void AdjustNearPlaneForPerspective(Matrix& perspective, const Vector4& clipPlane); - uint32_t mUpdateViewFlag; ///< This is non-zero if the view matrix requires an update uint32_t mUpdateProjectionFlag; ///< This is non-zero if the projection matrix requires an update int mProjectionRotation; ///< The rotaion angle of the projection -- 2.7.4