/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
// All the properties should still be the default values
// Defaults taken from scene-graph-camera.cpp
- DALI_TEST_EQUALS(4.0f / 3.0f, actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
+ DALI_TEST_EQUALS(800.0f / 480.0f, actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
DALI_TEST_EQUALS(45.0f * (Math::PI / 180.0f), actor.GetProperty(CameraActor::Property::FIELD_OF_VIEW).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
DALI_TEST_EQUALS(800.0f, actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
DALI_TEST_EQUALS(3.0f * 800.0f, actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get<float>(), FLOAT_EPSILON, TEST_LOCATION);
}
END_TEST;
}
+
+int UtcDaliCameraActorNewDefaultOrthogonalProjection01(void)
+{
+ TestApplication application;
+ tet_infoline("Test that changing to orthogonal projection and then adding to scene calculates the right defaults");
+
+ CameraActor actor = CameraActor::New();
+ DALI_TEST_CHECK(actor);
+
+ actor.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION);
+ application.GetScene().Add(actor);
+
+ // Test application screen size is 480x800
+ // Check that the properties match to that screen size
+ float value;
+ actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(value);
+ DALI_TEST_EQUALS(800.0f / 480.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(800.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(4895.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ actor.GetProperty(CameraActor::Property::LEFT_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(-240.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+ actor.GetProperty(CameraActor::Property::RIGHT_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(240.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ actor.GetProperty(CameraActor::Property::TOP_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(400.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+ actor.GetProperty(CameraActor::Property::BOTTOM_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(-400.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(1600.0f, actor.GetProperty(Actor::Property::POSITION_Z).Get<float>(), TEST_LOCATION);
+
+ DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::ORTHOGRAPHIC_PROJECTION, TEST_LOCATION);
+ END_TEST;
+}
+
+int UtcDaliCameraActorNewDefaultOrthogonalProjection02(void)
+{
+ TestApplication application;
+ tet_infoline("Test that changing to orthogonal projection and then adding to scene calculates the right defaults");
+
+ CameraActor actor = CameraActor::New();
+ DALI_TEST_CHECK(actor);
+
+ actor.SetOrthographicProjection(Vector2::ZERO);
+ DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::ORTHOGRAPHIC_PROJECTION, TEST_LOCATION);
+ application.GetScene().Add(actor);
+
+ // Test application screen size is 480x800
+ // Check that the properties match to that screen size
+ float value;
+ actor.GetProperty(CameraActor::Property::ASPECT_RATIO).Get(value);
+ DALI_TEST_EQUALS(800.0f / 480.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ actor.GetProperty(CameraActor::Property::NEAR_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(800.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ actor.GetProperty(CameraActor::Property::FAR_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(4895.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ actor.GetProperty(CameraActor::Property::LEFT_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(-240.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+ actor.GetProperty(CameraActor::Property::RIGHT_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(240.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ actor.GetProperty(CameraActor::Property::TOP_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(400.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+ actor.GetProperty(CameraActor::Property::BOTTOM_PLANE_DISTANCE).Get(value);
+ DALI_TEST_EQUALS(-400.0f, value, FLOAT_EPSILON, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(1600.0f, actor.GetProperty(Actor::Property::POSITION_Z).Get<float>(), TEST_LOCATION);
+
+ DALI_TEST_EQUALS(actor.GetProjectionMode(), Dali::Camera::ORTHOGRAPHIC_PROJECTION, TEST_LOCATION);
+ END_TEST;
+}
+
+// Add tests for culling:
+// add large actor just outside canvas, & rotate it 45% - should still be rendered
+// Rotate back to 0, should be culled.
+
+int UtcDaliCameraActorCulling01(void)
+{
+ TestApplication application;
+ auto& gfx = application.GetGraphicsController();
+
+ tet_infoline("Create a renderable actor and position it slightly to the left of the scene");
+ tet_infoline("The actor should not be rendered");
+
+ Actor a = CreateRenderableActor(CreateTexture(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 200, 200));
+
+ a[Actor::Property::PARENT_ORIGIN] = ParentOrigin::CENTER_LEFT;
+ a[Actor::Property::ANCHOR_POINT] = ParentOrigin::CENTER_RIGHT;
+ a[Actor::Property::POSITION] = Vector3(-10.0f, 0.0f, 0.0f);
+
+ application.GetScene().Add(a);
+
+ application.SendNotification();
+ application.Render();
+
+ auto& cmdStack = gfx.mCommandBufferCallStack;
+ DALI_TEST_CHECK(!cmdStack.FindMethod("Draw") && !cmdStack.FindMethod("DrawIndexed"));
+
+ tet_infoline("Rotate the actor 45 degrees, the actor should now be rendered");
+ a[Actor::Property::ORIENTATION] = Quaternion(Dali::ANGLE_45, Vector3::ZAXIS);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_CHECK(cmdStack.FindMethod("Draw") || cmdStack.FindMethod("DrawIndexed"));
+
+ END_TEST;
+}
END_TEST;
}
+int UtcDaliHitTestAlgorithmClippingActorStress(void)
+{
+ TestApplication application;
+ tet_infoline("Testing Dali::HitTestAlgorithm with many many stencil");
+
+ Stage stage = Stage::GetCurrent();
+ Actor rootLayer = stage.GetRootLayer();
+ rootLayer.SetProperty(Actor::Property::NAME, "RootLayer");
+
+ // Create a layer
+ Layer layer = Layer::New();
+ layer.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ layer.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ layer.SetProperty(Actor::Property::NAME, "layer");
+ stage.Add(layer);
+
+ // Create a clipping actor and add it to the layer.
+ Actor clippingActor = CreateRenderableActor();
+ clippingActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ clippingActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ clippingActor.SetProperty(Actor::Property::SIZE, Vector2(220.0f, 220.0f));
+ clippingActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
+ clippingActor.SetProperty(Actor::Property::NAME, "clippingActor");
+ layer.Add(clippingActor);
+
+ // Create a renderable actor and add it to the clipping actor.
+ Actor latestActor = clippingActor;
+ const int depthMax = 100;
+ for(int i = 0; i < depthMax; i++)
+ {
+ char tmp[29];
+ sprintf(tmp, "depth%03d", i);
+
+ Actor childActor = CreateRenderableActor();
+ childActor.SetProperty(Actor::Property::SIZE, Vector2(220.0f, 220.0f));
+ childActor.SetProperty(Actor::Property::POSITION, Vector2(200.0f / depthMax, 200.0f / depthMax));
+ childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+ childActor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
+ childActor.SetProperty(Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX);
+ childActor.SetProperty(Actor::Property::NAME, tmp);
+
+ latestActor.Add(childActor);
+ latestActor = childActor;
+ }
+ // NOTE : latestActor's TOP_LEFT position become 200.f, 200.0f
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Hit within clippingActor and latestActor.
+ HitTestAlgorithm::Results results;
+ HitTest(stage, Vector2(201.0f, 201.0f), results, &DefaultIsActorTouchableFunction);
+ tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
+ DALI_TEST_CHECK(results.actor == latestActor);
+
+ // Hit within childActor but outside of clippingActor, should hit the root-layer instead.
+ HitTest(stage, Vector2(221.0f, 221.0f), results, &DefaultIsActorTouchableFunction);
+ tet_printf("Hit: %s\n", (results.actor ? results.actor.GetProperty<std::string>(Actor::Property::NAME).c_str() : "NULL"));
+ DALI_TEST_CHECK(results.actor == rootLayer);
+
+ END_TEST;
+}
+
int UtcDaliHitTestAlgorithmOverlay(void)
{
TestApplication application;
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
void CameraActor::OnSceneConnectionInternal()
{
- // If the canvas size has not been set, then use the size of the scene we've been added to to set up the perspective projection
+ // If the canvas size has not been set, then use the size of the scene to which we've been added
+ // in order to set up the current projection
if((mCanvasSize.width < Math::MACHINE_EPSILON_1000) || (mCanvasSize.height < Math::MACHINE_EPSILON_1000))
{
- SetPerspectiveProjection(GetScene().GetSize());
+ if(mProjectionMode == Dali::Camera::ORTHOGRAPHIC_PROJECTION)
+ {
+ SetOrthographicProjection(GetScene().GetSize());
+ }
+ else //if(mProjectionMode == Dali::Camera::PERSPECTIVE_PROJECTION)
+ {
+ SetPerspectiveProjection(GetScene().GetSize());
+ }
}
}
void CameraActor::SetReflectByPlane(const Vector4& plane)
{
- SceneGraph::Camera* cam = const_cast<SceneGraph::Camera*>(GetCamera());
- if(cam)
+ if(mSceneObject)
{
- cam->SetReflectByPlane(plane);
+ SetReflectByPlaneMessage(GetEventThreadServices(), *mSceneObject, plane);
}
}
void CameraActor::SetPerspectiveProjection(const Size& size)
{
+ SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
mCanvasSize = size;
if((size.width < Math::MACHINE_EPSILON_1000) || (size.height < Math::MACHINE_EPSILON_1000))
const float aspectRatio = width / height;
// sceneObject is being used in a separate thread; queue a message to set
- SetProjectionMode(Dali::Camera::PERSPECTIVE_PROJECTION);
SetFieldOfView(fieldOfView);
SetNearClippingPlane(nearClippingPlane);
SetFarClippingPlane(farClippingPlane);
+ SetLeftClippingPlane(width * -0.5f);
+ SetRightClippingPlane(width * 0.5f);
+ SetTopClippingPlane(height * 0.5f); // Top is +ve to keep consistency with orthographic values
+ SetBottomClippingPlane(height * -0.5f); // Bottom is -ve to keep consistency with orthographic values
SetAspectRatio(aspectRatio);
SetZ(cameraZ);
}
void CameraActor::SetOrthographicProjection(const Vector2& size)
{
+ SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
+ mCanvasSize = size;
+
+ if((size.width < Math::MACHINE_EPSILON_1000) || (size.height < Math::MACHINE_EPSILON_1000))
+ {
+ // If the size given is invalid, i.e. ZERO, then check if we've been added to a scene
+ if(OnScene())
+ {
+ // We've been added to a scene already, set the canvas size to the scene's size
+ mCanvasSize = GetScene().GetSize();
+ }
+ else
+ {
+ // We've not been added to a scene yet, so just return.
+ // We'll set the canvas size when we get added to a scene later
+ return;
+ }
+ }
+
// Choose near, far and Z parameters to match the SetPerspectiveProjection above.
float nearClippingPlane;
float farClippingPlane;
float cameraZ;
CalculateClippingAndZ(size.width, size.height, nearClippingPlane, farClippingPlane, cameraZ);
- SetOrthographicProjection(-size.x * 0.5f, size.x * 0.5f, size.y * 0.5f, -size.y * 0.5f, nearClippingPlane, farClippingPlane);
+ SetOrthographicProjection(-size.x * 0.5f, size.x * 0.5f, size.y * 0.5f, size.y * -0.5f, nearClippingPlane, farClippingPlane);
SetZ(cameraZ);
}
void CameraActor::SetOrthographicProjection(float left, float right, float top, float bottom, float near, float far)
{
+ SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
SetLeftClippingPlane(left);
SetRightClippingPlane(right);
SetTopClippingPlane(top);
SetBottomClippingPlane(bottom);
SetNearClippingPlane(near);
SetFarClippingPlane(far);
- SetProjectionMode(Dali::Camera::ORTHOGRAPHIC_PROJECTION);
}
bool CameraActor::BuildPickingRay(const Vector2& screenCoordinates,
const bool& overlayed,
bool& overlayHit,
bool layerIs3d,
- uint32_t clippingDepth,
- uint32_t clippingBitPlaneMask,
const RayTest& rayTest,
const Integration::Point& point,
const uint32_t eventTime)
return hit;
}
- // For clipping, regardless of whether we have hit this actor or not,
- // we increase the clipping depth if we have hit a clipping actor.
+ // For clipping, regardless of whether we have hit this actor or not.
// This is used later to ensure all nested clipped children have hit
// all clipping actors also for them to be counted as hit.
- uint32_t newClippingDepth = clippingDepth;
- bool clippingActor = actor.GetClippingMode() != ClippingMode::DISABLED;
- bool overlayedActor = overlayed || actor.IsOverlay();
- if(clippingActor)
- {
- ++newClippingDepth;
- }
+ bool clippingActor = actor.GetClippingMode() != ClippingMode::DISABLED;
+ bool overlayedActor = overlayed || actor.IsOverlay();
// If we are a clipping actor or hittable...
if(clippingActor || hitCheck.IsActorHittable(&actor))
// Check if cameraDepthDistance is between clipping plane
if(cameraDepthDistance >= nearClippingPlane && cameraDepthDistance <= farClippingPlane)
{
- // If the hit has happened on a clipping actor, then add this clipping depth to the mask of hit clipping depths.
- // This mask shows all the actors that have been hit at different clipping depths.
- if(clippingActor)
- {
- clippingBitPlaneMask |= 1u << clippingDepth;
- }
-
if(overlayHit && !overlayedActor)
{
// If we have already hit an overlay and current actor is not an overlay ignore current actor.
overlayHit = true;
}
- // At this point we have hit an actor.
- // Now perform checks for clipping.
- // Assume we have hit the actor first as if it is not clipped this would be the case.
- bool haveHitActor = true;
-
- // Check if we are performing clipping. IE. if any actors so far have clipping enabled - not necessarily this one.
- // We can do this by checking the clipping depth has a value 1 or above.
- if(newClippingDepth >= 1u)
- {
- // Now for us to count this actor as hit, we must have also hit
- // all CLIPPING actors up to this point in the hierarchy as well.
- // This information is stored in the clippingBitPlaneMask we updated above.
- // Here we calculate a comparison mask by setting all the bits up to the current depth value.
- // EG. a depth of 4 (10000 binary) = a mask of 1111 binary.
- // This allows us a fast way of comparing all bits are set up to this depth.
- // Note: If the current Actor has clipping, that is included in the depth mask too.
- uint32_t clippingDepthMask = (1u << newClippingDepth) - 1u;
-
- // The two masks must be equal to be a hit, as we are already assuming a hit
- // (for non-clipping mode) then they must be not-equal to disqualify the hit.
- if(clippingBitPlaneMask != clippingDepthMask)
- {
- haveHitActor = false;
- }
- }
-
// If the hit actor does not want to hit, the hit-test continues.
- if(haveHitActor && hitCheck.ActorRequiresHitResultCheck(&actor, point, hitPointLocal, eventTime))
+ if(hitCheck.ActorRequiresHitResultCheck(&actor, point, hitPointLocal, eventTime))
{
hit.actor = &actor;
hit.hitPosition = hitPointLocal;
}
}
+ // If current actor is clipping, and hit failed, We should not checkup child actors. Fast return
+ if(clippingActor && !(hit.actor))
+ {
+ return hit;
+ }
+
// Find a child hit, until we run out of actors in the current layer.
HitActor childHit;
if(actor.GetChildCount() > 0)
overlayedActor,
overlayHit,
layerIs3d,
- newClippingDepth,
- clippingBitPlaneMask,
rayTest,
point,
eventTime));
overlayHit,
overlayHit,
layer->GetBehavior() == Dali::Layer::LAYER_3D,
- 0u,
- 0u,
rayTest,
results.point,
results.eventTime);
overlayHit,
overlayHit,
layer->GetBehavior() == Dali::Layer::LAYER_3D,
- 0u,
- 0u,
rayTest,
results.point,
results.eventTime);
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
RenderItem::~RenderItem() = default;
+ClippingBox RenderItem::CalculateTransformSpaceAABB(const Matrix& transformMatrix, const Vector3& size)
+{
+ // Calculate extent vector of the AABB:
+ const float halfActorX = size.x * 0.5f;
+ const float halfActorY = size.y * 0.5f;
+
+ // To transform the actor bounds to the transformed space, We do a fast, 2D version of a matrix multiply optimized for 2D quads.
+ // This reduces float multiplications from 64 (16 * 4) to 12 (4 * 3).
+ // We create an array of 4 corners and directly initialize the first 3 with the matrix multiplication result of the respective corner.
+ // This causes the construction of the vector arrays contents in-place for optimization.
+ // We place the coords into the array in clockwise order, so we know opposite corners are always i + 2 from corner i.
+ // We skip the 4th corner here as we can calculate that from the other 3, bypassing matrix multiplication.
+ // Note: The below transform methods use a fast (2D) matrix multiply (only 4 multiplications are done).
+ Vector2 corners[4]{Transform2D(transformMatrix, -halfActorX, -halfActorY),
+ Transform2D(transformMatrix, halfActorX, -halfActorY),
+ Transform2D(transformMatrix, halfActorX, halfActorY)};
+
+ // As we are dealing with a rectangle, we can do a fast calculation to get the 4th corner from knowing the other 3 (even if rotated).
+ corners[3] = Vector2(corners[0] + (corners[2] - corners[1]));
+
+ // Calculate the AABB:
+ // We use knowledge that opposite corners will be the max/min of each other. Doing this reduces the normal 12 branching comparisons to 3.
+ // The standard equivalent min/max code of the below would be:
+ // Vector2 AABBmax( std::max( corners[0].x, std::max( corners[1].x, std::max( corners[3].x, corners[2].x ) ) ),
+ // std::max( corners[0].y, std::max( corners[1].y, std::max( corners[3].y, corners[2].y ) ) ) );
+ // Vector2 AABBmin( std::min( corners[0].x, std::min( corners[1].x, std::min( corners[3].x, corners[2].x ) ) ),
+ // std::min( corners[0].y, std::min( corners[1].y, std::min( corners[3].y, corners[2].y ) ) ) );
+ unsigned int smallestX = 0u;
+ // Loop 3 times to find the index of the smallest X value.
+ // Note: We deliberately do NOT unroll the code here as this hampers the compilers output.
+ for(unsigned int i = 1u; i < 4u; ++i)
+ {
+ if(corners[i].x < corners[smallestX].x)
+ {
+ smallestX = i;
+ }
+ }
+
+ // As we are dealing with a rectangle, we can assume opposite corners are the largest.
+ // So without doing min/max branching, we can fetch the min/max values of all the remaining X/Y coords from this one index.
+ Vector4 aabb(corners[smallestX].x, corners[(smallestX + 3u) % 4].y, corners[(smallestX + 2u) % 4].x, corners[(smallestX + 1u) % 4].y);
+
+ // Round outwards from center
+ int x = static_cast<int>(floor(aabb.x));
+ int y = static_cast<int>(floor(aabb.y));
+ int z = static_cast<int>(ceilf(aabb.z));
+ int w = static_cast<int>(ceilf(aabb.w));
+
+ return ClippingBox(x, y, z - x, fabsf(w - y));
+}
+
ClippingBox RenderItem::CalculateViewportSpaceAABB(const Matrix& modelViewMatrix, const Vector3& size, const int viewportWidth, const int viewportHeight)
{
// Calculate extent vector of the AABB:
#define DALI_INTERNAL_SCENE_GRAPH_RENDER_ITEM_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
~RenderItem();
/**
+ * Produce a 2D AABB in transformed space
+ * See below for caveats.
+ *
+ * @param[in] transformMatrix The matrix for converting to a different space
+ * @param[in] size The size of the render item
+ */
+ static ClippingBox CalculateTransformSpaceAABB(const Matrix& transformMatrix, const Vector3& size);
+
+ /**
* @brief This method is an optimized calculation of a viewport-space AABB (Axis-Aligned-Bounding-Box).
*
* We use the model-view-matrix, but we do not use projection. Therefore we assume Z = 0.
*
* Note: We pass in the viewport dimensions rather than allow the caller to modify the raw AABB in order to optimally generate the final result.
*
+ * Note: ASSUMES THAT THE VIEWPORT COVERS THE SCREEN AND THAT THE CANVAS SIZE AND VIEWPORT SIZE ARE THE SAME!!!!! (Not the case for magnifier)
+ *
* @param[in] modelViewMatrix The model view matrix
* @param[in] size The size of the render item
* @param[in] viewportWidth The width of the viewport to calculate for
SetNodeUpdateSize(node, isLayer3d, nodeWorldMatrix, nodeSize, nodeUpdateSize);
nodeUpdateSizeSet = true;
- const Vector3& scale = node->GetWorldScale(updateBufferIndex);
- const Vector3& halfSize = nodeUpdateSize * scale * 0.5f;
- float radius(halfSize.Length());
+ const Vector3& scale = node->GetWorldScale(updateBufferIndex);
+ const Vector3& size = nodeUpdateSize * scale;
- if(radius > Math::MACHINE_EPSILON_1000)
+ if(size.LengthSquared() > Math::MACHINE_EPSILON_1000)
{
Matrix::Multiply(nodeModelViewMatrix, nodeWorldMatrix, viewMatrix);
nodeModelViewMatrixSet = true;
- ClippingBox clippingBox = RenderItem::CalculateViewportSpaceAABB(nodeModelViewMatrix, nodeUpdateSize, viewport.width, viewport.height);
- inside = clippingBox.Intersects(viewport);
+ // Assume actors are at z=0, compute AABB in view space & test rect intersection
+ // against z=0 plane boundaries for frustum. (NOT viewport). This should take into account
+ // magnification due to FOV etc.
+ ClippingBox boundingBox = RenderItem::CalculateTransformSpaceAABB(nodeModelViewMatrix, nodeUpdateSize);
+ ClippingBox clippingBox(camera.mLeftClippingPlane, camera.mBottomClippingPlane, camera.mRightClippingPlane - camera.mLeftClippingPlane, fabsf(camera.mBottomClippingPlane - camera.mTopClippingPlane));
+ inside = clippingBox.Intersects(boundingBox);
}
}
+ /*
+ * Note, the API Camera::CheckAABBInFrustum() can be used to test if a bounding box is (partially/fully) inside the view frustum.
+ */
}
if(inside)
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
const Dali::Camera::ProjectionMode Camera::DEFAULT_MODE(Dali::Camera::PERSPECTIVE_PROJECTION);
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(4.0f / 3.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);
#define DALI_INTERNAL_SCENE_GRAPH_CAMERA_H
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 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.
new(slot) LocalType(&camera, &Camera::SetFarClippingPlane, parameter);
}
+inline void SetReflectByPlaneMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector4& plane)
+{
+ using LocalType = MessageValue1<Camera, Vector4>;
+
+ // Reserve some memory inside the message queue
+ uint32_t* slot = eventThreadServices.ReserveMessageSlot(sizeof(LocalType));
+
+ // Construct message in the message queue memory; note that delete should not be called on the return value
+ new(slot) LocalType(&camera, &Camera::SetReflectByPlane, plane);
+}
+
inline void SetTargetPositionMessage(EventThreadServices& eventThreadServices, const Camera& camera, const Vector3& parameter)
{
using LocalType = MessageValue1<Camera, Vector3>;