"camera" : 1,
"translation" : [ 0.5, 0.5, 3.0 ],
"children": [
- 4
+ 4, 5, 6, 7
]
},
{
0.0,
1.0
]
+ },
+ {
+ "camera" : 3,
+ "translation" : [ 0.0, 0.0, 0.0 ]
+ },
+ {
+ "camera" : 4,
+ "translation" : [ 0.0, 0.0, 0.0 ]
+ },
+ {
+ "camera" : 5,
+ "translation" : [ 0.0, 0.0, 0.0 ]
}
],
"scene" : 0,
"zfar": 100.0,
"znear": 0.01
}
+ },
+ {
+ "type": "perspective",
+ "perspective": {
+ "aspectRatio": 1.0,
+ "yfov": 0.7,
+ "znear": 0.01
+ }
+ },
+ {
+ "type": "perspective",
+ "perspective": {
+ "aspectRatio": 1.0,
+ "zfar": 100.0,
+ "znear": 0.01
+ }
+ },
+ {
+ "type": "orthographic",
+ "orthographic": {
+ "xmag": 1.0,
+ "ymag": 1.0,
+ "znear": 0.01
+ }
}
],
"samplers": [
/*
- * 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.
Vector3::ZAXIS * -100.f);
camParams.orthographicSize = 3.0f;
camParams.aspectRatio = 1.0f;
- camParams.yFov = Degree(Radian(M_PI * .5)).degree;
+ camParams.yFovDegree = Degree(Radian(M_PI * .5));
camParams.zNear = 1.f;
camParams.zFar = 1000.f;
if(camParams.isPerspective)
{
- DALI_TEST_EQUAL(camera.GetProperty(Dali::CameraActor::Property::FIELD_OF_VIEW).Get<float>(), Radian(Degree(camParams.yFov)).radian);
+ DALI_TEST_EQUAL(camera.GetProperty(Dali::CameraActor::Property::FIELD_OF_VIEW).Get<float>(), Radian(camParams.yFovDegree).radian);
}
else
{
LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCube.gltf", sdf, ctx.loadResult);
DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
- DALI_TEST_EQUAL(6u, ctx.scene.GetNodeCount());
+ DALI_TEST_EQUAL(9u, ctx.scene.GetNodeCount());
// Default envmap is used
DALI_TEST_EQUAL(1u, ctx.resources.mEnvironmentMaps.size());
DALI_TEST_EQUAL(2u, ctx.resources.mShaders.size());
DALI_TEST_EQUAL(0u, ctx.resources.mSkeletons.size());
- DALI_TEST_EQUAL(3u, ctx.cameras.size());
+ DALI_TEST_EQUAL(6u, ctx.cameras.size());
DALI_TEST_EQUAL(0u, ctx.lights.size());
DALI_TEST_EQUAL(1u, ctx.animations.size());
DALI_TEST_EQUAL(0u, ctx.animationGroups.size());
/*
- * 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.
#include <dali-scene3d/public-api/controls/model/model.h>
+#include <dali/devel-api/actors/camera-actor-devel.h>
+
using namespace Dali;
using namespace Dali::Toolkit;
* These textures are based off version of Wave engine sample
* Take from https://github.com/WaveEngine/Samples
*
- * Copyright (c) 2022 Wave Coorporation
+ * Copyright (c) 2023 Wave Coorporation
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
END_TEST;
}
+int UtcDaliModelCameraGenerate01(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model model = Scene3D::Model::New(TEST_DLI_EXERCISE_FILE_NAME);
+ model.SetProperty(Dali::Actor::Property::SIZE, Vector2(50, 50));
+ application.GetScene().Add(model);
+
+ gResourceReadyCalled = false;
+ model.ResourceReadySignal().Connect(&OnResourceReady);
+ DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
+
+ uint32_t cameraCount = model.GetCameraCount();
+ DALI_TEST_EQUALS(1, cameraCount, TEST_LOCATION);
+
+ CameraActor generatedCamera = model.GenerateCamera(0u);
+ DALI_TEST_CHECK(generatedCamera);
+
+ generatedCamera = model.GenerateCamera(1u); // Fail to generate camera
+ DALI_TEST_CHECK(!generatedCamera);
+
+ END_TEST;
+}
+
+int UtcDaliModelCameraGenerate02(void)
+{
+ ToolkitTestApplication application;
+
+ Scene3D::Model model = Scene3D::Model::New(TEST_GLTF_FILE_NAME);
+ model.SetProperty(Dali::Actor::Property::SIZE, Vector2(50, 50));
+ application.GetScene().Add(model);
+
+ gResourceReadyCalled = false;
+ model.ResourceReadySignal().Connect(&OnResourceReady);
+ DALI_TEST_EQUALS(gResourceReadyCalled, false, TEST_LOCATION);
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(Test::WaitForEventThreadTrigger(1), true, TEST_LOCATION);
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS(gResourceReadyCalled, true, TEST_LOCATION);
+
+ uint32_t cameraCount = model.GetCameraCount();
+ DALI_TEST_EQUALS(6, cameraCount, TEST_LOCATION);
+
+ CameraActor generatedCamera0 = model.GenerateCamera(0u);
+ DALI_TEST_CHECK(generatedCamera0);
+ CameraActor generatedCamera1 = model.GenerateCamera(1u);
+ DALI_TEST_CHECK(generatedCamera1);
+ CameraActor generatedCamera2 = model.GenerateCamera(2u);
+ DALI_TEST_CHECK(generatedCamera2);
+ CameraActor generatedCamera3 = model.GenerateCamera(3u); // Infinity far camera
+ DALI_TEST_CHECK(generatedCamera3);
+ CameraActor generatedCamera4 = model.GenerateCamera(4u); // Broken camera 1
+ DALI_TEST_CHECK(!generatedCamera4);
+ CameraActor generatedCamera5 = model.GenerateCamera(5u); // Broken camera 2
+ DALI_TEST_CHECK(!generatedCamera5);
+ CameraActor generatedCamera6 = model.GenerateCamera(6u); // Out of bound
+ DALI_TEST_CHECK(!generatedCamera6);
+
+ CameraActor appliedCamera;
+ DALI_TEST_EQUALS(model.ApplyCamera(0u, appliedCamera), false, TEST_LOCATION); // Cannot apply into empty camera.
+
+ auto CompareCameraProperties = [](CameraActor lhs, CameraActor rhs, const char* location) {
+ DALI_TEST_EQUALS(lhs.GetProperty<int>(Dali::CameraActor::Property::PROJECTION_MODE), rhs.GetProperty<int>(Dali::CameraActor::Property::PROJECTION_MODE), TEST_LOCATION);
+ DALI_TEST_EQUALS(lhs.GetProperty<float>(Dali::CameraActor::Property::NEAR_PLANE_DISTANCE), rhs.GetProperty<float>(Dali::CameraActor::Property::NEAR_PLANE_DISTANCE), TEST_LOCATION);
+
+ if(lhs.GetProperty<int>(Dali::CameraActor::Property::PROJECTION_MODE) == static_cast<int>(Dali::Camera::ProjectionMode::PERSPECTIVE_PROJECTION))
+ {
+ DALI_TEST_EQUALS(lhs.GetProperty<float>(Dali::CameraActor::Property::FIELD_OF_VIEW), rhs.GetProperty<float>(Dali::CameraActor::Property::FIELD_OF_VIEW), TEST_LOCATION);
+ // TODO : Open this test when infinity far projection implement.
+ //DALI_TEST_EQUALS(lhs.GetProperty<float>(Dali::CameraActor::Property::FAR_PLANE_DISTANCE), rhs.GetProperty<float>(Dali::CameraActor::Property::FAR_PLANE_DISTANCE), TEST_LOCATION);
+ }
+ else
+ {
+ DALI_TEST_EQUALS(lhs.GetProperty<float>(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), rhs.GetProperty<float>(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE), TEST_LOCATION);
+ DALI_TEST_EQUALS(lhs.GetProperty<float>(Dali::CameraActor::Property::FAR_PLANE_DISTANCE), rhs.GetProperty<float>(Dali::CameraActor::Property::FAR_PLANE_DISTANCE), TEST_LOCATION);
+ }
+ };
+
+ appliedCamera = CameraActor::New();
+ DALI_TEST_EQUALS(model.ApplyCamera(0u, appliedCamera), true, TEST_LOCATION);
+ CompareCameraProperties(generatedCamera0, appliedCamera, TEST_LOCATION);
+ DALI_TEST_EQUALS(model.ApplyCamera(1u, appliedCamera), true, TEST_LOCATION);
+ CompareCameraProperties(generatedCamera1, appliedCamera, TEST_LOCATION);
+ DALI_TEST_EQUALS(model.ApplyCamera(2u, appliedCamera), true, TEST_LOCATION);
+ CompareCameraProperties(generatedCamera2, appliedCamera, TEST_LOCATION);
+ DALI_TEST_EQUALS(model.ApplyCamera(3u, appliedCamera), true, TEST_LOCATION);
+ CompareCameraProperties(generatedCamera3, appliedCamera, TEST_LOCATION);
+ DALI_TEST_EQUALS(model.ApplyCamera(4u, appliedCamera), false, TEST_LOCATION); // Broken camera 1
+ DALI_TEST_EQUALS(model.ApplyCamera(5u, appliedCamera), false, TEST_LOCATION); // Broken camera 2
+ DALI_TEST_EQUALS(model.ApplyCamera(6u, appliedCamera), false, TEST_LOCATION); // Cannot apply over the index.
+
+ END_TEST;
+}
+
int UtcDaliModelMultiplePrimitives(void)
{
ToolkitTestApplication application;
application.SendNotification();
application.Render();
- Actor actor = model.FindChildByName("AnimatedCube");
- Vector4 childColor = actor[Dali::Actor::Property::COLOR];
+ Actor actor = model.FindChildByName("AnimatedCube");
+ Vector4 childColor = actor[Dali::Actor::Property::COLOR];
Vector4 childWorldColor = actor[Dali::Actor::Property::WORLD_COLOR];
DALI_TEST_EQUALS(childColor, Color::WHITE, TEST_LOCATION);
Dali::Scene3D::Loader::ResourceBundle& resources, const Dali::Scene3D::Loader::SceneDefinition& scene, Actor root, std::vector<Dali::Scene3D::Loader::BlendshapeShaderConfigurationRequest>&& requests)
{
std::vector<std::string> errors;
- auto onError = [&errors](const std::string& msg)
- { errors.push_back(msg); };
+ auto onError = [&errors](const std::string& msg) { errors.push_back(msg); };
if(!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError))
{
Dali::Scene3D::Loader::ExceptionFlinger flinger(ASSERT_LOCATION);
return animation;
}
+uint32_t Model::GetCameraCount() const
+{
+ return mCameraParameters.size();
+}
+
+Dali::CameraActor Model::GenerateCamera(uint32_t index) const
+{
+ Dali::CameraActor camera;
+ if(mCameraParameters.size() > index)
+ {
+ camera = Dali::CameraActor::New3DCamera();
+ if(!mCameraParameters[index].ConfigureCamera(camera, false))
+ {
+ DALI_LOG_ERROR("Fail to generate %u's camera actor : Some property was not defined. Please check model file.\n", index);
+ camera.Reset();
+ return camera;
+ }
+
+ ApplyCameraTransform(camera);
+ }
+ return camera;
+}
+
+bool Model::ApplyCamera(uint32_t index, Dali::CameraActor camera) const
+{
+ if(camera && mCameraParameters.size() > index)
+ {
+ if(!mCameraParameters[index].ConfigureCamera(camera, false))
+ {
+ DALI_LOG_ERROR("Fail to apply %u's camera actor : Some property was not defined. Please check model file.\n", index);
+ return false;
+ }
+
+ ApplyCameraTransform(camera);
+ return true;
+ }
+ return false;
+}
+
///////////////////////////////////////////////////////////
//
// Private methods
}
}
+void Model::ApplyCameraTransform(Dali::CameraActor camera) const
+{
+ Vector3 selfPosition = Self().GetProperty<Vector3>(Actor::Property::POSITION);
+ Quaternion selfOrientation = Self().GetProperty<Quaternion>(Actor::Property::ORIENTATION);
+ Vector3 selfScale = Self().GetProperty<Vector3>(Actor::Property::SCALE);
+
+ Vector3 cameraPosition = camera.GetProperty<Vector3>(Actor::Property::POSITION);
+ Quaternion cameraOrientation = camera.GetProperty<Quaternion>(Actor::Property::ORIENTATION);
+ Vector3 cameraScale = camera.GetProperty<Vector3>(Actor::Property::SCALE);
+
+ // Models in glTF and dli are defined as right hand coordinate system.
+ // DALi uses left hand coordinate system. Scaling negative is for change winding order.
+ if(!Dali::Equals(Y_DIRECTION.Dot(Vector3::YAXIS), 1.0f))
+ {
+ // Reflect by XZ plane
+ cameraPosition.y = -cameraPosition.y;
+ Quaternion yDirectionQuaternion;
+ yDirectionQuaternion.mVector = Vector3::YAXIS;
+ // Reflect orientation
+ cameraOrientation = yDirectionQuaternion * cameraOrientation * yDirectionQuaternion;
+ }
+
+ Vector3 resultPosition;
+ Quaternion resultOrientation;
+ Vector3 resultScale;
+
+ Matrix selfMatrix(false);
+ Matrix cameraMatrix(false);
+ Matrix resultMatrix(false);
+ selfMatrix.SetTransformComponents(selfScale, selfOrientation, selfPosition);
+ cameraMatrix.SetTransformComponents(cameraScale, cameraOrientation, cameraPosition);
+ Matrix::Multiply(resultMatrix, cameraMatrix, selfMatrix);
+ resultMatrix.GetTransformComponents(resultPosition, resultOrientation, resultScale);
+
+ camera.SetProperty(Actor::Property::POSITION, resultPosition);
+ camera.SetProperty(Actor::Property::ORIENTATION, resultOrientation);
+ camera.SetProperty(Actor::Property::SCALE, resultScale);
+}
+
void Model::NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor)
{
if(mSceneDiffuseTexture != diffuseTexture || mSceneSpecularTexture != specularTexture)
auto* resources = &(mModelLoadTask->mResources);
auto* scene = &(mModelLoadTask->mScene);
CreateAnimations(*scene);
+ ResetCameraParameters();
+
if(!resources->mEnvironmentMaps.empty())
{
mDefaultDiffuseTexture = resources->mEnvironmentMaps.front().second.mDiffuse;
void Model::CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene)
{
+ mAnimations.clear();
if(!mModelLoadTask->mAnimations.empty())
{
- auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property)
- {
+ auto getActor = [&](const Scene3D::Loader::AnimatedProperty& property) {
if(property.mNodeIndex == Scene3D::Loader::INVALID_INDEX)
{
return mModelRoot.FindChildByName(property.mNodeName);
return mModelRoot.FindChildById(node->mNodeId);
};
- mAnimations.clear();
for(auto&& animation : mModelLoadTask->mAnimations)
{
Dali::Animation anim = animation.ReAnimate(getActor);
}
}
+void Model::ResetCameraParameters()
+{
+ mCameraParameters.clear();
+ if(!mModelLoadTask->mCameraParameters.empty())
+ {
+ // Copy camera parameters.
+ std::copy(mModelLoadTask->mCameraParameters.begin(), mModelLoadTask->mCameraParameters.end(), std::back_inserter(mCameraParameters));
+ }
+}
+
} // namespace Internal
} // namespace Scene3D
} // namespace Dali
#define DALI_SCENE3D_INTERNAL_MODEL_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.
// EXTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali/public-api/actors/camera-actor.h>
#include <dali/public-api/actors/layer.h>
#include <dali/public-api/animation/animation.h>
#include <dali/public-api/object/weak-handle.h>
{
public:
using AnimationData = std::pair<std::string, Dali::Animation>;
+ using CameraData = Loader::CameraParameters;
/**
* @brief Creates a new Model.
*/
Dali::Animation GetAnimation(const std::string& name) const;
+ /**
+ * @copydoc Model::GetCameraCount()
+ */
+ uint32_t GetCameraCount() const;
+
+ /**
+ * @copydoc Model::GenerateCamera()
+ */
+ Dali::CameraActor GenerateCamera(uint32_t index) const;
+
+ /**
+ * @copydoc Model::ApplyCamera()
+ */
+ bool ApplyCamera(uint32_t index, Dali::CameraActor camera) const;
+
protected:
/**
* @brief Constructs a new Model.
*/
bool IsResourceReady() const override;
+private:
/**
* @brief Scales the model to fit the control or to return to original size.
*/
*/
void UpdateImageBasedLightScaleFactor();
+ /**
+ * @brief Apply self transform into inputed camera.
+ * Inputed camera must be configured by CameraParameter. Mean, inputed camera coordinate depend on Model.
+ * After this API finished, CameraActor coordinate system converted as DALi coordinate system.
+ *
+ * @param[in,out] camera CameraActor who need to apply model itself's transform
+ */
+ void ApplyCameraTransform(Dali::CameraActor camera) const;
+
public: // Overrides ImageBasedLightObserver Methods.
/**
* @copydoc Dali::Scene3D::Internal::ImageBasedLightObserver::NotifyImageBasedLightTexture()
*/
void CreateAnimations(Dali::Scene3D::Loader::SceneDefinition& scene);
+ /**
+ * @brief Reset CameraData from loaded CameraParameters.
+ */
+ void ResetCameraParameters();
+
private:
std::string mModelUrl;
std::string mResourceDirectoryUrl;
Dali::Actor mModelRoot;
std::vector<AnimationData> mAnimations;
+ std::vector<CameraData> mCameraParameters;
std::vector<WeakHandle<Actor>> mRenderableActors;
WeakHandle<Scene3D::SceneView> mParentSceneView;
#ifndef DALI_SCENE3D_LOADER_GLTF2_ASSET_H_
#define DALI_SCENE3D_LOADER_GLTF2_ASSET_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.
*/
// INTERNAL INCLUDES
-#include "dali-scene3d/internal/loader/json-reader.h"
-#include "dali-scene3d/public-api/loader/index.h"
+#include <dali-scene3d/internal/loader/json-reader.h>
+#include <dali-scene3d/public-api/loader/index.h>
// EXTERNAL INCLUDES
+#include <dali/devel-api/common/map-wrapper.h>
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/public-api/math/quaternion.h>
+#include <dali/public-api/math/vector4.h>
#include <cstdint>
#include <memory>
-#include "dali/devel-api/common/map-wrapper.h"
-#include "dali/public-api/common/vector-wrapper.h"
-#include "dali/public-api/math/quaternion.h"
-#include "dali/public-api/math/vector4.h"
#define ENUM_STRING_MAPPING(t, x) \
{ \
namespace gltf2
{
-using Index = Dali::Scene3D::Loader::Index;
+using Index = Dali::Scene3D::Loader::Index;
+constexpr float UNDEFINED_FLOAT_VALUE = -1.0f; ///< Special marker for some non-negative only float values.
template<typename T>
class Ref
*/
struct MaterialIor
{
- float mIor = MAXFLOAT;
+ float mIor = UNDEFINED_FLOAT_VALUE;
};
/**
{
struct Perspective
{
- float mAspectRatio;
- float mYFov;
- float mZFar;
- float mZNear;
+ float mAspectRatio = UNDEFINED_FLOAT_VALUE;
+ float mYFov = UNDEFINED_FLOAT_VALUE;
+ float mZFar = UNDEFINED_FLOAT_VALUE;
+ float mZNear = UNDEFINED_FLOAT_VALUE;
//TODO: extras
//TODO: extensions
};
struct Orthographic
{
- float mXMag;
- float mYMag;
- float mZFar;
- float mZNear;
+ float mXMag = UNDEFINED_FLOAT_VALUE;
+ float mYMag = UNDEFINED_FLOAT_VALUE;
+ float mZFar = UNDEFINED_FLOAT_VALUE;
+ float mZNear = UNDEFINED_FLOAT_VALUE;
//TODO: extras
//TODO: extensions
};
/*
- * 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.
return GetImpl(*this).GetAnimation(name);
}
+uint32_t Model::GetCameraCount() const
+{
+ return GetImpl(*this).GetCameraCount();
+}
+
+Dali::CameraActor Model::GenerateCamera(uint32_t index) const
+{
+ return GetImpl(*this).GenerateCamera(index);
+}
+
+bool Model::ApplyCamera(uint32_t index, Dali::CameraActor camera) const
+{
+ return GetImpl(*this).ApplyCamera(index, camera);
+}
+
} // namespace Scene3D
} // namespace Dali
#define DALI_SCENE3D_MODEL_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.
// EXTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control.h>
+#include <dali/public-api/actors/camera-actor.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/rendering/texture.h>
*/
Dali::Animation GetAnimation(const std::string& name) const;
+ /**
+ * @brief Gets number of camera parameters those loaded from model file.
+ *
+ * @SINCE_2_2.15
+ * @return The number of loaded camera parameters.
+ * @note This method should be called after Model load finished.
+ */
+ uint32_t GetCameraCount() const;
+
+ /**
+ * @brief Generate camera actor using camera parameters at the index.
+ * If camera parameter is valid, create new CameraActor.
+ * Camera parameter decide at initialized time and
+ * didn't apply model node's current position (like Animation).
+ *
+ * @SINCE_2_2.15
+ * @param[in] index Index of camera to be used for generation camera.
+ * @return Generated CameraActor by the index, or empty Handle if generation failed.
+ * @note This method should be called after Model load finished.
+ */
+ Dali::CameraActor GenerateCamera(uint32_t index) const;
+
+ /**
+ * @brief Apply camera parameters at the index to inputed camera actor.
+ * If camera parameter is valid and camera actor is not empty, apply parameters.
+ * It will change camera's transform and near / far / fov or orthographic size / aspect ratio (if defined)
+ * Camera parameter decide at initialized time and
+ * didn't apply model node's current position (like Animation).
+ *
+ * @SINCE_2_2.15
+ * @param[in] index Index of camera to be used for generation camera.
+ * @param[in,out] camera Index of camera to be used for generation camera.
+ * @return True if apply successed. False otherwise.
+ * @note This method should be called after Model load finished.
+ */
+ bool ApplyCamera(uint32_t index, Dali::CameraActor camera) const;
+
public: // Not intended for application developers
/// @cond internal
/**
/*
- * 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.
* limitations under the License.
*
*/
-#include "dali-scene3d/public-api/loader/camera-parameters.h"
-#include "dali-scene3d/public-api/loader/utils.h"
-#include "dali/devel-api/actors/camera-actor-devel.h"
-#include "dali/integration-api/debug.h"
-#include "dali/public-api/actors/camera-actor.h"
-#include "dali/public-api/math/quaternion.h"
+
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/camera-parameters.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/actors/camera-actor-devel.h>
+#include <dali/integration-api/debug.h>
+#include <dali/public-api/actors/camera-actor.h>
+#include <dali/public-api/math/quaternion.h>
+
+// INTERNAL INCLUDES
+#include <dali-scene3d/internal/loader/gltf2-asset.h> // for gltf2::UNDEFINED_FLOAT_VALUE
+#include <dali-scene3d/public-api/loader/utils.h>
namespace Dali
{
ViewProjection CameraParameters::GetViewProjection() const
{
ViewProjection viewProjection;
+
// The projection matrix.
if(isPerspective)
{
Perspective(viewProjection.GetProjection(),
- Radian(Degree(yFov)),
+ Radian(yFovDegree),
1.f,
zNear,
zFar,
orientation *= viewQuaternion;
}
-void CameraParameters::ConfigureCamera(CameraActor& camera) const
+bool CameraParameters::ConfigureCamera(CameraActor& camera, bool invertY) const
{
- SetActorCentered(camera);
-
if(isPerspective)
{
+ if(Dali::Equals(zNear, gltf2::UNDEFINED_FLOAT_VALUE) ||
+ Dali::Equals(yFovDegree.degree, gltf2::UNDEFINED_FLOAT_VALUE))
+ {
+ return false;
+ }
+
camera.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION);
camera.SetNearClippingPlane(zNear);
- camera.SetFarClippingPlane(zFar);
- camera.SetFieldOfView(Radian(Degree(yFov)));
+ camera.SetFieldOfView(Radian(yFovDegree));
+
+ if(!Dali::Equals(zFar, gltf2::UNDEFINED_FLOAT_VALUE))
+ {
+ camera.SetFarClippingPlane(zFar);
+ }
+ else
+ {
+ // TODO : Infinite perspective projection didn't support yet. Just set big enough value now
+ camera.SetFarClippingPlane(1000.0f);
+ }
+
+ if(!Dali::Equals(aspectRatio, gltf2::UNDEFINED_FLOAT_VALUE))
+ {
+ // TODO: By gltf 2.0 spec, we should not 'crop' and 'non-uniform scaling' by viewport.
+ // If we skip to setup this value, 'non-uniform scaling' problem fixed.
+ // But we need to resolve 'crop' case in future.
+ //camera.SetAspectRatio(aspectRatio);
+ }
}
else
{
+ if(Dali::Equals(zNear, gltf2::UNDEFINED_FLOAT_VALUE) ||
+ Dali::Equals(zFar, gltf2::UNDEFINED_FLOAT_VALUE) ||
+ Dali::Equals(orthographicSize, gltf2::UNDEFINED_FLOAT_VALUE))
+ {
+ return false;
+ }
+
camera.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION);
camera.SetNearClippingPlane(zNear);
camera.SetFarClippingPlane(zFar);
- camera.SetAspectRatio(aspectRatio);
camera.SetProperty(Dali::DevelCameraActor::Property::ORTHOGRAPHIC_SIZE, orthographicSize);
+
+ if(!Dali::Equals(aspectRatio, gltf2::UNDEFINED_FLOAT_VALUE))
+ {
+ // TODO: By gltf 2.0 spec, we should not 'crop' and 'non-uniform scaling' by viewport.
+ // If we skip to setup this value, 'non-uniform scaling' problem fixed.
+ // But we need to resolve 'crop' case in future.
+ //camera.SetAspectRatio(aspectRatio);
+ }
}
+ SetActorCentered(camera);
+
// model
Vector3 camTranslation;
Vector3 camScale;
Quaternion camOrientation;
CalculateTransformComponents(camTranslation, camOrientation, camScale);
- camera.SetInvertYAxis(true);
+ camera.SetInvertYAxis(invertY);
camera.SetProperty(Actor::Property::POSITION, camTranslation);
camera.SetProperty(Actor::Property::ORIENTATION, camOrientation);
camera.SetProperty(Actor::Property::SCALE, camScale);
+
+ return true;
}
} // namespace Loader
#ifndef DALI_SCENE3D_LOADER_CAMERA_PARAMETERS_H
#define DALI_SCENE3D_LOADER_CAMERA_PARAMETERS_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.
*/
// INTERNAL INCLUDES
-#include "dali-scene3d/public-api/api.h"
-#include "dali-scene3d/public-api/loader/view-projection.h"
+#include <dali-scene3d/public-api/api.h>
+#include <dali-scene3d/public-api/loader/view-projection.h>
// EXTERNAL INCLUDES
-#include "dali/public-api/math/matrix.h"
-#include "dali/public-api/math/vector3.h"
+#include <dali/public-api/math/degree.h>
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/vector3.h>
namespace Dali
{
{
struct DALI_SCENE3D_API CameraParameters
{
+ // TODO : Is these default value has is meaning?
Matrix matrix = Matrix::IDENTITY;
float orthographicSize = 1.f;
float aspectRatio = 1.f;
- float yFov = 60.f;
+ Degree yFovDegree = Degree(60.f);
float zNear = 0.1f;
float zFar = 1000.f;
bool isPerspective = true;
* @brief Configures the camera in the way that it is supposed to be used with
* scene3d scenes. This means inverted Y and a rotation of 180 degrees
* along the Y axis, plus whatever the parameters define.
+ *
+ * @return True if success to generate camera. False otherwise.
*/
- void ConfigureCamera(CameraActor& camera) const;
+ bool ConfigureCamera(CameraActor& camera, bool invertY = true) const;
};
} // namespace Loader
/*
- * 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.
namespace
{
-const char* NODES = "nodes";
-const char* SCENES = "scenes";
-const char* NODE = "node";
-const char* URI = "uri";
-const char* URL = "url";
-const char* HINTS = "hints";
+const char* NODES = "nodes";
+const char* SCENES = "scenes";
+const char* NODE = "node";
+const char* URI = "uri";
+const char* URL = "url";
+const char* HINTS = "hints";
const char* NAME("name");
const char* BLEND_SHAPE_HEADER("blendShapeHeader");
const char* BLEND_SHAPES("blendShapes");
{
auto& jsonCamera = (*i0).second;
- ReadFloat(jsonCamera.GetChild("fov"), iCamera->yFov);
+ ReadFloat(jsonCamera.GetChild("fov"), iCamera->yFovDegree.degree);
ReadFloat(jsonCamera.GetChild("near"), iCamera->zNear);
ReadFloat(jsonCamera.GetChild("far"), iCamera->zFar);
if(ReadVector(jsonCamera.GetChild("orthographic"), dummyFloatArray, 4u))
Dali::Mutex gInitializeMutex;
Dali::Mutex gReadMutex;
-const char* POSITION_PROPERTY("position");
-const char* ORIENTATION_PROPERTY("orientation");
-const char* SCALE_PROPERTY("scale");
-const char* BLEND_SHAPE_WEIGHTS_UNIFORM("uBlendShapeWeight");
-const char* MRENDERER_MODEL_IDENTIFICATION("M-Renderer");
-const char* ROOT_NODE_NAME("RootNode");
-const Vector3 SCALE_TO_ADJUST(100.0f, 100.0f, 100.0f);
+const char* POSITION_PROPERTY("position");
+const char* ORIENTATION_PROPERTY("orientation");
+const char* SCALE_PROPERTY("scale");
+const char* BLEND_SHAPE_WEIGHTS_UNIFORM("uBlendShapeWeight");
+const char* MRENDERER_MODEL_IDENTIFICATION("M-Renderer");
+const char* ROOT_NODE_NAME("RootNode");
+const Vector3 SCALE_TO_ADJUST(100.0f, 100.0f, 100.0f);
const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{
Geometry::POINTS,
const auto CAMERA_ORTHOGRAPHIC_READER = std::move(js::Reader<gt::Camera::Orthographic>()
.Register(*js::MakeProperty("xmag", js::Read::Number<float>, >::Camera::Orthographic::mXMag))
- .Register(*js::MakeProperty("ymag", js::Read::Number<float>, >::Camera::Orthographic::mXMag))
+ .Register(*js::MakeProperty("ymag", js::Read::Number<float>, >::Camera::Orthographic::mYMag))
.Register(*js::MakeProperty("zfar", js::Read::Number<float>, >::Camera::Orthographic::mZFar))
.Register(*js::MakeProperty("znear", js::Read::Number<float>, >::Camera::Orthographic::mZNear)));
matDef.mEmissiveFactor = material.mEmissiveFactor;
}
- if(material.mMaterialExtensions.mMaterialIor.mIor < MAXFLOAT)
+ if(!Dali::Equals(material.mMaterialExtensions.mMaterialIor.mIor, gltf2::UNDEFINED_FLOAT_VALUE))
{
float ior = material.mMaterialExtensions.mMaterialIor.mIor;
matDef.mDielectricSpecular = powf((ior - 1.0f) / (ior + 1.0f), 2.0f);
if(camParams.isPerspective)
{
auto& perspective = camera.mPerspective;
- camParams.yFov = Degree(Radian(perspective.mYFov)).degree;
- camParams.zNear = perspective.mZNear;
- camParams.zFar = perspective.mZFar;
+ if(!Dali::Equals(perspective.mYFov, gltf2::UNDEFINED_FLOAT_VALUE))
+ {
+ camParams.yFovDegree = Degree(Radian(perspective.mYFov));
+ }
+ else
+ {
+ camParams.yFovDegree = Degree(gltf2::UNDEFINED_FLOAT_VALUE);
+ }
+ camParams.zNear = perspective.mZNear;
+ camParams.zFar = perspective.mZFar;
// TODO: yes, we seem to ignore aspectRatio in CameraParameters.
}
else
{
- auto& ortho = camera.mOrthographic;
- camParams.orthographicSize = ortho.mYMag * .5f;
- camParams.aspectRatio = ortho.mXMag / ortho.mYMag;
- camParams.zNear = ortho.mZNear;
- camParams.zFar = ortho.mZFar;
+ auto& ortho = camera.mOrthographic;
+ if(!Dali::Equals(ortho.mYMag, gltf2::UNDEFINED_FLOAT_VALUE) && !Dali::Equals(ortho.mXMag, gltf2::UNDEFINED_FLOAT_VALUE))
+ {
+ camParams.orthographicSize = ortho.mYMag * .5f;
+ camParams.aspectRatio = ortho.mXMag / ortho.mYMag;
+ }
+ else
+ {
+ camParams.orthographicSize = gltf2::UNDEFINED_FLOAT_VALUE;
+ camParams.aspectRatio = gltf2::UNDEFINED_FLOAT_VALUE;
+ }
+ camParams.zNear = ortho.mZNear;
+ camParams.zFar = ortho.mZFar;
}
}
{
const unsigned int TOOLKIT_MAJOR_VERSION = 2;
const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 14;
+const unsigned int TOOLKIT_MICRO_VERSION = 15;
const char* const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali2-toolkit
Summary: Dali 3D engine Toolkit
-Version: 2.2.14
+Version: 2.2.15
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT