Merge branch 'master' into scene_combiner_crash

This commit is contained in:
Kim Kulling
2017-11-22 13:46:14 +01:00
committed by GitHub
37 changed files with 197 additions and 66 deletions
+2 -2
View File
@@ -91,7 +91,7 @@ protected:
// -------------------------------------------------------------------
/** Report a validation warning. This won't throw an exception,
* control will return to the callera.
* control will return to the caller.
* @param msg Format string for sprintf().*/
void ReportWarning(const char* msg,...);
@@ -165,7 +165,7 @@ private:
inline void DoValidation(T** array, unsigned int size,
const char* firstName, const char* secondName);
// extended version: checks whethr T::mName occurs twice
// extended version: checks whether T::mName occurs twice
template <typename T>
inline void DoValidationEx(T** array, unsigned int size,
const char* firstName, const char* secondName);
+26 -5
View File
@@ -192,15 +192,31 @@ namespace glTF2
#include "./../include/assimp/Compiler/pushpack1.h"
#endif
//! For binary .glb files
//! 12-byte header (+ the JSON + a "body" data section)
struct GLB_Header
{
uint8_t magic[4]; //!< Magic number: "glTF"
uint32_t version; //!< Version number (always 2 as of the last update)
uint32_t length; //!< Total length of the Binary glTF, including header, scene, and body, in bytes
} PACK_STRUCT;
struct GLB_Chunk
{
uint32_t chunkLength;
uint32_t chunkType;
} PACK_STRUCT;
#ifdef ASSIMP_API
#include "./../include/assimp/Compiler/poppack1.h"
#endif
//! Values for the GLB_Header::sceneFormat field
enum SceneFormat
//! Values for the GLB_Chunk::chunkType field
enum ChunkType
{
SceneFormat_JSON = 0
ChunkType_JSON = 0x4E4F534A,
ChunkType_BIN = 0x004E4942
};
//! Values for the mesh primitive modes
@@ -420,7 +436,6 @@ namespace glTF2
{
Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
unsigned int byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
ComponentType componentType; //!< The datatype of components in the attribute. (required)
unsigned int count; //!< The number of attributes referenced by this accessor. (required)
AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
@@ -611,6 +626,7 @@ namespace glTF2
Ref<Buffer> buffer; //! The ID of the buffer. (required)
size_t byteOffset; //! The offset into the buffer in bytes. (required)
size_t byteLength; //! The length of the bufferView in bytes. (default: 0)
unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
BufferViewTarget target; //! The target that the WebGL buffer should be bound to.
@@ -1086,7 +1102,10 @@ namespace glTF2
}
//! Main function
void Load(const std::string& file);
void Load(const std::string& file, bool isBinary = false);
//! Enables binary encoding on the asset
void SetAsBinary();
//! Search for an available name, starting from the given strings
std::string FindUniqueID(const std::string& str, const char* suffix);
@@ -1095,6 +1114,8 @@ namespace glTF2
{ return mBodyBuffer; }
private:
void ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData);
void ReadExtensionsUsed(Document& doc);
IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);
+94 -11
View File
@@ -512,6 +512,7 @@ inline void BufferView::Read(Value& obj, Asset& r)
byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
byteLength = MemberOrDefault(obj, "byteLength", 0u);
byteStride = MemberOrDefault(obj, "byteStride", 0u);
}
//
@@ -526,7 +527,6 @@ inline void Accessor::Read(Value& obj, Asset& r)
}
byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
byteStride = MemberOrDefault(obj, "byteStride", 0u);
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
count = MemberOrDefault(obj, "count", 0u);
@@ -601,7 +601,7 @@ bool Accessor::ExtractData(T*& outData)
const size_t elemSize = GetElementSize();
const size_t totalSize = elemSize * count;
const size_t stride = byteStride ? byteStride : elemSize;
const size_t stride = bufferView && bufferView->byteStride ? bufferView->byteStride : elemSize;
const size_t targetElemSize = sizeof(T);
ai_assert(elemSize <= targetElemSize);
@@ -641,7 +641,7 @@ inline Accessor::Indexer::Indexer(Accessor& acc)
: accessor(acc)
, data(acc.GetPointer())
, elemSize(acc.GetElementSize())
, stride(acc.byteStride ? acc.byteStride : elemSize)
, stride(acc.bufferView && acc.bufferView->byteStride ? acc.bufferView->byteStride : elemSize)
{
}
@@ -1037,7 +1037,72 @@ inline void AssetMetadata::Read(Document& doc)
// Asset methods implementation
//
inline void Asset::Load(const std::string& pFile)
inline void Asset::ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData)
{
GLB_Header header;
if (stream.Read(&header, sizeof(header), 1) != 1) {
throw DeadlyImportError("GLTF: Unable to read the file header");
}
if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
throw DeadlyImportError("GLTF: Invalid binary glTF file");
}
AI_SWAP4(header.version);
asset.version = to_string(header.version);
if (header.version != 2) {
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
}
GLB_Chunk chunk;
if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
throw DeadlyImportError("GLTF: Unable to read JSON chunk");
}
AI_SWAP4(chunk.chunkLength);
AI_SWAP4(chunk.chunkType);
if (chunk.chunkType != ChunkType_JSON) {
throw DeadlyImportError("GLTF: JSON chunk missing");
}
// read the scene data
mSceneLength = chunk.chunkLength;
sceneData.resize(mSceneLength + 1);
sceneData[mSceneLength] = '\0';
if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
throw DeadlyImportError("GLTF: Could not read the file contents");
}
uint32_t padding = ((chunk.chunkLength + 3) & ~3) - chunk.chunkLength;
if (padding > 0) {
stream.Seek(padding, aiOrigin_CUR);
}
AI_SWAP4(header.length);
mBodyOffset = 12 + 8 + chunk.chunkLength + padding + 8;
if (header.length >= mBodyOffset) {
if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
throw DeadlyImportError("GLTF: Unable to read BIN chunk");
}
AI_SWAP4(chunk.chunkLength);
AI_SWAP4(chunk.chunkType);
if (chunk.chunkType != ChunkType_BIN) {
throw DeadlyImportError("GLTF: BIN chunk missing");
}
mBodyLength = chunk.chunkLength;
}
else {
mBodyOffset = mBodyLength = 0;
}
}
inline void Asset::Load(const std::string& pFile, bool isBinary)
{
mCurrentAssetDir.clear();
int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
@@ -1048,16 +1113,25 @@ inline void Asset::Load(const std::string& pFile)
throw DeadlyImportError("GLTF: Could not open file for reading");
}
mSceneLength = stream->FileSize();
mBodyLength = 0;
// is binary? then read the header
std::vector<char> sceneData;
if (isBinary) {
SetAsBinary(); // also creates the body buffer
ReadBinaryHeader(*stream, sceneData);
}
else {
mSceneLength = stream->FileSize();
mBodyLength = 0;
// read the scene data
std::vector<char> sceneData(mSceneLength + 1);
sceneData[mSceneLength] = '\0';
// read the scene data
if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
throw DeadlyImportError("GLTF: Could not read the file contents");
sceneData.resize(mSceneLength + 1);
sceneData[mSceneLength] = '\0';
if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
throw DeadlyImportError("GLTF: Could not read the file contents");
}
}
@@ -1110,6 +1184,15 @@ inline void Asset::Load(const std::string& pFile)
}
}
inline void Asset::SetAsBinary()
{
if (!mBodyBuffer) {
mBodyBuffer = buffers.Create("binary_glTF");
mBodyBuffer->MarkAsSpecial();
}
}
inline void Asset::ReadExtensionsUsed(Document& doc)
{
Value* extsUsed = FindArray(doc, "extensionsUsed");
+3 -4
View File
@@ -98,10 +98,6 @@ namespace glTF2 {
obj.AddMember("bufferView", a.bufferView->index, w.mAl);
obj.AddMember("byteOffset", a.byteOffset, w.mAl);
if (a.byteStride != 0) {
obj.AddMember("byteStride", a.byteStride, w.mAl);
}
obj.AddMember("componentType", int(a.componentType), w.mAl);
obj.AddMember("count", a.count, w.mAl);
obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
@@ -168,6 +164,9 @@ namespace glTF2 {
obj.AddMember("buffer", bv.buffer->index, w.mAl);
obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
if (bv.byteStride != 0) {
obj.AddMember("byteStride", bv.byteStride, w.mAl);
}
obj.AddMember("target", int(bv.target), w.mAl);
}
+1 -1
View File
@@ -170,13 +170,13 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
bv->buffer = buffer;
bv->byteOffset = unsigned(offset);
bv->byteLength = length; //! The target that the WebGL buffer should be bound to.
bv->byteStride = 0;
bv->target = isIndices ? BufferViewTarget_ELEMENT_ARRAY_BUFFER : BufferViewTarget_ARRAY_BUFFER;
// accessor
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
acc->bufferView = bv;
acc->byteOffset = 0;
acc->byteStride = 0;
acc->componentType = compType;
acc->count = count;
acc->type = typeOut;
+4 -4
View File
@@ -74,7 +74,7 @@ static const aiImporterDesc desc = {
"",
"",
"",
aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
0,
0,
0,
@@ -103,13 +103,13 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
{
const std::string &extension = GetExtension(pFile);
if (extension != "gltf") // We currently can't read glTF2 binary files (.glb), yet
if (extension != "gltf" && extension != "glb")
return false;
if (checkSig && pIOHandler) {
glTF2::Asset asset(pIOHandler);
try {
asset.Load(pFile);
asset.Load(pFile, extension == "glb");
std::string version = asset.asset.version;
return !version.empty() && version[0] == '2';
} catch (...) {
@@ -639,7 +639,7 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO
// read the asset file
glTF2::Asset asset(pIOHandler);
asset.Load(pFile);
asset.Load(pFile, GetExtension(pFile) == "glb");
//
// Copy the data out