Merge branch 'master' of https://github.com/assimp/assimp
commit
e2fa181aa6
|
@ -482,37 +482,43 @@ bool Importer::ValidateFlags(unsigned int pFlags) const {
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
|
||||
size_t pLength,
|
||||
unsigned int pFlags,
|
||||
const char* pHint /*= ""*/) {
|
||||
const aiScene* Importer::ReadFileFromMemory(const void* pBuffer, size_t pLength, unsigned int pFlags, const char* pHint ) {
|
||||
ai_assert(nullptr != pimpl);
|
||||
|
||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||
if (!pHint) {
|
||||
pHint = "";
|
||||
}
|
||||
|
||||
if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint ) {
|
||||
pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// prevent deletion of the previous IOHandler
|
||||
IOSystem* io = pimpl->mIOHandler;
|
||||
pimpl->mIOHandler = nullptr;
|
||||
try {
|
||||
if (pHint == nullptr) {
|
||||
pHint = "";
|
||||
}
|
||||
if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint ) {
|
||||
pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()";
|
||||
return nullptr;
|
||||
}
|
||||
// prevent deletion of the previous IOHandler
|
||||
pimpl->mIOHandler = nullptr;
|
||||
|
||||
SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength,io));
|
||||
SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength,io));
|
||||
|
||||
// read the file and recover the previous IOSystem
|
||||
static const size_t BufSize(Importer::MaxLenHint + 28);
|
||||
char fbuff[BufSize];
|
||||
ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
|
||||
// read the file and recover the previous IOSystem
|
||||
static const size_t BufSize(Importer::MaxLenHint + 28);
|
||||
char fbuff[BufSize];
|
||||
ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
|
||||
|
||||
ReadFile(fbuff,pFlags);
|
||||
SetIOHandler(io);
|
||||
ReadFile(fbuff,pFlags);
|
||||
SetIOHandler(io);
|
||||
} catch(const DeadlyImportError &e) {
|
||||
pimpl->mErrorString = e.what();
|
||||
pimpl->mException = std::current_exception();
|
||||
SetIOHandler(io);
|
||||
return ExceptionSwallower<const aiScene*>()(); \
|
||||
} catch(...) {
|
||||
pimpl->mErrorString = "Unknown exception";
|
||||
pimpl->mException = std::current_exception();
|
||||
SetIOHandler(io);
|
||||
return ExceptionSwallower<const aiScene*>()(); \
|
||||
|
||||
}
|
||||
|
||||
ASSIMP_END_EXCEPTION_REGION_WITH_ERROR_STRING(const aiScene*, pimpl->mErrorString, pimpl->mException);
|
||||
return pimpl->mScene;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2020, assimp team
|
||||
Copyright (c) 2006-2023, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -46,8 +46,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
using namespace Assimp;
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) {
|
||||
aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
|
||||
aiAttachLogStream(&stream);
|
||||
aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
|
||||
aiAttachLogStream(&stream);
|
||||
|
||||
Importer importer;
|
||||
const aiScene *sc = importer.ReadFileFromMemory(data, dataSize,
|
||||
|
@ -57,3 +57,4 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -66,23 +65,21 @@ namespace Assimp {
|
|||
// ----------------------------------------------------------------------------------
|
||||
class MemoryIOStream : public IOStream {
|
||||
public:
|
||||
MemoryIOStream (const uint8_t* buff, size_t len, bool own = false)
|
||||
: buffer (buff)
|
||||
, length(len)
|
||||
, pos((size_t)0)
|
||||
, own(own) {
|
||||
MemoryIOStream (const uint8_t* buff, size_t len, bool own = false) :
|
||||
buffer (buff),
|
||||
length(len),
|
||||
pos(static_cast<size_t>(0)),
|
||||
own(own) {
|
||||
// empty
|
||||
}
|
||||
|
||||
~MemoryIOStream () {
|
||||
~MemoryIOStream() override {
|
||||
if(own) {
|
||||
delete[] buffer;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Read from stream
|
||||
size_t Read(void* pvBuffer, size_t pSize, size_t pCount) {
|
||||
size_t Read(void* pvBuffer, size_t pSize, size_t pCount) override {
|
||||
ai_assert(nullptr != pvBuffer);
|
||||
ai_assert(0 != pSize);
|
||||
|
||||
|
@ -95,16 +92,12 @@ public:
|
|||
return cnt;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Write to stream
|
||||
size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/,size_t /*pCount*/) {
|
||||
size_t Write(const void*, size_t, size_t ) override {
|
||||
ai_assert(false); // won't be needed
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Seek specific position
|
||||
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) {
|
||||
aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override {
|
||||
if (aiOrigin_SET == pOrigin) {
|
||||
if (pOffset > length) {
|
||||
return AI_FAILURE;
|
||||
|
@ -124,21 +117,15 @@ public:
|
|||
return AI_SUCCESS;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get current seek position
|
||||
size_t Tell() const {
|
||||
size_t Tell() const override {
|
||||
return pos;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get size of file
|
||||
size_t FileSize() const {
|
||||
size_t FileSize() const override {
|
||||
return length;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Flush file contents
|
||||
void Flush() {
|
||||
void Flush() override{
|
||||
ai_assert(false); // won't be needed
|
||||
}
|
||||
|
||||
|
@ -149,24 +136,21 @@ private:
|
|||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** Dummy IO system to read from a memory buffer */
|
||||
/// @brief Dummy IO system to read from a memory buffer.
|
||||
class MemoryIOSystem : public IOSystem {
|
||||
public:
|
||||
/** Constructor. */
|
||||
MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io)
|
||||
: buffer(buff)
|
||||
, length(len)
|
||||
, existing_io(io)
|
||||
, created_streams() {
|
||||
/// @brief Constructor.
|
||||
MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io) : buffer(buff), length(len), existing_io(io) {
|
||||
// empty
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
/// @brief Destructor.
|
||||
~MemoryIOSystem() = default;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Tests for the existence of a file at the given path. */
|
||||
/// @brief Tests for the existence of a file at the given path.
|
||||
bool Exists(const char* pFile) const override {
|
||||
printf("Exists\n");
|
||||
if (0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) {
|
||||
return true;
|
||||
}
|
||||
|
@ -174,24 +158,24 @@ public:
|
|||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns the directory separator. */
|
||||
/// @brief Returns the directory separator.
|
||||
char getOsSeparator() const override {
|
||||
return existing_io ? existing_io->getOsSeparator()
|
||||
: '/'; // why not? it doesn't care
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Open a new file with a given path. */
|
||||
/// @brief Open a new file with a given path.
|
||||
IOStream* Open(const char* pFile, const char* pMode = "rb") override {
|
||||
if ( 0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) {
|
||||
created_streams.emplace_back(new MemoryIOStream(buffer, length));
|
||||
return created_streams.back();
|
||||
}
|
||||
return existing_io ? existing_io->Open(pFile, pMode) : NULL;
|
||||
return existing_io ? existing_io->Open(pFile, pMode) : nullptr;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Closes the given file and releases all resources associated with it. */
|
||||
/// @brief Closes the given file and releases all resources associated with it.
|
||||
void Close( IOStream* pFile) override {
|
||||
auto it = std::find(created_streams.begin(), created_streams.end(), pFile);
|
||||
if (it != created_streams.end()) {
|
||||
|
@ -203,36 +187,43 @@ public:
|
|||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Compare two paths */
|
||||
/// @brief Compare two paths
|
||||
bool ComparePaths(const char* one, const char* second) const override {
|
||||
return existing_io ? existing_io->ComparePaths(one, second) : false;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Will push the directory.
|
||||
bool PushDirectory( const std::string &path ) override {
|
||||
return existing_io ? existing_io->PushDirectory(path) : false;
|
||||
}
|
||||
|
||||
/// @brief Will return the current directory from the stack top.
|
||||
const std::string &CurrentDirectory() const override {
|
||||
static std::string empty;
|
||||
return existing_io ? existing_io->CurrentDirectory() : empty;
|
||||
}
|
||||
|
||||
/// @brief Returns the stack size.
|
||||
size_t StackSize() const override {
|
||||
return existing_io ? existing_io->StackSize() : 0;
|
||||
}
|
||||
|
||||
/// @brief Will pop the upper directory.
|
||||
bool PopDirectory() override {
|
||||
return existing_io ? existing_io->PopDirectory() : false;
|
||||
}
|
||||
|
||||
/// @brief Will create the directory.
|
||||
bool CreateDirectory( const std::string &path ) override {
|
||||
return existing_io ? existing_io->CreateDirectory(path) : false;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Will change the directory.
|
||||
bool ChangeDirectory( const std::string &path ) override {
|
||||
return existing_io ? existing_io->ChangeDirectory(path) : false;
|
||||
}
|
||||
|
||||
/// @brief Will delete the file.
|
||||
bool DeleteFile( const std::string &file ) override {
|
||||
return existing_io ? existing_io->DeleteFile(file) : false;
|
||||
}
|
||||
|
@ -246,4 +237,4 @@ private:
|
|||
|
||||
} // end namespace Assimp
|
||||
|
||||
#endif
|
||||
#endif // AI_MEMORYIOSTREAM_H_INC
|
||||
|
|
|
@ -631,7 +631,9 @@ struct aiMesh {
|
|||
*/
|
||||
C_STRUCT aiVector3D *mVertices;
|
||||
|
||||
/** Vertex normals.
|
||||
/**
|
||||
* @brief Vertex normals.
|
||||
*
|
||||
* The array contains normalized vectors, nullptr if not present.
|
||||
* The array is mNumVertices in size. Normals are undefined for
|
||||
* point and line primitives. A mesh consisting of points and
|
||||
|
@ -770,7 +772,7 @@ struct aiMesh {
|
|||
|
||||
#ifdef __cplusplus
|
||||
|
||||
//! Default constructor. Initializes all members to 0
|
||||
//! The default class constructor.
|
||||
aiMesh() AI_NO_EXCEPT
|
||||
: mPrimitiveTypes(0),
|
||||
mNumVertices(0),
|
||||
|
@ -952,17 +954,32 @@ struct aiMesh {
|
|||
#endif // __cplusplus
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief A skeleton bone represents a single bone in a aiSkeleton instance.
|
||||
*
|
||||
* Skeleton-Animations can be represented via a skeleton struct, which describes
|
||||
* a hierarchical tree assembled from skeleton bones. A bone is linked to a mesh.
|
||||
* The bone knows its parent bone. If there is no parent bone the parent id is
|
||||
* marked with -1.
|
||||
* The skeleton-bone stores a pointer to its used armature. If there is no
|
||||
* armature this value if set to nullptr.
|
||||
* A skeleton bone stores its offset-matrix, which is the absolute transformation
|
||||
* for the bone. The bone stores the locale transformation to its parent as well.
|
||||
* You can compute the offset matrix by multiplying the hierarchy like:
|
||||
* Tree: s1 -> s2 -> s3
|
||||
* Offset-Matrix s3 = locale-s3 * locale-s2 * locale-s1
|
||||
*/
|
||||
struct aiSkeletonBone {
|
||||
/// The parent bone index, is -1 one if this bone represents the root bone.
|
||||
int mParent;
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
|
||||
/// The bone armature node - used for skeleton conversion
|
||||
/// @brief The bone armature node - used for skeleton conversion
|
||||
/// you must enable aiProcess_PopulateArmatureData to populate this
|
||||
C_STRUCT aiNode *mArmature;
|
||||
|
||||
/// The bone node in the scene - used for skeleton conversion
|
||||
/// @brief The bone node in the scene - used for skeleton conversion
|
||||
/// you must enable aiProcess_PopulateArmatureData to populate this
|
||||
C_STRUCT aiNode *mNode;
|
||||
|
||||
|
@ -993,6 +1010,7 @@ struct aiSkeletonBone {
|
|||
C_STRUCT aiMatrix4x4 mLocalMatrix;
|
||||
|
||||
#ifdef __cplusplus
|
||||
/// @brief The class constructor.
|
||||
aiSkeletonBone() :
|
||||
mParent(-1),
|
||||
#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
|
||||
|
@ -1007,6 +1025,7 @@ struct aiSkeletonBone {
|
|||
// empty
|
||||
}
|
||||
|
||||
/// @brief The class destructor.
|
||||
~aiSkeletonBone() {
|
||||
delete[] mWeights;
|
||||
mWeights = nullptr;
|
||||
|
@ -1014,34 +1033,45 @@ struct aiSkeletonBone {
|
|||
#endif // __cplusplus
|
||||
};
|
||||
/**
|
||||
* @brief
|
||||
* @brief A skeleton represents the bone hierarchy of an animation.
|
||||
*
|
||||
* Skeleton animations can be described as a tree of bones:
|
||||
* root
|
||||
* |
|
||||
* node1
|
||||
* / \
|
||||
* node3 node4
|
||||
* If you want to calculate the transformation of node three you need to compute the
|
||||
* transformation hierarchy for the transformation chain of node3:
|
||||
* root->node1->node3
|
||||
* Each node is represented as a skeleton instance.
|
||||
*/
|
||||
struct aiSkeleton {
|
||||
/**
|
||||
*
|
||||
* @brief The name of the skeleton instance.
|
||||
*/
|
||||
C_STRUCT aiString mName;
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief The number of bones in the skeleton.
|
||||
*/
|
||||
unsigned int mNumBones;
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief The bone instance in the skeleton.
|
||||
*/
|
||||
C_STRUCT aiSkeletonBone **mBones;
|
||||
|
||||
#ifdef __cplusplus
|
||||
/**
|
||||
*
|
||||
* @brief The class constructor.
|
||||
*/
|
||||
aiSkeleton() AI_NO_EXCEPT : mName(), mNumBones(0), mBones(nullptr) {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief The class destructor.
|
||||
*/
|
||||
~aiSkeleton() {
|
||||
delete[] mBones;
|
||||
|
|
Loading…
Reference in New Issue