Add macro defs to shader regen 47/300847/2
authorDavid Steele <david.steele@samsung.com>
Thu, 2 Nov 2023 18:13:02 +0000 (18:13 +0000)
committerDavid Steele <david.steele@samsung.com>
Tue, 7 Nov 2023 13:51:23 +0000 (13:51 +0000)
Change-Id: I6292beb044c8f634e5d528f465a8e16444bc58e4

13 files changed:
automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2Asset.cpp
automated-tests/src/dali-scene3d-internal/utc-Dali-Gltf2LoaderImpl.cpp
automated-tests/src/dali-scene3d/utc-Dali-MeshDefinition.cpp
automated-tests/src/dali-scene3d/utc-Dali-ShaderManager.cpp
dali-scene3d/internal/model-components/model-primitive-impl.cpp
dali-scene3d/internal/model-components/model-primitive-impl.h
dali-scene3d/public-api/loader/mesh-definition.cpp
dali-scene3d/public-api/loader/mesh-definition.h
dali-scene3d/public-api/loader/node-definition.cpp
dali-scene3d/public-api/loader/shader-definition.cpp
dali-scene3d/public-api/loader/shader-manager.cpp
dali-scene3d/public-api/loader/shader-option.cpp
dali-scene3d/public-api/loader/shader-option.h

index 9b01631..e60dfe4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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.
@@ -18,9 +18,9 @@
 // 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;
@@ -52,8 +52,12 @@ int UtcDaliGltf2AssetComponentSize(void)
 }
 
 #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)
 {
@@ -81,15 +85,20 @@ int UtcDaliGltf2AssetAlphaMode(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;
 }
@@ -122,11 +131,11 @@ int UtcDaliGltf2AssetAccessorSparse(void)
 
   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);
@@ -138,4 +147,3 @@ int UtcDaliGltf2AssetAccessorSparse(void)
 
   END_TEST;
 }
-
index 4b93f7f..30ad93f 100644 (file)
@@ -419,7 +419,7 @@ int UtcDaliGltfLoaderSuccess1(void)
 
   using Blob     = MeshDefinition::Blob;
   using Accessor = MeshDefinition::Accessor;
-  const MeshDefinition meshGroundTruth[]{
+  MeshDefinition meshGroundTruth[]{
     {
       nullptr,
       0,
@@ -429,8 +429,6 @@ int UtcDaliGltfLoaderSuccess1(void)
       Accessor{Blob{0, 0}, {}},
       Accessor{Blob{0, 0}, {}},
       Accessor{Blob{0, 0}, {}},
-      Accessor{Blob{0, 0}, {}},
-      Accessor{Blob{0, 0}, {}},
     },
     {
       nullptr,
@@ -441,10 +439,12 @@ int UtcDaliGltfLoaderSuccess1(void)
       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)
@@ -454,19 +454,24 @@ int UtcDaliGltfLoaderSuccess1(void)
     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());
 
@@ -928,13 +933,14 @@ int UtcDaliGltfLoaderQuantizedMesh(void)
   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;
 }
index 5ee5617..ba67d42 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,8 +17,8 @@
 
 #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;
@@ -28,14 +28,14 @@ int UtcDaliMeshDefinitionBlobApplyMinMaxBothMinMaxApplied(void)
 {
   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);
   }
@@ -47,14 +47,14 @@ int UtcDaliMeshDefinitionBlobApplyMinMaxOnlyMin(void)
 {
   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);
   }
@@ -66,14 +66,14 @@ int UtcDaliMeshDefinitionBlobApplyMinMaxOnlyMax(void)
 {
   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);
   }
@@ -85,14 +85,14 @@ int UtcDaliMeshDefinitionBlobApplyMinMaxBothEmpty(void)
 {
   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);
   }
@@ -116,17 +116,17 @@ int UtcDaliMeshDefinitionByteSkinWeight(void)
   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)
@@ -139,7 +139,7 @@ int UtcDaliMeshDefinitionByteSkinWeight(void)
 
 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=";
@@ -153,17 +153,17 @@ int UtcDaliMeshDefinitionShortSkinWeight(void)
   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)
index f272ba9..191a631 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -68,89 +68,90 @@ int UtcDaliShaderManagerProduceShader(void)
 
   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 ||
@@ -160,19 +161,19 @@ int UtcDaliShaderManagerProduceShader(void)
      },
      {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}},
@@ -254,28 +255,41 @@ int UtcDaliShaderManagerProduceShader(void)
     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);
@@ -306,7 +320,7 @@ int UtcDaliShaderManagerAddAndRemoveLights(void)
 
   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);
index e411694..0a079ff 100644 (file)
 #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
 {
@@ -40,6 +45,46 @@ namespace Internal
 {
 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
  */
@@ -216,9 +261,10 @@ void ModelPrimitive::SetBlendShapeOptions(bool hasPositions, bool hasNormals, bo
   mBlendShapeVersion = version;
 }
 
-void ModelPrimitive::SetSkinned(bool isSkinned)
+void ModelPrimitive::SetSkinned(bool isSkinned, uint32_t numberOfJointSets)
 {
-  mHasSkinning = isSkinned;
+  mHasSkinning       = isSkinned;
+  mNumberOfJointSets = numberOfJointSets;
 }
 
 // From MaterialModifyObserver
@@ -244,6 +290,7 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag
     if(mHasSkinning)
     {
       shaderOption.AddOption(Scene3D::Loader::ShaderOption::Type::SKINNING);
+      shaderOption.AddJointMacros(mNumberOfJointSets);
     }
     if(mHasPositions || mHasNormals || mHasTangents)
     {
@@ -265,8 +312,26 @@ void ModelPrimitive::ApplyMaterialToRenderer(MaterialModifyObserver::ModifyFlag
       }
     }
 
-    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)
     {
index c6dbf37..1e6a04f 100644 (file)
@@ -182,8 +182,9 @@ public:
    * @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
   /**
@@ -216,9 +217,9 @@ private:
 
 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:
@@ -242,6 +243,9 @@ 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;
index 34f36f7..7875012 100644 (file)
@@ -967,6 +967,10 @@ bool MeshDefinition::IsSkinned() const
 {
   return !mJoints.empty() && !mWeights.empty();
 }
+uint32_t MeshDefinition::GetNumberOfJointSets() const
+{
+  return static_cast<uint32_t>(mJoints.size());
+}
 
 bool MeshDefinition::HasBlendShapes() const
 {
index 1f3bca5..2dec49b 100644 (file)
@@ -264,6 +264,11 @@ struct DALI_SCENE3D_API MeshDefinition
   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;
index f0a0eba..61f1491 100644 (file)
@@ -315,7 +315,7 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit
     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();
index 40a0a5a..a7727d6 100644 (file)
@@ -102,7 +102,7 @@ void RedefineMacro(std::string& shaderCode, const std::string& macro, const std:
     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();
     }
index 86267c2..69a804d 100644 (file)
@@ -45,9 +45,6 @@ namespace
 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;
@@ -119,27 +116,7 @@ ShaderOption MakeOption(const MaterialDefinition& materialDef, const MeshDefinit
   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))
index d09195d..eec5c6b 100644 (file)
@@ -20,6 +20,8 @@
 
 // EXTERNAL INCLUDES
 #include <algorithm>
+#include <ostream>
+#include <sstream>
 #include <string>
 
 namespace Dali::Scene3D::Loader
@@ -49,6 +51,8 @@ static constexpr std::string_view OPTION_KEYWORD[] =
     "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)
 {
@@ -92,6 +96,29 @@ void ShaderOption::AddOption(Type shaderOptionType)
   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; });
index 18fad44..bca29f7 100644 (file)
@@ -79,6 +79,11 @@ public:
   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);