Fixed bad sparse accessors for blendshapes on meshes with
multiple primitives.
This commit is contained in:
parent
957615c6e2
commit
6ca6d06f09
|
@ -105,6 +105,22 @@ class GltfModel {
|
||||||
return accessor;
|
return accessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <class T>
|
||||||
|
std::shared_ptr<AccessorData> AddSparseAccessor(
|
||||||
|
AccessorData& baseAccessor,
|
||||||
|
BufferViewData& indexBufferView,
|
||||||
|
const GLType& indexBufferViewType,
|
||||||
|
BufferViewData& bufferView,
|
||||||
|
const GLType& type,
|
||||||
|
// const std::vector<T>& source,
|
||||||
|
std::string name) {
|
||||||
|
auto accessor = accessors.hold(new AccessorData(baseAccessor, indexBufferView, bufferView, type, name));
|
||||||
|
//bufferView.appendAsBinaryArray(source, *binary, type);
|
||||||
|
accessor->count = baseAccessor.count;
|
||||||
|
accessor->sparseIdxBufferViewType = indexBufferViewType.componentType.glType;
|
||||||
|
return accessor;
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
std::shared_ptr<AccessorData>
|
std::shared_ptr<AccessorData>
|
||||||
AddAccessorAndView(BufferData& buffer, const GLType& type, const std::vector<T>& source) {
|
AddAccessorAndView(BufferData& buffer, const GLType& type, const std::vector<T>& source) {
|
||||||
|
|
|
@ -418,6 +418,9 @@ ModelData* Raw2Gltf(
|
||||||
surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex);
|
surfaceModel.GetMaterial(surfaceModel.GetTriangle(0).materialIndex);
|
||||||
const MaterialData& mData = require(materialsById, rawMaterial.id);
|
const MaterialData& mData = require(materialsById, rawMaterial.id);
|
||||||
|
|
||||||
|
if (verboseOutput)
|
||||||
|
fmt::printf("\rMaterial Name: %s\n", mData.name);
|
||||||
|
|
||||||
MeshData* mesh = nullptr;
|
MeshData* mesh = nullptr;
|
||||||
auto meshIter = meshBySurfaceId.find(surfaceId);
|
auto meshIter = meshBySurfaceId.find(surfaceId);
|
||||||
if (meshIter != meshBySurfaceId.end()) {
|
if (meshIter != meshBySurfaceId.end()) {
|
||||||
|
@ -474,6 +477,12 @@ ModelData* Raw2Gltf(
|
||||||
std::shared_ptr<AccessorData> pAccBase;
|
std::shared_ptr<AccessorData> pAccBase;
|
||||||
std::shared_ptr<AccessorData> nAccBase;
|
std::shared_ptr<AccessorData> nAccBase;
|
||||||
std::shared_ptr<AccessorData> tAccBase;
|
std::shared_ptr<AccessorData> tAccBase;
|
||||||
|
|
||||||
|
// Sparse accessors cannot be zero length, but morph targets can easily have
|
||||||
|
// no modified vertices in multiprim meshes. In order to utilise sparse accessors
|
||||||
|
// in this case, we need a couple of single element dummy buffer views to reference.
|
||||||
|
std::shared_ptr<BufferViewData> dummyIdxView;
|
||||||
|
std::shared_ptr<BufferViewData> dummyDataView;
|
||||||
{
|
{
|
||||||
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_POSITION) != 0) {
|
if ((surfaceModel.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_POSITION) != 0) {
|
||||||
const AttributeDefinition<Vec3f> ATTR_POSITION(
|
const AttributeDefinition<Vec3f> ATTR_POSITION(
|
||||||
|
@ -597,19 +606,42 @@ ModelData* Raw2Gltf(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
std::shared_ptr<AccessorData> pAccIx = gltf->AddAccessorWithView(
|
|
||||||
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ELEMENT_ARRAY_BUFFER),
|
|
||||||
useLongIndices ? GLT_UINT : GLT_USHORT,
|
|
||||||
sparseIndices,
|
|
||||||
channel.name);
|
|
||||||
*/
|
|
||||||
std::shared_ptr<AccessorData> pAcc;
|
std::shared_ptr<AccessorData> pAcc;
|
||||||
std::shared_ptr<AccessorData> nAcc;
|
std::shared_ptr<AccessorData> nAcc;
|
||||||
std::shared_ptr<AccessorData> tAcc;
|
std::shared_ptr<AccessorData> tAcc;
|
||||||
|
|
||||||
if(options.enableSparseBlendShapes){
|
if(options.enableSparseBlendShapes){
|
||||||
fmt::printf("\rSparse Index Count: %d \n", sparseIndices.size());
|
if (verboseOutput)
|
||||||
|
fmt::printf("\rChannel Name: %-50s Sparse Count: %d\n", channel.name,sparseIndices.size());
|
||||||
|
|
||||||
|
if(sparseIndices.size()==0){
|
||||||
|
// Initalize dummy bufferviews if needed
|
||||||
|
if(!dummyIdxView){
|
||||||
|
std::vector<TriangleIndex> dummyIndices;
|
||||||
|
dummyIndices.push_back(int(0));
|
||||||
|
|
||||||
|
dummyIdxView = gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
|
||||||
|
gltf->CopyToBufferView(*dummyIdxView, dummyIndices, useLongIndices ? GLT_UINT : GLT_USHORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dummyDataView){
|
||||||
|
std::vector<Vec3f> dummyData;
|
||||||
|
dummyData.push_back(Vec3f(0.0));
|
||||||
|
|
||||||
|
dummyDataView = gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
|
||||||
|
dummyDataView->appendAsBinaryArray(dummyData, *gltf->binary, GLT_VEC3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up sparse accessor with dummy buffer views
|
||||||
|
pAcc = gltf->AddSparseAccessor(
|
||||||
|
*pAccBase,
|
||||||
|
*dummyIdxView,
|
||||||
|
useLongIndices ? GLT_UINT : GLT_USHORT,
|
||||||
|
*dummyDataView,
|
||||||
|
GLT_VEC3F,
|
||||||
|
channel.name);
|
||||||
|
}else{
|
||||||
// Build Orphan Bufferview for Sparse Indices
|
// Build Orphan Bufferview for Sparse Indices
|
||||||
std::shared_ptr<BufferViewData> indexBufferView =
|
std::shared_ptr<BufferViewData> indexBufferView =
|
||||||
gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
|
gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
|
||||||
|
@ -643,6 +675,7 @@ ModelData* Raw2Gltf(
|
||||||
tangents,
|
tangents,
|
||||||
channel.name);
|
channel.name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
pAcc = gltf->AddAccessorWithView(
|
pAcc = gltf->AddAccessorWithView(
|
||||||
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER),
|
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER),
|
||||||
|
@ -664,7 +697,6 @@ ModelData* Raw2Gltf(
|
||||||
channel.name);
|
channel.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pAcc->min = toStdVec(shapeBounds.min);
|
pAcc->min = toStdVec(shapeBounds.min);
|
||||||
pAcc->max = toStdVec(shapeBounds.max);
|
pAcc->max = toStdVec(shapeBounds.max);
|
||||||
primitive->AddTarget(pAcc.get(), nAcc.get(), tAcc.get());
|
primitive->AddTarget(pAcc.get(), nAcc.get(), tAcc.get());
|
||||||
|
|
Loading…
Reference in New Issue