Merge branch 'master' into jakras-progress

pull/5190/head
Kim Kulling 2023-08-30 20:51:23 +02:00 committed by GitHub
commit bfc1207e78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 207 additions and 140 deletions

View File

@ -95,6 +95,7 @@ ColladaLoader::ColladaLoader() :
noSkeletonMesh(false), noSkeletonMesh(false),
removeEmptyBones(false), removeEmptyBones(false),
ignoreUpDirection(false), ignoreUpDirection(false),
ignoreUnitSize(false),
useColladaName(false), useColladaName(false),
mNodeNameCounter(0) { mNodeNameCounter(0) {
// empty // empty
@ -122,6 +123,7 @@ void ColladaLoader::SetupProperties(const Importer *pImp) {
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0; noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0; removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0; ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
ignoreUnitSize = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE, 0) != 0;
useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0; useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
} }
@ -170,12 +172,15 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
// ... then fill the materials with the now adjusted settings // ... then fill the materials with the now adjusted settings
FillMaterials(parser, pScene); FillMaterials(parser, pScene);
// Apply unit-size scale calculation if (!ignoreUnitSize) {
// Apply unit-size scale calculation
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0, pScene->mRootNode->mTransformation *= aiMatrix4x4(
0, parser.mUnitSize, 0, 0, parser.mUnitSize, 0, 0, 0,
0, 0, parser.mUnitSize, 0, 0, parser.mUnitSize, 0, 0,
0, 0, 0, 1); 0, 0, parser.mUnitSize, 0,
0, 0, 0, 1);
}
if (!ignoreUpDirection) { if (!ignoreUpDirection) {
// Convert to Y_UP, if different orientation // Convert to Y_UP, if different orientation
if (parser.mUpDirection == ColladaParser::UP_X) { if (parser.mUpDirection == ColladaParser::UP_X) {

View File

@ -239,6 +239,7 @@ protected:
bool noSkeletonMesh; bool noSkeletonMesh;
bool removeEmptyBones; bool removeEmptyBones;
bool ignoreUpDirection; bool ignoreUpDirection;
bool ignoreUnitSize;
bool useColladaName; bool useColladaName;
/** Used by FindNameForNode() to generate unique node names */ /** Used by FindNameForNode() to generate unique node names */

View File

@ -478,10 +478,10 @@ void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name
float focal_length_mm = cam.FocalLength(); float focal_length_mm = cam.FocalLength();
ASSIMP_LOG_VERBOSE_DEBUG("FBX FOV unspecified. Computing from FilmWidth (", film_width_inches, "inches) and FocalLength (", focal_length_mm, "mm)."); ASSIMP_LOG_VERBOSE_DEBUG("FBX FOV unspecified. Computing from FilmWidth (", film_width_inches, "inches) and FocalLength (", focal_length_mm, "mm).");
double half_fov_rad = std::atan2(film_width_inches * 25.4 * 0.5, focal_length_mm); double half_fov_rad = std::atan2(film_width_inches * 25.4 * 0.5, focal_length_mm);
out_camera->mHorizontalFOV = half_fov_rad; out_camera->mHorizontalFOV = static_cast<float>(half_fov_rad);
} else { } else {
// FBX fov is full-view degrees. We want half-view radians. // FBX fov is full-view degrees. We want half-view radians.
out_camera->mHorizontalFOV = AI_DEG_TO_RAD(fov_deg) * 0.5; out_camera->mHorizontalFOV = AI_DEG_TO_RAD(fov_deg) * 0.5f;
} }
out_camera->mClipPlaneNear = cam.NearPlane(); out_camera->mClipPlaneNear = cam.NearPlane();

View File

@ -211,7 +211,7 @@ Scope::Scope(Parser& parser,bool topLevel)
elements.insert(ElementMap::value_type(str, element)); elements.insert(ElementMap::value_type(str, element));
return; return;
} }
delete element; delete_Element(element);
ParseError("unexpected end of file",parser.LastToken()); ParseError("unexpected end of file",parser.LastToken());
} else { } else {
elements.insert(ElementMap::value_type(str, element)); elements.insert(ElementMap::value_type(str, element));

View File

@ -271,10 +271,16 @@ void MDLImporter::InternReadFile(const std::string &pFile,
} }
} }
// ------------------------------------------------------------------------------------------------
// Check whether we're still inside the valid file range
bool MDLImporter::IsPosValid(const void *szPos) const {
return szPos && (const unsigned char *)szPos <= this->mBuffer + this->iFileSize && szPos >= this->mBuffer;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check whether we're still inside the valid file range // Check whether we're still inside the valid file range
void MDLImporter::SizeCheck(const void *szPos) { void MDLImporter::SizeCheck(const void *szPos) {
if (!szPos || (const unsigned char *)szPos > this->mBuffer + this->iFileSize || szPos < this->mBuffer) { if (!IsPosValid(szPos)) {
throw DeadlyImportError("Invalid MDL file. The file is too small " throw DeadlyImportError("Invalid MDL file. The file is too small "
"or contains invalid data."); "or contains invalid data.");
} }
@ -284,7 +290,7 @@ void MDLImporter::SizeCheck(const void *szPos) {
// Just for debugging purposes // Just for debugging purposes
void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int iLine) { void MDLImporter::SizeCheck(const void *szPos, const char *szFile, unsigned int iLine) {
ai_assert(nullptr != szFile); ai_assert(nullptr != szFile);
if (!szPos || (const unsigned char *)szPos > mBuffer + iFileSize) { if (!IsPosValid(szPos)) {
// remove a directory if there is one // remove a directory if there is one
const char *szFilePtr = ::strrchr(szFile, '\\'); const char *szFilePtr = ::strrchr(szFile, '\\');
if (!szFilePtr) { if (!szFilePtr) {

View File

@ -150,6 +150,7 @@ protected:
*/ */
void SizeCheck(const void* szPos); void SizeCheck(const void* szPos);
void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine); void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
bool IsPosValid(const void* szPos) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Validate the header data structure of a game studio MDL7 file /** Validate the header data structure of a game studio MDL7 file

View File

@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/StreamReader.h> #include <assimp/StreamReader.h>
#include <map> #include <map>
#include <limits>
using namespace Assimp; using namespace Assimp;
@ -160,6 +161,9 @@ void NDOImporter::InternReadFile( const std::string& pFile,
temp = file_format >= 12 ? reader.GetU4() : reader.GetU2(); temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
head = (const char*)reader.GetPtr(); head = (const char*)reader.GetPtr();
if (std::numeric_limits<unsigned int>::max() - 76 < temp) {
throw DeadlyImportError("Invalid name length");
}
reader.IncPtr(temp + 76); /* skip unknown stuff */ reader.IncPtr(temp + 76); /* skip unknown stuff */
obj.name = std::string(head, temp); obj.name = std::string(head, temp);

View File

@ -263,7 +263,7 @@ size_t NZDiff(void *data, void *dataBase, size_t count, unsigned int numCompsIn,
for (short idx = 0; bufferData_ptr < bufferData_end; idx += 1, bufferData_ptr += numCompsIn) { for (short idx = 0; bufferData_ptr < bufferData_end; idx += 1, bufferData_ptr += numCompsIn) {
bool bNonZero = false; bool bNonZero = false;
//for the data, check any component Non Zero // for the data, check any component Non Zero
for (unsigned int j = 0; j < numCompsOut; j++) { for (unsigned int j = 0; j < numCompsOut; j++) {
double valueData = bufferData_ptr[j]; double valueData = bufferData_ptr[j];
double valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0; double valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0;
@ -273,11 +273,11 @@ size_t NZDiff(void *data, void *dataBase, size_t count, unsigned int numCompsIn,
} }
} }
//all zeros, continue // all zeros, continue
if (!bNonZero) if (!bNonZero)
continue; continue;
//non zero, store the data // non zero, store the data
for (unsigned int j = 0; j < numCompsOut; j++) { for (unsigned int j = 0; j < numCompsOut; j++) {
T valueData = bufferData_ptr[j]; T valueData = bufferData_ptr[j];
T valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0; T valueBase = bufferBase_ptr ? bufferBase_ptr[j] : 0;
@ -286,14 +286,14 @@ size_t NZDiff(void *data, void *dataBase, size_t count, unsigned int numCompsIn,
vNZIdx.push_back(idx); vNZIdx.push_back(idx);
} }
//avoid all-0, put 1 item // avoid all-0, put 1 item
if (vNZDiff.size() == 0) { if (vNZDiff.size() == 0) {
for (unsigned int j = 0; j < numCompsOut; j++) for (unsigned int j = 0; j < numCompsOut; j++)
vNZDiff.push_back(0); vNZDiff.push_back(0);
vNZIdx.push_back(0); vNZIdx.push_back(0);
} }
//process data // process data
outputNZDiff = new T[vNZDiff.size()]; outputNZDiff = new T[vNZDiff.size()];
memcpy(outputNZDiff, vNZDiff.data(), vNZDiff.size() * sizeof(T)); memcpy(outputNZDiff, vNZDiff.data(), vNZDiff.size() * sizeof(T));
@ -361,7 +361,7 @@ inline Ref<Accessor> ExportDataSparse(Asset &a, std::string &meshName, Ref<Buffe
acc->sparse.reset(new Accessor::Sparse); acc->sparse.reset(new Accessor::Sparse);
acc->sparse->count = nzCount; acc->sparse->count = nzCount;
//indices // indices
unsigned int bytesPerIdx = sizeof(unsigned short); unsigned int bytesPerIdx = sizeof(unsigned short);
size_t indices_offset = buffer->byteLength; size_t indices_offset = buffer->byteLength;
size_t indices_padding = indices_offset % bytesPerIdx; size_t indices_padding = indices_offset % bytesPerIdx;
@ -379,7 +379,7 @@ inline Ref<Accessor> ExportDataSparse(Asset &a, std::string &meshName, Ref<Buffe
acc->sparse->indicesByteOffset = 0; acc->sparse->indicesByteOffset = 0;
acc->WriteSparseIndices(nzCount, nzIdx, 1 * bytesPerIdx); acc->WriteSparseIndices(nzCount, nzIdx, 1 * bytesPerIdx);
//values // values
size_t values_offset = buffer->byteLength; size_t values_offset = buffer->byteLength;
size_t values_padding = values_offset % bytesPerComp; size_t values_padding = values_offset % bytesPerComp;
values_offset += values_padding; values_offset += values_padding;
@ -395,9 +395,9 @@ inline Ref<Accessor> ExportDataSparse(Asset &a, std::string &meshName, Ref<Buffe
acc->sparse->valuesByteOffset = 0; acc->sparse->valuesByteOffset = 0;
acc->WriteSparseValues(nzCount, nzDiff, numCompsIn * bytesPerComp); acc->WriteSparseValues(nzCount, nzDiff, numCompsIn * bytesPerComp);
//clear // clear
delete[](char *) nzDiff; delete[] (char *)nzDiff;
delete[](char *) nzIdx; delete[] (char *)nzIdx;
} }
return acc; return acc;
} }
@ -599,7 +599,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
if (curTex != nullptr) { // embedded if (curTex != nullptr) { // embedded
texture->source->name = curTex->mFilename.C_Str(); texture->source->name = curTex->mFilename.C_Str();
//basisu: embedded ktx2, bu // basisu: embedded ktx2, bu
if (curTex->achFormatHint[0]) { if (curTex->achFormatHint[0]) {
std::string mimeType = "image/"; std::string mimeType = "image/";
if (memcmp(curTex->achFormatHint, "jpg", 3) == 0) if (memcmp(curTex->achFormatHint, "jpg", 3) == 0)
@ -619,7 +619,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
} }
// The asset has its own buffer, see Image::SetData // The asset has its own buffer, see Image::SetData
//basisu: "image/ktx2", "image/basis" as is // basisu: "image/ktx2", "image/basis" as is
texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset); texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset);
} else { } else {
texture->source->uri = path; texture->source->uri = path;
@ -629,7 +629,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
} }
} }
//basisu // basisu
if (useBasisUniversal) { if (useBasisUniversal) {
mAsset->extensionsUsed.KHR_texture_basisu = true; mAsset->extensionsUsed.KHR_texture_basisu = true;
mAsset->extensionsRequired.KHR_texture_basisu = true; mAsset->extensionsRequired.KHR_texture_basisu = true;
@ -652,7 +652,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, ai
GetMatTex(mat, texture, prop.texCoord, tt, slot); GetMatTex(mat, texture, prop.texCoord, tt, slot);
if (texture) { if (texture) {
//GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
GetMatTexProp(mat, prop.scale, "scale", tt, slot); GetMatTexProp(mat, prop.scale, "scale", tt, slot);
} }
} }
@ -663,7 +663,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, OcclusionTextureInfo &prop,
GetMatTex(mat, texture, prop.texCoord, tt, slot); GetMatTex(mat, texture, prop.texCoord, tt, slot);
if (texture) { if (texture) {
//GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot); // GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
GetMatTexProp(mat, prop.strength, "strength", tt, slot); GetMatTexProp(mat, prop.strength, "strength", tt, slot);
} }
} }
@ -832,20 +832,30 @@ void glTF2Exporter::ExportMaterials() {
GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_BASE_COLOR); GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_BASE_COLOR);
if (!m->pbrMetallicRoughness.baseColorTexture.texture) { if (!m->pbrMetallicRoughness.baseColorTexture.texture) {
//if there wasn't a baseColorTexture defined in the source, fallback to any diffuse texture // if there wasn't a baseColorTexture defined in the source, fallback to any diffuse texture
GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE); GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE);
} }
GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_DIFFUSE_ROUGHNESS);
if (!m->pbrMetallicRoughness.metallicRoughnessTexture.texture) {
// if there wasn't a aiTextureType_DIFFUSE_ROUGHNESS defined in the source, fallback to aiTextureType_METALNESS
GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, aiTextureType_METALNESS);
}
if (!m->pbrMetallicRoughness.metallicRoughnessTexture.texture) {
// if there still wasn't a aiTextureType_METALNESS defined in the source, fallback to AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE
GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
}
if (GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_BASE_COLOR) != AI_SUCCESS) { if (GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_BASE_COLOR) != AI_SUCCESS) {
// if baseColorFactor wasn't defined, then the source is likely not a metallic roughness material. // if baseColorFactor wasn't defined, then the source is likely not a metallic roughness material.
//a fallback to any diffuse color should be used instead // a fallback to any diffuse color should be used instead
GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE); GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE);
} }
if (mat.Get(AI_MATKEY_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) { if (mat.Get(AI_MATKEY_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) {
//if metallicFactor wasn't defined, then the source is likely not a PBR file, and the metallicFactor should be 0 // if metallicFactor wasn't defined, then the source is likely not a PBR file, and the metallicFactor should be 0
m->pbrMetallicRoughness.metallicFactor = 0; m->pbrMetallicRoughness.metallicFactor = 0;
} }
@ -858,10 +868,10 @@ void glTF2Exporter::ExportMaterials() {
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
// convert specular color to luminance // convert specular color to luminance
float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f; float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
//normalize shininess (assuming max is 1000) with an inverse exponentional curve // normalize shininess (assuming max is 1000) with an inverse exponentional curve
float normalizedShininess = std::sqrt(shininess / 1000); float normalizedShininess = std::sqrt(shininess / 1000);
//clamp the shininess value between 0 and 1 // clamp the shininess value between 0 and 1
normalizedShininess = std::min(std::max(normalizedShininess, 0.0f), 1.0f); normalizedShininess = std::min(std::max(normalizedShininess, 0.0f), 1.0f);
// low specular intensity values should produce a rough material even if shininess is high. // low specular intensity values should produce a rough material even if shininess is high.
normalizedShininess = normalizedShininess * specularIntensity; normalizedShininess = normalizedShininess * specularIntensity;
@ -1059,7 +1069,7 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buf
if (boneIndexFitted != -1) { if (boneIndexFitted != -1) {
vertexJointData[vertexId][boneIndexFitted] = static_cast<float>(jointNamesIndex); vertexJointData[vertexId][boneIndexFitted] = static_cast<float>(jointNamesIndex);
} }
}else { } else {
vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex); vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex);
vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight; vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
@ -1071,7 +1081,7 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buf
Mesh::Primitive &p = meshRef->primitives.back(); Mesh::Primitive &p = meshRef->primitives.back();
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT); vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
if (vertexJointAccessor) { if (vertexJointAccessor) {
size_t offset = vertexJointAccessor->bufferView->byteOffset; size_t offset = vertexJointAccessor->bufferView->byteOffset;
size_t bytesLen = vertexJointAccessor->bufferView->byteLength; size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
@ -1155,7 +1165,7 @@ void glTF2Exporter::ExportMeshes() {
/******************* Vertices ********************/ /******************* Vertices ********************/
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3,
AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (v) { if (v) {
p.attributes.position.push_back(v); p.attributes.position.push_back(v);
} }
@ -1169,7 +1179,7 @@ void glTF2Exporter::ExportMeshes() {
} }
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3,
AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (n) { if (n) {
p.attributes.normal.push_back(n); p.attributes.normal.push_back(n);
} }
@ -1191,7 +1201,7 @@ void glTF2Exporter::ExportMeshes() {
AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3; AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i],
AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (tc) { if (tc) {
p.attributes.texcoord.push_back(tc); p.attributes.texcoord.push_back(tc);
} }
@ -1201,7 +1211,7 @@ void glTF2Exporter::ExportMeshes() {
/*************** Vertex colors ****************/ /*************** Vertex colors ****************/
for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) { for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) {
Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel],
AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER); AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
if (c) { if (c) {
p.attributes.color.push_back(c); p.attributes.color.push_back(c);
} }
@ -1219,7 +1229,7 @@ void glTF2Exporter::ExportMeshes() {
} }
p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR,
ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER); ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
} }
switch (aim->mPrimitiveTypes) { switch (aim->mPrimitiveTypes) {
@ -1362,24 +1372,24 @@ void glTF2Exporter::MergeMeshes() {
unsigned int nMeshes = static_cast<unsigned int>(node->meshes.size()); unsigned int nMeshes = static_cast<unsigned int>(node->meshes.size());
//skip if it's 1 or less meshes per node // skip if it's 1 or less meshes per node
if (nMeshes > 1) { if (nMeshes > 1) {
Ref<Mesh> firstMesh = node->meshes.at(0); Ref<Mesh> firstMesh = node->meshes.at(0);
//loop backwards to allow easy removal of a mesh from a node once it's merged // loop backwards to allow easy removal of a mesh from a node once it's merged
for (unsigned int m = nMeshes - 1; m >= 1; --m) { for (unsigned int m = nMeshes - 1; m >= 1; --m) {
Ref<Mesh> mesh = node->meshes.at(m); Ref<Mesh> mesh = node->meshes.at(m);
//append this mesh's primitives to the first mesh's primitives // append this mesh's primitives to the first mesh's primitives
firstMesh->primitives.insert( firstMesh->primitives.insert(
firstMesh->primitives.end(), firstMesh->primitives.end(),
mesh->primitives.begin(), mesh->primitives.begin(),
mesh->primitives.end()); mesh->primitives.end());
//remove the mesh from the list of meshes // remove the mesh from the list of meshes
unsigned int removedIndex = mAsset->meshes.Remove(mesh->id.c_str()); unsigned int removedIndex = mAsset->meshes.Remove(mesh->id.c_str());
//find the presence of the removed mesh in other nodes // find the presence of the removed mesh in other nodes
for (unsigned int nn = 0; nn < mAsset->nodes.Size(); ++nn) { for (unsigned int nn = 0; nn < mAsset->nodes.Size(); ++nn) {
Ref<Node> curNode = mAsset->nodes.Get(nn); Ref<Node> curNode = mAsset->nodes.Get(nn);
@ -1398,7 +1408,7 @@ void glTF2Exporter::MergeMeshes() {
} }
} }
//since we were looping backwards, reverse the order of merged primitives to their original order // since we were looping backwards, reverse the order of merged primitives to their original order
std::reverse(firstMesh->primitives.begin() + 1, firstMesh->primitives.end()); std::reverse(firstMesh->primitives.begin() + 1, firstMesh->primitives.end());
} }
} }
@ -1430,7 +1440,7 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode *n) {
return node.GetIndex(); return node.GetIndex();
} }
/* /*
* Export node and recursively calls ExportNode for all children. * Export node and recursively calls ExportNode for all children.
* Since these nodes are not the root node, we also export the parent Ref<Node> * Since these nodes are not the root node, we also export the parent Ref<Node>
*/ */
@ -1525,9 +1535,9 @@ inline void ExtractTranslationSampler(Asset &asset, std::string &animId, Ref<Buf
const aiVectorKey &key = nodeChannel->mPositionKeys[i]; const aiVectorKey &key = nodeChannel->mPositionKeys[i];
// mTime is measured in ticks, but GLTF time is measured in seconds, so convert. // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
times[i] = static_cast<float>(key.mTime / ticksPerSecond); times[i] = static_cast<float>(key.mTime / ticksPerSecond);
values[(i * 3) + 0] = (ai_real) key.mValue.x; values[(i * 3) + 0] = (ai_real)key.mValue.x;
values[(i * 3) + 1] = (ai_real) key.mValue.y; values[(i * 3) + 1] = (ai_real)key.mValue.y;
values[(i * 3) + 2] = (ai_real) key.mValue.z; values[(i * 3) + 2] = (ai_real)key.mValue.z;
} }
sampler.input = GetSamplerInputRef(asset, animId, buffer, times); sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
@ -1544,9 +1554,9 @@ inline void ExtractScaleSampler(Asset &asset, std::string &animId, Ref<Buffer> &
const aiVectorKey &key = nodeChannel->mScalingKeys[i]; const aiVectorKey &key = nodeChannel->mScalingKeys[i];
// mTime is measured in ticks, but GLTF time is measured in seconds, so convert. // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
times[i] = static_cast<float>(key.mTime / ticksPerSecond); times[i] = static_cast<float>(key.mTime / ticksPerSecond);
values[(i * 3) + 0] = (ai_real) key.mValue.x; values[(i * 3) + 0] = (ai_real)key.mValue.x;
values[(i * 3) + 1] = (ai_real) key.mValue.y; values[(i * 3) + 1] = (ai_real)key.mValue.y;
values[(i * 3) + 2] = (ai_real) key.mValue.z; values[(i * 3) + 2] = (ai_real)key.mValue.z;
} }
sampler.input = GetSamplerInputRef(asset, animId, buffer, times); sampler.input = GetSamplerInputRef(asset, animId, buffer, times);
@ -1563,10 +1573,10 @@ inline void ExtractRotationSampler(Asset &asset, std::string &animId, Ref<Buffer
const aiQuatKey &key = nodeChannel->mRotationKeys[i]; const aiQuatKey &key = nodeChannel->mRotationKeys[i];
// mTime is measured in ticks, but GLTF time is measured in seconds, so convert. // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
times[i] = static_cast<float>(key.mTime / ticksPerSecond); times[i] = static_cast<float>(key.mTime / ticksPerSecond);
values[(i * 4) + 0] = (ai_real) key.mValue.x; values[(i * 4) + 0] = (ai_real)key.mValue.x;
values[(i * 4) + 1] = (ai_real) key.mValue.y; values[(i * 4) + 1] = (ai_real)key.mValue.y;
values[(i * 4) + 2] = (ai_real) key.mValue.z; values[(i * 4) + 2] = (ai_real)key.mValue.z;
values[(i * 4) + 3] = (ai_real) key.mValue.w; values[(i * 4) + 3] = (ai_real)key.mValue.w;
} }
sampler.input = GetSamplerInputRef(asset, animId, buffer, times); sampler.input = GetSamplerInputRef(asset, animId, buffer, times);

View File

@ -234,7 +234,8 @@ inline void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot); SetMaterialTextureProperty(embeddedTexIdxs, r, (glTF2::TextureInfo)prop, mat, texType, texSlot);
if (prop.texture && prop.texture->source) { if (prop.texture && prop.texture->source) {
mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot)); std::string textureStrengthKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + "strength";
mat->AddProperty(&prop.strength, 1, textureStrengthKey.c_str(), texType, texSlot);
} }
} }

View File

@ -1420,25 +1420,29 @@ if(MSVC AND ASSIMP_INSTALL_PDB)
COMPILE_PDB_NAME assimp${LIBRARY_SUFFIX} COMPILE_PDB_NAME assimp${LIBRARY_SUFFIX}
COMPILE_PDB_NAME_DEBUG assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX} COMPILE_PDB_NAME_DEBUG assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}
) )
ENDIF()
IF(CMAKE_GENERATOR MATCHES "^Visual Studio") IF(GENERATOR_IS_MULTI_CONFIG)
install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
DESTINATION ${ASSIMP_LIB_INSTALL_DIR} DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
CONFIGURATIONS Debug CONFIGURATIONS Debug
) )
install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp${LIBRARY_SUFFIX}.pdb install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp${LIBRARY_SUFFIX}.pdb
DESTINATION ${ASSIMP_LIB_INSTALL_DIR} DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
CONFIGURATIONS RelWithDebInfo CONFIGURATIONS RelWithDebInfo
) )
ELSE()
install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
CONFIGURATIONS Debug
)
install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}.pdb
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
CONFIGURATIONS RelWithDebInfo
)
ENDIF()
ELSE() ELSE()
install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb install(FILES $<TARGET_PDB_FILE:assimp>
DESTINATION ${ASSIMP_LIB_INSTALL_DIR} DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
CONFIGURATIONS Debug
)
install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}.pdb
DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
CONFIGURATIONS RelWithDebInfo
) )
ENDIF() ENDIF()
ENDIF () ENDIF ()

View File

@ -312,12 +312,7 @@ std::string BaseImporter::GetExtension(const std::string &pFile) {
if (!pIOHandler) { if (!pIOHandler) {
return false; return false;
} }
union { const char *magic = reinterpret_cast<const char *>(_magic);
const char *magic;
const uint16_t *magic_u16;
const uint32_t *magic_u32;
};
magic = reinterpret_cast<const char *>(_magic);
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile)); std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile));
if (pStream) { if (pStream) {
@ -339,15 +334,15 @@ std::string BaseImporter::GetExtension(const std::string &pFile) {
// that's just for convenience, the chance that we cause conflicts // that's just for convenience, the chance that we cause conflicts
// is quite low and it can save some lines and prevent nasty bugs // is quite low and it can save some lines and prevent nasty bugs
if (2 == size) { if (2 == size) {
uint16_t rev = *magic_u16; uint16_t magic_u16;
ByteSwap::Swap(&rev); memcpy(&magic_u16, magic, 2);
if (data_u16[0] == *magic_u16 || data_u16[0] == rev) { if (data_u16[0] == magic_u16 || data_u16[0] == ByteSwap::Swapped(magic_u16)) {
return true; return true;
} }
} else if (4 == size) { } else if (4 == size) {
uint32_t rev = *magic_u32; uint32_t magic_u32;
ByteSwap::Swap(&rev); memcpy(&magic_u32, magic, 4);
if (data_u32[0] == *magic_u32 || data_u32[0] == rev) { if (data_u32[0] == magic_u32 || data_u32[0] == ByteSwap::Swapped(magic_u32)) {
return true; return true;
} }
} else { } else {

View File

@ -15,9 +15,11 @@ option( DDL_STATIC_LIBRARY "Deprecated, use BUILD_SHARED_LIBS instead."
# for backwards compatibility use DDL_STATIC_LIBRARY as initial value for cmake variable BUILD_SHARED_LIBS # for backwards compatibility use DDL_STATIC_LIBRARY as initial value for cmake variable BUILD_SHARED_LIBS
# https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html # https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html
if ( DDL_STATIC_LIBRARY ) if ( DDL_STATIC_LIBRARY )
set ( build_shared_libs_default OFF ) message("Building shared lib.")
set ( build_shared_libs_default OFF )
else() else()
set ( build_shared_libs_default ON ) message("Building static lib.")
set ( build_shared_libs_default ON )
endif() endif()
option( DDL_BUILD_SHARED_LIBS "Set to ON to build shared libary of OpenDDL Parser." ${build_shared_libs_default} ) option( DDL_BUILD_SHARED_LIBS "Set to ON to build shared libary of OpenDDL Parser." ${build_shared_libs_default} )
option( COVERALLS "Generate coveralls data" OFF ) option( COVERALLS "Generate coveralls data" OFF )
@ -36,6 +38,7 @@ endif()
add_definitions( -D_VARIADIC_MAX=10 ) add_definitions( -D_VARIADIC_MAX=10 )
add_definitions( -DGTEST_HAS_PTHREAD=0 ) add_definitions( -DGTEST_HAS_PTHREAD=0 )
if ( DDL_DEBUG_OUTPUT ) if ( DDL_DEBUG_OUTPUT )
message("Enable debug output.")
add_definitions( -DDDL_DEBUG_HEADER_NAME) add_definitions( -DDDL_DEBUG_HEADER_NAME)
endif() endif()
@ -62,10 +65,12 @@ if (COVERALLS)
include(Coveralls) include(Coveralls)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
message("Enable coveralls.")
endif() endif()
# Include the doc component. # Include the doc component.
if(DDL_DOCUMENTATION) if(DDL_DOCUMENTATION)
message("Generate doxygen documentation.")
find_package(Doxygen REQUIRED) find_package(Doxygen REQUIRED)
CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY ) CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY )
add_custom_target(doc ALL add_custom_target(doc ALL

View File

@ -5,13 +5,15 @@ The OpenDDL-Parser is a small and easy to use library for OpenDDL-file-format-pa
Build status Build status
============ ============
Linux build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
Linux build status: [![Build Status](https://travis-ci.com/kimkulling/openddl-parser.svg?branch=master)](https://travis-ci.com/kimkulling/openddl-parser)
Current coverity check status: Current coverity check status:
<a href="https://scan.coverity.com/projects/5606"> <a href="https://scan.coverity.com/projects/5606">
<img alt="Coverity Scan Build Status" <img alt="Coverity Scan Build Status"
src="https://scan.coverity.com/projects/5606/badge.svg"/> src="https://scan.coverity.com/projects/5606/badge.svg"/>
</a> </a>
Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls) Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls)
Get the source code Get the source code
=================== ===================
You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command: You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
@ -57,11 +59,11 @@ USE_ODDLPARSER_NS;
int main( int argc, char *argv[] ) { int main( int argc, char *argv[] ) {
if( argc < 3 ) { if( argc < 3 ) {
return 1; return Error;
} }
char *filename( nullptr ); char *filename( nullptr );
if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) { if( 0 == strncmp( FileOption, argv[1], strlen( FileOption ) ) ) {
filename = argv[ 2 ]; filename = argv[ 2 ];
} }
std::cout << "file to import: " << filename << std::endl; std::cout << "file to import: " << filename << std::endl;
@ -73,24 +75,27 @@ int main( int argc, char *argv[] ) {
FILE *fileStream = fopen( filename, "r+" ); FILE *fileStream = fopen( filename, "r+" );
if( NULL == filename ) { if( NULL == filename ) {
std::cerr << "Cannot open file " << filename << std::endl; std::cerr << "Cannot open file " << filename << std::endl;
return 1; return Error;
} }
// obtain file size: // obtain file size:
fseek( fileStream, 0, SEEK_END ); fseek( fileStream, 0, SEEK_END );
const size_t size( ftell( fileStream ) ); const size_t size = ftell( fileStream );
rewind( fileStream ); rewind( fileStream );
if( size > 0 ) { if( size > 0 ) {
char *buffer = new char[ size ]; char *buffer = new char[ size ];
const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) ); const size_t readSize = fread( buffer, sizeof( char ), size, fileStream );
assert( readSize == size ); assert( readSize == size );
// Set the memory buffer
OpenDDLParser theParser; OpenDDLParser theParser;
theParser.setBuffer( buffer, size ); theParser.setBuffer( buffer, size );
const bool result( theParser.parse() ); if( !theParser.parse() ) {
if( !result ) {
std::cerr << "Error while parsing file " << filename << "." << std::endl; std::cerr << "Error while parsing file " << filename << "." << std::endl;
return Error;
} }
} }
return 0; return 0;
} }
@ -106,9 +111,9 @@ theParser.setBuffer( buffer, size );
const bool result( theParser.parse() ); const bool result( theParser.parse() );
if ( result ) { if ( result ) {
DDLNode *root = theParser.getRoot(); DDLNode *root = theParser.getRoot();
DDLNode::DllNodeList childs = root->getChildNodeList(); DDLNode::DllNodeList children = root->getChildNodeList();
for ( size_t i=0; i<childs.size(); i++ ) { for ( size_t i=0; i<children.size(); i++ ) {
DDLNode *child = childs[ i ]; DDLNode *child = children[ i ];
Property *prop = child->getProperty(); // to get properties Property *prop = child->getProperty(); // to get properties
std::string type = child->getType(); // to get the node type std::string type = child->getType(); // to get the node type
Value *values = child->getValue(); // to get the data; Value *values = child->getValue(); // to get the data;

View File

@ -134,9 +134,10 @@ bool OpenDDLExport::writeToStream(const std::string &statement) {
} }
bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) { bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) {
bool success(true);
writeNodeHeader(node, statement); writeNodeHeader(node, statement);
if (node->hasProperties()) { if (node->hasProperties()) {
writeProperties(node, statement); success = writeProperties(node, statement);
} }
writeLineEnd(statement); writeLineEnd(statement);
@ -160,7 +161,7 @@ bool OpenDDLExport::writeNode(DDLNode *node, std::string &statement) {
writeToStream(statement); writeToStream(statement);
return true; return success;
} }
bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) { bool OpenDDLExport::writeNodeHeader(DDLNode *node, std::string &statement) {

View File

@ -30,7 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <sstream> #include <sstream>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> # ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# include <windows.h>
#endif // _WIN32 #endif // _WIN32
BEGIN_ODDLPARSER_NS BEGIN_ODDLPARSER_NS
@ -71,7 +74,7 @@ const char *getTypeToken(Value::ValueType type) {
return Grammar::PrimitiveTypeToken[(size_t)type]; return Grammar::PrimitiveTypeToken[(size_t)type];
} }
static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) { static void logInvalidTokenError(const char *in, const std::string &exp, OpenDDLParser::logCallback callback) {
if (callback) { if (callback) {
std::string full(in); std::string full(in);
std::string part(full.substr(0, 50)); std::string part(full.substr(0, 50));
@ -338,20 +341,25 @@ char *OpenDDLParser::parseStructure(char *in, char *end) {
bool error(false); bool error(false);
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in == *Grammar::OpenBracketToken) { if (in != end) {
// loop over all children ( data and nodes ) if (*in == *Grammar::OpenBracketToken) {
do { // loop over all children ( data and nodes )
in = parseStructureBody(in, end, error); do {
if (in == nullptr) { in = parseStructureBody(in, end, error);
return nullptr; if (in == nullptr) {
return nullptr;
}
} while (in != end &&
*in != *Grammar::CloseBracketToken);
if (in != end) {
++in;
} }
} while (*in != *Grammar::CloseBracketToken); } else {
++in; ++in;
} else { logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback);
++in; error = true;
logInvalidTokenError(in, std::string(Grammar::OpenBracketToken), m_logCallback); return nullptr;
error = true; }
return nullptr;
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
@ -418,8 +426,8 @@ char *OpenDDLParser::parseStructureBody(char *in, char *end, bool &error) {
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in != '}') { if (in == end || *in != '}') {
logInvalidTokenError(in, std::string(Grammar::CloseBracketToken), m_logCallback); logInvalidTokenError(in == end ? "" : in, std::string(Grammar::CloseBracketToken), m_logCallback);
return nullptr; return nullptr;
} else { } else {
//in++; //in++;
@ -455,7 +463,7 @@ DDLNode *OpenDDLParser::top() {
return nullptr; return nullptr;
} }
DDLNode *top(m_stack.back()); DDLNode *top = m_stack.back();
return top; return top;
} }
@ -647,12 +655,15 @@ char *OpenDDLParser::parseBooleanLiteral(char *in, char *end, Value **boolean) {
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
char *start(in); char *start(in);
size_t len(0);
while (!isSeparator(*in) && in != end) { while (!isSeparator(*in) && in != end) {
++in; ++in;
++len;
} }
int res = ::strncmp(Grammar::BoolTrue, start, strlen(Grammar::BoolTrue)); int res = ::strncmp(Grammar::BoolTrue, start, len);
if (0 != res) { if (0 != res) {
res = ::strncmp(Grammar::BoolFalse, start, strlen(Grammar::BoolFalse)); res = ::strncmp(Grammar::BoolFalse, start, len);
if (0 != res) { if (0 != res) {
*boolean = nullptr; *boolean = nullptr;
return in; return in;
@ -733,7 +744,7 @@ char *OpenDDLParser::parseFloatingLiteral(char *in, char *end, Value **floating,
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
char *start(in); char *start(in);
while (!isSeparator(*in) && in != end) { while (in != end && !isSeparator(*in)) {
++in; ++in;
} }
@ -838,6 +849,13 @@ char *OpenDDLParser::parseHexaLiteral(char *in, char *end, Value **data) {
int value(0); int value(0);
while (pos > 0) { while (pos > 0) {
int v = hex2Decimal(*start); int v = hex2Decimal(*start);
if (v < 0) {
while (isEndofLine(*in)) {
++in;
}
return in;
}
--pos; --pos;
value = (value << 4) | v; value = (value << 4) | v;
++start; ++start;
@ -901,10 +919,10 @@ char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, V
} }
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (*in == '{') { if (in != end && *in == '{') {
++in; ++in;
Value *current(nullptr), *prev(nullptr); Value *current(nullptr), *prev(nullptr);
while ('}' != *in) { while (in != end && '}' != *in) {
current = nullptr; current = nullptr;
in = lookForNextToken(in, end); in = lookForNextToken(in, end);
if (Value::ValueType::ddl_ref == type) { if (Value::ValueType::ddl_ref == type) {
@ -962,11 +980,12 @@ char *OpenDDLParser::parseDataList(char *in, char *end, Value::ValueType type, V
} }
in = getNextSeparator(in, end); in = getNextSeparator(in, end);
if (',' != *in && Grammar::CloseBracketToken[0] != *in && !isSpace(*in)) { if (in == end || (',' != *in && Grammar::CloseBracketToken[0] != *in && !isSpace(*in))) {
break; break;
} }
} }
++in; if (in != end)
++in;
} }
return in; return in;

View File

@ -26,8 +26,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string> #include <string>
#include <vector> #include <vector>
#include <stdio.h> #include <cstdio>
#include <string.h> #include <cstring>
#ifndef _WIN32 #ifndef _WIN32
#include <inttypes.h> #include <inttypes.h>
#endif #endif

View File

@ -40,15 +40,6 @@ struct Identifier;
struct Reference; struct Reference;
struct Property; struct Property;
template <class T>
inline bool isEmbeddedCommentOpenTag(T *in, T *end) {
if (in == '/' && in + 1 == '*') {
return true;
}
return false;
}
/// @brief Utility function to search for the next token or the end of the buffer. /// @brief Utility function to search for the next token or the end of the buffer.
/// @param in [in] The start position in the buffer. /// @param in [in] The start position in the buffer.
/// @param end [in] The end position in the buffer. /// @param end [in] The end position in the buffer.

View File

@ -54,7 +54,9 @@ inline bool isSeparator(T in) {
return false; return false;
} }
static const unsigned char chartype_table[256] = { const size_t CharTableSize = 256;
static const unsigned char chartype_table[CharTableSize] = {
0, 0,
0, 0,
0, 0,
@ -318,6 +320,10 @@ static const unsigned char chartype_table[256] = {
template <class T> template <class T>
inline bool isNumeric(const T in) { inline bool isNumeric(const T in) {
if (static_cast<size_t>(in) >= CharTableSize) {
return '\0';
}
size_t idx = static_cast<size_t>(in); size_t idx = static_cast<size_t>(in);
return idx < sizeof(chartype_table) && (chartype_table[idx] == 1); return idx < sizeof(chartype_table) && (chartype_table[idx] == 1);
} }
@ -433,7 +439,7 @@ inline bool isEndofLine(const T in) {
template <class T> template <class T>
inline static T *getNextSeparator(T *in, T *end) { inline static T *getNextSeparator(T *in, T *end) {
while (!isSeparator(*in) || in == end) { while (in != end && !isSeparator(*in)) {
++in; ++in;
} }
return in; return in;

View File

@ -302,7 +302,9 @@ bool TXmlParser<TNodeType>::parse(IOStream *stream) {
stream->Read(&mData[0], 1, len); stream->Read(&mData[0], 1, len);
mDoc = new pugi::xml_document(); mDoc = new pugi::xml_document();
pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full); // load_string assumes native encoding (aka always utf-8 per build options)
//pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
pugi::xml_parse_result parse_result = mDoc->load_buffer(&mData[0], mData.size(), pugi::parse_full);
if (parse_result.status == pugi::status_ok) { if (parse_result.status == pugi::status_ok) {
return true; return true;
} }

View File

@ -1035,6 +1035,15 @@ enum aiComponent
*/ */
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION" #define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
// ---------------------------------------------------------------------------
/** @brief Specifies whether the Collada loader will ignore the provided unit size.
*
* If this property is set to true, the unit size provided in the file header will
* be ignored and the file will be loaded without scaling the assets.
* Property type: Bool. Default value: false.
*/
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE "IMPORT_COLLADA_IGNORE_UNIT_SIZE"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Specifies whether the Collada loader should use Collada names. /** @brief Specifies whether the Collada loader should use Collada names.
* *

View File

@ -211,7 +211,8 @@ AI_FORCE_INLINE aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
unsigned int idx,aiColor3D& pOut) const { unsigned int idx,aiColor3D& pOut) const {
aiColor4D c; aiColor4D c;
const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c); const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
pOut = aiColor3D(c.r,c.g,c.b); if (ret == aiReturn_SUCCESS)
pOut = aiColor3D(c.r,c.g,c.b);
return ret; return ret;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -94,6 +94,7 @@ enum aiPostProcessSteps
* indexed geometry, this step is compulsory or you'll just waste rendering * indexed geometry, this step is compulsory or you'll just waste rendering
* time. <b>If this flag is not specified</b>, no vertices are referenced by * time. <b>If this flag is not specified</b>, no vertices are referenced by
* more than one face and <b>no index buffer is required</b> for rendering. * more than one face and <b>no index buffer is required</b> for rendering.
* Unless the importer (like ply) had to split vertices. Then you need one regardless.
*/ */
aiProcess_JoinIdenticalVertices = 0x2, aiProcess_JoinIdenticalVertices = 0x2,