Merge branch 'master' into ColladaSubmeshFix

pull/3607/head
contriteobserver 2021-01-26 00:38:37 -08:00
commit f92a34e0b7
1 changed files with 101 additions and 86 deletions

View File

@ -334,7 +334,7 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "unit") { if (currentName == "unit") {
mUnitSize = 1.f; mUnitSize = 1.f;
XmlParser::getFloatAttribute(node, "meter", mUnitSize); XmlParser::getFloatAttribute(currentNode, "meter", mUnitSize);
} else if (currentName == "up_axis") { } else if (currentName == "up_axis") {
std::string v; std::string v;
if (!XmlParser::getValueAsString(currentNode, v)) { if (!XmlParser::getValueAsString(currentNode, v)) {
@ -459,7 +459,6 @@ void ColladaParser::PostProcessRootAnimations() {
if (animation != mAnimationLibrary.end()) { if (animation != mAnimationLibrary.end()) {
Animation *pSourceAnimation = animation->second; Animation *pSourceAnimation = animation->second;
pSourceAnimation->CollectChannelsRecursively(clip->mChannels); pSourceAnimation->CollectChannelsRecursively(clip->mChannels);
} }
} }
@ -1738,14 +1737,16 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// and read all indices into a temporary array // and read all indices into a temporary array
std::vector<size_t> indices; std::vector<size_t> indices;
if (expectedPointCount > 0) if (expectedPointCount > 0) {
indices.reserve(expectedPointCount * numOffsets); indices.reserve(expectedPointCount * numOffsets);
}
if (pNumPrimitives > 0) // It is possible to not contain any indices // It is possible to not contain any indices
{ if (pNumPrimitives > 0) {
std::string v; std::string v;
XmlParser::getValueAsString(node, v); XmlParser::getValueAsString(node, v);
const char *content = v.c_str(); const char *content = v.c_str();
SkipSpacesAndLineEnd(&content);
while (*content != 0) { while (*content != 0) {
// read a value. // read a value.
// Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways. // Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
@ -1772,21 +1773,24 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
// find the data for all sources // find the data for all sources
for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) { for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
InputChannel &input = *it; InputChannel &input = *it;
if (input.mResolved) if (input.mResolved) {
continue; continue;
}
// find accessor // find accessor
input.mResolved = &ResolveLibraryReference(mAccessorLibrary, input.mAccessor); input.mResolved = &ResolveLibraryReference(mAccessorLibrary, input.mAccessor);
// resolve accessor's data pointer as well, if necessary // resolve accessor's data pointer as well, if necessary
const Accessor *acc = input.mResolved; const Accessor *acc = input.mResolved;
if (!acc->mData) if (!acc->mData) {
acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource); acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
} }
}
// and the same for the per-index channels // and the same for the per-index channels
for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) { for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
InputChannel &input = *it; InputChannel &input = *it;
if (input.mResolved) if (input.mResolved) {
continue; continue;
}
// ignore vertex pointer, it doesn't refer to an accessor // ignore vertex pointer, it doesn't refer to an accessor
if (input.mType == IT_Vertex) { if (input.mType == IT_Vertex) {
@ -1801,9 +1805,10 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
input.mResolved = &ResolveLibraryReference(mAccessorLibrary, input.mAccessor); input.mResolved = &ResolveLibraryReference(mAccessorLibrary, input.mAccessor);
// resolve accessor's data pointer as well, if necessary // resolve accessor's data pointer as well, if necessary
const Accessor *acc = input.mResolved; const Accessor *acc = input.mResolved;
if (!acc->mData) if (!acc->mData) {
acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource); acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
} }
}
// For continued primitives, the given count does not come all in one <p>, but only one primitive per <p> // For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
size_t numPrimitives = pNumPrimitives; size_t numPrimitives = pNumPrimitives;
@ -1884,11 +1889,13 @@ void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t n
ai_assert((baseOffset + numOffsets - 1) < indices.size()); ai_assert((baseOffset + numOffsets - 1) < indices.size());
// extract per-vertex channels using the global per-vertex offset // extract per-vertex channels using the global per-vertex offset
for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) for (std::vector<InputChannel>::iterator it = pMesh.mPerVertexData.begin(); it != pMesh.mPerVertexData.end(); ++it) {
ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh); ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh);
}
// and extract per-index channels using there specified offset // and extract per-index channels using there specified offset
for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it) {
ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh); ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh);
}
// store the vertex-data index for later assignment of bone vertex weights // store the vertex-data index for later assignment of bone vertex weights
pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]); pMesh.mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]);
@ -1912,8 +1919,9 @@ void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset,
// Extracts a single object from an input channel and stores it in the appropriate mesh data array // Extracts a single object from an input channel and stores it in the appropriate mesh data array
void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, size_t pLocalIndex, Mesh &pMesh) { void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, size_t pLocalIndex, Mesh &pMesh) {
// ignore vertex referrer - we handle them that separate // ignore vertex referrer - we handle them that separate
if (pInput.mType == IT_Vertex) if (pInput.mType == IT_Vertex) {
return; return;
}
const Accessor &acc = *pInput.mResolved; const Accessor &acc = *pInput.mResolved;
if (pLocalIndex >= acc.mCount) { if (pLocalIndex >= acc.mCount) {
@ -1926,16 +1934,18 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
// assemble according to the accessors component sub-offset list. We don't care, yet, // assemble according to the accessors component sub-offset list. We don't care, yet,
// what kind of object exactly we're extracting here // what kind of object exactly we're extracting here
ai_real obj[4]; ai_real obj[4];
for (size_t c = 0; c < 4; ++c) for (size_t c = 0; c < 4; ++c) {
obj[c] = dataObject[acc.mSubOffset[c]]; obj[c] = dataObject[acc.mSubOffset[c]];
}
// now we reinterpret it according to the type we're reading here // now we reinterpret it according to the type we're reading here
switch (pInput.mType) { switch (pInput.mType) {
case IT_Position: // ignore all position streams except 0 - there can be only one position case IT_Position: // ignore all position streams except 0 - there can be only one position
if (pInput.mIndex == 0) if (pInput.mIndex == 0) {
pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2])); pMesh.mPositions.push_back(aiVector3D(obj[0], obj[1], obj[2]));
else } else {
ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported"); ASSIMP_LOG_ERROR("Collada: just one vertex position stream supported");
}
break; break;
case IT_Normal: case IT_Normal:
// pad to current vertex count if necessary // pad to current vertex count if necessary
@ -1943,10 +1953,11 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0)); pMesh.mNormals.insert(pMesh.mNormals.end(), pMesh.mPositions.size() - pMesh.mNormals.size() - 1, aiVector3D(0, 1, 0));
// ignore all normal streams except 0 - there can be only one normal // ignore all normal streams except 0 - there can be only one normal
if (pInput.mIndex == 0) if (pInput.mIndex == 0) {
pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2])); pMesh.mNormals.push_back(aiVector3D(obj[0], obj[1], obj[2]));
else } else {
ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported"); ASSIMP_LOG_ERROR("Collada: just one vertex normal stream supported");
}
break; break;
case IT_Tangent: case IT_Tangent:
// pad to current vertex count if necessary // pad to current vertex count if necessary
@ -1954,21 +1965,24 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0)); pMesh.mTangents.insert(pMesh.mTangents.end(), pMesh.mPositions.size() - pMesh.mTangents.size() - 1, aiVector3D(1, 0, 0));
// ignore all tangent streams except 0 - there can be only one tangent // ignore all tangent streams except 0 - there can be only one tangent
if (pInput.mIndex == 0) if (pInput.mIndex == 0) {
pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2])); pMesh.mTangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
else } else {
ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported"); ASSIMP_LOG_ERROR("Collada: just one vertex tangent stream supported");
}
break; break;
case IT_Bitangent: case IT_Bitangent:
// pad to current vertex count if necessary // pad to current vertex count if necessary
if (pMesh.mBitangents.size() < pMesh.mPositions.size() - 1) if (pMesh.mBitangents.size() < pMesh.mPositions.size() - 1) {
pMesh.mBitangents.insert(pMesh.mBitangents.end(), pMesh.mPositions.size() - pMesh.mBitangents.size() - 1, aiVector3D(0, 0, 1)); pMesh.mBitangents.insert(pMesh.mBitangents.end(), pMesh.mPositions.size() - pMesh.mBitangents.size() - 1, aiVector3D(0, 0, 1));
}
// ignore all bitangent streams except 0 - there can be only one bitangent // ignore all bitangent streams except 0 - there can be only one bitangent
if (pInput.mIndex == 0) if (pInput.mIndex == 0) {
pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2])); pMesh.mBitangents.push_back(aiVector3D(obj[0], obj[1], obj[2]));
else } else {
ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported"); ASSIMP_LOG_ERROR("Collada: just one vertex bitangent stream supported");
}
break; break;
case IT_Texcoord: case IT_Texcoord:
// up to 4 texture coord sets are fine, ignore the others // up to 4 texture coord sets are fine, ignore the others
@ -1979,8 +1993,9 @@ void ColladaParser::ExtractDataObjectFromChannel(const InputChannel &pInput, siz
pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0)); pMesh.mPositions.size() - pMesh.mTexCoords[pInput.mIndex].size() - 1, aiVector3D(0, 0, 0));
pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2])); pMesh.mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */ if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) {
pMesh.mNumUVComponents[pInput.mIndex] = 3; pMesh.mNumUVComponents[pInput.mIndex] = 3;
}
} else { } else {
ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping."); ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
} }