#include <vector>
-#include "dali-scene3d/public-api/loader/mesh-definition.h"
+#include <dali-scene3d/public-api/loader/mesh-definition.h>
+#include <dali-scene3d/public-api/loader/buffer-definition.h>
#include <dali-test-suite-utils.h>
using namespace Dali;
END_TEST;
}
+int UtcDaliMeshDefinitionByteSkinWeight(void)
+{
+ float data8[8] = {0.003922, 0.062745, 0.250980, 0.098039, 0.937255, 0.749020, 0.741176, 0.937255};
+
+ BufferDefinition bufferDefinition;
+ bufferDefinition.mUri = "data:application/base64,ARBAGe+/ve+/vT9hc2RmYXNkZmFzZGZhc2RmYXNkZmE=";
+ bufferDefinition.mByteLength = 32;
+ BufferDefinition::Vector buffers;
+ buffers.push_back(std::move(bufferDefinition));
+
+ MeshDefinition meshDefinition;
+ meshDefinition.mFlags = MeshDefinition::U16_JOINT_IDS | MeshDefinition::U8_WEIGHT;
+ MeshDefinition::SparseBlob sparseBlob;
+ 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::Accessor{
+ std::move(MeshDefinition::Blob{0, 16, 0, (uint16_t)16, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0};
+ meshDefinition.mWeights0 =
+ MeshDefinition::Accessor{
+ 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].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)
+ {
+ DALI_TEST_EQUALS(*value, data8[i], TEST_LOCATION);
+ value++;
+ }
+ END_TEST;
+}
+
+int UtcDaliMeshDefinitionShortSkinWeight(void)
+{
+ 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=";
+ bufferDefinition.mByteLength = 32;
+ BufferDefinition::Vector buffers;
+ buffers.push_back(std::move(bufferDefinition));
+
+ MeshDefinition meshDefinition;
+ meshDefinition.mFlags = MeshDefinition::U16_JOINT_IDS | MeshDefinition::U16_WEIGHT;
+ MeshDefinition::SparseBlob sparseBlob;
+ 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::Accessor{
+ std::move(MeshDefinition::Blob{0, 16, 0, (uint16_t)16, std::vector<float>(), std::vector<float>()}), std::move(sparseBlob), 0};
+ meshDefinition.mWeights0 =
+ MeshDefinition::Accessor{
+ 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].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)
+ {
+ DALI_TEST_EQUALS(*value, data8[i], TEST_LOCATION);
+ value++;
+ }
+ END_TEST;
+}
raw.mAttribs.push_back({"aJoints", Property::VECTOR4, static_cast<uint32_t>(outBufferSize / sizeof(Vector4)), std::move(buffer)});
}
+template<typename T>
+void ReadWeightAccessor(MeshDefinition::RawData& raw, const MeshDefinition::Accessor& accessor, std::istream& source, const std::string& meshPath)
+{
+ constexpr auto sizeofBlobUnit = sizeof(T) * 4;
+
+ DALI_ASSERT_ALWAYS(((accessor.mBlob.mLength % sizeofBlobUnit == 0) ||
+ accessor.mBlob.mStride >= sizeofBlobUnit) &&
+ "weights buffer length not a multiple of element size");
+ const auto inBufferSize = accessor.mBlob.GetBufferSize();
+ const auto outBufferSize = (sizeof(Vector4) / sizeofBlobUnit) * inBufferSize;
+
+ std::vector<uint8_t> buffer(outBufferSize);
+ auto inBuffer = buffer.data() + outBufferSize - inBufferSize;
+ if(!ReadAccessor(accessor, source, inBuffer))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read weights from '" << meshPath << "'.";
+ }
+
+ if constexpr(sizeofBlobUnit != sizeof(Vector4))
+ {
+ auto floats = reinterpret_cast<float*>(buffer.data());
+ const auto end = inBuffer + inBufferSize;
+ while(inBuffer != end)
+ {
+ const auto value = *reinterpret_cast<T*>(inBuffer);
+ // Normalize weight value. value /= 255 for uint8_t weight, and value /= 65535 for uint16_t weight.
+ *floats = static_cast<float>(value) / static_cast<float>((1 << (sizeof(T) * 8)) - 1);
+
+ inBuffer += sizeof(T);
+ ++floats;
+ }
+ }
+ raw.mAttribs.push_back({"aWeights", Property::VECTOR4, static_cast<uint32_t>(outBufferSize / sizeof(Vector4)), std::move(buffer)});
+}
+
template<bool use32BitsIndices, typename IndexProviderType = IndexProvider<use32BitsIndices>>
bool GenerateNormals(MeshDefinition::RawData& raw)
{
ReadJointAccessor<float>(raw, mJoints0, streamJoint, pathJoint);
}
- DALI_ASSERT_ALWAYS(((mWeights0.mBlob.mLength % sizeof(Vector4) == 0) ||
- mWeights0.mBlob.mStride >= sizeof(Vector4)) &&
- "Weights buffer length not a multiple of element size");
- const auto bufferSize = mWeights0.mBlob.GetBufferSize();
- std::vector<uint8_t> buffer(bufferSize);
-
std::string pathWeight;
auto& streamWeight = GetAvailableData(fileStream, meshPath, buffers[mWeights0.mBufferIdx], pathWeight);
- if(!ReadAccessor(mWeights0, streamWeight, buffer.data()))
+ if(MaskMatch(mFlags, U16_WEIGHT))
{
- ExceptionFlinger(ASSERT_LOCATION) << "Failed to read weights from '" << pathWeight << "'.";
+ ReadWeightAccessor<uint16_t>(raw, mWeights0, streamWeight, pathWeight);
+ }
+ else if(MaskMatch(mFlags, U8_WEIGHT))
+ {
+ ReadWeightAccessor<uint8_t>(raw, mWeights0, streamWeight, pathWeight);
+ }
+ else
+ {
+ ReadWeightAccessor<float>(raw, mWeights0, streamWeight, pathWeight);
}
-
- raw.mAttribs.push_back({"aWeights", Property::VECTOR4, static_cast<uint32_t>(bufferSize / sizeof(Vector4)), std::move(buffer)});
}
// Calculate the Blob for the blend shapes.