/*
- * Copyright (c) 2020 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.
// Enable debug log for test coverage
#define DEBUG_ENABLED 1
-#include "dali-scene3d/internal/loader/gltf2-asset.h"
#include <dali-test-suite-utils.h>
#include <string>
+#include "dali-scene3d/internal/loader/gltf2-asset.h"
using namespace Dali;
using namespace Dali::Scene3D::Loader;
}
#define FROM_STRING_HELPER(x) FromString(#x, strlen(#x))
+#define TARGET_FROM_STRING_HELPER(x) TargetFromString(#x, strlen(#x))
+#define HASH_FROM_STRING_HELPER(x) HashFromString(#x, strlen(#x))
-#define STRING_CHECK(type, x) DALI_TEST_EQUAL(gltf2::type:: FROM_STRING_HELPER(x), gltf2::type::x)
+#define STRING_CHECK(type, x) DALI_TEST_EQUAL(gltf2::type::FROM_STRING_HELPER(x), gltf2::type::x)
+#define TARGET_STRING_CHECK(type, x) DALI_TEST_EQUAL(gltf2::type::TARGET_FROM_STRING_HELPER(x), gltf2::type::x)
+#define HASH_STRING_CHECK(type, x, y, z) DALI_TEST_EQUAL(gltf2::type::HASH_FROM_STRING_HELPER(x), gltf2::type::ToHash(gltf2::type::y, true, z))
int UtcDaliGltf2AssetAccessorType(void)
{
int UtcDaliGltf2AssetAttribute(void)
{
- STRING_CHECK(Attribute, POSITION);
- STRING_CHECK(Attribute, NORMAL);
- STRING_CHECK(Attribute, TANGENT);
- STRING_CHECK(Attribute, TEXCOORD_0);
- STRING_CHECK(Attribute, TEXCOORD_1);
- STRING_CHECK(Attribute, COLOR_0);
- STRING_CHECK(Attribute, JOINTS_0);
- STRING_CHECK(Attribute, WEIGHTS_0);
- DALI_TEST_EQUAL(gltf2::Attribute::FROM_STRING_HELPER(VISCOSITY), gltf2::Attribute::INVALID);
+ TARGET_STRING_CHECK(Attribute, POSITION);
+ TARGET_STRING_CHECK(Attribute, NORMAL);
+ TARGET_STRING_CHECK(Attribute, TANGENT);
+ HASH_STRING_CHECK(Attribute, TEXCOORD_0, TEXCOORD_N, 0);
+ HASH_STRING_CHECK(Attribute, TEXCOORD_1, TEXCOORD_N, 1);
+ HASH_STRING_CHECK(Attribute, COLOR_0, COLOR_N, 0);
+ HASH_STRING_CHECK(Attribute, COLOR_1, COLOR_N, 1);
+ HASH_STRING_CHECK(Attribute, JOINTS_0, JOINTS_N, 0);
+ HASH_STRING_CHECK(Attribute, JOINTS_1, JOINTS_N, 1);
+ HASH_STRING_CHECK(Attribute, JOINTS_2, JOINTS_N, 2);
+ HASH_STRING_CHECK(Attribute, WEIGHTS_0, WEIGHTS_N, 0);
+ HASH_STRING_CHECK(Attribute, WEIGHTS_1, WEIGHTS_N, 1);
+ HASH_STRING_CHECK(Attribute, WEIGHTS_2, WEIGHTS_N, 2);
+ DALI_TEST_EQUAL(gltf2::Attribute::TARGET_FROM_STRING_HELPER(VISCOSITY), gltf2::Attribute::INVALID);
END_TEST;
}
std::vector<gltf2::BufferView> bufferViews;
- gltf2::Accessor::Sparse sparse{ 256u };
- sparse.mIndices.mBufferView = gltf2::Ref<gltf2::BufferView>(bufferViews, 5u);
+ gltf2::Accessor::Sparse sparse{256u};
+ sparse.mIndices.mBufferView = gltf2::Ref<gltf2::BufferView>(bufferViews, 5u);
sparse.mIndices.mComponentType = gltf2::Component::FLOAT;
- sparse.mValues.mBufferView = gltf2::Ref<gltf2::BufferView>(bufferViews, 284u);
- sparse.mValues.mByteOffset = 16532;
+ sparse.mValues.mBufferView = gltf2::Ref<gltf2::BufferView>(bufferViews, 284u);
+ sparse.mValues.mByteOffset = 16532;
acc.SetSparse(sparse);
DALI_TEST_EQUAL(acc.mSparse->mCount, sparse.mCount);
END_TEST;
}
-
using Blob = MeshDefinition::Blob;
using Accessor = MeshDefinition::Accessor;
- const MeshDefinition meshGroundTruth[]{
+ MeshDefinition meshGroundTruth[]{
{
nullptr,
0,
Accessor{Blob{0, 0}, {}},
Accessor{Blob{0, 0}, {}},
Accessor{Blob{0, 0}, {}},
- Accessor{Blob{0, 0}, {}},
- Accessor{Blob{0, 0}, {}},
},
{
nullptr,
Accessor{Blob{0, 0}, {}},
Accessor{Blob{0, 0}, {}},
Accessor{Blob{0, 0}, {}},
- Accessor{Blob{0, 0}, {}},
- Accessor{Blob{0, 0}, {}},
},
};
+ meshGroundTruth[0].mColors.push_back(Accessor{Blob{0, 0}, {}});
+ meshGroundTruth[0].mTexCoords.push_back(Accessor{Blob{0, 0}, {}});
+ meshGroundTruth[1].mColors.push_back(Accessor{Blob{0, 0}, {}});
+ meshGroundTruth[1].mTexCoords.push_back(Accessor{Blob{0, 0}, {}});
auto iMesh = meshes.begin();
for(auto& m : meshGroundTruth)
auto& md = iMesh->first;
DALI_TEST_EQUAL(md.mFlags, m.mFlags);
DALI_TEST_EQUAL(md.mPrimitiveType, m.mPrimitiveType);
- for(auto mp : {
- &MeshDefinition::mIndices,
- &MeshDefinition::mPositions,
- &MeshDefinition::mNormals,
- &MeshDefinition::mTexCoords,
- &MeshDefinition::mColors,
- &MeshDefinition::mTangents,
- &MeshDefinition::mJoints0,
- &MeshDefinition::mWeights0})
- {
- DALI_TEST_EQUAL((md.*mp).IsDefined(), (m.*mp).IsDefined());
- DALI_TEST_EQUAL((md.*mp).mBlob.IsDefined(), (m.*mp).mBlob.IsDefined());
- }
+
+ DALI_TEST_EQUAL((md.mIndices).IsDefined(), (m.mIndices).IsDefined());
+ DALI_TEST_EQUAL((md.mIndices).mBlob.IsDefined(), (m.mIndices).mBlob.IsDefined());
+
+ DALI_TEST_EQUAL((md.mPositions).IsDefined(), (m.mPositions).IsDefined());
+ DALI_TEST_EQUAL((md.mPositions).mBlob.IsDefined(), (m.mPositions).mBlob.IsDefined());
+
+ DALI_TEST_EQUAL((md.mNormals).IsDefined(), (m.mNormals).IsDefined());
+ DALI_TEST_EQUAL((md.mNormals).mBlob.IsDefined(), (m.mNormals).mBlob.IsDefined());
+
+ DALI_TEST_EQUAL((md.mTangents).IsDefined(), (m.mTangents).IsDefined());
+ DALI_TEST_EQUAL((md.mTangents).mBlob.IsDefined(), (m.mTangents).mBlob.IsDefined());
+
+ DALI_TEST_EQUAL(md.mTexCoords.empty(), m.mTexCoords.empty());
+ DALI_TEST_EQUAL(md.mColors.empty(), m.mColors.empty());
+
+ DALI_TEST_EQUAL(md.mJoints.empty(), (m.mJoints.empty()));
+ DALI_TEST_EQUAL(md.mWeights.empty(), (m.mWeights.empty()));
DALI_TEST_EQUAL(md.mBlendShapeHeader.IsDefined(), m.mBlendShapeHeader.IsDefined());
DALI_TEST_EQUAL(0u, md.mTangents.mBlob.mMin.size());
DALI_TEST_EQUAL(0u, md.mTangents.mBlob.mMax.size());
- DALI_TEST_EQUAL(true, md.mTexCoords.IsDefined());
- DALI_TEST_EQUAL(false, md.mTexCoords.mNormalized);
- DALI_TEST_EQUAL(sizeof(uint16_t) * 2, md.mTexCoords.mBlob.mElementSizeHint);
- DALI_TEST_EQUAL(true, md.mTexCoords.mBlob.IsDefined());
- DALI_TEST_EQUAL(1624, md.mTexCoords.mBlob.mLength);
- DALI_TEST_EQUAL(0u, md.mTexCoords.mBlob.mMin.size());
- DALI_TEST_EQUAL(0u, md.mTexCoords.mBlob.mMax.size());
+ DALI_TEST_EQUAL(false, md.mTexCoords.empty());
+ DALI_TEST_EQUAL(true, md.mTexCoords[0].IsDefined());
+ DALI_TEST_EQUAL(false, md.mTexCoords[0].mNormalized);
+ DALI_TEST_EQUAL(sizeof(uint16_t) * 2, md.mTexCoords[0].mBlob.mElementSizeHint);
+ DALI_TEST_EQUAL(true, md.mTexCoords[0].mBlob.IsDefined());
+ DALI_TEST_EQUAL(1624, md.mTexCoords[0].mBlob.mLength);
+ DALI_TEST_EQUAL(0u, md.mTexCoords[0].mBlob.mMin.size());
+ DALI_TEST_EQUAL(0u, md.mTexCoords[0].mBlob.mMax.size());
END_TEST;
}
/*
- * 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 <vector>
-#include <dali-scene3d/public-api/loader/mesh-definition.h>
#include <dali-scene3d/public-api/loader/buffer-definition.h>
+#include <dali-scene3d/public-api/loader/mesh-definition.h>
#include <dali-test-suite-utils.h>
using namespace Dali;
{
using Container = std::vector<float>;
- Container buffer = { 4.0f, 6.0f, 8.0f, 10.0f, 12.0f };
- Container minValues = { 5.0f };
- Container maxValues = { 10.0f };
- Container result = {5.0f, 6.0f, 8.0f, 10.0f, 10.0f};
+ Container buffer = {4.0f, 6.0f, 8.0f, 10.0f, 12.0f};
+ Container minValues = {5.0f};
+ Container maxValues = {10.0f};
+ Container result = {5.0f, 6.0f, 8.0f, 10.0f, 10.0f};
MeshDefinition::Blob::ApplyMinMax(minValues, maxValues, 5, buffer.data());
- for( auto i = 0u; i < result.size(); ++i)
+ for(auto i = 0u; i < result.size(); ++i)
{
DALI_TEST_EQUALS(buffer[i], result[i], TEST_LOCATION);
}
{
using Container = std::vector<float>;
- Container buffer = { 4.0f, 6.0f, 8.0f, 10.0f, 12.0f };
- Container minValues = { 5.0f };
+ Container buffer = {4.0f, 6.0f, 8.0f, 10.0f, 12.0f};
+ Container minValues = {5.0f};
Container maxValues = {};
- Container result = {5.0f, 6.0f, 8.0f, 10.0f, 12.0f};
+ Container result = {5.0f, 6.0f, 8.0f, 10.0f, 12.0f};
MeshDefinition::Blob::ApplyMinMax(minValues, maxValues, 5, buffer.data());
- for( auto i = 0u; i < result.size(); ++i)
+ for(auto i = 0u; i < result.size(); ++i)
{
DALI_TEST_EQUALS(buffer[i], result[i], TEST_LOCATION);
}
{
using Container = std::vector<float>;
- Container buffer = { 4.0f, 6.0f, 8.0f, 10.0f, 12.0f };
- Container minValues = { };
- Container maxValues = { 10.0f };
- Container result = {4.0f, 6.0f, 8.0f, 10.0f, 10.0f};
+ Container buffer = {4.0f, 6.0f, 8.0f, 10.0f, 12.0f};
+ Container minValues = {};
+ Container maxValues = {10.0f};
+ Container result = {4.0f, 6.0f, 8.0f, 10.0f, 10.0f};
MeshDefinition::Blob::ApplyMinMax(minValues, maxValues, 5, buffer.data());
- for( auto i = 0u; i < result.size(); ++i)
+ for(auto i = 0u; i < result.size(); ++i)
{
DALI_TEST_EQUALS(buffer[i], result[i], TEST_LOCATION);
}
{
using Container = std::vector<float>;
- Container buffer = { 4.0f, 6.0f, 8.0f, 10.0f, 12.0f };
+ Container buffer = {4.0f, 6.0f, 8.0f, 10.0f, 12.0f};
Container minValues;
Container maxValues;
Container result = {4.0f, 6.0f, 8.0f, 10.0f, 12.0f};
MeshDefinition::Blob::ApplyMinMax(minValues, maxValues, 5, buffer.data());
- for( auto i = 0u; i < result.size(); ++i)
+ for(auto i = 0u; i < result.size(); ++i)
{
DALI_TEST_EQUALS(buffer[i], result[i], TEST_LOCATION);
}
meshDefinition.mPositions =
MeshDefinition::Accessor{
std::move(MeshDefinition::Blob{0, 12, 0, (uint16_t)12, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0};
- meshDefinition.mJoints0 =
+ meshDefinition.mJoints.push_back(
MeshDefinition::Accessor{
- std::move(MeshDefinition::Blob{0, 16, 0, (uint16_t)16, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0};
- meshDefinition.mWeights0 =
+ std::move(MeshDefinition::Blob{0, 16, 0, (uint16_t)16, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0});
+ meshDefinition.mWeights.push_back(
MeshDefinition::Accessor{
- std::move(MeshDefinition::Blob{0, 8, 0, (uint16_t)8, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0};
+ std::move(MeshDefinition::Blob{0, 8, 0, (uint16_t)8, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0});
MeshDefinition::RawData rawData = meshDefinition.LoadRaw("", buffers);
DALI_TEST_EQUALS(rawData.mAttribs.size(), 4, TEST_LOCATION);
- DALI_TEST_EQUALS(rawData.mAttribs[3].mName, "aWeights", TEST_LOCATION);
+ DALI_TEST_EQUALS(rawData.mAttribs[3].mName, "aWeights0", TEST_LOCATION);
DALI_TEST_EQUALS(rawData.mAttribs[3].mNumElements, 2, TEST_LOCATION);
float* value = reinterpret_cast<float*>(rawData.mAttribs[3].mData.data());
for(uint32_t i = 0; i < rawData.mAttribs[3].mNumElements * 4; ++i)
int UtcDaliMeshDefinitionShortSkinWeight(void)
{
- float data8[8] = {0.062516, 0.098634, 0.749752, 0.936492, 0.741207, 0.379873, 0.392386, 0.380468};
+ float data8[8] = {0.062516, 0.098634, 0.749752, 0.936492, 0.741207, 0.379873, 0.392386, 0.380468};
BufferDefinition bufferDefinition;
bufferDefinition.mUri = "data:application/base64,ARBAGe+/ve+/vT9hc2RmYXNkZmFzZGZhc2RmYXNkZmE=";
meshDefinition.mPositions =
MeshDefinition::Accessor{
std::move(MeshDefinition::Blob{0, 12, 0, (uint16_t)12, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0};
- meshDefinition.mJoints0 =
+ meshDefinition.mJoints.push_back(
MeshDefinition::Accessor{
- std::move(MeshDefinition::Blob{0, 16, 0, (uint16_t)16, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0};
- meshDefinition.mWeights0 =
+ std::move(MeshDefinition::Blob{0, 16, 0, (uint16_t)16, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0});
+ meshDefinition.mWeights.push_back(
MeshDefinition::Accessor{
- std::move(MeshDefinition::Blob{0, 16, 0, (uint16_t)16, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0};
+ std::move(MeshDefinition::Blob{0, 16, 0, (uint16_t)16, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0});
MeshDefinition::RawData rawData = meshDefinition.LoadRaw("", buffers);
DALI_TEST_EQUALS(rawData.mAttribs.size(), 4, TEST_LOCATION);
- DALI_TEST_EQUALS(rawData.mAttribs[3].mName, "aWeights", TEST_LOCATION);
+ DALI_TEST_EQUALS(rawData.mAttribs[3].mName, "aWeights0", TEST_LOCATION);
DALI_TEST_EQUALS(rawData.mAttribs[3].mNumElements, 2, TEST_LOCATION);
float* value = reinterpret_cast<float*>(rawData.mAttribs[3].mData.data());
for(uint32_t i = 0; i < rawData.mAttribs[3].mNumElements * 4; ++i)
/*
- * 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.
Permutation permutations[]{
{
+ //0
[](ShaderParameters& p) {},
{},
RendererState::DEPTH_TEST | RendererState::CULL_BACK,
},
{
- [](ShaderParameters& p)
- {
+ //1
+ [](ShaderParameters& p) {
p.materialDefinition.mFlags |= MaterialDefinition::TRANSPARENCY;
},
{ShaderOption::Type::THREE_TEXTURE},
RendererState::ALPHA_BLEND,
},
- {[](ShaderParameters& p)
- {
+ {//2
+ [](ShaderParameters& p) {
p.materialDefinition.mFlags |= MaterialDefinition::ALBEDO;
p.materialDefinition.mTextureStages.push_back({MaterialDefinition::ALBEDO, {}});
},
{ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::BASE_COLOR_TEXTURE}},
- {[](ShaderParameters& p)
- {
+ {//3
+ [](ShaderParameters& p) {
p.materialDefinition.mTextureStages.push_back({MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {}});
},
{ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE}},
- {[](ShaderParameters& p)
- {
+ {//4
+ [](ShaderParameters& p) {
p.materialDefinition.mFlags |= MaterialDefinition::NORMAL;
p.materialDefinition.mTextureStages.push_back({MaterialDefinition::NORMAL, {}});
},
{ShaderOption::Type::THREE_TEXTURE, ShaderOption::Type::NORMAL_TEXTURE}},
- {[](ShaderParameters& p)
- {
+ {//5
+ [](ShaderParameters& p) {
p.materialDefinition.mFlags |= MaterialDefinition::SUBSURFACE;
},
{ShaderOption::Type::SUBSURFACE}},
- {[](ShaderParameters& p)
- {
+ {//6
+ [](ShaderParameters& p) {
p.materialDefinition.SetAlphaCutoff(.5f);
},
{ShaderOption::Type::ALPHA_TEST}},
- {[](ShaderParameters& p)
- {
+ {//7
+ [](ShaderParameters& p) {
p.materialDefinition.SetAlphaCutoff(1.f);
},
{ShaderOption::Type::ALPHA_TEST}},
- {[](ShaderParameters& p)
- {
+ {//8
+ [](ShaderParameters& p) {
p.materialDefinition.mFlags |= MaterialDefinition::GLTF_CHANNELS;
},
{ShaderOption::Type::GLTF_CHANNELS}},
- {[](ShaderParameters& p)
- {
- p.meshDefinition.mJoints0.mBlob.mOffset = 0;
- p.meshDefinition.mWeights0.mBlob.mOffset = 0;
+ {//9
+ [](ShaderParameters& p) {
+ p.meshDefinition.mJoints[0].mBlob.mOffset = 0;
+ p.meshDefinition.mWeights[0].mBlob.mOffset = 0;
},
{ShaderOption::Type::SKINNING}},
- {[](ShaderParameters& p)
- {
+ {//10
+ [](ShaderParameters& p) {
p.meshDefinition.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL;
},
{ShaderOption::Type::FLIP_UVS_VERTICAL}},
{
- [](ShaderParameters& p)
- {
+ //11
+ [](ShaderParameters& p) {
p.meshDefinition.mBlendShapes.push_back({});
},
},
- {[](ShaderParameters& p)
- {
+ {//12
+ [](ShaderParameters& p) {
p.meshDefinition.mBlendShapes.back().deltas.mBlob.mOffset = 0;
},
{ShaderOption::Type::MORPH_POSITION}},
- {[](ShaderParameters& p)
- {
+ {//13
+ [](ShaderParameters& p) {
p.meshDefinition.mBlendShapes.back().normals.mBlob.mOffset = 0;
},
{ShaderOption::Type::MORPH_NORMAL}},
- {[](ShaderParameters& p)
- {
+ {//14
+ [](ShaderParameters& p) {
p.meshDefinition.mBlendShapes.back().tangents.mBlob.mOffset = 0;
},
{ShaderOption::Type::MORPH_TANGENT}},
- {[](ShaderParameters& p)
- {
+ {//15
+ [](ShaderParameters& p) {
auto& blendShapes = p.meshDefinition.mBlendShapes;
DALI_ASSERT_ALWAYS(!blendShapes.empty() &&
(blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID ||
},
{ShaderOption::Type::MORPH_VERSION_2_0}},
- {[](ShaderParameters& p)
- {
+ {//16
+ [](ShaderParameters& p) {
p.materialDefinition.mFlags |= MaterialDefinition::OCCLUSION;
},
{ShaderOption::Type::OCCLUSION}},
- {[](ShaderParameters& p)
- {
- p.meshDefinition.mColors.mBlob.mOffset = 0;
+ {//17
+ [](ShaderParameters& p) {
+ p.meshDefinition.mColors[0].mBlob.mOffset = 0;
},
{ShaderOption::Type::COLOR_ATTRIBUTE}},
- {[](ShaderParameters& p)
- {
+ {//18
+ [](ShaderParameters& p) {
p.meshDefinition.mTangentType = Property::VECTOR4;
},
{ShaderOption::Type::VEC4_TANGENT}},
MeshDefinition meshDefinition;
MaterialDefinition materialDefinition;
ShaderParameters shaderParameter{meshDefinition, materialDefinition, nodeDefinition};
-
+ // Only define skinning accessors for skinning test...
+ if(permutationSet.permutations.size() > 1)
+ {
+ auto& checkP = permutationSet.permutations[1];
+ if(auto search = checkP->options.find(ShaderOption::Type::SKINNING);
+ search != checkP->options.end())
+ {
+ meshDefinition.mJoints.push_back(MeshDefinition::Accessor{MeshDefinition::Blob{0, 0}, {}});
+ meshDefinition.mWeights.push_back(MeshDefinition::Accessor{MeshDefinition::Blob{0, 0}, {}});
+ }
+ }
std::set<std::string> defines;
- ShaderOption option;
+ ShaderOption option1;
RendererState::Type rendererState = 0;
for(auto permutation : permutationSet.permutations)
{
permutation->configureFn(shaderParameter);
if(materialDefinition.mFlags & MaterialDefinition::TRANSPARENCY)
{
- option.SetTransparency();
+ option1.SetTransparency();
}
for(auto&& optionType : permutation->options)
{
- option.AddOption(optionType);
+ option1.AddOption(optionType);
}
rendererState = (rendererState | permutation->rendererStateSet) & ~permutation->rendererStateClear;
}
- option.AddOption(ShaderOption::Type::THREE_TEXTURE);
+ option1.AddOption(ShaderOption::Type::THREE_TEXTURE);
- Shader shaderFromMeshAndMaterial = shaderManager.ProduceShader(materialDefinition, meshDefinition);
- Shader shaderFromOption = shaderManager.ProduceShader(option);
- DALI_TEST_EQUAL(shaderFromMeshAndMaterial, shaderFromOption);
+ ShaderOption option2 = shaderManager.ProduceShaderOption(materialDefinition, meshDefinition);
+
+ Shader shaderFromOption1 = shaderManager.ProduceShader(option1);
+ Shader shaderFromOption2 = shaderManager.ProduceShader(option2);
+ DALI_TEST_EQUAL(option1.GetOptionHash(), option2.GetOptionHash());
+ DALI_TEST_EQUAL(shaderFromOption1, shaderFromOption2);
RendererState::Type rendererStateFromMaterialDefinition = shaderManager.GetRendererState(materialDefinition);
DALI_TEST_EQUAL(rendererStateFromMaterialDefinition, rendererState);
DALI_TEST_EQUALS(shader1.GetProperty<int>(shader1.GetPropertyIndex("uLightCount")), 1, TEST_LOCATION);
DALI_TEST_EQUALS(shader2.GetProperty<int>(shader2.GetPropertyIndex("uLightCount")), 1, TEST_LOCATION);
-
+
ShaderOption option3;
option3.AddOption(ShaderOption::Type::METALLIC_ROUGHNESS_TEXTURE);
Dali::Shader shader3 = shaderManager.ProduceShader(option3);
#include <dali-scene3d/public-api/loader/environment-definition.h>
#include <dali/integration-api/debug.h>
+#include <dali/public-api/object/property-array.h>
+#include <dali/public-api/object/property-map.h>
+
+#include <filesystem>
+namespace fs = std::filesystem;
namespace Dali
{
{
namespace
{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_SCENE3D_MODEL_PRIMITIVE");
+
+#define DALI_LOG_WRITE_FILE(filename, stream) \
+ { \
+ fs::path tmp = fs::temp_directory_path(); \
+ tmp /= filename; \
+ std::ofstream ostrm(tmp, std::ios::out); \
+ ostrm << stream; \
+ ostrm.flush(); \
+ }
+
+inline Property::Map GetMap(Shader shader)
+{
+ Property::Value program = shader[Shader::Property::PROGRAM];
+ Property::Map* map{nullptr};
+ if(program.GetType() == Property::ARRAY)
+ {
+ Property::Array* array = program.GetArray();
+ if(array)
+ {
+ Property::Value& value = array->GetElementAt(0);
+ if(value.GetType() == Property::MAP)
+ {
+ map = value.GetMap();
+ }
+ }
+ }
+ else if(program.GetType() == Property::MAP)
+ {
+ map = program.GetMap();
+ }
+ if(map)
+ {
+ return *map;
+ }
+ return Property::Map();
+}
+
+#endif
/**
* Creates control through type registry
*/
mBlendShapeVersion = version;
}
-void ModelPrimitive::SetSkinned(bool isSkinned)
+void ModelPrimitive::SetSkinned(bool isSkinned, uint32_t numberOfJointSets)
{
- mHasSkinning = isSkinned;
+ mHasSkinning = isSkinned;
+ mNumberOfJointSets = numberOfJointSets;
}
// From MaterialModifyObserver
if(mHasSkinning)
{
shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::SKINNING);
+ shaderOption.AddJointMacros(mNumberOfJointSets);
}
if(mHasPositions || mHasNormals || mHasTangents)
{
}
}
- mShader.Reset();
- mShader = mShaderManager->ProduceShader(shaderOption);
+ Shader newShader = mShaderManager->ProduceShader(shaderOption);
+ if(mShader != newShader)
+ {
+ DALI_LOG_INFO(gLogFilter, Debug::General, "Warning! Model primitive shader changed\n");
+#if defined(DEBUG_ENABLED)
+ if(mShader)
+ {
+ Property::Map oldMap = GetMap(mShader);
+ DALI_LOG_WRITE_FILE("oldShader.txt", "Vertex Shader:\n"
+ << oldMap["vertex"] << "\n\nFragmentShader: " << oldMap["fragment"] << "\n");
+ }
+ if(newShader)
+ {
+ Property::Map newMap = GetMap(newShader);
+ DALI_LOG_WRITE_FILE("newShader.txt", "Vertex Shader:\n"
+ << newMap["vertex"] << "\n\nFragmentShader: " << newMap["fragment"] << "\n");
+ }
+#endif
+ }
+ mShader = newShader;
if(!mRenderer)
{
* @brief Sets whether or not this model primitive is skinned.
*
* @param[in] isSkinned Whether or not this model primitive is skinned.
+ * @param[in] numberOfJointSets How many joint sets the mesh expects in the shader
*/
- void SetSkinned(bool isSkinned);
+ void SetSkinned(bool isSkinned, uint32_t numberOfJointSets);
private: // From MaterialModifyObserver
/**
private:
// Delete copy & move operator
- ModelPrimitive(const ModelPrimitive&) = delete;
- ModelPrimitive(ModelPrimitive&&) = delete;
- ModelPrimitive& operator=(const ModelPrimitive& rhs) = delete;
+ ModelPrimitive(const ModelPrimitive&) = delete;
+ ModelPrimitive(ModelPrimitive&&) = delete;
+ ModelPrimitive& operator=(const ModelPrimitive& rhs) = delete;
ModelPrimitive& operator=(ModelPrimitive&& rhs) noexcept = delete;
private:
float mIblScaleFactor{1.0f};
uint32_t mSpecularMipmapLevels{1u};
+ // For skinning
+ uint32_t mNumberOfJointSets{0};
+
// For blend shape
Scene3D::Loader::BlendShapes::BlendShapeData mBlendShapeData;
Dali::Texture mBlendShapeGeometry;
{
return !mJoints.empty() && !mWeights.empty();
}
+uint32_t MeshDefinition::GetNumberOfJointSets() const
+{
+ return static_cast<uint32_t>(mJoints.size());
+}
bool MeshDefinition::HasBlendShapes() const
{
bool IsSkinned() const;
/**
+ * @brief Returns the number of joint sets defined by the mesh
+ */
+ uint32_t GetNumberOfJointSets() const;
+
+ /**
* @brief Whether the mesh has blend shapes.
*/
bool HasBlendShapes() const;
mesh.first.RetrieveBlendShapeComponents(hasPositions, hasNormals, hasTangents);
GetImplementation(primitive).SetBlendShapeOptions(hasPositions, hasNormals, hasTangents, mesh.first.mBlendShapeVersion);
GetImplementation(primitive).SetBlendShapeGeometry(mesh.second.blendShapeGeometry);
- GetImplementation(primitive).SetSkinned(mesh.first.IsSkinned());
+ GetImplementation(primitive).SetSkinned(mesh.first.IsSkinned(), mesh.first.GetNumberOfJointSets());
}
auto shader = renderer.GetShader();
std::sregex_token_iterator first{value.begin(), value.end(), re, -1}, last;
for(auto i = first; i != last; ++i)
{
- std::string line = std::string("\\\n") + (*i).str();
+ std::string line = std::string(" \\\n") + (*i).str();
shaderCode.insert(insertionPoint, line);
insertionPoint += line.length();
}
static constexpr uint32_t INDEX_FOR_LIGHT_CONSTRAINT_TAG = 10;
static constexpr uint32_t INDEX_FOR_SHADOW_CONSTRAINT_TAG = 100;
-static const char* ADD_EXTRA_SKINNING_ATTRIBUTES{"ADD_EXTRA_SKINNING_ATTRIBUTES"};
-static const char* ADD_EXTRA_WEIGHTS{"ADD_EXTRA_WEIGHTS"};
-
ShaderOption MakeOption(const MaterialDefinition& materialDef, const MeshDefinition& meshDef)
{
ShaderOption option;
if(meshDef.IsSkinned())
{
option.AddOption(ShaderOption::Type::SKINNING);
-
- // Add options for ADD_EXTRA_SKINNING_ATTRIBUTES and ADD_EXTRA_WEIGHTS:
- size_t numberOfSets = meshDef.mJoints.size();
- if(numberOfSets > 1)
- {
- std::ostringstream attributes;
- std::ostringstream weights;
- for(size_t i = 1; i < numberOfSets; ++i)
- {
- attributes << "in vec4 aJoints" << i << ";\n";
- attributes << "in vec4 aWeights" << i << ";\n";
-
- weights << "bone +=\n"
- << "uBone[int(aJoints" << i << ".x)] * aWeights" << i << ".x +\n"
- << "uBone[int(aJoints" << i << ".y)] * aWeights" << i << ".y +\n"
- << "uBone[int(aJoints" << i << ".z)] * aWeights" << i << ".z +\n"
- << "uBone[int(aJoints" << i << ".w)] * aWeights" << i << ".w;\n";
- }
- option.AddMacroDefinition(ADD_EXTRA_SKINNING_ATTRIBUTES, attributes.str());
- option.AddMacroDefinition(ADD_EXTRA_WEIGHTS, weights.str());
- }
+ option.AddJointMacros(meshDef.mJoints.size());
}
if(MaskMatch(meshDef.mFlags, MeshDefinition::FLIP_UVS_VERTICAL))
// EXTERNAL INCLUDES
#include <algorithm>
+#include <ostream>
+#include <sstream>
#include <string>
namespace Dali::Scene3D::Loader
"MORPH_VERSION_2_0",
};
static constexpr uint32_t NUMBER_OF_OPTIONS = sizeof(OPTION_KEYWORD) / sizeof(OPTION_KEYWORD[0]);
+static const char* ADD_EXTRA_SKINNING_ATTRIBUTES{"ADD_EXTRA_SKINNING_ATTRIBUTES"};
+static const char* ADD_EXTRA_WEIGHTS{"ADD_EXTRA_WEIGHTS"};
inline void HashString(std::uint64_t& hash, const char* string)
{
mOptionHash |= (1 << static_cast<uint32_t>(shaderOptionType));
}
+void ShaderOption::AddJointMacros(size_t numberOfJointSets)
+{
+ // Add options for ADD_EXTRA_SKINNING_ATTRIBUTES and ADD_EXTRA_WEIGHTS:
+ if(numberOfJointSets > 1)
+ {
+ std::ostringstream attributes;
+ std::ostringstream weights;
+ for(size_t i = 1; i < numberOfJointSets; ++i)
+ {
+ attributes << "in vec4 aJoints" << i << ";\n";
+ attributes << "in vec4 aWeights" << i << ";\n";
+
+ weights << "bone +=\n"
+ << "uBone[int(aJoints" << i << ".x)] * aWeights" << i << ".x +\n"
+ << "uBone[int(aJoints" << i << ".y)] * aWeights" << i << ".y +\n"
+ << "uBone[int(aJoints" << i << ".z)] * aWeights" << i << ".z +\n"
+ << "uBone[int(aJoints" << i << ".w)] * aWeights" << i << ".w;\n";
+ }
+ AddMacroDefinition(ADD_EXTRA_SKINNING_ATTRIBUTES, attributes.str());
+ AddMacroDefinition(ADD_EXTRA_WEIGHTS, weights.str());
+ }
+}
+
void ShaderOption::AddMacroDefinition(std::string macro, std::string definition)
{
auto iter = std::find_if(mMacros.begin(), mMacros.end(), [macro](ShaderOption::MacroDefinition& md) { return md.macro == macro; });
void AddOption(Type shaderOptionType);
/**
+ * Adds macro definitions for joints based on the number of joint sets.
+ */
+ void AddJointMacros(size_t numberOfJointSets);
+
+ /**
* Enables empty preprocessor definitions to be defined to a value
*/
void AddMacroDefinition(std::string macro, std::string definition);