/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
}
+void MeshDefinition::Blob::ComputeMinMax(std::vector<float>& min, std::vector<float>& max, uint32_t numComponents, uint32_t count, const float* values)
+{
+ min.assign(numComponents, MAXFLOAT);
+ max.assign(numComponents, -MAXFLOAT);
+ for(uint32_t i = 0; i < count; ++i)
+ {
+ for(uint32_t j = 0; j < numComponents; ++j)
+ {
+ min[j] = std::min(min[j], *values);
+ max[j] = std::max(max[j], *values);
+ values++;
+ }
+ }
+}
+
void MeshDefinition::Blob::ApplyMinMax(const std::vector<float>& min, const std::vector<float>& max, uint32_t count, float* values)
{
DALI_ASSERT_DEBUG(max.size() == min.size() || max.size() * min.size() == 0);
return IsConsecutive() ? mLength : (mLength * mElementSizeHint / mStride);
}
+void MeshDefinition::Blob::ComputeMinMax(uint32_t numComponents, uint32_t count, float* values)
+{
+ ComputeMinMax(mMin, mMax, numComponents, count, values);
+}
+
void MeshDefinition::Blob::ApplyMinMax(uint32_t count, float* values) const
{
ApplyMinMax(mMin, mMax, count, values);
}
MeshDefinition::RawData
-MeshDefinition::LoadRaw(const std::string& modelsPath) const
+MeshDefinition::LoadRaw(const std::string& modelsPath)
{
RawData raw;
if(IsQuad())
}
uint32_t numVector3 = bufferSize / sizeof(Vector3);
- mPositions.mBlob.ApplyMinMax(numVector3, reinterpret_cast<float*>(buffer.data()));
+ if(mPositions.mBlob.mMin.size() != 3u || mPositions.mBlob.mMax.size() != 3u)
+ {
+ mPositions.mBlob.ComputeMinMax(3u, numVector3, reinterpret_cast<float*>(buffer.data()));
+ }
+ else
+ {
+ mPositions.mBlob.ApplyMinMax(numVector3, reinterpret_cast<float*>(buffer.data()));
+ }
if(HasBlendShapes())
{
if(mTangents.IsDefined())
{
- DALI_ASSERT_ALWAYS(((mTangents.mBlob.mLength % sizeof(Vector3) == 0) ||
- mTangents.mBlob.mStride >= sizeof(Vector3)) &&
+ uint32_t propertySize = (mTangentType == Property::VECTOR4) ? sizeof(Vector4) : sizeof(Vector3);
+ DALI_ASSERT_ALWAYS(((mTangents.mBlob.mLength % propertySize == 0) ||
+ mTangents.mBlob.mStride >= propertySize) &&
"Tangents buffer length not a multiple of element size");
const auto bufferSize = mTangents.mBlob.GetBufferSize();
std::vector<uint8_t> buffer(bufferSize);
{
ExceptionFlinger(ASSERT_LOCATION) << "Failed to read tangents from '" << meshPath << "'.";
}
+ mTangents.mBlob.ApplyMinMax(bufferSize / propertySize, reinterpret_cast<float*>(buffer.data()));
- mTangents.mBlob.ApplyMinMax(bufferSize / sizeof(Vector3), reinterpret_cast<float*>(buffer.data()));
-
- raw.mAttribs.push_back({"aTangent", Property::VECTOR3, static_cast<uint32_t>(bufferSize / sizeof(Vector3)), std::move(buffer)});
+ raw.mAttribs.push_back({"aTangent", mTangentType, static_cast<uint32_t>(bufferSize / propertySize), std::move(buffer)});
}
else if(mTangents.mBlob.mLength != 0 && hasNormals && isTriangles)
{
hasUvs ? GenerateTangentsWithUvs(raw) : GenerateTangents(raw);
}
+ if(mColors.IsDefined())
+ {
+ uint32_t propertySize = mColors.mBlob.mElementSizeHint;
+ Property::Type propertyType = (propertySize == sizeof(Vector4)) ? Property::VECTOR4 : ((propertySize == sizeof(Vector3)) ? Property::VECTOR3 : Property::NONE);
+ if(propertyType != Property::NONE)
+ {
+ DALI_ASSERT_ALWAYS(((mColors.mBlob.mLength % propertySize == 0) ||
+ mColors.mBlob.mStride >= propertySize) &&
+ "Colors buffer length not a multiple of element size");
+ const auto bufferSize = mColors.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if(!ReadAccessor(mColors, binFile, buffer.data()))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read colors from '" << meshPath << "'.";
+ }
+ mColors.mBlob.ApplyMinMax(bufferSize / propertySize, reinterpret_cast<float*>(buffer.data()));
+
+ raw.mAttribs.push_back({"aVertexColor", propertyType, static_cast<uint32_t>(bufferSize / propertySize), std::move(buffer)});
+ }
+ }
+
if(IsSkinned())
{
if(MaskMatch(mFlags, U16_JOINT_IDS))