X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fupdate%2Frender-tasks%2Fscene-graph-camera.cpp;h=586d7cc199737a65422f46b6474939135230835c;hb=e7cebecdd8cf3da43453f493278464c28a34fc8d;hp=e8350a032accec6ecb3e0bcacc5e7ff791c2b4f8;hpb=65a298ff258cc898f11b042175f95a10a1bc1179;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/update/render-tasks/scene-graph-camera.cpp b/dali/internal/update/render-tasks/scene-graph-camera.cpp index e8350a0..586d7cc 100644 --- a/dali/internal/update/render-tasks/scene-graph-camera.cpp +++ b/dali/internal/update/render-tasks/scene-graph-camera.cpp @@ -23,6 +23,8 @@ // INTERNAL INCLUDES #include +#include +#include #include #include #include @@ -45,6 +47,9 @@ namespace SceneGraph { namespace { +//Memory pool used to allocate new camera. Memory used by this pool will be released when shutting down DALi +MemoryPoolObjectAllocator gCameraMemoryPool; + template T Sign(T value) { @@ -114,27 +119,39 @@ void Perspective(Matrix& result, Dali::DevelCameraActor::ProjectionDirection fov Frustum(result, -frustumW, frustumW, -frustumH, frustumH, near, far, invertYAxis); } -void Orthographic(Matrix& result, float left, float right, float bottom, float top, float near, float far, bool invertYAxis) +void Orthographic(Matrix& result, Dali::DevelCameraActor::ProjectionDirection orthographicDir, float orthographicSize, float aspect, float near, float far, bool invertYAxis) { - if(Equals(right, left) || Equals(top, bottom) || Equals(far, near)) + if(EqualsZero(orthographicSize) || EqualsZero(aspect) || Equals(far, near)) { DALI_LOG_ERROR("Cannot create orthographic projection matrix with a zero dimension.\n"); DALI_ASSERT_DEBUG("Cannot create orthographic projection matrix with a zero dimension."); return; } - float deltaX = right - left; - float deltaY = invertYAxis ? bottom - top : top - bottom; + float halfDeltaX; + float halfDeltaY; + if(orthographicDir == Dali::DevelCameraActor::ProjectionDirection::VERTICAL) + { + halfDeltaY = orthographicSize; + halfDeltaX = halfDeltaY * aspect; + } + else + { + halfDeltaX = orthographicSize; + halfDeltaY = halfDeltaX / aspect; + } + float deltaZ = far - near; float* m = result.AsFloat(); - m[0] = -2.0f / deltaX; - m[1] = 0.0f; - m[2] = 0.0f; - m[3] = 0.0f; + + m[0] = -1.0f / halfDeltaX; + m[1] = 0.0f; + m[2] = 0.0f; + m[3] = 0.0f; m[4] = 0.0f; - m[5] = -2.0f / deltaY; + m[5] = (invertYAxis ? 1.0f : -1.0f) / halfDeltaY; m[6] = 0.0f; m[7] = 0.0f; @@ -142,8 +159,9 @@ void Orthographic(Matrix& result, float left, float right, float bottom, float t m[9] = 0.0f; m[10] = 2.0f / deltaZ; m[11] = 0.0f; - m[12] = -(right + left) / deltaX; - m[13] = -(top + bottom) / deltaY; + + m[12] = 0.0f; + m[13] = 0.0f; m[14] = -(near + far) / deltaZ; m[15] = 1.0f; } @@ -155,30 +173,24 @@ const Dali::Camera::ProjectionMode Camera::DEFAULT_MODE(Dali::Cam const Dali::DevelCameraActor::ProjectionDirection Camera::DEFAULT_PROJECTION_DIRECTION(Dali::DevelCameraActor::VERTICAL); const bool Camera::DEFAULT_INVERT_Y_AXIS(false); const float Camera::DEFAULT_FIELD_OF_VIEW(45.0f * (Math::PI / 180.0f)); -const float Camera::DEFAULT_ASPECT_RATIO(800.0f / 480.0f); -const float Camera::DEFAULT_LEFT_CLIPPING_PLANE(-240.0f); -const float Camera::DEFAULT_RIGHT_CLIPPING_PLANE(240.0f); -const float Camera::DEFAULT_TOP_CLIPPING_PLANE(-400.0f); -const float Camera::DEFAULT_BOTTOM_CLIPPING_PLANE(400.0f); -const float Camera::DEFAULT_NEAR_CLIPPING_PLANE(800.0f); // default height of the screen +const float Camera::DEFAULT_ORTHOGRAPHIC_SIZE(400.0f); // half of default height of the screen +const float Camera::DEFAULT_ASPECT_RATIO(480.0f / 800.0f); // default width / default height of the screen +const float Camera::DEFAULT_NEAR_CLIPPING_PLANE(800.0f); // default height of the screen const float Camera::DEFAULT_FAR_CLIPPING_PLANE(DEFAULT_NEAR_CLIPPING_PLANE + 2.f * DEFAULT_NEAR_CLIPPING_PLANE); const Vector3 Camera::DEFAULT_TARGET_POSITION(0.0f, 0.0f, 0.0f); Camera::Camera() -: mUpdateViewFlag(UPDATE_COUNT), +: Node(), + mUpdateViewFlag(UPDATE_COUNT), mUpdateProjectionFlag(UPDATE_COUNT), mProjectionRotation(0), - mNode(nullptr), mType(DEFAULT_TYPE), mProjectionMode(DEFAULT_MODE), mProjectionDirection(DEFAULT_PROJECTION_DIRECTION), mInvertYAxis(DEFAULT_INVERT_Y_AXIS), mFieldOfView(DEFAULT_FIELD_OF_VIEW), + mOrthographicSize(DEFAULT_ORTHOGRAPHIC_SIZE), mAspectRatio(DEFAULT_ASPECT_RATIO), - mLeftClippingPlane(DEFAULT_LEFT_CLIPPING_PLANE), - mRightClippingPlane(DEFAULT_RIGHT_CLIPPING_PLANE), - mTopClippingPlane(DEFAULT_TOP_CLIPPING_PLANE), - mBottomClippingPlane(DEFAULT_BOTTOM_CLIPPING_PLANE), mNearClippingPlane(DEFAULT_NEAR_CLIPPING_PLANE), mFarClippingPlane(DEFAULT_FAR_CLIPPING_PLANE), mTargetPosition(DEFAULT_TARGET_POSITION), @@ -187,23 +199,20 @@ Camera::Camera() mInverseViewProjection(Matrix::IDENTITY), mFinalProjection(Matrix::IDENTITY) { + // set a flag the node to say this is a camera + mIsCamera = true; } Camera* Camera::New() { - return new Camera(); + return new(gCameraMemoryPool.AllocateRawThreadSafe()) Camera(); } Camera::~Camera() = default; -void Camera::SetNode(const Node* node) +void Camera::operator delete(void* ptr) { - mNode = node; -} - -const Node* Camera::GetNode() const -{ - return mNode; + gCameraMemoryPool.FreeThreadSafe(static_cast(ptr)); } void Camera::SetType(Dali::Camera::Type type) @@ -229,39 +238,21 @@ void Camera::SetInvertYAxis(bool invertYAxis) mUpdateProjectionFlag = UPDATE_COUNT; } -void Camera::SetFieldOfView(float fieldOfView) -{ - mFieldOfView = fieldOfView; - mUpdateProjectionFlag = UPDATE_COUNT; -} - -void Camera::SetAspectRatio(float aspectRatio) -{ - mAspectRatio = aspectRatio; - mUpdateProjectionFlag = UPDATE_COUNT; -} - -void Camera::SetLeftClippingPlane(float leftClippingPlane) -{ - mLeftClippingPlane = leftClippingPlane; - mUpdateProjectionFlag = UPDATE_COUNT; -} - -void Camera::SetRightClippingPlane(float rightClippingPlane) +void Camera::BakeFieldOfView(BufferIndex updateBufferIndex, float fieldOfView) { - mRightClippingPlane = rightClippingPlane; + mFieldOfView.Bake(updateBufferIndex, fieldOfView); mUpdateProjectionFlag = UPDATE_COUNT; } -void Camera::SetTopClippingPlane(float topClippingPlane) +void Camera::BakeOrthographicSize(BufferIndex updateBufferIndex, float orthographicSize) { - mTopClippingPlane = topClippingPlane; + mOrthographicSize.Bake(updateBufferIndex, orthographicSize); mUpdateProjectionFlag = UPDATE_COUNT; } -void Camera::SetBottomClippingPlane(float bottomClippingPlane) +void Camera::BakeAspectRatio(BufferIndex updateBufferIndex, float aspectRatio) { - mBottomClippingPlane = bottomClippingPlane; + mAspectRatio.Bake(updateBufferIndex, aspectRatio); mUpdateProjectionFlag = UPDATE_COUNT; } @@ -370,6 +361,21 @@ const Matrix& Camera::GetFinalProjectionMatrix(BufferIndex bufferIndex) const return mFinalProjection[bufferIndex]; } +const PropertyBase* Camera::GetFieldOfView() const +{ + return &mFieldOfView; +} + +const PropertyBase* Camera::GetOrthographicSize() const +{ + return &mOrthographicSize; +} + +const PropertyBase* Camera::GetAspectRatio() const +{ + return &mAspectRatio; +} + const PropertyInputImpl* Camera::GetProjectionMatrix() const { return &mProjectionMatrix; @@ -382,12 +388,12 @@ const PropertyInputImpl* Camera::GetViewMatrix() const void Camera::Update(BufferIndex updateBufferIndex) { - // if owning node has changes in world position we need to update camera for next 2 frames - if(mNode->IsLocalMatrixDirty()) + // if this has changes in world position we need to update camera for next 2 frames + if(IsLocalMatrixDirty()) { mUpdateViewFlag = UPDATE_COUNT; } - if(mNode->GetDirtyFlags() & NodePropertyFlags::VISIBLE) + if(GetDirtyFlags() & NodePropertyFlags::VISIBLE) { // If the visibility changes, the projection matrix needs to be re-calculated. // It may happen the first time an actor is rendered it's rendered only once and becomes invisible, @@ -396,6 +402,12 @@ void Camera::Update(BufferIndex updateBufferIndex) mUpdateProjectionFlag = UPDATE_COUNT; } + // If projection matrix relative properties are animated now, flag change. + if(IsProjectionMatrixAnimated()) + { + mUpdateProjectionFlag = UPDATE_COUNT; + } + // if either matrix changed, we need to recalculate the inverse matrix for hit testing to work uint32_t viewUpdateCount = UpdateViewMatrix(updateBufferIndex); uint32_t projectionUpdateCount = UpdateProjection(updateBufferIndex); @@ -404,7 +416,7 @@ void Camera::Update(BufferIndex updateBufferIndex) if(viewUpdateCount > COPY_PREVIOUS_MATRIX || projectionUpdateCount > COPY_PREVIOUS_MATRIX) { // either has actually changed so recalculate - Matrix::Multiply(mInverseViewProjection[updateBufferIndex], mViewMatrix[updateBufferIndex], mProjectionMatrix[updateBufferIndex]); + MatrixUtils::Multiply(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 @@ -419,11 +431,18 @@ void Camera::Update(BufferIndex updateBufferIndex) } } -bool Camera::ViewMatrixUpdated() +bool Camera::ViewMatrixUpdated() const { return 0u != mUpdateViewFlag; } +bool Camera::IsProjectionMatrixAnimated() const +{ + return !mFieldOfView.IsClean() || + !mOrthographicSize.IsClean() || + !mAspectRatio.IsClean(); +} + uint32_t Camera::UpdateViewMatrix(BufferIndex updateBufferIndex) { uint32_t retval(mUpdateViewFlag); @@ -442,11 +461,11 @@ uint32_t Camera::UpdateViewMatrix(BufferIndex updateBufferIndex) case Dali::Camera::FREE_LOOK: { Matrix& viewMatrix = mViewMatrix.Get(updateBufferIndex); - viewMatrix = mNode->GetWorldMatrix(updateBufferIndex); + viewMatrix = GetWorldMatrix(updateBufferIndex); if(mUseReflection) { - const Matrix& owningNodeMatrix(mNode->GetWorldMatrix(updateBufferIndex)); + const Matrix& owningNodeMatrix(GetWorldMatrix(updateBufferIndex)); Vector3 position{}, scale{}; Quaternion orientation{}; owningNodeMatrix.GetTransformComponents(position, orientation, scale); @@ -455,7 +474,7 @@ uint32_t Camera::UpdateViewMatrix(BufferIndex updateBufferIndex) Matrix& viewMatrix = mViewMatrix.Get(updateBufferIndex); Matrix oldViewMatrix(viewMatrix); - Matrix::Multiply(viewMatrix, oldViewMatrix, mReflectionMtx); + MatrixUtils::Multiply(viewMatrix, oldViewMatrix, mReflectionMtx); } viewMatrix.Invert(); @@ -466,7 +485,7 @@ uint32_t Camera::UpdateViewMatrix(BufferIndex updateBufferIndex) // camera orientation constrained to look at a target case Dali::Camera::LOOK_AT_TARGET: { - const Matrix& owningNodeMatrix(mNode->GetWorldMatrix(updateBufferIndex)); + const Matrix& owningNodeMatrix(GetWorldMatrix(updateBufferIndex)); Vector3 position, scale; Quaternion orientation; owningNodeMatrix.GetTransformComponents(position, orientation, scale); @@ -498,7 +517,7 @@ uint32_t Camera::UpdateViewMatrix(BufferIndex updateBufferIndex) Matrix oldViewMatrix(viewMatrix); Matrix tmp; tmp.SetIdentityAndScale(Vector3(-1.0, 1.0, 1.0)); - Matrix::Multiply(viewMatrix, oldViewMatrix, tmp); + MatrixUtils::Multiply(viewMatrix, oldViewMatrix, tmp); mReflectionEye = positionNew; mUseReflectionClip = true; @@ -521,7 +540,7 @@ void Camera::UpdateFrustum(BufferIndex updateBufferIndex, bool normalize) { // Extract the clip matrix planes Matrix clipMatrix; - Matrix::Multiply(clipMatrix, mViewMatrix[updateBufferIndex], mProjectionMatrix[updateBufferIndex]); + MatrixUtils::Multiply(clipMatrix, mViewMatrix[updateBufferIndex], mProjectionMatrix[updateBufferIndex]); const float* cm = clipMatrix.AsFloat(); FrustumPlanes& planes = mFrustum[updateBufferIndex]; @@ -585,7 +604,7 @@ void Camera::UpdateFrustum(BufferIndex updateBufferIndex, bool normalize) mFrustum[updateBufferIndex ? 0 : 1] = planes; } -bool Camera::CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius) +bool Camera::CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin, float radius) const { const FrustumPlanes& planes = mFrustum[bufferIndex]; for(uint32_t i = 0; i < 6; ++i) @@ -598,7 +617,7 @@ bool Camera::CheckSphereInFrustum(BufferIndex bufferIndex, const Vector3& origin return true; } -bool Camera::CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents) +bool Camera::CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, const Vector3& halfExtents) const { const FrustumPlanes& planes = mFrustum[bufferIndex]; for(uint32_t i = 0; i < 6; ++i) @@ -612,6 +631,16 @@ bool Camera::CheckAABBInFrustum(BufferIndex bufferIndex, const Vector3& origin, } return true; } +Dali::Rect Camera::GetOrthographicClippingBox(BufferIndex bufferIndex) const +{ + const float orthographicSize = mOrthographicSize[bufferIndex]; + const float aspect = mAspectRatio[bufferIndex]; + + const float halfWidth = mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? orthographicSize * aspect : orthographicSize; + const float halfHeight = mProjectionDirection == DevelCameraActor::ProjectionDirection::VERTICAL ? orthographicSize : orthographicSize / aspect; + + return Dali::Rect(-halfWidth, -halfHeight, halfWidth * 2.0f, halfHeight * 2.0f); +} uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex) { @@ -638,8 +667,8 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex) Matrix& projectionMatrix = mProjectionMatrix.Get(updateBufferIndex); Perspective(projectionMatrix, mProjectionDirection, - mFieldOfView, - mAspectRatio, + mFieldOfView[updateBufferIndex], + mAspectRatio[updateBufferIndex], mNearClippingPlane, mFarClippingPlane, mInvertYAxis); @@ -667,7 +696,7 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex) matZ.SetIdentity(); float* vZ = matZ.AsFloat(); vZ[10] = -vZ[10]; - Matrix::Multiply(projectionMatrix, projectionMatrix, matZ); + MatrixUtils::Multiply(projectionMatrix, projectionMatrix, matZ); } break; } @@ -675,10 +704,9 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex) { Matrix& projectionMatrix = mProjectionMatrix.Get(updateBufferIndex); Orthographic(projectionMatrix, - mLeftClippingPlane, - mRightClippingPlane, - mBottomClippingPlane, - mTopClippingPlane, + mProjectionDirection, + mOrthographicSize[updateBufferIndex], + mAspectRatio[updateBufferIndex], mNearClippingPlane, mFarClippingPlane, mInvertYAxis); @@ -715,7 +743,7 @@ uint32_t Camera::UpdateProjection(BufferIndex updateBufferIndex) rotation.SetIdentity(); rotation.SetTransformComponents(Vector3(1.0f, 1.0f, 1.0f), rotationAngle, Vector3(0.0f, 0.0f, 0.0f)); - Matrix::Multiply(finalProjection, mProjectionMatrix.Get(updateBufferIndex), rotation); + MatrixUtils::Multiply(finalProjection, mProjectionMatrix.Get(updateBufferIndex), rotation); } --mUpdateProjectionFlag; }