Merge branch 'master' into GLTF2_recursive_references_fix

pull/3070/head
Kim Kulling 2020-04-16 11:29:37 +02:00 committed by GitHub
commit c0dc26de8e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 2446 additions and 739 deletions

View File

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: configure
run: cmake CMakeLists.txt
- name: build
@ -23,7 +23,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: configure
run: cmake CMakeLists.txt
- name: build
@ -35,7 +35,7 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v2
- name: configure
run: cmake CMakeLists.txt
- name: build

View File

@ -7,6 +7,14 @@ set(CMAKE_IMPORT_FILE_VERSION 1)
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
if ("${LIB64}" STREQUAL "TRUE")
set(LIBSUFFIX 64)
else()
set(LIBSUFFIX "")
endif()
if(MSVC)
if(MSVC_TOOLSET_VERSION)
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
@ -75,23 +83,20 @@ else()
endif()
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib${LIBSUFFIX}/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib${LIBSUFFIX}/${sharedLibraryName}" )
else()
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib${LIBSUFFIX}/${staticLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}" )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib${LIBSUFFIX}/${staticLibraryName}" )
endif()
endif()
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)

View File

@ -7,6 +7,14 @@ set(CMAKE_IMPORT_FILE_VERSION 1)
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
if ("${LIB64}" STREQUAL "TRUE")
set(LIBSUFFIX 64)
else()
set(LIBSUFFIX "")
endif()
if(MSVC)
if(MSVC_TOOLSET_VERSION)
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
@ -75,17 +83,17 @@ else()
endif()
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib${LIBSUFFIX}/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib${LIBSUFFIX}/${sharedLibraryName}" )
else()
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib${LIBSUFFIX}/${staticLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}" )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib${LIBSUFFIX}/${staticLibraryName}" )
endif()
endif()

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -43,7 +41,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the 3ds importer class */
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// internal headers

View File

@ -322,7 +322,7 @@ struct Face : public FaceWithSmoothingGroup {
};
#ifdef _WIN32
# pragma warning(disable : 4315)
#pragma warning(disable : 4315)
#endif
// ---------------------------------------------------------------------------
@ -441,30 +441,52 @@ struct Material {
// empty
}
Material(const Material &other) = default;
Material &operator=(const Material &other) = default;
Material(const Material &other) :
mName(other.mName),
mDiffuse(other.mDiffuse),
mSpecularExponent(other.mSpecularExponent),
mShininessStrength(other.mShininessStrength),
mSpecular(other.mSpecular),
mAmbient(other.mAmbient),
mShading(other.mShading),
mTransparency(other.mTransparency),
sTexDiffuse(other.sTexDiffuse),
sTexOpacity(other.sTexOpacity),
sTexSpecular(other.sTexSpecular),
sTexReflective(other.sTexReflective),
sTexBump(other.sTexBump),
sTexEmissive(other.sTexEmissive),
sTexShininess(other.sTexShininess),
mBumpHeight(other.mBumpHeight),
mEmissive(other.mEmissive),
sTexAmbient(other.sTexAmbient),
mTwoSided(other.mTwoSided) {
// empty
}
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
Material(Material &&other) AI_NO_EXCEPT
: mName(std::move(other.mName)),
mDiffuse(std::move(other.mDiffuse)),
mSpecularExponent(std::move(other.mSpecularExponent)),
mShininessStrength(std::move(other.mShininessStrength)),
mSpecular(std::move(other.mSpecular)),
mAmbient(std::move(other.mAmbient)),
mShading(std::move(other.mShading)),
mTransparency(std::move(other.mTransparency)),
sTexDiffuse(std::move(other.sTexDiffuse)),
sTexOpacity(std::move(other.sTexOpacity)),
sTexSpecular(std::move(other.sTexSpecular)),
sTexReflective(std::move(other.sTexReflective)),
sTexBump(std::move(other.sTexBump)),
sTexEmissive(std::move(other.sTexEmissive)),
sTexShininess(std::move(other.sTexShininess)),
mBumpHeight(std::move(other.mBumpHeight)),
mEmissive(std::move(other.mEmissive)),
sTexAmbient(std::move(other.sTexAmbient)),
mTwoSided(std::move(other.mTwoSided)) {
Material(Material &&other) AI_NO_EXCEPT :
mName(std::move(other.mName)),
mDiffuse(std::move(other.mDiffuse)),
mSpecularExponent(std::move(other.mSpecularExponent)),
mShininessStrength(std::move(other.mShininessStrength)),
mSpecular(std::move(other.mSpecular)),
mAmbient(std::move(other.mAmbient)),
mShading(std::move(other.mShading)),
mTransparency(std::move(other.mTransparency)),
sTexDiffuse(std::move(other.sTexDiffuse)),
sTexOpacity(std::move(other.sTexOpacity)),
sTexSpecular(std::move(other.sTexSpecular)),
sTexReflective(std::move(other.sTexReflective)),
sTexBump(std::move(other.sTexBump)),
sTexEmissive(std::move(other.sTexEmissive)),
sTexShininess(std::move(other.sTexShininess)),
mBumpHeight(std::move(other.mBumpHeight)),
mEmissive(std::move(other.mEmissive)),
sTexAmbient(std::move(other.sTexAmbient)),
mTwoSided(std::move(other.mTwoSided)) {
// empty
}
Material &operator=(Material &&other) AI_NO_EXCEPT {

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -72,7 +70,6 @@ static const aiImporterDesc desc = {
"3ds prj"
};
// ------------------------------------------------------------------------------------------------
// Begins a new parsing block
// - Reads the current chunk and validates it
@ -141,15 +138,13 @@ bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandle
// ------------------------------------------------------------------------------------------------
// Loader registry entry
const aiImporterDesc* Discreet3DSImporter::GetInfo () const
{
const aiImporterDesc* Discreet3DSImporter::GetInfo () const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties
void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/)
{
void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/) {
// nothing to be done for the moment
}
@ -200,7 +195,7 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
}
// Replace all occurences of the default material with a
// Replace all occurrences 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();
@ -227,8 +222,7 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------
// Applies a master-scaling factor to the imported scene
void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene)
{
void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene) {
// There are some 3DS files with a zero scaling factor
if (!mMasterScale)mMasterScale = 1.0f;
else mMasterScale = 1.0f / mMasterScale;
@ -1084,7 +1078,7 @@ void Discreet3DSImporter::ParseMeshChunk()
mMesh.mFaceMaterials.resize(mMesh.mFaces.size(),0xcdcdcdcd);
// Larger 3DS files could have multiple FACE chunks here
chunkSize = stream->GetRemainingSizeToLimit();
chunkSize = (int)stream->GetRemainingSizeToLimit();
if ( chunkSize > (int) sizeof(Discreet3DS::Chunk ) )
ParseFaceChunk();
}

View File

@ -65,15 +65,11 @@ using namespace D3DS;
// ---------------------------------------------------------------------------------
/** Importer class for 3D Studio r3 and r4 3DS files
*/
class Discreet3DSImporter : public BaseImporter
{
class Discreet3DSImporter : public BaseImporter {
public:
Discreet3DSImporter();
~Discreet3DSImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.

View File

@ -9,6 +9,9 @@ For details, see http://sourceforge.net/projects/libb64
const int CHARS_PER_LINE = 72;
#pragma warning(push)
#pragma warning(disable : 4244)
void base64_init_encodestate(base64_encodestate* state_in)
{
state_in->step = step_A;
@ -107,3 +110,4 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
return (int)(codechar - code_out);
}
#pragma warning(pop)

View File

@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp>
#include <assimp/Exporter.hpp>
namespace Assimp {
namespace Assimp {
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
{

View File

@ -206,7 +206,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
inflateInit2(&zstream, 16+MAX_WBITS);
zstream.next_in = reinterpret_cast<Bytef*>( reader->GetPtr() );
zstream.avail_in = reader->GetRemainingSize();
zstream.avail_in = (uInt) reader->GetRemainingSize();
size_t total = 0l;

View File

@ -178,7 +178,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
*ot++ = *buffer++;
*ot = '\0';
nda->mNodeName.length = (ai_uint32)(ot-nda->mNodeName.data);
nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data);
}
anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());

View File

@ -83,32 +83,61 @@ namespace Assimp {
void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
// ------------------------------------------------------------------------------------------------
// Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
// do not use const, because some exporter need to convert the scene temporary
// Exporter worker function prototypes. Do not use const, because some exporter need to convert
// the scene temporary
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneObjNoMtl(const char*,IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneGLB2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
#endif
#ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
void ExportSceneM3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
void ExportSceneM3DA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
#endif
#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
#endif
static void setupExporterArray(std::vector<Exporter::ExportFormatEntry> &exporters) {
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER

View File

@ -1483,6 +1483,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
*/
delete root;
delete reader;
}
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER

View File

@ -189,42 +189,42 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
continue;
if (aiProps[k].pKey) {
switch (m3d_propertytypes[k].format) {
case m3dpf_color:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, c) == AI_SUCCESS)
addProp(&m3d->material[mi],
m3d_propertytypes[k].id, mkColor(&c));
break;
case m3dpf_float:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, f) == AI_SUCCESS)
addProp(&m3d->material[mi],
m3d_propertytypes[k].id,
/* not (uint32_t)f, because we don't want to convert
case m3dpf_color:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, c) == AI_SUCCESS)
addProp(&m3d->material[mi],
m3d_propertytypes[k].id, mkColor(&c));
break;
case m3dpf_float:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, f) == AI_SUCCESS)
addProp(&m3d->material[mi],
m3d_propertytypes[k].id,
/* not (uint32_t)f, because we don't want to convert
* it, we want to see it as 32 bits of memory */
*((uint32_t *)&f));
break;
case m3dpf_uint8:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, j) == AI_SUCCESS) {
// special conversion for illumination model property
if (m3d_propertytypes[k].id == m3dp_il) {
switch (j) {
case aiShadingMode_NoShading: j = 0; break;
case aiShadingMode_Phong: j = 2; break;
default: j = 1; break;
}
*((uint32_t *)&f));
break;
case m3dpf_uint8:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, j) == AI_SUCCESS) {
// special conversion for illumination model property
if (m3d_propertytypes[k].id == m3dp_il) {
switch (j) {
case aiShadingMode_NoShading: j = 0; break;
case aiShadingMode_Phong: j = 2; break;
default: j = 1; break;
}
addProp(&m3d->material[mi],
m3d_propertytypes[k].id, j);
}
break;
default:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, j) == AI_SUCCESS)
addProp(&m3d->material[mi],
m3d_propertytypes[k].id, j);
break;
addProp(&m3d->material[mi],
m3d_propertytypes[k].id, j);
}
break;
default:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, j) == AI_SUCCESS)
addProp(&m3d->material[mi],
m3d_propertytypes[k].id, j);
break;
}
}
if (aiTxProps[k].pKey &&
@ -292,8 +292,8 @@ void ExportSceneM3D(
// Prototyped and registered in Exporter.cpp
void ExportSceneM3DA(
const char *,
IOSystem*,
const aiScene*,
IOSystem *,
const aiScene *,
const ExportProperties *
) {
@ -312,7 +312,9 @@ void ExportSceneM3DA(
M3DExporter::M3DExporter(const aiScene *pScene, const ExportProperties *pProperties) :
mScene(pScene),
mProperties(pProperties),
outfile() {}
outfile() {
// empty
}
// ------------------------------------------------------------------------------------------------
void M3DExporter::doExport(
@ -352,6 +354,9 @@ void M3DExporter::doExport(
// explicitly release file pointer,
// so we don't have to rely on class destruction.
outfile.reset();
M3D_FREE(m3d->name);
m3d->name = nullptr;
}
// ------------------------------------------------------------------------------------------------

View File

@ -50,15 +50,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef ASSIMP_USE_M3D_READFILECB
# if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
# define threadlocal thread_local
# else
# if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
# define threadlocal __declspec(thread)
# else
# define threadlocal
# endif
# endif
#if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
#define threadlocal thread_local
#else
#if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
#define threadlocal __declspec(thread)
#else
#define threadlocal
#endif
#endif
extern "C" {
@ -66,37 +66,37 @@ extern "C" {
threadlocal void *m3dimporter_pIOHandler;
unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
ai_assert(nullptr != fn);
ai_assert(nullptr != size);
std::string file(fn);
std::unique_ptr<Assimp::IOStream> pStream(
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
size_t fileSize = 0;
unsigned char *data = NULL;
// sometimes pStream is nullptr in a single-threaded scenario too for some reason
// (should be an empty object returning nothing I guess)
if (pStream) {
fileSize = pStream->FileSize();
// should be allocated with malloc(), because the library will call free() to deallocate
data = (unsigned char *)malloc(fileSize);
if (!data || !pStream.get() || !fileSize || fileSize != pStream->Read(data, 1, fileSize)) {
pStream.reset();
*size = 0;
// don't throw a deadly exception, it's not fatal if we can't read an external asset
return nullptr;
}
pStream.reset();
}
*size = (int)fileSize;
return data;
ai_assert(nullptr != fn);
ai_assert(nullptr != size);
std::string file(fn);
std::unique_ptr<Assimp::IOStream> pStream(
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
size_t fileSize = 0;
unsigned char *data = NULL;
// sometimes pStream is nullptr in a single-threaded scenario too for some reason
// (should be an empty object returning nothing I guess)
if (pStream) {
fileSize = pStream->FileSize();
// should be allocated with malloc(), because the library will call free() to deallocate
data = (unsigned char *)malloc(fileSize);
if (!data || !pStream.get() || !fileSize || fileSize != pStream->Read(data, 1, fileSize)) {
pStream.reset();
*size = 0;
// don't throw a deadly exception, it's not fatal if we can't read an external asset
return nullptr;
}
pStream.reset();
}
*size = (int)fileSize;
return data;
}
}
#endif
namespace Assimp {
M3DWrapper::M3DWrapper() {
// use malloc() here because m3d_free() will call free()
m3d_ = (m3d_t *)calloc(1, sizeof(m3d_t));
// use malloc() here because m3d_free() will call free()
m3d_ = (m3d_t *)calloc(1, sizeof(m3d_t));
}
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
@ -105,41 +105,42 @@ M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &b
}
#ifdef ASSIMP_USE_M3D_READFILECB
// pass this IOHandler to the C callback in a thread-local pointer
m3dimporter_pIOHandler = pIOHandler;
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
// Clear the C callback
m3dimporter_pIOHandler = nullptr;
// pass this IOHandler to the C callback in a thread-local pointer
m3dimporter_pIOHandler = pIOHandler;
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
// Clear the C callback
m3dimporter_pIOHandler = nullptr;
#else
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
#endif
}
M3DWrapper::~M3DWrapper() {
reset();
reset();
}
void M3DWrapper::reset() {
ClearSave();
if (m3d_)
m3d_free(m3d_);
m3d_ = nullptr;
ClearSave();
if (m3d_) {
m3d_free(m3d_);
}
m3d_ = nullptr;
}
unsigned char *M3DWrapper::Save(int quality, int flags, unsigned int &size) {
#if (!(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER))
ClearSave();
saved_output_ = m3d_save(m3d_, quality, flags, &size);
return saved_output_;
ClearSave();
saved_output_ = m3d_save(m3d_, quality, flags, &size);
return saved_output_;
#else
return nullptr;
return nullptr;
#endif
}
void M3DWrapper::ClearSave() {
if (saved_output_)
M3D_FREE(saved_output_);
saved_output_ = nullptr;
if (saved_output_)
M3D_FREE(saved_output_);
saved_output_ = nullptr;
}
} // namespace Assimp

View File

@ -5440,13 +5440,13 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
out += 2;
break;
case 4:
*((float *)out) = vrtx[i].data.x;
memcpy(out, &vrtx[i].data.x, sizeof(float));
out += 4;
*((float *)out) = vrtx[i].data.y;
memcpy(out, &vrtx[i].data.y, sizeof(float));
out += 4;
*((float *)out) = vrtx[i].data.z;
memcpy(out, &vrtx[i].data.z, sizeof(float));
out += 4;
*((float *)out) = vrtx[i].data.w;
memcpy(out, &vrtx[i].data.w, sizeof(float));
out += 4;
break;
case 8:
@ -5474,9 +5474,11 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
}
out = _m3d_addidx(out, sk_s, vrtx[i].data.skinid);
}
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
memcpy(length, &v, sizeof(uint32_t));
//*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
out = NULL;
len += *length;
len += v;
}
/* bones chunk */
if (model->numbone && model->bone && !(flags & M3D_EXP_NOBONE)) {
@ -5660,8 +5662,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
out = _m3d_addidx(out, vi_s, vrtxidx[face[i].data.normal[j]]);
}
}
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
len += *length;
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
memcpy(length, &v, sizeof(uint32_t));
len += v;
out = NULL;
}
/* mathematical shapes face */
@ -5721,8 +5724,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
}
}
}
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
len += *length;
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
memcpy( length, &v, sizeof(uint32_t));
len += v;
out = NULL;
}
}
@ -5765,8 +5769,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
out = _m3d_addidx(out, si_s, _m3d_stridx(str, numstr, model->label[l].text));
}
if (length) {
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
len += *length;
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
memcpy( length, &v, sizeof(uint32_t));
len += v;
}
out = NULL;
sn = sl = NULL;
@ -5796,8 +5801,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
out = _m3d_addidx(out, vi_s, vrtxidx[a->frame[i].transform[k].ori]);
}
}
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
len += *length;
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
memcpy( length, &v, sizeof(uint32_t));
len += v;
out = NULL;
}
}

View File

@ -503,7 +503,7 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
pcNew->mData = new char[pSizeInBytes];
memcpy (pcNew->mData,pInput,pSizeInBytes);
pcNew->mKey.length = (ai_uint32)::strlen(pKey);
pcNew->mKey.length = static_cast<ai_uint32>( ::strlen(pKey) );
ai_assert ( MAXLEN > pcNew->mKey.length);
strcpy( pcNew->mKey.data, pKey );

View File

@ -617,7 +617,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *model
// We'll leave it up to the user to figure out which extension the file has.
aiString name;
strncpy( name.data, pTexture->strName, sizeof name.data );
name.length = (ai_uint32)strlen( name.data );
name.length = static_cast<ai_uint32>(strlen( name.data ));
pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
}
}

View File

@ -616,7 +616,7 @@ void SMDImporter::CreateOutputMaterials() {
if (aszTextures[iMat].length())
{
::strncpy(szName.data, aszTextures[iMat].c_str(),MAXLEN-1);
szName.length = (ai_uint32)aszTextures[iMat].length();
szName.length = static_cast<ai_uint32>( aszTextures[iMat].length() );
pcMat->AddProperty(&szName,AI_MATKEY_TEXTURE_DIFFUSE(0));
}
}

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -43,17 +41,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the Terragen importer class */
#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
#include "TerragenLoader.h"
#include <assimp/StreamReader.h>
#include <assimp/Importer.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include <assimp/IOSystem.hpp>
#include <assimp/Importer.hpp>
using namespace Assimp;
@ -72,78 +68,72 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
TerragenImporter::TerragenImporter()
: configComputeUVs (false)
{}
TerragenImporter::TerragenImporter() :
configComputeUVs(false) {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
TerragenImporter::~TerragenImporter()
{}
TerragenImporter::~TerragenImporter() {}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool TerragenImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
bool TerragenImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
// check file extension
std::string extension = GetExtension(pFile);
if( extension == "ter")
if (extension == "ter")
return true;
if( !extension.length() || checkSig) {
if (!extension.length() || checkSig) {
/* If CanRead() is called in order to check whether we
* support a specific file extension in general pIOHandler
* might be NULL and it's our duty to return true here.
*/
if (!pIOHandler)return true;
const char* tokens[] = {"terragen"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
if (!pIOHandler) return true;
const char *tokens[] = { "terragen" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
}
// ------------------------------------------------------------------------------------------------
// Build a string of all file extensions supported
const aiImporterDesc* TerragenImporter::GetInfo () const
{
const aiImporterDesc *TerragenImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup import properties
void TerragenImporter::SetupProperties(const Importer* pImp)
{
void TerragenImporter::SetupProperties(const Importer *pImp) {
// AI_CONFIG_IMPORT_TER_MAKE_UVS
configComputeUVs = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS,0) );
configComputeUVs = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 0));
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void TerragenImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
IOStream* file = pIOHandler->Open( pFile, "rb");
void TerragenImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
IOStream *file = pIOHandler->Open(pFile, "rb");
// Check whether we can read from the file
if( file == NULL)
throw DeadlyImportError( "Failed to open TERRAGEN TERRAIN file " + pFile + ".");
if (file == NULL)
throw DeadlyImportError("Failed to open TERRAGEN TERRAIN file " + pFile + ".");
// Construct a stream reader to read all data in the correct endianness
StreamReaderLE reader(file);
if(reader.GetRemainingSize() < 16)
throw DeadlyImportError( "TER: file is too small" );
if (reader.GetRemainingSize() < 16)
throw DeadlyImportError("TER: file is too small");
// Check for the existence of the two magic strings 'TERRAGEN' and 'TERRAIN '
if (::strncmp((const char*)reader.GetPtr(),AI_TERR_BASE_STRING,8))
throw DeadlyImportError( "TER: Magic string \'TERRAGEN\' not found" );
if (::strncmp((const char *)reader.GetPtr(), AI_TERR_BASE_STRING, 8))
throw DeadlyImportError("TER: Magic string \'TERRAGEN\' not found");
if (::strncmp((const char*)reader.GetPtr()+8,AI_TERR_TERRAIN_STRING,8))
throw DeadlyImportError( "TER: Magic string \'TERRAIN\' not found" );
if (::strncmp((const char *)reader.GetPtr() + 8, AI_TERR_TERRAIN_STRING, 8))
throw DeadlyImportError("TER: Magic string \'TERRAIN\' not found");
unsigned int x = 0,y = 0,mode = 0;
unsigned int x = 0, y = 0, mode = 0;
aiNode* root = pScene->mRootNode = new aiNode();
aiNode *root = pScene->mRootNode = new aiNode();
root->mName.Set("<TERRAGEN.TERRAIN>");
// Default scaling is 30
@ -151,104 +141,98 @@ void TerragenImporter::InternReadFile( const std::string& pFile,
// Now read all chunks until we're finished or an EOF marker is encountered
reader.IncPtr(16);
while (reader.GetRemainingSize() >= 4)
{
const char* head = (const char*)reader.GetPtr();
while (reader.GetRemainingSize() >= 4) {
const char *head = (const char *)reader.GetPtr();
reader.IncPtr(4);
// EOF, break in every case
if (!::strncmp(head,AI_TERR_EOF_STRING,4))
if (!::strncmp(head, AI_TERR_EOF_STRING, 4))
break;
// Number of x-data points
if (!::strncmp(head,AI_TERR_CHUNK_XPTS,4))
{
if (!::strncmp(head, AI_TERR_CHUNK_XPTS, 4)) {
x = (uint16_t)reader.GetI2();
}
// Number of y-data points
else if (!::strncmp(head,AI_TERR_CHUNK_YPTS,4))
{
else if (!::strncmp(head, AI_TERR_CHUNK_YPTS, 4)) {
y = (uint16_t)reader.GetI2();
}
// Squared terrains width-1.
else if (!::strncmp(head,AI_TERR_CHUNK_SIZE,4))
{
x = y = (uint16_t)reader.GetI2()+1;
else if (!::strncmp(head, AI_TERR_CHUNK_SIZE, 4)) {
x = y = (uint16_t)reader.GetI2() + 1;
}
// terrain scaling
else if (!::strncmp(head,AI_TERR_CHUNK_SCAL,4))
{
else if (!::strncmp(head, AI_TERR_CHUNK_SCAL, 4)) {
root->mTransformation.a1 = reader.GetF4();
root->mTransformation.b2 = reader.GetF4();
root->mTransformation.c3 = reader.GetF4();
}
// mapping == 1: earth radius
else if (!::strncmp(head,AI_TERR_CHUNK_CRAD,4))
{
else if (!::strncmp(head, AI_TERR_CHUNK_CRAD, 4)) {
reader.GetF4();
}
// mapping mode
else if (!::strncmp(head,AI_TERR_CHUNK_CRVM,4))
{
else if (!::strncmp(head, AI_TERR_CHUNK_CRVM, 4)) {
mode = reader.GetI1();
if (0 != mode)
ASSIMP_LOG_ERROR("TER: Unsupported mapping mode, a flat terrain is returned");
}
// actual terrain data
else if (!::strncmp(head,AI_TERR_CHUNK_ALTW,4))
{
float hscale = (float)reader.GetI2() / 65536;
else if (!::strncmp(head, AI_TERR_CHUNK_ALTW, 4)) {
float hscale = (float)reader.GetI2() / 65536;
float bheight = (float)reader.GetI2();
if (!hscale)hscale = 1;
if (!hscale) hscale = 1;
// Ensure we have enough data
if (reader.GetRemainingSize() < x*y*2)
if (reader.GetRemainingSize() < x * y * 2)
throw DeadlyImportError("TER: ALTW chunk is too small");
if (x <= 1 || y <= 1)
throw DeadlyImportError("TER: Invalid terrain size");
// Allocate the output mesh
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes = 1];
aiMesh* m = pScene->mMeshes[0] = new aiMesh();
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes = 1];
aiMesh *m = pScene->mMeshes[0] = new aiMesh();
// We return quads
aiFace* f = m->mFaces = new aiFace[m->mNumFaces = (x-1)*(y-1)];
aiVector3D* pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces*4];
aiFace *f = m->mFaces = new aiFace[m->mNumFaces = (x - 1) * (y - 1)];
aiVector3D *pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces * 4];
aiVector3D *uv( NULL );
float step_y( 0.0f ), step_x( 0.0f );
aiVector3D *uv(NULL);
float step_y(0.0f), step_x(0.0f);
if (configComputeUVs) {
uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
step_y = 1.f/y;
step_x = 1.f/x;
step_y = 1.f / y;
step_x = 1.f / x;
}
const int16_t* data = (const int16_t*)reader.GetPtr();
const int16_t *data = (const int16_t *)reader.GetPtr();
for (unsigned int yy = 0, t = 0; yy < y-1;++yy) {
for (unsigned int xx = 0; xx < x-1;++xx,++f) {
for (unsigned int yy = 0, t = 0; yy < y - 1; ++yy) {
for (unsigned int xx = 0; xx < x - 1; ++xx, ++f) {
// make verts
const float fy = (float)yy, fx = (float)xx;
unsigned tmp,tmp2;
*pv++ = aiVector3D(fx,fy, (float)data[(tmp2=x*yy) + xx] * hscale + bheight);
*pv++ = aiVector3D(fx,fy+1, (float)data[(tmp=x*(yy+1)) + xx] * hscale + bheight);
*pv++ = aiVector3D(fx+1,fy+1,(float)data[tmp + xx+1] * hscale + bheight);
*pv++ = aiVector3D(fx+1,fy, (float)data[tmp2 + xx+1] * hscale + bheight);
unsigned tmp, tmp2;
*pv++ = aiVector3D(fx, fy, (float)data[(tmp2 = x * yy) + xx] * hscale + bheight);
*pv++ = aiVector3D(fx, fy + 1, (float)data[(tmp = x * (yy + 1)) + xx] * hscale + bheight);
*pv++ = aiVector3D(fx + 1, fy + 1, (float)data[tmp + xx + 1] * hscale + bheight);
*pv++ = aiVector3D(fx + 1, fy, (float)data[tmp2 + xx + 1] * hscale + bheight);
// also make texture coordinates, if necessary
if (configComputeUVs) {
*uv++ = aiVector3D( step_x*xx, step_y*yy, 0.f );
*uv++ = aiVector3D( step_x*xx, step_y*(yy+1), 0.f );
*uv++ = aiVector3D( step_x*(xx+1), step_y*(yy+1), 0.f );
*uv++ = aiVector3D( step_x*(xx+1), step_y*yy, 0.f );
*uv++ = aiVector3D(step_x * xx, step_y * yy, 0.f);
*uv++ = aiVector3D(step_x * xx, step_y * (yy + 1), 0.f);
*uv++ = aiVector3D(step_x * (xx + 1), step_y * (yy + 1), 0.f);
*uv++ = aiVector3D(step_x * (xx + 1), step_y * yy, 0.f);
}
// make indices
f->mIndices = new unsigned int[f->mNumIndices = 4];
for (unsigned int i = 0; i < 4;++i)
f->mIndices[i] = t++;
for (unsigned int i = 0; i < 4; ++i) {
f->mIndices[i] = t;
t++;
}
}
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -47,21 +46,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
#include <assimp/BaseImporter.h>
namespace Assimp {
namespace Assimp {
// Magic strings
#define AI_TERR_BASE_STRING "TERRAGEN"
#define AI_TERR_TERRAIN_STRING "TERRAIN "
#define AI_TERR_EOF_STRING "EOF "
#define AI_TERR_BASE_STRING "TERRAGEN"
#define AI_TERR_TERRAIN_STRING "TERRAIN "
#define AI_TERR_EOF_STRING "EOF "
// Chunka
#define AI_TERR_CHUNK_XPTS "XPTS"
#define AI_TERR_CHUNK_YPTS "YPTS"
#define AI_TERR_CHUNK_SIZE "SIZE"
#define AI_TERR_CHUNK_SCAL "SCAL"
#define AI_TERR_CHUNK_CRAD "CRAD"
#define AI_TERR_CHUNK_CRVM "CRVM"
#define AI_TERR_CHUNK_ALTW "ALTW"
#define AI_TERR_CHUNK_XPTS "XPTS"
#define AI_TERR_CHUNK_YPTS "YPTS"
#define AI_TERR_CHUNK_SIZE "SIZE"
#define AI_TERR_CHUNK_SCAL "SCAL"
#define AI_TERR_CHUNK_CRAD "CRAD"
#define AI_TERR_CHUNK_CRVM "CRVM"
#define AI_TERR_CHUNK_ALTW "ALTW"
// ---------------------------------------------------------------------------
/** @brief Importer class to load Terragen (0.9) terrain files.
@ -69,33 +68,28 @@ namespace Assimp {
* The loader is basing on the information found here:
* http://www.planetside.co.uk/terragen/dev/tgterrain.html#chunks
*/
class TerragenImporter : public BaseImporter
{
class TerragenImporter : public BaseImporter {
public:
TerragenImporter();
~TerragenImporter();
public:
// -------------------------------------------------------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
protected:
// -------------------------------------------------------------------
const aiImporterDesc *GetInfo() const;
// -------------------------------------------------------------------
const aiImporterDesc* GetInfo () const;
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
// -------------------------------------------------------------------
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
// -------------------------------------------------------------------
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer *pImp);
private:
bool configComputeUVs;
}; //! class TerragenImporter

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -48,26 +46,112 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* http://local.wasp.uwa.edu.au/~pbourke/dataformats/unreal/
*/
#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
#include "Unreal/UnrealLoader.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include <assimp/StreamReader.h>
#include <assimp/ParsingUtils.h>
#include <assimp/StreamReader.h>
#include <assimp/fast_atof.h>
#include <assimp/Importer.hpp>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
#include <assimp/Importer.hpp>
#include <stdint.h>
#include <memory>
using namespace Assimp;
namespace Unreal {
/*
0 = Normal one-sided
1 = Normal two-sided
2 = Translucent two-sided
3 = Masked two-sided
4 = Modulation blended two-sided
8 = Placeholder triangle for weapon positioning (invisible)
*/
enum MeshFlags {
MF_NORMAL_OS = 0,
MF_NORMAL_TS = 1,
MF_NORMAL_TRANS_TS = 2,
MF_NORMAL_MASKED_TS = 3,
MF_NORMAL_MOD_TS = 4,
MF_WEAPON_PLACEHOLDER = 8
};
// a single triangle
struct Triangle {
uint16_t mVertex[3]; // Vertex indices
char mType; // James' Mesh Type
char mColor; // Color for flat and Gourand Shaded
unsigned char mTex[3][2]; // Texture UV coordinates
unsigned char mTextureNum; // Source texture offset
char mFlags; // Unreal Mesh Flags (unused)
unsigned int matIndex;
};
// temporary representation for a material
struct TempMat {
TempMat() :
type(MF_NORMAL_OS), tex(), numFaces(0) {}
explicit TempMat(const Triangle &in) :
type((Unreal::MeshFlags)in.mType), tex(in.mTextureNum), numFaces(0) {}
// type of mesh
Unreal::MeshFlags type;
// index of texture
unsigned int tex;
// number of faces using us
unsigned int numFaces;
// for std::find
bool operator==(const TempMat &o) {
return (tex == o.tex && type == o.type);
}
};
struct Vertex {
int32_t X : 11;
int32_t Y : 11;
int32_t Z : 10;
};
// UNREAL vertex compression
inline void CompressVertex(const aiVector3D &v, uint32_t &out) {
union {
Vertex n;
int32_t t;
};
t = 0;
n.X = (int32_t)v.x;
n.Y = (int32_t)v.y;
n.Z = (int32_t)v.z;
::memcpy(&out, &t, sizeof(int32_t));
}
// UNREAL vertex decompression
inline void DecompressVertex(aiVector3D &v, int32_t in) {
union {
Vertex n;
int32_t i;
};
i = in;
v.x = (float)n.X;
v.y = (float)n.Y;
v.z = (float)n.Z;
}
} // end namespace Unreal
static const aiImporterDesc desc = {
"Unreal Mesh Importer",
"",
@ -81,79 +165,70 @@ static const aiImporterDesc desc = {
"3d uc"
};
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
UnrealImporter::UnrealImporter()
: configFrameID (0)
, configHandleFlags (true)
{}
UnrealImporter::UnrealImporter() :
mConfigFrameID(0), mConfigHandleFlags(true) {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
UnrealImporter::~UnrealImporter()
{}
UnrealImporter::~UnrealImporter() {}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool UnrealImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
{
return SimpleExtensionCheck(pFile,"3d","uc");
bool UnrealImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
return SimpleExtensionCheck(pFile, "3d", "uc");
}
// ------------------------------------------------------------------------------------------------
// Build a string of all file extensions supported
const aiImporterDesc* UnrealImporter::GetInfo () const
{
const aiImporterDesc *UnrealImporter::GetInfo() const {
return &desc;
}
// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
void UnrealImporter::SetupProperties(const Importer* pImp)
{
void UnrealImporter::SetupProperties(const Importer *pImp) {
// The
// AI_CONFIG_IMPORT_UNREAL_KEYFRAME option overrides the
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_KEYFRAME,-1);
if(static_cast<unsigned int>(-1) == configFrameID) {
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
mConfigFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_KEYFRAME, -1);
if (static_cast<unsigned int>(-1) == mConfigFrameID) {
mConfigFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME, 0);
}
// AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS, default is true
configHandleFlags = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS,1));
mConfigHandleFlags = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS, 1));
}
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void UnrealImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
void UnrealImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
// For any of the 3 files being passed get the three correct paths
// First of all, determine file extension
std::string::size_type pos = pFile.find_last_of('.');
std::string extension = GetExtension(pFile);
std::string d_path,a_path,uc_path;
if (extension == "3d") {
std::string d_path, a_path, uc_path;
if (extension == "3d") {
// jjjj_d.3d
// jjjj_a.3d
pos = pFile.find_last_of('_');
if (std::string::npos == pos) {
throw DeadlyImportError("UNREAL: Unexpected naming scheme");
}
extension = pFile.substr(0,pos);
}
else {
extension = pFile.substr(0,pos);
extension = pFile.substr(0, pos);
} else {
extension = pFile.substr(0, pos);
}
// build proper paths
d_path = extension+"_d.3d";
a_path = extension+"_a.3d";
uc_path = extension+".uc";
d_path = extension + "_d.3d";
a_path = extension + "_a.3d";
uc_path = extension + ".uc";
ASSIMP_LOG_DEBUG_F( "UNREAL: data file is ", d_path);
ASSIMP_LOG_DEBUG_F("UNREAL: data file is ", d_path);
ASSIMP_LOG_DEBUG_F("UNREAL: aniv file is ", a_path);
ASSIMP_LOG_DEBUG_F("UNREAL: uc file is ", uc_path);
@ -174,11 +249,11 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
// collect triangles
std::vector<Unreal::Triangle> triangles(numTris);
for (auto & tri : triangles) {
for (unsigned int i = 0; i < 3;++i) {
for (auto &tri : triangles) {
for (unsigned int i = 0; i < 3; ++i) {
tri.mVertex[i] = d_reader.GetI2();
if (tri.mVertex[i] >= numTris) {
if (tri.mVertex[i] >= numTris) {
ASSIMP_LOG_WARN("UNREAL: vertex index out of range");
tri.mVertex[i] = 0;
}
@ -186,7 +261,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
tri.mType = d_reader.GetI1();
// handle mesh flagss?
if (configHandleFlags)
if (mConfigHandleFlags)
tri.mType = Unreal::MF_NORMAL_OS;
else {
// ignore MOD and MASKED for the moment, treat them as two-sided
@ -195,12 +270,12 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
}
d_reader.IncPtr(1);
for (unsigned int i = 0; i < 3;++i)
for (unsigned int i2 = 0; i2 < 2;++i2)
for (unsigned int i = 0; i < 3; ++i)
for (unsigned int i2 = 0; i2 < 2; ++i2)
tri.mTex[i][i2] = d_reader.GetI1();
tri.mTextureNum = d_reader.GetI1();
maxTexIdx = std::max(maxTexIdx,(unsigned int)tri.mTextureNum);
maxTexIdx = std::max(maxTexIdx, (unsigned int)tri.mTextureNum);
d_reader.IncPtr(1);
}
@ -211,63 +286,64 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
// read number of frames
const uint32_t numFrames = a_reader.GetI2();
if (configFrameID >= numFrames) {
if (mConfigFrameID >= numFrames) {
throw DeadlyImportError("UNREAL: The requested frame does not exist");
}
uint32_t st = a_reader.GetI2();
if (st != numVert*4u)
if (st != numVert * 4u)
throw DeadlyImportError("UNREAL: Unexpected aniv file length");
// skip to our frame
a_reader.IncPtr(configFrameID *numVert*4);
a_reader.IncPtr(mConfigFrameID * numVert * 4);
// collect vertices
std::vector<aiVector3D> vertices(numVert);
for (auto &vertex : vertices) {
for (auto &vertex : vertices) {
int32_t val = a_reader.GetI4();
Unreal::DecompressVertex(vertex ,val);
Unreal::DecompressVertex(vertex, val);
}
// list of textures.
std::vector< std::pair<unsigned int, std::string> > textures;
std::vector<std::pair<unsigned int, std::string>> textures;
// allocate the output scene
aiNode* nd = pScene->mRootNode = new aiNode();
aiNode *nd = pScene->mRootNode = new aiNode();
nd->mName.Set("<UnrealRoot>");
// we can live without the uc file if necessary
std::unique_ptr<IOStream> pb (pIOHandler->Open(uc_path));
if (pb.get()) {
std::unique_ptr<IOStream> pb(pIOHandler->Open(uc_path));
if (pb.get()) {
std::vector<char> _data;
TextFileToBuffer(pb.get(),_data);
const char* data = &_data[0];
TextFileToBuffer(pb.get(), _data);
const char *data = &_data[0];
std::vector< std::pair< std::string,std::string > > tempTextures;
std::vector<std::pair<std::string, std::string>> tempTextures;
// do a quick search in the UC file for some known, usually texture-related, tags
for (;*data;++data) {
if (TokenMatchI(data,"#exec",5)) {
for (; *data; ++data) {
if (TokenMatchI(data, "#exec", 5)) {
SkipSpacesAndLineEnd(&data);
// #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...]
if (TokenMatchI(data,"TEXTURE",7)) {
if (TokenMatchI(data, "TEXTURE", 7)) {
SkipSpacesAndLineEnd(&data);
if (TokenMatchI(data,"IMPORT",6)) {
tempTextures.push_back(std::pair< std::string,std::string >());
std::pair< std::string,std::string >& me = tempTextures.back();
for (;!IsLineEnd(*data);++data) {
if (!::ASSIMP_strincmp(data,"NAME=",5)) {
const char *d = data+=5;
for (;!IsSpaceOrNewLine(*data);++data);
me.first = std::string(d,(size_t)(data-d));
}
else if (!::ASSIMP_strincmp(data,"FILE=",5)) {
const char *d = data+=5;
for (;!IsSpaceOrNewLine(*data);++data);
me.second = std::string(d,(size_t)(data-d));
if (TokenMatchI(data, "IMPORT", 6)) {
tempTextures.push_back(std::pair<std::string, std::string>());
std::pair<std::string, std::string> &me = tempTextures.back();
for (; !IsLineEnd(*data); ++data) {
if (!::ASSIMP_strincmp(data, "NAME=", 5)) {
const char *d = data += 5;
for (; !IsSpaceOrNewLine(*data); ++data)
;
me.first = std::string(d, (size_t)(data - d));
} else if (!::ASSIMP_strincmp(data, "FILE=", 5)) {
const char *d = data += 5;
for (; !IsSpaceOrNewLine(*data); ++data)
;
me.second = std::string(d, (size_t)(data - d));
}
}
if (!me.first.length() || !me.second.length())
@ -276,65 +352,61 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
}
// #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
// #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
else if (TokenMatchI(data,"MESHMAP",7)) {
else if (TokenMatchI(data, "MESHMAP", 7)) {
SkipSpacesAndLineEnd(&data);
if (TokenMatchI(data,"SETTEXTURE",10)) {
if (TokenMatchI(data, "SETTEXTURE", 10)) {
textures.push_back(std::pair<unsigned int, std::string>());
std::pair<unsigned int, std::string>& me = textures.back();
std::pair<unsigned int, std::string> &me = textures.back();
for (;!IsLineEnd(*data);++data) {
if (!::ASSIMP_strincmp(data,"NUM=",4)) {
for (; !IsLineEnd(*data); ++data) {
if (!::ASSIMP_strincmp(data, "NUM=", 4)) {
data += 4;
me.first = strtoul10(data,&data);
}
else if (!::ASSIMP_strincmp(data,"TEXTURE=",8)) {
me.first = strtoul10(data, &data);
} else if (!::ASSIMP_strincmp(data, "TEXTURE=", 8)) {
data += 8;
const char *d = data;
for (;!IsSpaceOrNewLine(*data);++data);
me.second = std::string(d,(size_t)(data-d));
for (; !IsSpaceOrNewLine(*data); ++data)
;
me.second = std::string(d, (size_t)(data - d));
// try to find matching path names, doesn't care if we don't find them
for (std::vector< std::pair< std::string,std::string > >::const_iterator it = tempTextures.begin();
it != tempTextures.end(); ++it) {
if ((*it).first == me.second) {
for (std::vector<std::pair<std::string, std::string>>::const_iterator it = tempTextures.begin();
it != tempTextures.end(); ++it) {
if ((*it).first == me.second) {
me.second = (*it).second;
break;
}
}
}
}
}
else if (TokenMatchI(data,"SCALE",5)) {
} else if (TokenMatchI(data, "SCALE", 5)) {
for (;!IsLineEnd(*data);++data) {
if (data[0] == 'X' && data[1] == '=') {
data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.a1);
}
else if (data[0] == 'Y' && data[1] == '=') {
data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.b2);
}
else if (data[0] == 'Z' && data[1] == '=') {
data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.c3);
for (; !IsLineEnd(*data); ++data) {
if (data[0] == 'X' && data[1] == '=') {
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.a1);
} else if (data[0] == 'Y' && data[1] == '=') {
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.b2);
} else if (data[0] == 'Z' && data[1] == '=') {
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.c3);
}
}
}
}
}
}
}
else {
} else {
ASSIMP_LOG_ERROR("Unable to open .uc file");
}
std::vector<Unreal::TempMat> materials;
materials.reserve(textures.size()*2+5);
materials.reserve(textures.size() * 2 + 5);
// find out how many output meshes and materials we'll have and build material indices
for (Unreal::Triangle &tri : triangles) {
for (Unreal::Triangle &tri : triangles) {
Unreal::TempMat mat(tri);
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(), materials.end(), mat);
if (nt == materials.end()) {
// add material
tri.matIndex = static_cast<unsigned int>(materials.size());
@ -342,9 +414,8 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
materials.push_back(mat);
++pScene->mNumMeshes;
}
else {
tri.matIndex = static_cast<unsigned int>(nt-materials.begin());
} else {
tri.matIndex = static_cast<unsigned int>(nt - materials.begin());
++nt->numFaces;
}
}
@ -354,65 +425,65 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
}
// allocate meshes and bind them to the node graph
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials = pScene->mNumMeshes];
nd->mNumMeshes = pScene->mNumMeshes;
nd->mNumMeshes = pScene->mNumMeshes;
nd->mMeshes = new unsigned int[nd->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
aiMesh* m = pScene->mMeshes[i] = new aiMesh();
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
aiMesh *m = pScene->mMeshes[i] = new aiMesh();
m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
const unsigned int num = materials[i].numFaces;
m->mFaces = new aiFace [num];
m->mVertices = new aiVector3D [num*3];
m->mTextureCoords[0] = new aiVector3D [num*3];
m->mFaces = new aiFace[num];
m->mVertices = new aiVector3D[num * 3];
m->mTextureCoords[0] = new aiVector3D[num * 3];
nd->mMeshes[i] = i;
// create materials, too
aiMaterial* mat = new aiMaterial();
aiMaterial *mat = new aiMaterial();
pScene->mMaterials[i] = mat;
// all white by default - texture rulez
aiColor3D color(1.f,1.f,1.f);
aiColor3D color(1.f, 1.f, 1.f);
aiString s;
::ai_snprintf( s.data, MAXLEN, "mat%u_tx%u_",i,materials[i].tex );
::ai_snprintf(s.data, MAXLEN, "mat%u_tx%u_", i, materials[i].tex);
// set the two-sided flag
if (materials[i].type == Unreal::MF_NORMAL_TS) {
const int twosided = 1;
mat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
::strcat(s.data,"ts_");
}
else ::strcat(s.data,"os_");
mat->AddProperty(&twosided, 1, AI_MATKEY_TWOSIDED);
::strcat(s.data, "ts_");
} else
::strcat(s.data, "os_");
// make TRANS faces 90% opaque that RemRedundantMaterials won't catch us
if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS) {
if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS) {
const float opac = 0.9f;
mat->AddProperty(&opac,1,AI_MATKEY_OPACITY);
::strcat(s.data,"tran_");
}
else ::strcat(s.data,"opaq_");
mat->AddProperty(&opac, 1, AI_MATKEY_OPACITY);
::strcat(s.data, "tran_");
} else
::strcat(s.data, "opaq_");
// a special name for the weapon attachment point
if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER) {
s.length = ::ai_snprintf( s.data, MAXLEN, "$WeaponTag$" );
color = aiColor3D(0.f,0.f,0.f);
s.length = ::ai_snprintf(s.data, MAXLEN, "$WeaponTag$");
color = aiColor3D(0.f, 0.f, 0.f);
}
// set color and name
mat->AddProperty(&color,1,AI_MATKEY_COLOR_DIFFUSE);
s.length = (ai_uint32)::strlen(s.data);
mat->AddProperty(&s,AI_MATKEY_NAME);
mat->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE);
s.length = static_cast<ai_uint32>(::strlen(s.data));
mat->AddProperty(&s, AI_MATKEY_NAME);
// set texture, if any
const unsigned int tex = materials[i].tex;
for (std::vector< std::pair< unsigned int, std::string > >::const_iterator it = textures.begin();it != textures.end();++it) {
for (std::vector<std::pair<unsigned int, std::string>>::const_iterator it = textures.begin(); it != textures.end(); ++it) {
if ((*it).first == tex) {
s.Set((*it).second);
mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
break;
}
}
@ -421,17 +492,17 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
// fill them.
for (const Unreal::Triangle &tri : triangles) {
Unreal::TempMat mat(tri);
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(), materials.end(), mat);
aiMesh* mesh = pScene->mMeshes[nt-materials.begin()];
aiFace& f = mesh->mFaces[mesh->mNumFaces++];
f.mIndices = new unsigned int[f.mNumIndices = 3];
aiMesh *mesh = pScene->mMeshes[nt - materials.begin()];
aiFace &f = mesh->mFaces[mesh->mNumFaces++];
f.mIndices = new unsigned int[f.mNumIndices = 3];
for (unsigned int i = 0; i < 3;++i,mesh->mNumVertices++) {
for (unsigned int i = 0; i < 3; ++i, mesh->mNumVertices++) {
f.mIndices[i] = mesh->mNumVertices;
mesh->mVertices[mesh->mNumVertices] = vertices[ tri.mVertex[i] ];
mesh->mTextureCoords[0][mesh->mNumVertices] = aiVector3D( tri.mTex[i][0] / 255.f, 1.f - tri.mTex[i][1] / 255.f, 0.f);
mesh->mVertices[mesh->mNumVertices] = vertices[tri.mVertex[i]];
mesh->mTextureCoords[0][mesh->mNumVertices] = aiVector3D(tri.mTex[i][0] / 255.f, 1.f - tri.mTex[i][1] / 255.f, 0.f);
}
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -47,161 +46,57 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define INCLUDED_AI_3D_LOADER_H
#include <assimp/BaseImporter.h>
#include <stdint.h>
namespace Assimp {
namespace Unreal {
/*
0 = Normal one-sided
1 = Normal two-sided
2 = Translucent two-sided
3 = Masked two-sided
4 = Modulation blended two-sided
8 = Placeholder triangle for weapon positioning (invisible)
*/
enum MeshFlags {
MF_NORMAL_OS = 0,
MF_NORMAL_TS = 1,
MF_NORMAL_TRANS_TS = 2,
MF_NORMAL_MASKED_TS = 3,
MF_NORMAL_MOD_TS = 4,
MF_WEAPON_PLACEHOLDER = 8
};
// a single triangle
struct Triangle {
uint16_t mVertex[3]; // Vertex indices
char mType; // James' Mesh Type
char mColor; // Color for flat and Gourand Shaded
unsigned char mTex[3][2]; // Texture UV coordinates
unsigned char mTextureNum; // Source texture offset
char mFlags; // Unreal Mesh Flags (unused)
unsigned int matIndex;
};
// temporary representation for a material
struct TempMat {
TempMat()
: type()
, tex()
, numFaces (0)
{}
explicit TempMat(const Triangle& in)
: type ((Unreal::MeshFlags)in.mType)
, tex (in.mTextureNum)
, numFaces (0)
{}
// type of mesh
Unreal::MeshFlags type;
// index of texture
unsigned int tex;
// number of faces using us
unsigned int numFaces;
// for std::find
bool operator == (const TempMat& o ) {
return (tex == o.tex && type == o.type);
}
};
struct Vertex
{
int32_t X : 11;
int32_t Y : 11;
int32_t Z : 10;
};
// UNREAL vertex compression
inline void CompressVertex(const aiVector3D& v, uint32_t& out)
{
union {
Vertex n;
int32_t t;
};
n.X = (int32_t)v.x;
n.Y = (int32_t)v.y;
n.Z = (int32_t)v.z;
::memcpy( &out, &t, sizeof(int32_t));
//out = t;
}
// UNREAL vertex decompression
inline void DecompressVertex(aiVector3D& v, int32_t in)
{
union {
Vertex n;
int32_t i;
};
i = in;
v.x = (float)n.X;
v.y = (float)n.Y;
v.z = (float)n.Z;
}
} // end namespace Unreal
namespace Assimp {
// ---------------------------------------------------------------------------
/** @brief Importer class to load UNREAL files (*.3d)
*/
class UnrealImporter : public BaseImporter
{
class UnrealImporter : public BaseImporter {
public:
UnrealImporter();
~UnrealImporter();
public:
// -------------------------------------------------------------------
/** @brief Returns whether we can handle the format of the given file
*
* See BaseImporter::CanRead() for details.
**/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
bool checkSig) const;
protected:
// -------------------------------------------------------------------
/** @brief Called by Importer::GetExtensionList()
*
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc *GetInfo() const;
// -------------------------------------------------------------------
/** @brief Setup properties for the importer
*
* See BaseImporter::SetupProperties() for details
*/
void SetupProperties(const Importer* pImp);
void SetupProperties(const Importer *pImp);
// -------------------------------------------------------------------
/** @brief Imports the given file into the given scene structure.
*
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
private:
//! frame to be loaded
uint32_t configFrameID;
uint32_t mConfigFrameID;
//! process surface flags
bool configHandleFlags;
bool mConfigHandleFlags;
}; // !class UnrealImporter
} // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC

View File

@ -176,7 +176,7 @@ void XGLImporter::InternReadFile( const std::string& pFile,
raw_reader->IncPtr(2);
zstream.next_in = reinterpret_cast<Bytef*>( raw_reader->GetPtr() );
zstream.avail_in = raw_reader->GetRemainingSize();
zstream.avail_in = (uInt) raw_reader->GetRemainingSize();
size_t total = 0l;

View File

@ -380,8 +380,8 @@ struct Accessor : public Object {
inline uint8_t *GetPointer();
template <class T>
bool ExtractData(T *&outData);
template<class T>
void ExtractData(T *&outData);
void WriteData(size_t count, const void *src_buffer, size_t src_stride);

View File

@ -620,10 +620,13 @@ inline void CopyData(size_t count,
}
} // namespace
template <class T>
bool Accessor::ExtractData(T *&outData) {
uint8_t *data = GetPointer();
if (!data) return false;
template<class T>
void Accessor::ExtractData(T *&outData)
{
uint8_t* data = GetPointer();
if (!data) {
throw DeadlyImportError("GLTF: data is NULL");
}
const size_t elemSize = GetElementSize();
const size_t totalSize = elemSize * count;
@ -643,8 +646,6 @@ bool Accessor::ExtractData(T *&outData) {
memcpy(outData + i, data + i * stride, elemSize);
}
}
return true;
}
inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t src_stride) {

View File

@ -15,7 +15,11 @@ if ( MSVC )
endif ( MSVC )
IF(CMAKE_SYSTEM_NAME MATCHES "(Darwin|FreeBSD)")
add_library(IrrXML ${IrrXML_SRCS})
IF(APPLE)
add_library(IrrXML STATIC ${IrrXML_SRCS})
ELSE()
add_library(IrrXML ${IrrXML_SRCS})
ENDIF()
ELSE()
add_library(IrrXML STATIC ${IrrXML_SRCS})
ENDIF()

View File

@ -8,16 +8,7 @@
#include "irrXML.h"
#include "irrString.h"
#include "irrArray.h"
#include <cassert>
#include <stdlib.h>
#include <cctype>
#include <cstdint>
//using namespace Assimp;
// For locale independent number conversion
#include <sstream>
#include <locale>
#include "fast_atof.h"
#ifdef _DEBUG
#define IRR_DEBUGPRINT(x) printf((x));
@ -37,14 +28,23 @@ template<class char_type, class superclass>
class CXMLReaderImpl : public IIrrXMLReader<char_type, superclass>
{
public:
//! Constructor
CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true)
: TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE),
SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII)
{
if (!callback)
CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true)
: TextData(0)
, P(0)
, TextBegin(0)
, TextSize(0)
, CurrentNodeType(EXN_NONE)
, SourceFormat(ETF_ASCII)
, TargetFormat(ETF_ASCII)
, NodeName ()
, EmptyString()
, IsEmptyElement(false)
, SpecialCharacters()
, Attributes() {
if (!callback) {
return;
}
storeTargetFormat();
@ -168,8 +168,7 @@ public:
return 0;
core::stringc c = attr->Value.c_str();
return static_cast<float>(atof(c.c_str()));
//return fast_atof(c.c_str());
return core::fast_atof(c.c_str());
}
@ -181,11 +180,7 @@ public:
return 0;
core::stringc c = attrvalue;
std::istringstream sstr(c.c_str());
sstr.imbue(std::locale("C")); // Locale free number convert
float fNum;
sstr >> fNum;
return fNum;
return core::fast_atof(c.c_str());
}
@ -228,7 +223,7 @@ private:
{
char_type* start = P;
// move forward until '<' found
// more forward until '<' found
while(*P != L'<' && *P)
++P;
@ -438,10 +433,6 @@ private:
while(*P != L'>')
++P;
// remove trailing whitespace, if any
while( std::isspace( P[-1]))
--P;
NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose));
++P;
}
@ -676,12 +667,8 @@ private:
TextData = new char_type[sizeWithoutHeader];
// MSVC debugger complains here about loss of data ...
size_t numShift = sizeof( char_type) * 8;
assert(numShift < 64);
const src_char_type cc = (src_char_type)(((uint64_t(1u) << numShift) - 1));
for (int i=0; i<sizeWithoutHeader; ++i)
TextData[i] = char_type( source[i] & cc);
TextData[i] = (char_type)source[i];
TextBegin = TextData;
TextSize = sizeWithoutHeader;

View File

@ -0,0 +1,139 @@
// Copyright (C) 2002-2005 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
#ifndef __FAST_A_TO_F_H_INCLUDED__
#define __FAST_A_TO_F_H_INCLUDED__
#include <stdlib.h>
#include <math.h>
namespace irr
{
namespace core
{
const float fast_atof_table[] = {
0.f,
0.1f,
0.01f,
0.001f,
0.0001f,
0.00001f,
0.000001f,
0.0000001f,
0.00000001f,
0.000000001f,
0.0000000001f,
0.00000000001f,
0.000000000001f,
0.0000000000001f,
0.00000000000001f,
0.000000000000001f
};
//! Provides a fast function for converting a string into a float,
//! about 6 times faster than atof in win32.
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
inline char* fast_atof_move(char* c, float& out)
{
bool inv = false;
char *t;
float f;
if (*c=='-')
{
c++;
inv = true;
}
f = (float)strtol(c, &t, 10);
c = t;
if (*c == '.')
{
c++;
float pl = (float)strtol(c, &t, 10);
pl *= fast_atof_table[t-c];
f += pl;
c = t;
if (*c == 'e')
{
++c;
float exp = (float)strtol(c, &t, 10);
f *= (float)pow(10.0f, exp);
c = t;
}
}
if (inv)
f *= -1.0f;
out = f;
return c;
}
//! Provides a fast function for converting a string into a float,
//! about 6 times faster than atof in win32.
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
inline const char* fast_atof_move_const(const char* c, float& out)
{
bool inv = false;
char *t;
float f;
if (*c=='-')
{
c++;
inv = true;
}
f = (float)strtol(c, &t, 10);
c = t;
if (*c == '.')
{
c++;
float pl = (float)strtol(c, &t, 10);
pl *= fast_atof_table[t-c];
f += pl;
c = t;
if (*c == 'e')
{
++c;
f32 exp = (f32)strtol(c, &t, 10);
f *= (f32)powf(10.0f, exp);
c = t;
}
}
if (inv)
f *= -1.0f;
out = f;
return c;
}
inline float fast_atof(const char* c)
{
float ret;
fast_atof_move_const(c, ret);
return ret;
}
} // end namespace core
}// end namespace irr
#endif

View File

@ -21,7 +21,8 @@ class array
{
public:
array()
array()
: data(0), allocated(0), used(0),
free_when_destroyed(true), is_sorted(true)
{

View File

@ -29,7 +29,7 @@ public:
//! Default constructor
string()
: array(0), allocated(1), used(1)
: array(0), allocated(1), used(1)
{
array = new T[1];
array[0] = 0x0;
@ -39,7 +39,7 @@ public:
//! Constructor
string(const string<T>& other)
: array(0), allocated(0), used(0)
: array(0), allocated(0), used(0)
{
*this = other;
}
@ -47,7 +47,7 @@ public:
//! Constructs a string from an int
string(int number)
: array(0), allocated(0), used(0)
: array(0), allocated(0), used(0)
{
// store if negative and make positive
@ -117,7 +117,7 @@ public:
//! Constructor for unicode and ascii strings
template <class B>
string(const B* c)
: array(0),allocated(0), used(0)
: array(0), allocated(0), used(0)
{
*this = c;
}

View File

@ -79,13 +79,8 @@ typedef unsigned short wchar_t;
#endif // microsoft compiler
//! define a break macro for debugging only in Win32 mode.
// WORKAROUND (assimp): remove __asm
#if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
#if defined(_M_IX86)
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) /*if (_CONDITION_) {_asm int 3}*/
#else
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
#endif
#if !defined(_WIN64) && defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) if (_CONDITION_) {_asm int 3}
#else
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
#endif
@ -96,10 +91,8 @@ When you call unmanaged code that returns a bool type value of false from manage
the return value may appear as true. See
http://support.microsoft.com/default.aspx?kbid=823071 for details.
Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/
// WORKAROUND (assimp): remove __asm
#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400)
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX /*__asm mov eax,100*/
#if !defined(_WIN64) && defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400)
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX __asm mov eax,100
#else
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX
#endif // _IRR_MANAGED_MARSHALLING_BUGFIX

View File

@ -2,14 +2,10 @@
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
// Need to include Assimp, too. We're using Assimp's version of fast_atof
// so we need stdint.h. But no PCH.
#include "irrXML.h"
#include "irrString.h"
#include "irrArray.h"
//#include <assimp/fast_atof.h>
#include "fast_atof.h"
#include "CXMLReaderImpl.h"
namespace irr
@ -18,7 +14,7 @@ namespace io
{
//! Implementation of the file read callback for ordinary files
class IRRXML_API CFileReadCallBack : public IFileReadCallBack
class CFileReadCallBack : public IFileReadCallBack
{
public:

View File

@ -7,12 +7,6 @@
#include <stdio.h>
#ifdef _WIN32
# define IRRXML_API __declspec(dllexport)
#else
# define IRRXML_API __attribute__ ((visibility("default")))
#endif // _WIN32
/** \mainpage irrXML 1.2 API documentation
<div align="center"><img src="logobig.png" ></div>
@ -178,7 +172,7 @@ namespace io
ETF_UTF32_BE,
//! UTF-32 format, little endian
ETF_UTF32_LE
ETF_UTF32_LE,
};
@ -215,7 +209,7 @@ namespace io
two methods to read your data and give a pointer to an instance of
your implementation when calling createIrrXMLReader(),
createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
class IRRXML_API IFileReadCallBack
class IFileReadCallBack
{
public:
@ -415,7 +409,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReader* createIrrXMLReader(const char* filename);
IrrXMLReader* createIrrXMLReader(const char* filename);
//! Creates an instance of an UFT-8 or ASCII character xml parser.
/** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can
@ -427,7 +421,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReader* createIrrXMLReader(FILE* file);
IrrXMLReader* createIrrXMLReader(FILE* file);
//! Creates an instance of an UFT-8 or ASCII character xml parser.
/** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can
@ -440,7 +434,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback);
IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback);
//! Creates an instance of an UFT-16 xml parser.
/** This means that
@ -452,7 +446,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename);
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename);
//! Creates an instance of an UFT-16 xml parser.
/** This means that all character data will be returned in UTF-16. The file to read can
@ -464,7 +458,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file);
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file);
//! Creates an instance of an UFT-16 xml parser.
/** This means that all character data will be returned in UTF-16. The file to read can
@ -477,7 +471,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback);
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback);
//! Creates an instance of an UFT-32 xml parser.
@ -489,7 +483,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename);
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename);
//! Creates an instance of an UFT-32 xml parser.
/** This means that all character data will be returned in UTF-32. The file to read can
@ -501,7 +495,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file);
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file);
//! Creates an instance of an UFT-32 xml parser.
/** This means that
@ -515,7 +509,7 @@ namespace io
\return Returns a pointer to the created xml parser. This pointer should be
deleted using 'delete' after no longer needed. Returns 0 if an error occured
and the file could not be opened. */
IRRXML_API IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback);
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback);
/*! \file irrxml.h

View File

@ -55,36 +55,51 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
namespace Math {
// TODO: use binary GCD for unsigned integers ....
template < typename IntegerType >
inline
IntegerType gcd( IntegerType a, IntegerType b ) {
/// @brief Will return the greatest common divisor.
/// @param a [in] Value a.
/// @param b [in] Value b.
/// @return The greatest common divisor.
template <typename IntegerType>
inline IntegerType gcd( IntegerType a, IntegerType b ) {
const IntegerType zero = (IntegerType)0;
while ( true ) {
if ( a == zero )
if ( a == zero ) {
return b;
}
b %= a;
if ( b == zero )
if ( b == zero ) {
return a;
}
a %= b;
}
}
/// @brief Will return the greatest common divisor.
/// @param a [in] Value a.
/// @param b [in] Value b.
/// @return The greatest common divisor.
template < typename IntegerType >
inline
IntegerType lcm( IntegerType a, IntegerType b ) {
inline IntegerType lcm( IntegerType a, IntegerType b ) {
const IntegerType t = gcd (a,b);
if (!t)
if (!t) {
return t;
}
return a / t * b;
}
/// @brief Will return the smallest epsilon-value for the requested type.
/// @return The numercical limit epsilon depending on its type.
template<class T>
inline
T getEpsilon() {
inline T getEpsilon() {
return std::numeric_limits<T>::epsilon();
}
/// @brief Will return the constant PI for the requested type.
/// @return Pi
template<class T>
inline T PI() {
return static_cast<T>(3.14159265358979323846);
}
}
} // namespace Math
} // namespace Assimp

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -49,13 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_STREAMREADER_H_INCLUDED
#ifdef __GNUC__
# pragma GCC system_header
#pragma GCC system_header
#endif
#include <assimp/IOStream.hpp>
#include <assimp/Defines.h>
#include <assimp/ByteSwapper.h>
#include <assimp/Defines.h>
#include <assimp/Exceptional.h>
#include <assimp/IOStream.hpp>
#include <memory>
@ -74,10 +72,8 @@ namespace Assimp {
template <bool SwapEndianess = false, bool RuntimeSwitch = false>
class StreamReader {
public:
// FIXME: use these data types throughout the whole library,
// then change them to 64 bit values :-)
using diff = int;
using pos = unsigned int;
using diff = size_t;
using pos = size_t;
// ---------------------------------------------------------------------
/** Construction from a given stream with a well-defined endianness.
@ -91,40 +87,45 @@ public:
* stream is in little endian byte order. Otherwise the
* endianness information is contained in the @c SwapEndianess
* template parameter and this parameter is meaningless. */
StreamReader(std::shared_ptr<IOStream> stream, bool le = false)
: stream(stream)
, le(le)
{
StreamReader(std::shared_ptr<IOStream> stream, bool le = false) :
mStream(stream),
mBuffer(nullptr),
mCurrent(nullptr),
mEnd(nullptr),
mLimit(nullptr),
mLe(le) {
ai_assert(stream);
InternBegin();
}
// ---------------------------------------------------------------------
StreamReader(IOStream* stream, bool le = false)
: stream(std::shared_ptr<IOStream>(stream))
, le(le)
{
ai_assert(stream);
StreamReader(IOStream *stream, bool le = false) :
mStream(std::shared_ptr<IOStream>(stream)),
mBuffer(nullptr),
mCurrent(nullptr),
mEnd(nullptr),
mLimit(nullptr),
mLe(le) {
ai_assert(nullptr != stream);
InternBegin();
}
// ---------------------------------------------------------------------
~StreamReader() {
delete[] buffer;
delete[] mBuffer;
}
// deprecated, use overloaded operator>> instead
// ---------------------------------------------------------------------
/** Read a float from the stream */
float GetF4()
{
/// Read a float from the stream.
float GetF4() {
return Get<float>();
}
// ---------------------------------------------------------------------
/** Read a double from the stream */
double GetF8() {
/// Read a double from the stream.
double GetF8() {
return Get<double>();
}
@ -136,7 +137,7 @@ public:
// ---------------------------------------------------------------------
/** Read a signed 8 bit integer from the stream */
int8_t GetI1() {
int8_t GetI1() {
return Get<int8_t>();
}
@ -154,55 +155,55 @@ public:
// ---------------------------------------------------------------------
/** Read a unsigned 16 bit integer from the stream */
uint16_t GetU2() {
uint16_t GetU2() {
return Get<uint16_t>();
}
// ---------------------------------------------------------------------
/** Read a unsigned 8 bit integer from the stream */
/// Read a unsigned 8 bit integer from the stream
uint8_t GetU1() {
return Get<uint8_t>();
}
// ---------------------------------------------------------------------
/** Read an unsigned 32 bit integer from the stream */
uint32_t GetU4() {
/// Read an unsigned 32 bit integer from the stream
uint32_t GetU4() {
return Get<uint32_t>();
}
// ---------------------------------------------------------------------
/** Read a unsigned 64 bit integer from the stream */
uint64_t GetU8() {
/// Read a unsigned 64 bit integer from the stream
uint64_t GetU8() {
return Get<uint64_t>();
}
// ---------------------------------------------------------------------
/** Get the remaining stream size (to the end of the stream) */
unsigned int GetRemainingSize() const {
return (unsigned int)(end - current);
/// Get the remaining stream size (to the end of the stream)
size_t GetRemainingSize() const {
return (unsigned int)(mEnd - mCurrent);
}
// ---------------------------------------------------------------------
/** Get the remaining stream size (to the current read limit). The
* return value is the remaining size of the stream if no custom
* read limit has been set. */
unsigned int GetRemainingSizeToLimit() const {
return (unsigned int)(limit - current);
size_t GetRemainingSizeToLimit() const {
return (unsigned int)(mLimit - mCurrent);
}
// ---------------------------------------------------------------------
/** Increase the file pointer (relative seeking) */
void IncPtr(intptr_t plus) {
current += plus;
if (current > limit) {
void IncPtr(intptr_t plus) {
mCurrent += plus;
if (mCurrent > mLimit) {
throw DeadlyImportError("End of file or read limit was reached");
}
}
// ---------------------------------------------------------------------
/** Get the current file pointer */
int8_t* GetPtr() const {
return current;
int8_t *GetPtr() const {
return mCurrent;
}
// ---------------------------------------------------------------------
@ -211,9 +212,9 @@ public:
* large chunks of data at once.
* @param p The new pointer, which is validated against the size
* limit and buffer boundaries. */
void SetPtr(int8_t* p) {
current = p;
if (current > limit || current < buffer) {
void SetPtr(int8_t *p) {
mCurrent = p;
if (mCurrent > mLimit || mCurrent < mBuffer) {
throw DeadlyImportError("End of file or read limit was reached");
}
}
@ -222,21 +223,20 @@ public:
/** Copy n bytes to an external buffer
* @param out Destination for copying
* @param bytes Number of bytes to copy */
void CopyAndAdvance(void* out, size_t bytes) {
int8_t* ur = GetPtr();
SetPtr(ur+bytes); // fire exception if eof
void CopyAndAdvance(void *out, size_t bytes) {
int8_t *ur = GetPtr();
SetPtr(ur + bytes); // fire exception if eof
::memcpy(out,ur,bytes);
::memcpy(out, ur, bytes);
}
// ---------------------------------------------------------------------
/** Get the current offset from the beginning of the file */
int GetCurrentPos() const {
return (unsigned int)(current - buffer);
/// @brief Get the current offset from the beginning of the file
int GetCurrentPos() const {
return (unsigned int)(mCurrent - mBuffer);
}
void SetCurrentPos(size_t pos) {
SetPtr(buffer + pos);
SetPtr(mBuffer + pos);
}
// ---------------------------------------------------------------------
@ -246,15 +246,15 @@ public:
* the beginning of the file. Specifying UINT_MAX
* resets the limit to the original end of the stream.
* Returns the previously set limit. */
unsigned int SetReadLimit(unsigned int _limit) {
unsigned int SetReadLimit(unsigned int _limit) {
unsigned int prev = GetReadLimit();
if (UINT_MAX == _limit) {
limit = end;
mLimit = mEnd;
return prev;
}
limit = buffer + _limit;
if (limit > end) {
mLimit = mBuffer + _limit;
if (mLimit > mEnd) {
throw DeadlyImportError("StreamReader: Invalid read limit");
}
return prev;
@ -263,21 +263,21 @@ public:
// ---------------------------------------------------------------------
/** Get the current read limit in bytes. Reading over this limit
* accidentally raises an exception. */
unsigned int GetReadLimit() const {
return (unsigned int)(limit - buffer);
unsigned int GetReadLimit() const {
return (unsigned int)(mLimit - mBuffer);
}
// ---------------------------------------------------------------------
/** Skip to the read limit in bytes. Reading over this limit
* accidentally raises an exception. */
void SkipToReadLimit() {
current = limit;
void SkipToReadLimit() {
mCurrent = mLimit;
}
// ---------------------------------------------------------------------
/** overload operator>> and allow chaining of >> ops. */
template <typename T>
StreamReader& operator >> (T& f) {
StreamReader &operator>>(T &f) {
f = Get<T>();
return *this;
}
@ -286,14 +286,14 @@ public:
/** Generic read method. ByteSwap::Swap(T*) *must* be defined */
template <typename T>
T Get() {
if ( current + sizeof(T) > limit) {
if (mCurrent + sizeof(T) > mLimit) {
throw DeadlyImportError("End of file or stream limit was reached");
}
T f;
::memcpy (&f, current, sizeof(T));
Intern::Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
current += sizeof(T);
::memcpy(&f, mCurrent, sizeof(T));
Intern::Getter<SwapEndianess, T, RuntimeSwitch>()(&f, mLe);
mCurrent += sizeof(T);
return f;
}
@ -301,46 +301,44 @@ public:
private:
// ---------------------------------------------------------------------
void InternBegin() {
if (!stream) {
// in case someone wonders: StreamReader is frequently invoked with
// no prior validation whether the input stream is valid. Since
// no one bothers changing the error message, this message here
// is passed down to the caller and 'unable to open file'
// simply describes best what happened.
if (nullptr == mStream) {
throw DeadlyImportError("StreamReader: Unable to open file");
}
const size_t s = stream->FileSize() - stream->Tell();
if (!s) {
const size_t filesize = mStream->FileSize() - mStream->Tell();
if (0 == filesize) {
throw DeadlyImportError("StreamReader: File is empty or EOF is already reached");
}
current = buffer = new int8_t[s];
const size_t read = stream->Read(current,1,s);
mCurrent = mBuffer = new int8_t[filesize];
const size_t read = mStream->Read(mCurrent, 1, filesize);
// (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable
ai_assert(read <= s);
end = limit = &buffer[read-1] + 1;
ai_assert(read <= filesize);
mEnd = mLimit = &mBuffer[read - 1] + 1;
}
private:
std::shared_ptr<IOStream> stream;
int8_t *buffer, *current, *end, *limit;
bool le;
std::shared_ptr<IOStream> mStream;
int8_t *mBuffer;
int8_t *mCurrent;
int8_t *mEnd;
int8_t *mLimit;
bool mLe;
};
// --------------------------------------------------------------------------------------------
// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster.
#ifdef AI_BUILD_BIG_ENDIAN
typedef StreamReader<true> StreamReaderLE;
typedef StreamReader<false> StreamReaderBE;
typedef StreamReader<true> StreamReaderLE;
typedef StreamReader<false> StreamReaderBE;
#else
typedef StreamReader<true> StreamReaderBE;
typedef StreamReader<false> StreamReaderLE;
typedef StreamReader<true> StreamReaderBE;
typedef StreamReader<false> StreamReaderLE;
#endif
// `dynamic` StreamReader. The byte order of the input data is specified in the
// c'tor. This involves runtime branching and might be a little bit slower.
typedef StreamReader<true,true> StreamReaderAny;
typedef StreamReader<true, true> StreamReaderAny;
} // end namespace Assimp

View File

@ -1,3 +1,5 @@
SET(SAMPLE_PROJECT_NAME assimp_simpleogl)
FIND_PACKAGE(OpenGL)
FIND_PACKAGE(GLUT)
IF ( MSVC )
@ -16,6 +18,10 @@ IF ( NOT GLUT_FOUND )
ENDIF ()
ENDIF ()
# Used for usage and error messages in the program.
ADD_COMPILE_DEFINITIONS(ASSIMP_VERSION="${ASSIMP_VERSION}")
ADD_COMPILE_DEFINITIONS(PROJECT_NAME="${SAMPLE_PROJECT_NAME}")
if ( MSVC )
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
@ -34,17 +40,17 @@ LINK_DIRECTORIES(
${Assimp_BINARY_DIR}/lib
)
ADD_EXECUTABLE( assimp_simpleogl
ADD_EXECUTABLE( ${SAMPLE_PROJECT_NAME}
Sample_SimpleOpenGL.c
)
SET_PROPERTY(TARGET assimp_simpleogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
SET_PROPERTY(TARGET ${SAMPLE_PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
TARGET_LINK_LIBRARIES( assimp_simpleogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${M_LIB} )
SET_TARGET_PROPERTIES( assimp_simpleogl PROPERTIES
OUTPUT_NAME assimp_simpleogl
TARGET_LINK_LIBRARIES( ${SAMPLE_PROJECT_NAME} assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${M_LIB} )
SET_TARGET_PROPERTIES( ${SAMPLE_PROJECT_NAME} PROPERTIES
OUTPUT_NAME ${SAMPLE_PROJECT_NAME}
)
INSTALL( TARGETS assimp_simpleogl
INSTALL( TARGETS ${SAMPLE_PROJECT_NAME}
DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
)

View File

@ -15,9 +15,9 @@
#include <stdio.h>
#ifdef __APPLE__
#include <glut.h>
#include <freeglut.h>
#else
#include <GL/glut.h>
#include <GL/freeglut.h>
#endif
/* assimp include files. These three are usually needed. */
@ -25,6 +25,39 @@
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#define COMMAND_USAGE "--usage"
/* ---------------------------------------------------------------------------- */
inline static void print_run_command(const char* command_name) {
printf("Run '%s %s' for more information.\n",
PROJECT_NAME, command_name);
}
/* ---------------------------------------------------------------------------- */
inline static void print_error(const char* msg) {
printf("ERROR: %s\n", msg);
}
#define NEW_LINE "\n"
#define DOUBLE_NEW_LINE NEW_LINE NEW_LINE
/* ---------------------------------------------------------------------------- */
inline static void print_usage() {
static const char* usage_format =
"Usage: "
PROJECT_NAME
" <file>" DOUBLE_NEW_LINE
"where:" DOUBLE_NEW_LINE
" %-10s %s" DOUBLE_NEW_LINE
"options:" DOUBLE_NEW_LINE
" %-10s %s" DOUBLE_NEW_LINE;
printf(usage_format,
// where
"file", "The input model file to load.",
// options
COMMAND_USAGE, "Display usage.");
}
/* the global Assimp scene object */
const C_STRUCT aiScene* scene = NULL;
GLuint scene_list = 0;
@ -245,7 +278,7 @@ void do_motion (void)
static int frames = 0;
int time = glutGet(GLUT_ELAPSED_TIME);
angle += (time-prev_time)*0.01f;
angle += static_cast<float>((time-prev_time)*0.01);
prev_time = time;
frames += 1;
@ -324,12 +357,42 @@ int loadasset (const char* path)
/* ---------------------------------------------------------------------------- */
int main(int argc, char **argv)
{
const char* model_file = NULL;
C_STRUCT aiLogStream stream;
if (argc < 2) {
print_error("No input model file specifed.");
print_run_command(COMMAND_USAGE);
return EXIT_FAILURE;
}
// Find and execute available commands entered by the user.
for (int i = 1; i < argc; ++i) {
if (!strncmp(argv[i], COMMAND_USAGE, strlen(COMMAND_USAGE))) {
print_usage();
return EXIT_SUCCESS;
}
}
// Check and validate the specified model file extension.
model_file = argv[1];
const char* extension = strchr(model_file, '.');
if (!extension) {
print_error("Please provide a file with a valid extension.");
return EXIT_FAILURE;
}
if (AI_FALSE == aiIsExtensionSupported(extension)) {
print_error("The specified model file extension is currently "
"unsupported in Assimp " ASSIMP_VERSION ".");
return EXIT_FAILURE;
}
glutInitWindowSize(900,600);
glutInitWindowPosition(100,100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInit(&argc, argv);
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutCreateWindow("Assimp - Very simple OpenGL sample");
glutDisplayFunc(display);
@ -346,14 +409,11 @@ int main(int argc, char **argv)
stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
aiAttachLogStream(&stream);
/* the model name can be specified on the command line. If none
is specified, we try to locate one of the more expressive test
models from the repository (/models-nonbsd may be missing in
some distributions so we need a fallback from /models!). */
if( 0 != loadasset( argc >= 2 ? argv[1] : "../../test/models-nonbsd/X/dwarf.x")) {
if( argc != 1 || (0 != loadasset( "../../../../test/models-nonbsd/X/dwarf.x") && 0 != loadasset( "../../test/models/X/Testwuson.X"))) {
return -1;
}
// Load the model file.
if(0 != loadasset(model_file)) {
print_error("Failed to load model. Please ensure that the specified file exists.");
aiDetachAllLogStreams();
return EXIT_FAILURE;
}
glClearColor(0.1f,0.1f,0.1f,1.f);
@ -384,5 +444,5 @@ int main(int argc, char **argv)
again. This will definitely release the last resources allocated
by Assimp.*/
aiDetachAllLogStreams();
return 0;
return EXIT_SUCCESS;
}

View File

@ -61,6 +61,14 @@ SET( COMMON
unit/utIssues.cpp
unit/utAnim.cpp
unit/AssimpAPITest.cpp
unit/AssimpAPITest_aiMatrix3x3.cpp
unit/AssimpAPITest_aiMatrix4x4.cpp
unit/AssimpAPITest_aiQuaternion.cpp
unit/AssimpAPITest_aiVector2D.cpp
unit/AssimpAPITest_aiVector3D.cpp
unit/MathTest.cpp
unit/MathTest.h
unit/RandomNumberGeneration.h
unit/utBatchLoader.cpp
unit/utDefaultIOStream.cpp
unit/utFastAtof.cpp
@ -76,10 +84,12 @@ SET( COMMON
unit/utProfiler.cpp
unit/utSharedPPData.cpp
unit/utStringUtils.cpp
unit/Common/uiScene.cpp
unit/Common/utLineSplitter.cpp
)
SET( IMPORTERS
unit/ImportExport/Assxml/utAssxmlImportExport.cpp
unit/utLWSImportExport.cpp
unit/utLWOImportExport.cpp
unit/utSMDImportExport.cpp
@ -136,6 +146,9 @@ SET( IMPORTERS
unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp
unit/ImportExport/MDL/utMDLImporter_HL1_Materials.cpp
unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
#unit/ImportExport/IRR/utIrrImportExport.cpp
unit/ImportExport/RAW/utRAWImportExport.cpp
unit/ImportExport/Terragen/utTerragenImportExport.cpp
)
SET( MATERIAL

Binary file not shown.

View File

@ -0,0 +1,151 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "MathTest.h"
using namespace Assimp;
class AssimpAPITest_aiMatrix3x3 : public AssimpMathTest {
protected:
virtual void SetUp() {
result_c = result_cpp = aiMatrix3x3();
}
aiMatrix3x3 result_c, result_cpp;
};
TEST_F(AssimpAPITest_aiMatrix3x3, aiIdentityMatrix3Test) {
// Force a non-identity matrix.
result_c = aiMatrix3x3(0,0,0,0,0,0,0,0,0);
aiIdentityMatrix3(&result_c);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromMatrix4Test) {
const auto m = random_mat4();
result_cpp = aiMatrix3x3(m);
aiMatrix3FromMatrix4(&result_c, &m);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromQuaternionTest) {
const auto q = random_quat();
result_cpp = q.GetMatrix();
aiMatrix3FromQuaternion(&result_c, &q);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3AreEqualTest) {
result_c = result_cpp = random_mat3();
EXPECT_EQ(result_cpp == result_c,
(bool)aiMatrix3AreEqual(&result_cpp, &result_c));
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3AreEqualEpsilonTest) {
result_c = result_cpp = random_mat3();
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
(bool)aiMatrix3AreEqualEpsilon(&result_cpp, &result_c, Epsilon));
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMultiplyMatrix3Test) {
const auto m = random_mat3();
result_c = result_cpp = random_mat3();
result_cpp *= m;
aiMultiplyMatrix3(&result_c, &m);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiTransposeMatrix3Test) {
result_c = result_cpp = random_mat3();
result_cpp.Transpose();
aiTransposeMatrix3(&result_c);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3InverseTest) {
// Use a predetermined matrix to prevent arbitrary
// cases where it could have a null determinant.
result_c = result_cpp = aiMatrix3x3(
5, 2, 7,
4, 6, 9,
1, 8, 3);
result_cpp.Inverse();
aiMatrix3Inverse(&result_c);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3DeterminantTest) {
result_c = result_cpp = random_mat3();
EXPECT_EQ(result_cpp.Determinant(),
aiMatrix3Determinant(&result_c));
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3RotationZTest) {
const float angle(RandPI.next());
aiMatrix3x3::RotationZ(angle, result_cpp);
aiMatrix3RotationZ(&result_c, angle);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromRotationAroundAxisTest) {
const float angle(RandPI.next());
const auto axis = random_unit_vec3();
aiMatrix3x3::Rotation(angle, axis, result_cpp);
aiMatrix3FromRotationAroundAxis(&result_c, &axis, angle);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3TranslationTest) {
const auto axis = random_vec2();
aiMatrix3x3::Translation(axis, result_cpp);
aiMatrix3Translation(&result_c, &axis);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromToTest) {
// Use predetermined vectors to prevent running into division by zero.
const auto from = aiVector3D(1,2,1).Normalize(), to = aiVector3D(-1,1,1).Normalize();
aiMatrix3x3::FromToMatrix(from, to, result_cpp);
aiMatrix3FromTo(&result_c, &from, &to);
EXPECT_EQ(result_cpp, result_c);
}

View File

@ -0,0 +1,259 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "MathTest.h"
using namespace Assimp;
class AssimpAPITest_aiMatrix4x4 : public AssimpMathTest {
protected:
virtual void SetUp() {
result_c = result_cpp = aiMatrix4x4();
}
/* Generates a predetermined transformation matrix to use
for the aiDecompose functions to prevent running into
division by zero. */
aiMatrix4x4 get_predetermined_transformation_matrix_for_decomposition() const {
aiMatrix4x4 t, r;
aiMatrix4x4::Translation(aiVector3D(14,-25,-8), t);
aiMatrix4x4::Rotation(Math::PI<float>() / 4.0f, aiVector3D(1).Normalize(), r);
return t * r;
}
aiMatrix4x4 result_c, result_cpp;
};
TEST_F(AssimpAPITest_aiMatrix4x4, aiIdentityMatrix4Test) {
// Force a non-identity matrix.
result_c = aiMatrix4x4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
aiIdentityMatrix4(&result_c);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromMatrix3Test) {
aiMatrix3x3 m = random_mat3();
result_cpp = aiMatrix4x4(m);
aiMatrix4FromMatrix3(&result_c, &m);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromScalingQuaternionPositionTest) {
const aiVector3D s = random_vec3();
const aiQuaternion q = random_quat();
const aiVector3D t = random_vec3();
result_cpp = aiMatrix4x4(s, q, t);
aiMatrix4FromScalingQuaternionPosition(&result_c, &s, &q, &t);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4AddTest) {
const aiMatrix4x4 temp = random_mat4();
result_c = result_cpp = random_mat4();
result_cpp = result_cpp + temp;
aiMatrix4Add(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4AreEqualTest) {
result_c = result_cpp = random_mat4();
EXPECT_EQ(result_cpp == result_c,
(bool)aiMatrix4AreEqual(&result_cpp, &result_c));
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4AreEqualEpsilonTest) {
result_c = result_cpp = random_mat4();
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
(bool)aiMatrix4AreEqualEpsilon(&result_cpp, &result_c, Epsilon));
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMultiplyMatrix4Test) {
const auto m = random_mat4();
result_c = result_cpp = random_mat4();
result_cpp *= m;
aiMultiplyMatrix4(&result_c, &m);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiTransposeMatrix4Test) {
result_c = result_cpp = random_mat4();
result_cpp.Transpose();
aiTransposeMatrix4(&result_c);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4InverseTest) {
// Use a predetermined matrix to prevent arbitrary
// cases where it could have a null determinant.
result_c = result_cpp = aiMatrix4x4(
6, 10, 15, 3,
14, 2, 12, 8,
9, 13, 5, 16,
4, 7, 11, 1);
result_cpp.Inverse();
aiMatrix4Inverse(&result_c);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DeterminantTest) {
result_c = result_cpp = random_mat4();
EXPECT_EQ(result_cpp.Determinant(),
aiMatrix4Determinant(&result_c));
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4IsIdentityTest) {
EXPECT_EQ(result_cpp.IsIdentity(),
(bool)aiMatrix4IsIdentity(&result_c));
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiDecomposeMatrixTest) {
aiVector3D scaling_c, scaling_cpp,
position_c, position_cpp;
aiQuaternion rotation_c, rotation_cpp;
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
result_cpp.Decompose(scaling_cpp, rotation_cpp, position_cpp);
aiDecomposeMatrix(&result_c, &scaling_c, &rotation_c, &position_c);
EXPECT_EQ(scaling_cpp, scaling_c);
EXPECT_EQ(position_cpp, position_c);
EXPECT_EQ(rotation_cpp, rotation_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DecomposeIntoScalingEulerAnglesPositionTest) {
aiVector3D scaling_c, scaling_cpp,
rotation_c, rotation_cpp,
position_c, position_cpp;
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
result_cpp.Decompose(scaling_cpp, rotation_cpp, position_cpp);
aiMatrix4DecomposeIntoScalingEulerAnglesPosition(&result_c, &scaling_c, &rotation_c, &position_c);
EXPECT_EQ(scaling_cpp, scaling_c);
EXPECT_EQ(position_cpp, position_c);
EXPECT_EQ(rotation_cpp, rotation_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DecomposeIntoScalingAxisAnglePositionTest) {
aiVector3D scaling_c, scaling_cpp,
axis_c, axis_cpp,
position_c, position_cpp;
float angle_c, angle_cpp;
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
result_cpp.Decompose(scaling_cpp, axis_cpp, angle_cpp, position_cpp);
aiMatrix4DecomposeIntoScalingAxisAnglePosition(&result_c, &scaling_c, &axis_c, &angle_c, &position_c);
EXPECT_EQ(scaling_cpp, scaling_c);
EXPECT_EQ(axis_cpp, axis_c);
EXPECT_EQ(angle_cpp, angle_c);
EXPECT_EQ(position_cpp, position_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DecomposeNoScalingTest) {
aiVector3D position_c, position_cpp;
aiQuaternion rotation_c, rotation_cpp;
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
result_cpp.DecomposeNoScaling(rotation_cpp, position_cpp);
aiMatrix4DecomposeNoScaling(&result_c, &rotation_c, &position_c);
EXPECT_EQ(position_cpp, position_c);
EXPECT_EQ(rotation_cpp, rotation_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromEulerAnglesTest) {
const float x(RandPI.next()),
y(RandPI.next()),
z(RandPI.next());
result_cpp.FromEulerAnglesXYZ(x, y, z);
aiMatrix4FromEulerAngles(&result_c, x, y, z);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4RotationXTest) {
const float angle(RandPI.next());
aiMatrix4x4::RotationX(angle, result_cpp);
aiMatrix4RotationX(&result_c, angle);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4RotationYTest) {
const float angle(RandPI.next());
aiMatrix4x4::RotationY(angle, result_cpp);
aiMatrix4RotationY(&result_c, angle);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4RotationZTest) {
const float angle(RandPI.next());
aiMatrix4x4::RotationZ(angle, result_cpp);
aiMatrix4RotationZ(&result_c, angle);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromRotationAroundAxisTest) {
const float angle(RandPI.next());
const auto axis = random_unit_vec3();
aiMatrix4x4::Rotation(angle, axis, result_cpp);
aiMatrix4FromRotationAroundAxis(&result_c, &axis, angle);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4TranslationTest) {
const auto axis = random_vec3();
aiMatrix4x4::Translation(axis, result_cpp);
aiMatrix4Translation(&result_c, &axis);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4ScalingTest) {
const auto scaling = random_vec3();
aiMatrix4x4::Scaling(scaling, result_cpp);
aiMatrix4Scaling(&result_c, &scaling);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromToTest) {
// Use predetermined vectors to prevent running into division by zero.
const auto from = aiVector3D(1,2,1).Normalize(), to = aiVector3D(-1,1,1).Normalize();
aiMatrix4x4::FromToMatrix(from, to, result_cpp);
aiMatrix4FromTo(&result_c, &from, &to);
EXPECT_EQ(result_cpp, result_c);
}

View File

@ -0,0 +1,135 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "MathTest.h"
using namespace Assimp;
class AssimpAPITest_aiQuaternion : public AssimpMathTest {
protected:
virtual void SetUp() {
result_c = result_cpp = aiQuaternion();
}
aiQuaternion result_c, result_cpp;
};
TEST_F(AssimpAPITest_aiQuaternion, aiCreateQuaternionFromMatrixTest) {
// Use a predetermined transformation matrix
// to prevent running into division by zero.
aiMatrix3x3 m, r;
aiMatrix3x3::Translation(aiVector2D(14,-25), m);
aiMatrix3x3::RotationZ(Math::PI<float>() / 4.0f, r);
m = m * r;
result_cpp = aiQuaternion(m);
aiCreateQuaternionFromMatrix(&result_c, &m);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionFromEulerAnglesTest) {
const float x(RandPI.next()),
y(RandPI.next()),
z(RandPI.next());
result_cpp = aiQuaternion(x, y, z);
aiQuaternionFromEulerAngles(&result_c, x, y, z);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionFromAxisAngleTest) {
const float angle(RandPI.next());
const aiVector3D axis(random_unit_vec3());
result_cpp = aiQuaternion(axis, angle);
aiQuaternionFromAxisAngle(&result_c, &axis, angle);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionFromNormalizedQuaternionTest) {
const auto qvec3 = random_unit_vec3();
result_cpp = aiQuaternion(qvec3);
aiQuaternionFromNormalizedQuaternion(&result_c, &qvec3);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionAreEqualTest) {
result_c = result_cpp = random_quat();
EXPECT_EQ(result_cpp == result_c,
(bool)aiQuaternionAreEqual(&result_cpp, &result_c));
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionAreEqualEpsilonTest) {
result_c = result_cpp = random_quat();
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
(bool)aiQuaternionAreEqualEpsilon(&result_cpp, &result_c, Epsilon));
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionNormalizeTest) {
result_c = result_cpp = random_quat();
aiQuaternionNormalize(&result_c);
EXPECT_EQ(result_cpp.Normalize(), result_c);
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionConjugateTest) {
result_c = result_cpp = random_quat();
aiQuaternionConjugate(&result_c);
EXPECT_EQ(result_cpp.Conjugate(), result_c);
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionMultiplyTest) {
const aiQuaternion temp = random_quat();
result_c = result_cpp = random_quat();
result_cpp = result_cpp * temp;
aiQuaternionMultiply(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionInterpolateTest) {
// Use predetermined quaternions to prevent division by zero
// during slerp calculations.
const float INTERPOLATION(0.5f);
const auto q1 = aiQuaternion(aiVector3D(-1,1,1).Normalize(), Math::PI<float>() / 4.0f);
const auto q2 = aiQuaternion(aiVector3D(1,2,1).Normalize(), Math::PI<float>() / 2.0f);
aiQuaternion::Interpolate(result_cpp, q1, q2, INTERPOLATION);
aiQuaternionInterpolate(&result_c, &q1, &q2, INTERPOLATION);
EXPECT_EQ(result_cpp, result_c);
}

View File

@ -0,0 +1,140 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "MathTest.h"
using namespace Assimp;
class AssimpAPITest_aiVector2D : public AssimpMathTest {
protected:
virtual void SetUp() {
result_c = result_cpp = aiVector2D();
temp = random_vec2(); // Generates a random 2D vector != null vector.
}
aiVector2D result_c, result_cpp, temp;
};
TEST_F(AssimpAPITest_aiVector2D, aiVector2AreEqualTest) {
result_c = result_cpp = random_vec2();
EXPECT_EQ(result_cpp == result_c,
(bool)aiVector2AreEqual(&result_cpp, &result_c));
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2AreEqualEpsilonTest) {
result_c = result_cpp = random_vec2();
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
(bool)aiVector2AreEqualEpsilon(&result_cpp, &result_c, Epsilon));
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2AddTest) {
result_c = result_cpp = random_vec2();
result_cpp += temp;
aiVector2Add(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2SubtractTest) {
result_c = result_cpp = random_vec2();
result_cpp -= temp;
aiVector2Subtract(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2ScaleTest) {
const float FACTOR = RandNonZero.next();
result_c = result_cpp = random_vec2();
result_cpp *= FACTOR;
aiVector2Scale(&result_c, FACTOR);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2SymMulTest) {
result_c = result_cpp = random_vec2();
result_cpp = result_cpp.SymMul(temp);
aiVector2SymMul(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2DivideByScalarTest) {
const float DIVISOR = RandNonZero.next();
result_c = result_cpp = random_vec2();
result_cpp /= DIVISOR;
aiVector2DivideByScalar(&result_c, DIVISOR);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2DivideByVectorTest) {
result_c = result_cpp = random_vec2();
result_cpp = result_cpp / temp;
aiVector2DivideByVector(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2LengthTest) {
result_c = result_cpp = random_vec2();
EXPECT_EQ(result_cpp.Length(), aiVector2Length(&result_c));
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2SquareLengthTest) {
result_c = result_cpp = random_vec2();
EXPECT_EQ(result_cpp.SquareLength(), aiVector2SquareLength(&result_c));
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2NegateTest) {
result_c = result_cpp = random_vec2();
aiVector2Negate(&result_c);
EXPECT_EQ(-result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2DotProductTest) {
result_c = result_cpp = random_vec2();
EXPECT_EQ(result_cpp * result_c,
aiVector2DotProduct(&result_cpp, &result_c));
}
TEST_F(AssimpAPITest_aiVector2D, aiVector2NormalizeTest) {
result_c = result_cpp = random_vec2();
aiVector2Normalize(&result_c);
EXPECT_EQ(result_cpp.Normalize(), result_c);
}

View File

@ -0,0 +1,185 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "MathTest.h"
using namespace Assimp;
class AssimpAPITest_aiVector3D : public AssimpMathTest {
protected:
virtual void SetUp() {
result_c = result_cpp = aiVector3D();
temp = random_vec3(); // Generates a random 3D vector != null vector.
}
aiVector3D result_c, result_cpp, temp;
};
TEST_F(AssimpAPITest_aiVector3D, aiVector3AreEqualTest) {
result_c = result_cpp = random_vec3();
EXPECT_EQ(result_cpp == result_c,
(bool)aiVector3AreEqual(&result_cpp, &result_c));
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3AreEqualEpsilonTest) {
result_c = result_cpp = random_vec3();
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
(bool)aiVector3AreEqualEpsilon(&result_cpp, &result_c, Epsilon));
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3LessThanTest) {
result_c = result_cpp = random_vec3();
EXPECT_EQ(result_cpp < temp,
(bool)aiVector3LessThan(&result_c, &temp));
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3AddTest) {
result_c = result_cpp = random_vec3();
result_cpp += temp;
aiVector3Add(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3SubtractTest) {
result_c = result_cpp = random_vec3();
result_cpp -= temp;
aiVector3Subtract(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3ScaleTest) {
const float FACTOR = RandNonZero.next();
result_c = result_cpp = random_vec3();
result_cpp *= FACTOR;
aiVector3Scale(&result_c, FACTOR);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3SymMulTest) {
result_c = result_cpp = random_vec3();
result_cpp = result_cpp.SymMul(temp);
aiVector3SymMul(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3DivideByScalarTest) {
const float DIVISOR = RandNonZero.next();
result_c = result_cpp = random_vec3();
result_cpp /= DIVISOR;
aiVector3DivideByScalar(&result_c, DIVISOR);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3DivideByVectorTest) {
result_c = result_cpp = random_vec3();
result_cpp = result_cpp / temp;
aiVector3DivideByVector(&result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3LengthTest) {
result_c = result_cpp = random_vec3();
EXPECT_EQ(result_cpp.Length(), aiVector3Length(&result_c));
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3SquareLengthTest) {
result_c = result_cpp = random_vec3();
EXPECT_EQ(result_cpp.SquareLength(), aiVector3SquareLength(&result_c));
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3NegateTest) {
result_c = result_cpp = random_vec3();
aiVector3Negate(&result_c);
EXPECT_EQ(-result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3DotProductTest) {
result_c = result_cpp = random_vec3();
EXPECT_EQ(result_cpp * result_c,
aiVector3DotProduct(&result_cpp, &result_c));
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3CrossProductTest) {
result_c = result_cpp = random_vec3();
result_cpp = result_cpp ^ temp;
aiVector3CrossProduct(&result_c, &result_c, &temp);
EXPECT_EQ(result_cpp, result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3NormalizeTest) {
result_c = result_cpp = random_vec3();
aiVector3Normalize(&result_c);
EXPECT_EQ(result_cpp.Normalize(), result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3NormalizeSafeTest) {
result_c = result_cpp = random_vec3();
aiVector3NormalizeSafe(&result_c);
EXPECT_EQ(result_cpp.NormalizeSafe(), result_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiVector3RotateByQuaternionTest) {
aiVector3D v_c, v_cpp;
v_c = v_cpp = random_vec3();
const auto q = random_quat();
aiVector3RotateByQuaternion(&v_c, &q);
EXPECT_EQ(q.Rotate(v_cpp), v_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiTransformVecByMatrix3Test) {
const auto m = random_mat3();
aiVector3D v_c, v_cpp;
v_c = v_cpp = random_vec3();
v_cpp *= m;
aiTransformVecByMatrix3(&v_c, &m);
EXPECT_EQ(v_cpp, v_c);
}
TEST_F(AssimpAPITest_aiVector3D, aiTransformVecByMatrix4Test) {
const auto m = random_mat4();
aiVector3D v_c, v_cpp;
v_c = v_cpp = random_vec3();
v_cpp *= m;
aiTransformVecByMatrix4(&v_c, &m);
EXPECT_EQ(v_cpp, v_c);
}

View File

@ -0,0 +1,93 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include <assimp/scene.h>
using namespace Assimp;
class utScene : public ::testing::Test {
protected:
aiScene *scene;
void SetUp() override {
scene = new aiScene;
}
void TearDown() override {
delete scene;
scene = nullptr;
}
};
TEST_F(utScene, findNodeTest) {
scene->mRootNode = new aiNode();
scene->mRootNode->mName.Set("test");
aiNode *child = new aiNode;
child->mName.Set("child");
scene->mRootNode->addChildren(1, &child);
aiNode *found = scene->mRootNode->FindNode("child");
EXPECT_EQ(child, found);
}
TEST_F(utScene, sceneHasContentTest) {
EXPECT_FALSE(scene->HasAnimations());
EXPECT_FALSE(scene->HasMaterials());
EXPECT_FALSE(scene->HasMeshes());
EXPECT_FALSE(scene->HasCameras());
EXPECT_FALSE(scene->HasLights());
EXPECT_FALSE(scene->HasTextures());
}
TEST_F(utScene, getShortFilenameTest) {
std::string long_filename1 = "foo_bar/name";
const char *name1 = scene->GetShortFilename(long_filename1.c_str());
EXPECT_NE(nullptr, name1);
std::string long_filename2 = "foo_bar\\name";
const char *name2 = scene->GetShortFilename(long_filename2.c_str());
EXPECT_NE(nullptr, name2);
}
TEST_F(utScene, getEmbeddedTextureTest) {
}

View File

@ -0,0 +1,76 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2019, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "AbstractImportExportBase.h"
#include "SceneDiffer.h"
#include "UnitTestPCH.h"
#include <assimp/postprocess.h>
#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
using namespace Assimp;
class utAssxmlImportExport : public AbstractImportExportBase {
public:
bool importerTest() override {
return true;
}
#ifndef ASSIMP_BUILD_NO_EXPORT
bool exporterTest() override {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", aiProcess_ValidateDataStructure);
EXPECT_NE(scene, nullptr );
::Assimp::Exporter exporter;
return AI_SUCCESS == exporter.Export(scene, "assxml", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_out.assxml");
}
#endif
};
#ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F(utAssxmlImportExport, exportAssxmlTest) {
EXPECT_TRUE(exporterTest());
}
#endif

View File

@ -0,0 +1,66 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "AbstractImportExportBase.h"
#include "UnitTestPCH.h"
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <assimp/Importer.hpp>
using namespace Assimp;
class utIrrImportExport : public AbstractImportExportBase {
public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/IRR/box.irr", aiProcess_ValidateDataStructure);
return nullptr != scene;
}
};
TEST_F(utIrrImportExport, importSimpleIrrTest) {
EXPECT_TRUE(importerTest());
}
TEST_F(utIrrImportExport, importSGIrrTest) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/IRR/dawfInCellar_SameHierarchy.irr", aiProcess_ValidateDataStructure);
EXPECT_NE( nullptr,scene);
}

View File

@ -0,0 +1,64 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "AbstractImportExportBase.h"
#include "UnitTestPCH.h"
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <assimp/Importer.hpp>
using namespace Assimp;
class utRAWImportExport : public AbstractImportExportBase {
public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/RAW/Wuson.raw", aiProcess_ValidateDataStructure);
#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
return nullptr != scene;
#else
return nullptr == scene;
#endif
}
};
TEST_F(utRAWImportExport, importSimpleRAWTest) {
EXPECT_TRUE(importerTest());
}

View File

@ -0,0 +1,60 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "AbstractImportExportBase.h"
#include "UnitTestPCH.h"
#include <assimp/postprocess.h>
#include <assimp/Importer.hpp>
class utTerragenImportExport : public AbstractImportExportBase {
public:
virtual bool importerTest() {
/*Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/TER/RealisticTerrain.ter", aiProcess_ValidateDataStructure);
return nullptr != scene;*/
return true;
}
};
TEST_F(utTerragenImportExport, importX3DFromFileTest) {
EXPECT_TRUE(importerTest());
}

View File

@ -0,0 +1,56 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "MathTest.h"
namespace Assimp {
// Initialize epsilon value.
const float AssimpMathTest::Epsilon = Math::getEpsilon<float>();
// Initialize with an interval of [1,100].
RandomUniformFloatGenerator AssimpMathTest::RandNonZero(1.0f, 100.0f);
// Initialize with an interval of [-PI,PI] inclusively.
RandomUniformFloatGenerator AssimpMathTest::RandPI(-Math::PI<float>(), Math::PI<float>());
}

View File

@ -0,0 +1,103 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_MATH_TEST_H
#define ASSIMP_MATH_TEST_H
#include "UnitTestPCH.h"
#include <assimp/types.h>
#include "RandomNumberGeneration.h"
namespace Assimp {
/** Custom test class providing several math related utilities. */
class AssimpMathTest : public ::testing::Test {
public:
/** Return a random non-null 2D vector. */
inline static aiVector2D random_vec2() {
return aiVector2D(RandNonZero.next(), RandNonZero.next());
}
/** Return a random non-null 3D vector. */
inline static aiVector3D random_vec3() {
return aiVector3D(RandNonZero.next(), RandNonZero.next(),RandNonZero.next());
}
/** Return a random unit 3D vector. */
inline static aiVector3D random_unit_vec3() {
return random_vec3().NormalizeSafe();
}
/** Return a quaternion with random orientation and
* rotation angle around axis. */
inline static aiQuaternion random_quat() {
return aiQuaternion(random_unit_vec3(), RandPI.next());
}
/** Return a random non-null 3x3 matrix. */
inline static aiMatrix3x3 random_mat3() {
return aiMatrix3x3(
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(),
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(),
RandNonZero.next(), RandNonZero.next(),RandNonZero.next());
}
/** Return a random non-null 4x4 matrix. */
inline static aiMatrix4x4 random_mat4() {
return aiMatrix4x4(
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(), RandNonZero.next(),
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(), RandNonZero.next(),
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(), RandNonZero.next(),
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(), RandNonZero.next());
}
/** Epsilon value to use in tests. */
static const float Epsilon;
/** Random number generators. */
static RandomUniformFloatGenerator RandNonZero, RandPI;
};
}
#endif // ASSIMP_MATH_TEST_H

View File

@ -0,0 +1,82 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_RANDOM_NUMBER_GENERATION_H
#define ASSIMP_RANDOM_NUMBER_GENERATION_H
#include <random>
namespace Assimp {
/** Helper class to use for generating pseudo-random
* real numbers, with a uniform distribution. */
template<typename T>
class RandomUniformRealGenerator {
public:
RandomUniformRealGenerator() :
dist_(),
rd_(),
re_(rd_()) {
// empty
}
RandomUniformRealGenerator(T min, T max) :
dist_(min, max),
rd_(),
re_(rd_()) {
// empty
}
inline T next() {
return dist_(re_);
}
private:
std::uniform_real_distribution<T> dist_;
std::random_device rd_;
std::default_random_engine re_;
};
using RandomUniformFloatGenerator = RandomUniformRealGenerator<float>;
}
#endif // ASSIMP_RANDOM_NUMBER_GENERATION_H

View File

@ -43,6 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AbstractImportExportBase.h"
#include "UnitTestPCH.h"
#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/postprocess.h>
#include <assimp/Importer.hpp>
@ -50,17 +52,33 @@ using namespace Assimp;
class utM3DImportExport : public AbstractImportExportBase {
public:
virtual bool importerTest() {
bool importerTest() override {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/M3D/cube_normals.m3d", aiProcess_ValidateDataStructure);
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
return nullptr != scene;
return nullptr != scene;
#else
return nullptr == scene;
#endif // ASSIMP_BUILD_NO_M3D_IMPORTER
}
#ifndef ASSIMP_BUILD_NO_EXPORT
bool exporterTest() override {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/M3D/cube_normals.m3d", aiProcess_ValidateDataStructure);
Exporter exporter;
aiReturn ret = exporter.Export(scene, "m3d", ASSIMP_TEST_MODELS_DIR "/M3D/cube_normals_out.m3d");
return ret == AI_SUCCESS;
}
#endif
};
TEST_F(utM3DImportExport, importM3DFromFileTest) {
EXPECT_TRUE(importerTest());
}
#ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F(utM3DImportExport, exportM3DFromFileTest) {
EXPECT_TRUE(exporterTest());
}
#endif // ASSIMP_BUILD_NO_EXPORT

View File

@ -402,13 +402,12 @@ int CMaterialManager::FindValidPath(aiString* p_szString)
}
fclose(pFile);
// copy the result string back to the aiString
const size_t iLen = strlen(szTemp);
size_t iLen2 = iLen+1;
iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
memcpy(p_szString->data,szTemp,iLen2);
p_szString->length = static_cast<ai_uint32>(iLen);
// copy the result string back to the aiStr
const size_t len = strlen(szTemp);
size_t len2 = len+1;
len2 = len2 > MAXLEN ? MAXLEN : len2;
memcpy(p_szString->data, szTemp, len2);
p_szString->length = static_cast<ai_uint32>(len);
}
return 1;
}
@ -1490,4 +1489,5 @@ int CMaterialManager::EndMaterial (AssetHelper::MeshHelper* pcMesh)
return 1;
}
}; // end namespace AssimpView
} // end namespace AssimpView