Fixed bad sparse accessors for blendshapes on meshes with

multiple primitives.
This commit is contained in:
Gordon Chapman 2020-05-14 19:49:07 -07:00
parent 957615c6e2
commit 6ca6d06f09
2 changed files with 84 additions and 36 deletions

View File

@ -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) {

View File

@ -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,51 +606,75 @@ 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)
// Build Orphan Bufferview for Sparse Indices fmt::printf("\rChannel Name: %-50s Sparse Count: %d\n", channel.name,sparseIndices.size());
std::shared_ptr<BufferViewData> indexBufferView =
gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
gltf->CopyToBufferView(*indexBufferView, sparseIndices, useLongIndices ? GLT_UINT : GLT_USHORT);
pAcc = gltf->AddSparseAccessorWithView( if(sparseIndices.size()==0){
*pAccBase, // Initalize dummy bufferviews if needed
*indexBufferView, if(!dummyIdxView){
useLongIndices ? GLT_UINT : GLT_USHORT, std::vector<TriangleIndex> dummyIndices;
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE), dummyIndices.push_back(int(0));
GLT_VEC3F,
positions, dummyIdxView = gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
channel.name); gltf->CopyToBufferView(*dummyIdxView, dummyIndices, useLongIndices ? GLT_UINT : GLT_USHORT);
if (!normals.empty()) { }
nAcc = gltf->AddSparseAccessorWithView(
*nAccBase, 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
std::shared_ptr<BufferViewData> indexBufferView =
gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE);
gltf->CopyToBufferView(*indexBufferView, sparseIndices, useLongIndices ? GLT_UINT : GLT_USHORT);
pAcc = gltf->AddSparseAccessorWithView(
*pAccBase,
*indexBufferView, *indexBufferView,
useLongIndices ? GLT_UINT : GLT_USHORT, useLongIndices ? GLT_UINT : GLT_USHORT,
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE), *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE),
GLT_VEC3F, GLT_VEC3F,
normals, positions,
channel.name);
}
if (!tangents.empty()) {
tAcc = gltf->AddSparseAccessorWithView(
*nAccBase,
*indexBufferView,
useLongIndices ? GLT_UINT : GLT_USHORT,
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE),
GLT_VEC4F,
tangents,
channel.name); channel.name);
if (!normals.empty()) {
nAcc = gltf->AddSparseAccessorWithView(
*nAccBase,
*indexBufferView,
useLongIndices ? GLT_UINT : GLT_USHORT,
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE),
GLT_VEC3F,
normals,
channel.name);
}
if (!tangents.empty()) {
tAcc = gltf->AddSparseAccessorWithView(
*nAccBase,
*indexBufferView,
useLongIndices ? GLT_UINT : GLT_USHORT,
*gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_NONE),
GLT_VEC4F,
tangents,
channel.name);
}
} }
}else{ }else{
pAcc = gltf->AddAccessorWithView( pAcc = gltf->AddAccessorWithView(
@ -664,8 +697,7 @@ 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());
} }