Merge branch 'master' into gltf2-anim-duration

This commit is contained in:
Kim Kulling
2018-12-01 13:41:54 +01:00
committed by GitHub
16 changed files with 497 additions and 567 deletions

View File

@@ -161,19 +161,21 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
this->stream = &stream;
// We should have at least one chunk
if (stream.GetRemainingSize() < 16) {
throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
}
this->stream = &stream;
// Allocate our temporary 3DS representation
mScene = new D3DS::Scene();
D3DS::Scene _scene;
mScene = &_scene;
// Initialize members
D3DS::Node _rootNode("UNNAMED");
mLastNodeIndex = -1;
mCurrentNode = new D3DS::Node("UNNAMED");
mCurrentNode = &_rootNode;
mRootNode = mCurrentNode;
mRootNode->mHierarchyPos = -1;
mRootNode->mHierarchyIndex = -1;
@@ -193,7 +195,6 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
// file.
for (auto &mesh : mScene->mMeshes) {
if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
delete mScene;
throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile);
}
CheckIndices(mesh);
@@ -201,7 +202,7 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
}
// Replace all occurrences of the default material with a
// Replace all occurences of the default material with a
// valid material. Generate it if no material containing
// DEFAULT in its name has been found in the file
ReplaceDefaultMaterial();
@@ -218,10 +219,8 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
// Now apply the master scaling factor to the scene
ApplyMasterScale(pScene);
// Delete our internal scene representation and the root
// node, so the whole hierarchy will follow
delete mRootNode;
delete mScene;
// Our internal scene representation and the root
// node will be automatically deleted, so the whole hierarchy will follow
AI_DEBUG_INVALIDATE_PTR(mRootNode);
AI_DEBUG_INVALIDATE_PTR(mScene);

View File

@@ -89,7 +89,7 @@ size_t Write<unsigned int>(IOStream * stream, const unsigned int& w) {
const uint32_t t = (uint32_t)w;
if (w > t) {
// this shouldn't happen, integers in Assimp data structures never exceed 2^32
throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion");
throw DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion");
}
stream->Write(&t,4,1);
@@ -805,10 +805,16 @@ public:
WriteBinaryScene( &uncompressedStream, pScene );
uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());
uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.);
uLongf compressedSize = (uLongf)compressBound(uncompressedSize);
uint8_t* compressedBuffer = new uint8_t[ compressedSize ];
compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 );
int res = compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 );
if(res != Z_OK)
{
delete [] compressedBuffer;
pIOSystem->Close(out);
throw DeadlyExportError("Compression failed.");
}
out->Write( &uncompressedSize, sizeof(uint32_t), 1 );
out->Write( compressedBuffer, sizeof(char), compressedSize );

View File

@@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/anim.h>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <memory>
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
@@ -103,7 +104,9 @@ bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bo
template <typename T>
T Read(IOStream * stream) {
T t;
stream->Read( &t, sizeof(T), 1 );
size_t res = stream->Read( &t, sizeof(T), 1 );
if(res != 1)
throw DeadlyImportError("Unexpected EOF");
return t;
}
@@ -144,7 +147,8 @@ template <>
aiString Read<aiString>(IOStream * stream) {
aiString s;
stream->Read(&s.length,4,1);
stream->Read(s.data,s.length,1);
if(s.length)
stream->Read(s.data,s.length,1);
s.data[s.length] = 0;
return s;
}
@@ -207,46 +211,48 @@ void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n ) {
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AINODE);
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** onode, aiNode* parent ) {
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AINODE)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
*node = new aiNode();
std::unique_ptr<aiNode> node(new aiNode());
(*node)->mName = Read<aiString>(stream);
(*node)->mTransformation = Read<aiMatrix4x4>(stream);
(*node)->mNumChildren = Read<unsigned int>(stream);
(*node)->mNumMeshes = Read<unsigned int>(stream);
node->mName = Read<aiString>(stream);
node->mTransformation = Read<aiMatrix4x4>(stream);
unsigned numChildren = Read<unsigned int>(stream);
unsigned numMeshes = Read<unsigned int>(stream);
unsigned int nb_metadata = Read<unsigned int>(stream);
if(parent) {
(*node)->mParent = parent;
node->mParent = parent;
}
if ((*node)->mNumMeshes) {
(*node)->mMeshes = new unsigned int[(*node)->mNumMeshes];
for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) {
(*node)->mMeshes[i] = Read<unsigned int>(stream);
if (numMeshes)
{
node->mMeshes = new unsigned int[numMeshes];
for (unsigned int i = 0; i < numMeshes; ++i) {
node->mMeshes[i] = Read<unsigned int>(stream);
node->mNumMeshes++;
}
}
if ((*node)->mNumChildren) {
(*node)->mChildren = new aiNode*[(*node)->mNumChildren];
for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) {
ReadBinaryNode( stream, &(*node)->mChildren[i], *node );
if (numChildren) {
node->mChildren = new aiNode*[numChildren];
for (unsigned int i = 0; i < numChildren; ++i) {
ReadBinaryNode( stream, &node->mChildren[i], node.get() );
node->mNumChildren++;
}
}
if ( nb_metadata > 0 ) {
(*node)->mMetaData = aiMetadata::Alloc(nb_metadata);
node->mMetaData = aiMetadata::Alloc(nb_metadata);
for (unsigned int i = 0; i < nb_metadata; ++i) {
(*node)->mMetaData->mKeys[i] = Read<aiString>(stream);
(*node)->mMetaData->mValues[i].mType = (aiMetadataType) Read<uint16_t>(stream);
void* data( nullptr );
node->mMetaData->mKeys[i] = Read<aiString>(stream);
node->mMetaData->mValues[i].mType = (aiMetadataType) Read<uint16_t>(stream);
void* data = nullptr;
switch ((*node)->mMetaData->mValues[i].mType) {
switch (node->mMetaData->mValues[i].mType) {
case AI_BOOL:
data = new bool(Read<bool>(stream));
break;
@@ -275,16 +281,16 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* p
break;
}
(*node)->mMetaData->mValues[i].mData = data;
node->mMetaData->mValues[i].mData = data;
}
}
*onode = node.release();
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIBONE)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
b->mName = Read<aiString>(stream);
@@ -306,12 +312,10 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b ) {
static bool fitsIntoUI16(unsigned int mNumVertices) {
return ( mNumVertices < (1u<<16) );
}
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMESH)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
mesh->mPrimitiveTypes = Read<unsigned int>(stream);
@@ -423,9 +427,8 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh ) {
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMATERIALPROPERTY)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
prop->mKey = Read<aiString>(stream);
@@ -440,9 +443,8 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIMATERIAL)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
@@ -462,9 +464,8 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat) {
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AINODEANIM)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
nd->mNodeName = Read<aiString>(stream);
@@ -508,9 +509,8 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd) {
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AIANIMATION)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
anim->mName = Read<aiString> (stream);
@@ -529,9 +529,8 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim ) {
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AITEXTURE)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
tex->mWidth = Read<unsigned int>(stream);
@@ -551,9 +550,8 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex) {
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AILIGHT)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
l->mName = Read<aiString>(stream);
@@ -577,9 +575,8 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l ) {
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AICAMERA)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
cam->mName = Read<aiString>(stream);
@@ -594,9 +591,8 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam ) {
// -----------------------------------------------------------------------------------
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
uint32_t chunkID = Read<uint32_t>(stream);
(void)(chunkID);
ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
if(Read<uint32_t>(stream) != ASSBIN_CHUNK_AISCENE)
throw DeadlyImportError("Magic chunk identifiers are wrong!");
/*uint32_t size =*/ Read<uint32_t>(stream);
scene->mFlags = Read<unsigned int>(stream);
@@ -614,6 +610,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
// Read all meshes
if (scene->mNumMeshes) {
scene->mMeshes = new aiMesh*[scene->mNumMeshes];
memset(scene->mMeshes, 0, scene->mNumMeshes*sizeof(aiMesh*));
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
scene->mMeshes[i] = new aiMesh();
ReadBinaryMesh( stream,scene->mMeshes[i]);
@@ -623,6 +620,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
// Read materials
if (scene->mNumMaterials) {
scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
memset(scene->mMaterials, 0, scene->mNumMaterials*sizeof(aiMaterial*));
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
scene->mMaterials[i] = new aiMaterial();
ReadBinaryMaterial(stream,scene->mMaterials[i]);
@@ -632,6 +630,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
// Read all animations
if (scene->mNumAnimations) {
scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
memset(scene->mAnimations, 0, scene->mNumAnimations*sizeof(aiAnimation*));
for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
scene->mAnimations[i] = new aiAnimation();
ReadBinaryAnim(stream,scene->mAnimations[i]);
@@ -641,6 +640,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
// Read all textures
if (scene->mNumTextures) {
scene->mTextures = new aiTexture*[scene->mNumTextures];
memset(scene->mTextures, 0, scene->mNumTextures*sizeof(aiTexture*));
for (unsigned int i = 0; i < scene->mNumTextures;++i) {
scene->mTextures[i] = new aiTexture();
ReadBinaryTexture(stream,scene->mTextures[i]);
@@ -650,6 +650,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
// Read lights
if (scene->mNumLights) {
scene->mLights = new aiLight*[scene->mNumLights];
memset(scene->mLights, 0, scene->mNumLights*sizeof(aiLight*));
for (unsigned int i = 0; i < scene->mNumLights;++i) {
scene->mLights[i] = new aiLight();
ReadBinaryLight(stream,scene->mLights[i]);
@@ -659,6 +660,7 @@ void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene ) {
// Read cameras
if (scene->mNumCameras) {
scene->mCameras = new aiCamera*[scene->mNumCameras];
memset(scene->mCameras, 0, scene->mNumCameras*sizeof(aiCamera*));
for (unsigned int i = 0; i < scene->mNumCameras;++i) {
scene->mCameras[i] = new aiCamera();
ReadBinaryCamera(stream,scene->mCameras[i]);
@@ -675,7 +677,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
}
// signature
stream->Seek( 44, aiOrigin_CUR );
stream->Seek( 44, aiOrigin_CUR );
unsigned int versionMajor = Read<unsigned int>(stream);
unsigned int versionMinor = Read<unsigned int>(stream);
@@ -701,11 +703,19 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell());
unsigned char * compressedData = new unsigned char[ compressedSize ];
stream->Read( compressedData, 1, compressedSize );
size_t len = stream->Read( compressedData, 1, compressedSize );
ai_assert(len == compressedSize);
unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
uncompress( uncompressedData, &uncompressedSize, compressedData, compressedSize );
int res = uncompress( uncompressedData, &uncompressedSize, compressedData, len );
if(res != Z_OK)
{
delete [] uncompressedData;
delete [] compressedData;
pIOHandler->Close(stream);
throw DeadlyImportError("Zlib decompression failed.");
}
MemoryIOStream io( uncompressedData, uncompressedSize );

View File

@@ -181,8 +181,7 @@ void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints,
ch->mParent = nd;
ch->mTransformation = aiMatrix4x4::Translation(joints[i].position,aiMatrix4x4()=aiMatrix4x4())*
// XXX actually, I don't *know* why we need the inverse here. Probably column vs. row order?
aiMatrix4x4().FromEulerAnglesXYZ(joints[i].rotation).Transpose();
aiMatrix4x4().FromEulerAnglesXYZ(joints[i].rotation);
const aiMatrix4x4 abs = absTrafo*ch->mTransformation;
for(unsigned int a = 0; a < mScene->mNumMeshes; ++a) {
@@ -639,11 +638,8 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
aiQuatKey& q = nd->mRotationKeys[nd->mNumRotationKeys++];
q.mTime = (*rot).time*animfps;
// XXX it seems our matrix&quaternion code has faults in its conversion routines --
// aiQuaternion(x,y,z) seems to besomething different as quat(matrix.fromeuler(x,y,z)).
q.mValue = aiQuaternion(aiMatrix3x3(aiMatrix4x4().FromEulerAnglesXYZ((*rot).value)*
aiMatrix4x4().FromEulerAnglesXYZ((*it).rotation)).Transpose());
q.mValue = aiQuaternion(aiMatrix3x3(aiMatrix4x4().FromEulerAnglesXYZ((*it).rotation)*
aiMatrix4x4().FromEulerAnglesXYZ((*rot).value)));
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -219,6 +219,7 @@ protected:
/** Parse the SMD file and create the output scene
*/
void ParseFile();
void ReadSmd(const std::string &pFile, IOSystem* pIOHandler);
// -------------------------------------------------------------------
/** Parse the triangles section of the SMD file
@@ -289,13 +290,6 @@ protected:
*/
unsigned int GetTextureIndex(const std::string& filename);
// -------------------------------------------------------------------
/** Computes absolute bone transformations
* All output transformations are in worldspace.
*/
void ComputeAbsoluteBoneTransformations();
// -------------------------------------------------------------------
/** Parse a line in the skeleton section
*/
@@ -344,7 +338,9 @@ protected:
*/
void CreateOutputMeshes();
void CreateOutputNodes();
void CreateOutputAnimations();
void CreateOutputAnimations(const std::string &pFile, IOSystem* pIOHandler);
void CreateOutputAnimation(int index, const std::string &name);
void GetAnimationFileList(const std::string &pFile, IOSystem* pIOHandler, std::vector<std::tuple<std::string, std::string>>& outList);
void CreateOutputMaterials();
@@ -413,6 +409,8 @@ private:
*/
unsigned int iLineNumber;
bool bLoadAnimationList = true;
bool noSkeletonMesh = false;
};
} // end of namespace Assimp

View File

@@ -1357,6 +1357,13 @@ inline void Asset::Load(const std::string& pFile, bool isBinary)
}
}
// Force reading of skins since they're not always directly referenced
if (Value* skinsArray = FindArray(doc, "skins")) {
for (unsigned int i = 0; i < skinsArray->Size(); ++i) {
skins.Retrieve(i);
}
}
if (Value* animsArray = FindArray(doc, "animations")) {
for (unsigned int i = 0; i < animsArray->Size(); ++i) {
animations.Retrieve(i);