Merge branch 'master' of https://github.com/assimp/assimp
commit
a1f773c305
|
@ -7,7 +7,7 @@ if [ $ANDROID ]; then
|
||||||
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
||||||
else
|
else
|
||||||
generate \
|
generate \
|
||||||
&& make \
|
&& make -j4 \
|
||||||
&& sudo make install \
|
&& sudo make install \
|
||||||
&& sudo ldconfig \
|
&& sudo ldconfig \
|
||||||
&& (cd test/unit; ../../bin/unit) \
|
&& (cd test/unit; ../../bin/unit) \
|
||||||
|
|
|
@ -316,7 +316,6 @@ ELSE (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
|
||||||
ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY( code/ )
|
ADD_SUBDIRECTORY( code/ )
|
||||||
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
IF ( WIN32 )
|
IF ( WIN32 )
|
||||||
|
|
|
@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "3DSExporter.h"
|
#include "3DSExporter.h"
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
|
#include "3DSHelper.h"
|
||||||
#include "SceneCombiner.h"
|
#include "SceneCombiner.h"
|
||||||
#include "SplitLargeMeshes.h"
|
#include "SplitLargeMeshes.h"
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
|
@ -54,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
using namespace D3DS;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
|
@ -369,14 +369,13 @@ struct Material
|
||||||
{
|
{
|
||||||
//! Default constructor. Builds a default name for the material
|
//! Default constructor. Builds a default name for the material
|
||||||
Material()
|
Material()
|
||||||
:
|
: mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
|
||||||
mDiffuse (0.6,0.6,0.6), // FIX ... we won't want object to be black
|
, mSpecularExponent ( ai_real( 0.0 ) )
|
||||||
mSpecularExponent (0.0),
|
, mShininessStrength ( ai_real( 1.0 ) )
|
||||||
mShininessStrength (1.0),
|
, mShading(Discreet3DS::Gouraud)
|
||||||
mShading(Discreet3DS::Gouraud),
|
, mTransparency ( ai_real( 1.0 ) )
|
||||||
mTransparency (1.0),
|
, mBumpHeight ( ai_real( 1.0 ) )
|
||||||
mBumpHeight (1.0),
|
, mTwoSided (false)
|
||||||
mTwoSided (false)
|
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
|
|
||||||
|
|
|
@ -1166,14 +1166,15 @@ void Discreet3DSImporter::ParseMaterialChunk()
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_TRANSPARENCY:
|
case Discreet3DS::CHUNK_MAT_TRANSPARENCY:
|
||||||
{
|
{
|
||||||
// This is the material's transparency
|
// This is the material's transparency
|
||||||
ai_real* pcf = &mScene->mMaterials.back().mTransparency;
|
ai_real* pcf = &mScene->mMaterials.back().mTransparency;
|
||||||
*pcf = ParsePercentageChunk();
|
*pcf = ParsePercentageChunk();
|
||||||
|
|
||||||
// NOTE: transparency, not opacity
|
// NOTE: transparency, not opacity
|
||||||
if (is_qnan(*pcf))
|
if (is_qnan(*pcf))
|
||||||
*pcf = 1.0;
|
*pcf = ai_real( 1.0 );
|
||||||
else *pcf = 1.0 - *pcf * (ai_real)0xFFFF / 100.0;
|
else
|
||||||
|
*pcf = ai_real( 1.0 ) - *pcf * (ai_real)0xFFFF / ai_real( 100.0 );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1199,21 +1200,23 @@ void Discreet3DSImporter::ParseMaterialChunk()
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT:
|
case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT:
|
||||||
{ // This is the shininess strength of the material
|
{ // This is the shininess strength of the material
|
||||||
ai_real* pcf = &mScene->mMaterials.back().mShininessStrength;
|
ai_real* pcf = &mScene->mMaterials.back().mShininessStrength;
|
||||||
*pcf = ParsePercentageChunk();
|
*pcf = ParsePercentageChunk();
|
||||||
if (is_qnan(*pcf))
|
if (is_qnan(*pcf))
|
||||||
*pcf = 0.0;
|
*pcf = ai_real( 0.0 );
|
||||||
else *pcf *= (ai_real)0xffff / 100.0;
|
else
|
||||||
|
*pcf *= (ai_real)0xffff / ai_real( 100.0 );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
|
case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
|
||||||
{ // This is the self illumination strength of the material
|
{ // This is the self illumination strength of the material
|
||||||
ai_real f = ParsePercentageChunk();
|
ai_real f = ParsePercentageChunk();
|
||||||
if (is_qnan(f))
|
if (is_qnan(f))
|
||||||
f = 0.0;
|
f = ai_real( 0.0 );
|
||||||
else f *= (ai_real)0xFFFF / 100.0;
|
else
|
||||||
mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
|
f *= (ai_real)0xFFFF / ai_real( 100.0 );
|
||||||
|
mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1272,7 +1275,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTD:
|
case Discreet3DS::CHUNK_PERCENTD:
|
||||||
// Manually parse the blend factor
|
// Manually parse the blend factor
|
||||||
pcOut->mTextureBlend = stream->GetF8();
|
pcOut->mTextureBlend = ai_real( stream->GetF8() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTF:
|
case Discreet3DS::CHUNK_PERCENTF:
|
||||||
|
@ -1282,7 +1285,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTW:
|
case Discreet3DS::CHUNK_PERCENTW:
|
||||||
// Manually parse the blend factor
|
// Manually parse the blend factor
|
||||||
pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / 100.0;
|
pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / ai_real( 100.0 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_MAP_USCALE:
|
case Discreet3DS::CHUNK_MAT_MAP_USCALE:
|
||||||
|
@ -1355,8 +1358,7 @@ ai_real Discreet3DSImporter::ParsePercentageChunk()
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
|
// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
|
||||||
void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
|
void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent )
|
||||||
bool acceptPercent)
|
|
||||||
{
|
{
|
||||||
ai_assert(out != NULL);
|
ai_assert(out != NULL);
|
||||||
|
|
||||||
|
@ -1389,13 +1391,16 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
|
||||||
case Discreet3DS::CHUNK_LINRGBB:
|
case Discreet3DS::CHUNK_LINRGBB:
|
||||||
bGamma = true;
|
bGamma = true;
|
||||||
case Discreet3DS::CHUNK_RGBB:
|
case Discreet3DS::CHUNK_RGBB:
|
||||||
if (sizeof(char) * 3 > diff) {
|
{
|
||||||
*out = clrError;
|
if ( sizeof( char ) * 3 > diff ) {
|
||||||
return;
|
*out = clrError;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ai_real invVal = ai_real( 1.0 ) / ai_real( 255.0 );
|
||||||
|
out->r = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
|
||||||
|
out->g = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
|
||||||
|
out->b = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
|
||||||
}
|
}
|
||||||
out->r = (ai_real)(uint8_t)stream->GetI1() / 255.0;
|
|
||||||
out->g = (ai_real)(uint8_t)stream->GetI1() / 255.0;
|
|
||||||
out->b = (ai_real)(uint8_t)stream->GetI1() / 255.0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Percentage chunks are accepted, too.
|
// Percentage chunks are accepted, too.
|
||||||
|
@ -1409,7 +1414,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTW:
|
case Discreet3DS::CHUNK_PERCENTW:
|
||||||
if (acceptPercent && 1 <= diff) {
|
if (acceptPercent && 1 <= diff) {
|
||||||
out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / 255.0;
|
out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / ai_real( 255.0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*out = clrError;
|
*out = clrError;
|
||||||
|
|
|
@ -227,7 +227,7 @@ std::string TextureConverted_ID;
|
||||||
// check that all textures has same size
|
// check that all textures has same size
|
||||||
if(src_texture_4check.size() > 1)
|
if(src_texture_4check.size() > 1)
|
||||||
{
|
{
|
||||||
for(uint8_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++)
|
for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++)
|
||||||
{
|
{
|
||||||
if((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) ||
|
if((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) ||
|
||||||
(src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth))
|
(src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth))
|
||||||
|
|
|
@ -618,7 +618,8 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||||
if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21))
|
if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21))
|
||||||
{
|
{
|
||||||
ParseLV4MeshFloat(mat.mTransparency);
|
ParseLV4MeshFloat(mat.mTransparency);
|
||||||
mat.mTransparency = 1.0 - mat.mTransparency;continue;
|
mat.mTransparency = ai_real( 1.0 ) - mat.mTransparency;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
// material self illumination
|
// material self illumination
|
||||||
if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18))
|
if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18))
|
||||||
|
|
|
@ -481,7 +481,7 @@ namespace Assimp
|
||||||
BatchLoader::PropertyMap map;
|
BatchLoader::PropertyMap map;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
bool operator== (const std::string& f) {
|
bool operator== (const std::string& f) const {
|
||||||
return file == f;
|
return file == f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -489,13 +489,22 @@ namespace Assimp
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// BatchLoader::pimpl data structure
|
// BatchLoader::pimpl data structure
|
||||||
struct Assimp::BatchData
|
struct Assimp::BatchData {
|
||||||
{
|
BatchData( IOSystem* pIO, bool validate )
|
||||||
BatchData()
|
: pIOSystem( pIO )
|
||||||
: pIOSystem()
|
, pImporter( nullptr )
|
||||||
, pImporter()
|
, next_id(0xffff)
|
||||||
, next_id(0xffff)
|
, validate( validate ) {
|
||||||
{}
|
ai_assert( NULL != pIO );
|
||||||
|
|
||||||
|
pImporter = new Importer();
|
||||||
|
pImporter->SetIOHandler( pIO );
|
||||||
|
}
|
||||||
|
|
||||||
|
~BatchData() {
|
||||||
|
pImporter->SetIOHandler( NULL ); /* get pointer back into our possession */
|
||||||
|
delete pImporter;
|
||||||
|
}
|
||||||
|
|
||||||
// IO system to be used for all imports
|
// IO system to be used for all imports
|
||||||
IOSystem* pIOSystem;
|
IOSystem* pIOSystem;
|
||||||
|
@ -511,53 +520,59 @@ struct Assimp::BatchData
|
||||||
|
|
||||||
// Id for next item
|
// Id for next item
|
||||||
unsigned int next_id;
|
unsigned int next_id;
|
||||||
|
|
||||||
|
// Validation enabled state
|
||||||
|
bool validate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::list<LoadRequest>::iterator LoadReqIt;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BatchLoader::BatchLoader(IOSystem* pIO)
|
BatchLoader::BatchLoader(IOSystem* pIO, bool validate )
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pIO);
|
ai_assert(NULL != pIO);
|
||||||
|
|
||||||
data = new BatchData();
|
m_data = new BatchData( pIO, validate );
|
||||||
data->pIOSystem = pIO;
|
|
||||||
|
|
||||||
data->pImporter = new Importer();
|
|
||||||
data->pImporter->SetIOHandler(data->pIOSystem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BatchLoader::~BatchLoader()
|
BatchLoader::~BatchLoader()
|
||||||
{
|
{
|
||||||
// delete all scenes wthat have not been polled by the user
|
// delete all scenes what have not been polled by the user
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
|
||||||
|
|
||||||
delete (*it).scene;
|
delete (*it).scene;
|
||||||
}
|
}
|
||||||
data->pImporter->SetIOHandler(NULL); /* get pointer back into our possession */
|
delete m_data;
|
||||||
delete data->pImporter;
|
|
||||||
delete data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BatchLoader::setValidation( bool enabled ) {
|
||||||
|
m_data->validate = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int BatchLoader::AddLoadRequest (const std::string& file,
|
bool BatchLoader::getValidation() const {
|
||||||
|
return m_data->validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
unsigned int BatchLoader::AddLoadRequest(const std::string& file,
|
||||||
unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
|
unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
|
||||||
{
|
{
|
||||||
ai_assert(!file.empty());
|
ai_assert(!file.empty());
|
||||||
|
|
||||||
// check whether we have this loading request already
|
// check whether we have this loading request already
|
||||||
std::list<LoadRequest>::iterator it;
|
for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
|
||||||
for (it = data->requests.begin();it != data->requests.end(); ++it) {
|
|
||||||
|
|
||||||
// Call IOSystem's path comparison function here
|
// Call IOSystem's path comparison function here
|
||||||
if (data->pIOSystem->ComparePaths((*it).file,file)) {
|
if ( m_data->pIOSystem->ComparePaths((*it).file,file)) {
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
if (!((*it).map == *map))
|
if ( !( ( *it ).map == *map ) ) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!(*it).map.empty())
|
else if ( !( *it ).map.empty() ) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
(*it).refCnt++;
|
(*it).refCnt++;
|
||||||
return (*it).id;
|
return (*it).id;
|
||||||
|
@ -565,20 +580,18 @@ unsigned int BatchLoader::AddLoadRequest (const std::string& file,
|
||||||
}
|
}
|
||||||
|
|
||||||
// no, we don't have it. So add it to the queue ...
|
// no, we don't have it. So add it to the queue ...
|
||||||
data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
|
m_data->requests.push_back(LoadRequest(file,steps,map, m_data->next_id));
|
||||||
return data->next_id++;
|
return m_data->next_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiScene* BatchLoader::GetImport (unsigned int which)
|
aiScene* BatchLoader::GetImport( unsigned int which )
|
||||||
{
|
{
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
|
||||||
|
|
||||||
if ((*it).id == which && (*it).loaded) {
|
if ((*it).id == which && (*it).loaded) {
|
||||||
|
|
||||||
aiScene* sc = (*it).scene;
|
aiScene* sc = (*it).scene;
|
||||||
if (!(--(*it).refCnt)) {
|
if (!(--(*it).refCnt)) {
|
||||||
data->requests.erase(it);
|
m_data->requests.erase(it);
|
||||||
}
|
}
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
@ -590,14 +603,15 @@ aiScene* BatchLoader::GetImport (unsigned int which)
|
||||||
void BatchLoader::LoadAll()
|
void BatchLoader::LoadAll()
|
||||||
{
|
{
|
||||||
// no threaded implementation for the moment
|
// no threaded implementation for the moment
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
|
||||||
// force validation in debug builds
|
// force validation in debug builds
|
||||||
unsigned int pp = (*it).flags;
|
unsigned int pp = (*it).flags;
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
if ( m_data->validate ) {
|
||||||
pp |= aiProcess_ValidateDataStructure;
|
pp |= aiProcess_ValidateDataStructure;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
// setup config properties if necessary
|
// setup config properties if necessary
|
||||||
ImporterPimpl* pimpl = data->pImporter->Pimpl();
|
ImporterPimpl* pimpl = m_data->pImporter->Pimpl();
|
||||||
pimpl->mFloatProperties = (*it).map.floats;
|
pimpl->mFloatProperties = (*it).map.floats;
|
||||||
pimpl->mIntProperties = (*it).map.ints;
|
pimpl->mIntProperties = (*it).map.ints;
|
||||||
pimpl->mStringProperties = (*it).map.strings;
|
pimpl->mStringProperties = (*it).map.strings;
|
||||||
|
@ -608,8 +622,8 @@ void BatchLoader::LoadAll()
|
||||||
DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
|
DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
|
||||||
DefaultLogger::get()->info("File: " + (*it).file);
|
DefaultLogger::get()->info("File: " + (*it).file);
|
||||||
}
|
}
|
||||||
data->pImporter->ReadFile((*it).file,pp);
|
m_data->pImporter->ReadFile((*it).file,pp);
|
||||||
(*it).scene = data->pImporter->GetOrphanedScene();
|
(*it).scene = m_data->pImporter->GetOrphanedScene();
|
||||||
(*it).loaded = true;
|
(*it).loaded = true;
|
||||||
|
|
||||||
DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
|
DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
|
||||||
|
|
|
@ -347,7 +347,12 @@ public: // static utilities
|
||||||
static void ConvertUTF8toISO8859_1(
|
static void ConvertUTF8toISO8859_1(
|
||||||
std::string& data);
|
std::string& data);
|
||||||
|
|
||||||
enum TextFileMode { ALLOW_EMPTY, FORBID_EMPTY };
|
// -------------------------------------------------------------------
|
||||||
|
/// @brief Enum to define, if empty files are ok or not.
|
||||||
|
enum TextFileMode {
|
||||||
|
ALLOW_EMPTY,
|
||||||
|
FORBID_EMPTY
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Utility for text file loaders which copies the contents of the
|
/** Utility for text file loaders which copies the contents of the
|
||||||
|
@ -382,14 +387,10 @@ public: // static utilities
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/// Error description in case there was one.
|
||||||
/** Error description in case there was one. */
|
|
||||||
std::string m_ErrorText;
|
std::string m_ErrorText;
|
||||||
|
/// Currently set progress handler.
|
||||||
/** Currently set progress handler */
|
|
||||||
ProgressHandler* m_progress;
|
ProgressHandler* m_progress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -56,10 +56,10 @@ using namespace Assimp::Formatter;
|
||||||
static bool match4(StreamReaderAny& stream, const char* string) {
|
static bool match4(StreamReaderAny& stream, const char* string) {
|
||||||
ai_assert( nullptr != string );
|
ai_assert( nullptr != string );
|
||||||
char tmp[] = {
|
char tmp[] = {
|
||||||
(stream).GetI1(),
|
(const char)(stream).GetI1(),
|
||||||
(stream).GetI1(),
|
(const char)(stream).GetI1(),
|
||||||
(stream).GetI1(),
|
(const char)(stream).GetI1(),
|
||||||
(stream).GetI1()
|
(const char)(stream).GetI1()
|
||||||
};
|
};
|
||||||
return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
|
return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
|
||||||
}
|
}
|
||||||
|
@ -346,10 +346,10 @@ void SectionParser :: Next()
|
||||||
stream.SetCurrentPos(current.start + current.size);
|
stream.SetCurrentPos(current.start + current.size);
|
||||||
|
|
||||||
const char tmp[] = {
|
const char tmp[] = {
|
||||||
stream.GetI1(),
|
(const char)stream.GetI1(),
|
||||||
stream.GetI1(),
|
(const char)stream.GetI1(),
|
||||||
stream.GetI1(),
|
(const char)stream.GetI1(),
|
||||||
stream.GetI1()
|
(const char)stream.GetI1()
|
||||||
};
|
};
|
||||||
current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
|
current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,6 @@ public:
|
||||||
BlenderImporter();
|
BlenderImporter();
|
||||||
~BlenderImporter();
|
~BlenderImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
|
@ -91,8 +91,17 @@ namespace Blender {
|
||||||
// value for the field.
|
// value for the field.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define WARN // warn if field is missing, substitute default value
|
// warn if field is missing, substitute default value
|
||||||
#define FAIL // fail the import if the field does not exist
|
#ifdef WARN
|
||||||
|
# undef WARN
|
||||||
|
#endif
|
||||||
|
#define WARN
|
||||||
|
|
||||||
|
// fail the import if the field does not exist
|
||||||
|
#ifdef FAIL
|
||||||
|
# undef FAIL
|
||||||
|
#endif
|
||||||
|
#define FAIL
|
||||||
|
|
||||||
struct Object;
|
struct Object;
|
||||||
struct MTex;
|
struct MTex;
|
||||||
|
|
|
@ -172,6 +172,7 @@ SET( Common_SRCS
|
||||||
Bitmap.h
|
Bitmap.h
|
||||||
XMLTools.h
|
XMLTools.h
|
||||||
Version.cpp
|
Version.cpp
|
||||||
|
IOStreamBuffer.h
|
||||||
)
|
)
|
||||||
SOURCE_GROUP(Common FILES ${Common_SRCS})
|
SOURCE_GROUP(Common FILES ${Common_SRCS})
|
||||||
|
|
||||||
|
@ -462,7 +463,7 @@ ADD_ASSIMP_IMPORTER( IFC
|
||||||
STEPFileEncoding.h
|
STEPFileEncoding.h
|
||||||
)
|
)
|
||||||
if (MSVC AND ASSIMP_BUILD_IFC_IMPORTER)
|
if (MSVC AND ASSIMP_BUILD_IFC_IMPORTER)
|
||||||
set_source_files_properties(IFCReaderGen.cpp PROPERTIES COMPILE_FLAGS "/bigobj")
|
set_source_files_properties(IFCReaderGen1.cpp IFCReaderGen2.cpp PROPERTIES COMPILE_FLAGS "/bigobj")
|
||||||
endif (MSVC AND ASSIMP_BUILD_IFC_IMPORTER)
|
endif (MSVC AND ASSIMP_BUILD_IFC_IMPORTER)
|
||||||
|
|
||||||
ADD_ASSIMP_IMPORTER( XGL
|
ADD_ASSIMP_IMPORTER( XGL
|
||||||
|
|
|
@ -150,7 +150,7 @@ void ColladaExporter::WriteFile()
|
||||||
// Writes the asset header
|
// Writes the asset header
|
||||||
void ColladaExporter::WriteHeader()
|
void ColladaExporter::WriteHeader()
|
||||||
{
|
{
|
||||||
static const ai_real epsilon = 0.00001;
|
static const ai_real epsilon = ai_real( 0.00001 );
|
||||||
static const aiQuaternion x_rot(aiMatrix3x3(
|
static const aiQuaternion x_rot(aiMatrix3x3(
|
||||||
0, -1, 0,
|
0, -1, 0,
|
||||||
1, 0, 0,
|
1, 0, 0,
|
||||||
|
@ -636,9 +636,24 @@ void ColladaExporter::WriteMaterials()
|
||||||
const aiMaterial* mat = mScene->mMaterials[a];
|
const aiMaterial* mat = mScene->mMaterials[a];
|
||||||
|
|
||||||
aiString name;
|
aiString name;
|
||||||
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
|
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS ) {
|
||||||
name = "mat";
|
name = "mat";
|
||||||
materials[a].name = std::string( "m") + to_string(a) + name.C_Str();
|
materials[a].name = std::string( "m") + to_string(a) + name.C_Str();
|
||||||
|
} else {
|
||||||
|
// try to use the material's name if no other material has already taken it, else append #
|
||||||
|
std::string testName = name.C_Str();
|
||||||
|
size_t materialCountWithThisName = 0;
|
||||||
|
for( size_t i = 0; i < a; i ++ ) {
|
||||||
|
if( materials[i].name == testName ) {
|
||||||
|
materialCountWithThisName ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( materialCountWithThisName == 0 ) {
|
||||||
|
materials[a].name = name.C_Str();
|
||||||
|
} else {
|
||||||
|
materials[a].name = std::string(name.C_Str()) + to_string(materialCountWithThisName);
|
||||||
|
}
|
||||||
|
}
|
||||||
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
|
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
|
||||||
if( !isalnum_C( *it ) ) {
|
if( !isalnum_C( *it ) ) {
|
||||||
*it = '_';
|
*it = '_';
|
||||||
|
|
|
@ -1071,7 +1071,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// resolve the data pointers for all anim channels. Find the minimum time while we're at it
|
// resolve the data pointers for all anim channels. Find the minimum time while we're at it
|
||||||
ai_real startTime = 1e20, endTime = -1e20;
|
ai_real startTime = ai_real( 1e20 ), endTime = ai_real( -1e20 );
|
||||||
for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
|
for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
|
||||||
{
|
{
|
||||||
Collada::ChannelEntry& e = *it;
|
Collada::ChannelEntry& e = *it;
|
||||||
|
@ -1152,7 +1152,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
||||||
resultTrafos.push_back( mat);
|
resultTrafos.push_back( mat);
|
||||||
|
|
||||||
// find next point in time to evaluate. That's the closest frame larger than the current in any channel
|
// find next point in time to evaluate. That's the closest frame larger than the current in any channel
|
||||||
ai_real nextTime = 1e20;
|
ai_real nextTime = ai_real( 1e20 );
|
||||||
for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
|
for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
|
||||||
{
|
{
|
||||||
Collada::ChannelEntry& channelElement = *it;
|
Collada::ChannelEntry& channelElement = *it;
|
||||||
|
|
|
@ -3075,7 +3075,7 @@ aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform
|
||||||
case TF_ROTATE:
|
case TF_ROTATE:
|
||||||
{
|
{
|
||||||
aiMatrix4x4 rot;
|
aiMatrix4x4 rot;
|
||||||
ai_real angle = tf.f[3] * ai_real( AI_MATH_PI) / 180.0;
|
ai_real angle = tf.f[3] * ai_real( AI_MATH_PI) / ai_real( 180.0 );
|
||||||
aiVector3D axis( tf.f[0], tf.f[1], tf.f[2]);
|
aiVector3D axis( tf.f[0], tf.f[1], tf.f[2]);
|
||||||
aiMatrix4x4::Rotation( angle, axis, rot);
|
aiMatrix4x4::Rotation( angle, axis, rot);
|
||||||
res *= rot;
|
res *= rot;
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace {
|
||||||
const static aiVector3D base_axis_y(0.0,1.0,0.0);
|
const static aiVector3D base_axis_y(0.0,1.0,0.0);
|
||||||
const static aiVector3D base_axis_x(1.0,0.0,0.0);
|
const static aiVector3D base_axis_x(1.0,0.0,0.0);
|
||||||
const static aiVector3D base_axis_z(0.0,0.0,1.0);
|
const static aiVector3D base_axis_z(0.0,0.0,1.0);
|
||||||
const static ai_real angle_epsilon = 0.95;
|
const static ai_real angle_epsilon = ai_real( 0.95 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -109,11 +109,11 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
|
||||||
// much easier, but I don't know how and am currently too tired to
|
// much easier, but I don't know how and am currently too tired to
|
||||||
// to think about a better solution.
|
// to think about a better solution.
|
||||||
|
|
||||||
const static ai_real LOWER_LIMIT = 0.1;
|
const static ai_real LOWER_LIMIT = ai_real( 0.1 );
|
||||||
const static ai_real UPPER_LIMIT = 0.9;
|
const static ai_real UPPER_LIMIT = ai_real( 0.9 );
|
||||||
|
|
||||||
const static ai_real LOWER_EPSILON = 10e-3;
|
const static ai_real LOWER_EPSILON = ai_real( 10e-3 );
|
||||||
const static ai_real UPPER_EPSILON = 1.0-10e-3;
|
const static ai_real UPPER_EPSILON = ai_real( 1.0-10e-3 );
|
||||||
|
|
||||||
for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx)
|
for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
void Flush();
|
void Flush();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// File datastructure, using clib
|
// File data-structure, using clib
|
||||||
FILE* mFile;
|
FILE* mFile;
|
||||||
// Filename
|
// Filename
|
||||||
std::string mFilename;
|
std::string mFilename;
|
||||||
|
@ -114,7 +114,6 @@ private:
|
||||||
mutable size_t mCachedSize;
|
mutable size_t mCachedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline DefaultIOStream::DefaultIOStream () :
|
inline DefaultIOStream::DefaultIOStream () :
|
||||||
mFile (NULL),
|
mFile (NULL),
|
||||||
|
@ -124,7 +123,6 @@ inline DefaultIOStream::DefaultIOStream () :
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
inline DefaultIOStream::DefaultIOStream (FILE* pFile,
|
inline DefaultIOStream::DefaultIOStream (FILE* pFile,
|
||||||
const std::string &strFilename) :
|
const std::string &strFilename) :
|
||||||
|
|
|
@ -3068,9 +3068,7 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
|
||||||
const KeyTimeList::value_type timeA = std::get<0>(kfl)->at( id0 );
|
const KeyTimeList::value_type timeA = std::get<0>(kfl)->at( id0 );
|
||||||
const KeyTimeList::value_type timeB = std::get<0>(kfl)->at( id1 );
|
const KeyTimeList::value_type timeB = std::get<0>(kfl)->at( id1 );
|
||||||
|
|
||||||
// do the actual interpolation in double-precision arithmetics
|
const ai_real factor = timeB == timeA ? 0. : static_cast<ai_real>( ( time - timeA ) ) / ( timeB - timeA );
|
||||||
// because it is a bit sensitive to rounding errors.
|
|
||||||
const double factor = timeB == timeA ? 0. : static_cast<double>( ( time - timeA ) / ( timeB - timeA ) );
|
|
||||||
const ai_real interpValue = static_cast<ai_real>( valueA + ( valueB - valueA ) * factor );
|
const ai_real interpValue = static_cast<ai_real>( valueA + ( valueB - valueA ) * factor );
|
||||||
|
|
||||||
result[ std::get<2>(kfl) ] = interpValue;
|
result[ std::get<2>(kfl) ] = interpValue;
|
||||||
|
|
|
@ -154,7 +154,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
|
||||||
// check whether we can reuse the SpatialSort of a previous step.
|
// check whether we can reuse the SpatialSort of a previous step.
|
||||||
SpatialSort* vertexFinder = NULL;
|
SpatialSort* vertexFinder = NULL;
|
||||||
SpatialSort _vertexFinder;
|
SpatialSort _vertexFinder;
|
||||||
ai_real posEpsilon = 1e-5;
|
ai_real posEpsilon = ai_real( 1e-5 );
|
||||||
if (shared) {
|
if (shared) {
|
||||||
std::vector<std::pair<SpatialSort,ai_real> >* avf;
|
std::vector<std::pair<SpatialSort,ai_real> >* avf;
|
||||||
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
|
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 <assimp/types.h>
|
||||||
|
#include <assimp/IOStream.hpp>
|
||||||
|
#include "ParsingUtils.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Implementation of a cached stream buffer.
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class IOStreamBuffer {
|
||||||
|
public:
|
||||||
|
/// @brief The class constructor.
|
||||||
|
IOStreamBuffer( size_t cache = 4096 * 4096 );
|
||||||
|
|
||||||
|
/// @brief The class destructor.
|
||||||
|
~IOStreamBuffer();
|
||||||
|
|
||||||
|
/// @brief Will open the cached access for a given stream.
|
||||||
|
/// @param stream The stream to cache.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool open( IOStream *stream );
|
||||||
|
|
||||||
|
/// @brief Will close the cached access.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool close();
|
||||||
|
|
||||||
|
/// @brief Returns the filesize.
|
||||||
|
/// @return The filesize.
|
||||||
|
size_t size() const;
|
||||||
|
|
||||||
|
/// @brief Returns the cache size.
|
||||||
|
/// @return The cache size.
|
||||||
|
size_t cacheSize() const;
|
||||||
|
|
||||||
|
/// @brief Will read the next block.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool readNextBlock();
|
||||||
|
|
||||||
|
/// @brief Returns the number of blocks to read.
|
||||||
|
/// @return The number of blocks.
|
||||||
|
size_t getNumBlocks() const;
|
||||||
|
|
||||||
|
/// @brief Returns the current block index.
|
||||||
|
/// @return The current block index.
|
||||||
|
size_t getCurrentBlockIndex() const;
|
||||||
|
|
||||||
|
/// @brief Returns the current file pos.
|
||||||
|
/// @return The current file pos.
|
||||||
|
size_t getFilePos() const;
|
||||||
|
|
||||||
|
/// @brief Will read the next line.
|
||||||
|
/// @param buffer The buffer for the next line.
|
||||||
|
/// @return true if successful.
|
||||||
|
bool getNextLine( std::vector<T> &buffer );
|
||||||
|
|
||||||
|
private:
|
||||||
|
IOStream *m_stream;
|
||||||
|
size_t m_filesize;
|
||||||
|
size_t m_cacheSize;
|
||||||
|
size_t m_numBlocks;
|
||||||
|
size_t m_blockIdx;
|
||||||
|
std::vector<T> m_cache;
|
||||||
|
size_t m_cachePos;
|
||||||
|
size_t m_filePos;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
|
||||||
|
: m_stream( nullptr )
|
||||||
|
, m_filesize( 0 )
|
||||||
|
, m_cacheSize( cache )
|
||||||
|
, m_numBlocks( 0 )
|
||||||
|
, m_blockIdx( 0 )
|
||||||
|
, m_cachePos( 0 )
|
||||||
|
, m_filePos( 0 ) {
|
||||||
|
m_cache.resize( cache );
|
||||||
|
std::fill( m_cache.begin(), m_cache.end(), '\n' );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
IOStreamBuffer<T>::~IOStreamBuffer() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::open( IOStream *stream ) {
|
||||||
|
// file still opened!
|
||||||
|
if ( nullptr != m_stream ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid stream pointer
|
||||||
|
if ( nullptr == stream ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream = stream;
|
||||||
|
m_filesize = m_stream->FileSize();
|
||||||
|
if ( m_filesize == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( m_filesize < m_cacheSize ) {
|
||||||
|
m_cacheSize = m_filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_numBlocks = m_filesize / m_cacheSize;
|
||||||
|
if ( ( m_filesize % m_cacheSize ) > 0 ) {
|
||||||
|
m_numBlocks++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::close() {
|
||||||
|
if ( nullptr == m_stream ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init counters and state vars
|
||||||
|
m_stream = nullptr;
|
||||||
|
m_filesize = 0;
|
||||||
|
m_numBlocks = 0;
|
||||||
|
m_blockIdx = 0;
|
||||||
|
m_cachePos = 0;
|
||||||
|
m_filePos = 0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::size() const {
|
||||||
|
return m_filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::cacheSize() const {
|
||||||
|
return m_cacheSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::readNextBlock() {
|
||||||
|
m_stream->Seek( m_filePos, aiOrigin_SET );
|
||||||
|
size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
|
||||||
|
if ( readLen == 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( readLen < m_cacheSize ) {
|
||||||
|
m_cacheSize = readLen;
|
||||||
|
}
|
||||||
|
m_filePos += m_cacheSize;
|
||||||
|
m_cachePos = 0;
|
||||||
|
m_blockIdx++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::getNumBlocks() const {
|
||||||
|
return m_numBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
|
||||||
|
return m_blockIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
size_t IOStreamBuffer<T>::getFilePos() const {
|
||||||
|
return m_filePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline
|
||||||
|
bool IOStreamBuffer<T>::getNextLine( std::vector<T> &buffer ) {
|
||||||
|
buffer.resize( m_cacheSize );
|
||||||
|
if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
|
||||||
|
if ( !readNextBlock() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t i = 0;
|
||||||
|
while ( !IsLineEnd( m_cache[ m_cachePos ] ) ) {
|
||||||
|
buffer[ i ] = m_cache[ m_cachePos ];
|
||||||
|
m_cachePos++;
|
||||||
|
i++;
|
||||||
|
if ( m_cachePos >= m_cacheSize ) {
|
||||||
|
if ( !readNextBlock() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer[ i ] = '\n';
|
||||||
|
m_cachePos++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // !ns Assimp
|
|
@ -542,7 +542,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
|
||||||
{
|
{
|
||||||
aiVectorKey& key = anim->mPositionKeys[i];
|
aiVectorKey& key = anim->mPositionKeys[i];
|
||||||
|
|
||||||
const ai_real dt = (i * in.speed * 0.001 );
|
const ai_real dt = (i * in.speed * ai_real( 0.001 ) );
|
||||||
const ai_real u = dt - std::floor(dt);
|
const ai_real u = dt - std::floor(dt);
|
||||||
const int idx = (int)std::floor(dt) % size;
|
const int idx = (int)std::floor(dt) % size;
|
||||||
|
|
||||||
|
@ -556,9 +556,9 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
|
||||||
const ai_real u2 = u*u;
|
const ai_real u2 = u*u;
|
||||||
const ai_real u3 = u2*2;
|
const ai_real u3 = u2*2;
|
||||||
|
|
||||||
const ai_real h1 = 2.0 * u3 - 3.0 * u2 + 1.0;
|
const ai_real h1 = ai_real( 2.0 ) * u3 - ai_real( 3.0 ) * u2 + ai_real( 1.0 );
|
||||||
const ai_real h2 = -2.0 * u3 + 3.0 * u3;
|
const ai_real h2 = ai_real( -2.0 ) * u3 + ai_real( 3.0 ) * u3;
|
||||||
const ai_real h3 = u3 - 2.0 * u3;
|
const ai_real h3 = u3 - ai_real( 2.0 ) * u3;
|
||||||
const ai_real h4 = u3 - u2;
|
const ai_real h4 = u3 - u2;
|
||||||
|
|
||||||
// compute the spline tangents
|
// compute the spline tangents
|
||||||
|
|
|
@ -116,10 +116,10 @@ private:
|
||||||
|
|
||||||
explicit Animator(AT t = UNKNOWN)
|
explicit Animator(AT t = UNKNOWN)
|
||||||
: type (t)
|
: type (t)
|
||||||
, speed (0.001)
|
, speed ( ai_real( 0.001 ) )
|
||||||
, direction (0.0,1.0,0.0)
|
, direction ( ai_real( 0.0 ), ai_real( 1.0 ), ai_real( 0.0 ) )
|
||||||
, circleRadius (1.0)
|
, circleRadius ( ai_real( 1.0) )
|
||||||
, tightness (0.5f)
|
, tightness ( ai_real( 0.5 ) )
|
||||||
, loop (true)
|
, loop (true)
|
||||||
, timeForWay (100)
|
, timeForWay (100)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,6 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @file Importer.h mostly internal stuff for use by #Assimp::Importer */
|
/** @file Importer.h mostly internal stuff for use by #Assimp::Importer */
|
||||||
|
#pragma once
|
||||||
#ifndef INCLUDED_AI_IMPORTER_H
|
#ifndef INCLUDED_AI_IMPORTER_H
|
||||||
#define INCLUDED_AI_IMPORTER_H
|
#define INCLUDED_AI_IMPORTER_H
|
||||||
|
|
||||||
|
@ -133,12 +134,11 @@ struct BatchData;
|
||||||
* could, this has not yet been implemented at the moment).
|
* could, this has not yet been implemented at the moment).
|
||||||
*
|
*
|
||||||
* @note The class may not be used by more than one thread*/
|
* @note The class may not be used by more than one thread*/
|
||||||
class BatchLoader
|
class ASSIMP_API BatchLoader
|
||||||
{
|
{
|
||||||
// friend of Importer
|
// friend of Importer
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! @cond never
|
//! @cond never
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Wraps a full list of configuration properties for an importer.
|
/** Wraps a full list of configuration properties for an importer.
|
||||||
|
@ -162,14 +162,28 @@ public:
|
||||||
//! @endcond
|
//! @endcond
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Construct a batch loader from a given IO system to be used
|
/** Construct a batch loader from a given IO system to be used
|
||||||
* to access external files */
|
* to access external files
|
||||||
explicit BatchLoader(IOSystem* pIO);
|
*/
|
||||||
|
explicit BatchLoader(IOSystem* pIO, bool validate = false );
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** The class destructor.
|
||||||
|
*/
|
||||||
~BatchLoader();
|
~BatchLoader();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Sets the validation step. True for enable validation during postprocess.
|
||||||
|
* @param enable True for validation.
|
||||||
|
*/
|
||||||
|
void setValidation( bool enabled );
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Returns the current validation step.
|
||||||
|
* @return The current validation step.
|
||||||
|
*/
|
||||||
|
bool getValidation() const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Add a new file to the list of files to be loaded.
|
/** Add a new file to the list of files to be loaded.
|
||||||
|
@ -185,7 +199,6 @@ public:
|
||||||
const PropertyMap* map = NULL
|
const PropertyMap* map = NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Get an imported scene.
|
/** Get an imported scene.
|
||||||
* This polls the import from the internal request list.
|
* This polls the import from the internal request list.
|
||||||
|
@ -199,20 +212,16 @@ public:
|
||||||
unsigned int which
|
unsigned int which
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Waits until all scenes have been loaded. This returns
|
/** Waits until all scenes have been loaded. This returns
|
||||||
* immediately if no scenes are queued.*/
|
* immediately if no scenes are queued.*/
|
||||||
void LoadAll();
|
void LoadAll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// No need to have that in the public API ...
|
// No need to have that in the public API ...
|
||||||
BatchData* data;
|
BatchData *m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
#endif // INCLUDED_AI_IMPORTER_H
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -286,7 +286,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
|
||||||
{
|
{
|
||||||
float fGloss;
|
float fGloss;
|
||||||
if (mIsLWO2) {
|
if (mIsLWO2) {
|
||||||
fGloss = std::pow( surf.mGlossiness*10.0+2.0, 2.0);
|
fGloss = std::pow( surf.mGlossiness*ai_real( 10.0 )+ ai_real( 2.0 ), ai_real( 2.0 ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -312,7 +312,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
|
||||||
|
|
||||||
// emissive color
|
// emissive color
|
||||||
// luminosity is not really the same but it affects the surface in a similar way. Some scaling looks good.
|
// luminosity is not really the same but it affects the surface in a similar way. Some scaling looks good.
|
||||||
clr.g = clr.b = clr.r = surf.mLuminosity*0.8;
|
clr.g = clr.b = clr.r = surf.mLuminosity*ai_real( 0.8 );
|
||||||
pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
|
pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
|
||||||
|
|
||||||
// opacity ... either additive or default-blended, please
|
// opacity ... either additive or default-blended, please
|
||||||
|
|
|
@ -261,13 +261,13 @@ inline void LatLngNormalToVec3(uint16_t p_iNormal, ai_real* p_afOut)
|
||||||
{
|
{
|
||||||
ai_real lat = (ai_real)(( p_iNormal >> 8u ) & 0xff);
|
ai_real lat = (ai_real)(( p_iNormal >> 8u ) & 0xff);
|
||||||
ai_real lng = (ai_real)(( p_iNormal & 0xff ));
|
ai_real lng = (ai_real)(( p_iNormal & 0xff ));
|
||||||
lat *= 3.141926/128.0;
|
const ai_real invVal( ai_real( 1.0 ) / ai_real( 128.0 ) );
|
||||||
lng *= 3.141926/128.0;
|
lat *= ai_real( 3.141926 ) * invVal;
|
||||||
|
lng *= ai_real( 3.141926 ) * invVal;
|
||||||
|
|
||||||
p_afOut[0] = std::cos(lat) * std::sin(lng);
|
p_afOut[ 0 ] = std::cos(lat) * std::sin(lng);
|
||||||
p_afOut[1] = std::sin(lat) * std::sin(lng);
|
p_afOut[ 1 ] = std::sin(lat) * std::sin(lng);
|
||||||
p_afOut[2] = std::cos(lng);
|
p_afOut[ 2 ] = std::cos(lng);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -408,7 +408,7 @@ void MDCImporter::InternReadFile(
|
||||||
|
|
||||||
// copy texture coordinates
|
// copy texture coordinates
|
||||||
pcUVCur->x = pcUVs[quak].u;
|
pcUVCur->x = pcUVs[quak].u;
|
||||||
pcUVCur->y = 1.0-pcUVs[quak].v; // DX to OGL
|
pcUVCur->y = ai_real( 1.0 )-pcUVs[quak].v; // DX to OGL
|
||||||
}
|
}
|
||||||
pcVertCur->x += pcFrame->localOrigin[0] ;
|
pcVertCur->x += pcFrame->localOrigin[0] ;
|
||||||
pcVertCur->y += pcFrame->localOrigin[1] ;
|
pcVertCur->y += pcFrame->localOrigin[1] ;
|
||||||
|
|
|
@ -42,8 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of the material system of the library
|
* @brief Implementation of the material system of the library
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "Hash.h"
|
#include "Hash.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
|
@ -71,7 +69,7 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
|
||||||
* could be improved by hashing, but it's possibly
|
* could be improved by hashing, but it's possibly
|
||||||
* no worth the effort (we're bound to C structures,
|
* no worth the effort (we're bound to C structures,
|
||||||
* thus std::map or derivates are not applicable. */
|
* thus std::map or derivates are not applicable. */
|
||||||
for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
|
for ( unsigned int i = 0; i < pMat->mNumProperties; ++i ) {
|
||||||
aiMaterialProperty* prop = pMat->mProperties[i];
|
aiMaterialProperty* prop = pMat->mProperties[i];
|
||||||
|
|
||||||
if (prop /* just for safety ... */
|
if (prop /* just for safety ... */
|
||||||
|
@ -151,14 +149,15 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
|
||||||
iWrite = *pMax;
|
iWrite = *pMax;
|
||||||
}
|
}
|
||||||
// strings are zero-terminated with a 32 bit length prefix, so this is safe
|
// strings are zero-terminated with a 32 bit length prefix, so this is safe
|
||||||
const char* cur = prop->mData+4;
|
const char *cur = prop->mData + 4;
|
||||||
ai_assert(prop->mDataLength>=5 && !prop->mData[prop->mDataLength-1]);
|
ai_assert( prop->mDataLength >= 5 );
|
||||||
for (unsigned int a = 0; ;++a) {
|
ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
|
||||||
|
for ( unsigned int a = 0; ;++a) {
|
||||||
cur = fast_atoreal_move<ai_real>(cur,pOut[a]);
|
cur = fast_atoreal_move<ai_real>(cur,pOut[a]);
|
||||||
if(a==iWrite-1) {
|
if ( a==iWrite-1 ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!IsSpace(*cur)) {
|
if ( !IsSpace(*cur) ) {
|
||||||
DefaultLogger::get()->error("Material property" + std::string(pKey) +
|
DefaultLogger::get()->error("Material property" + std::string(pKey) +
|
||||||
" is a string; failed to parse a float array out of it.");
|
" is a string; failed to parse a float array out of it.");
|
||||||
return AI_FAILURE;
|
return AI_FAILURE;
|
||||||
|
@ -170,7 +169,6 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AI_SUCCESS;
|
return AI_SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -224,8 +222,9 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
|
||||||
iWrite = *pMax;
|
iWrite = *pMax;
|
||||||
}
|
}
|
||||||
// strings are zero-terminated with a 32 bit length prefix, so this is safe
|
// strings are zero-terminated with a 32 bit length prefix, so this is safe
|
||||||
const char* cur = prop->mData+4;
|
const char *cur = prop->mData+4;
|
||||||
ai_assert(prop->mDataLength>=5 && !prop->mData[prop->mDataLength-1]);
|
ai_assert( prop->mDataLength >= 5 );
|
||||||
|
ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
|
||||||
for (unsigned int a = 0; ;++a) {
|
for (unsigned int a = 0; ;++a) {
|
||||||
pOut[a] = strtol10(cur,&cur);
|
pOut[a] = strtol10(cur,&cur);
|
||||||
if(a==iWrite-1) {
|
if(a==iWrite-1) {
|
||||||
|
@ -298,7 +297,8 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
|
||||||
// The string is stored as 32 but length prefix followed by zero-terminated UTF8 data
|
// The string is stored as 32 but length prefix followed by zero-terminated UTF8 data
|
||||||
pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t*>(prop->mData));
|
pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t*>(prop->mData));
|
||||||
|
|
||||||
ai_assert(pOut->length+1+4==prop->mDataLength && !prop->mData[prop->mDataLength-1]);
|
ai_assert( pOut->length+1+4==prop->mDataLength );
|
||||||
|
ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
|
||||||
memcpy(pOut->data,prop->mData+4,pOut->length+1);
|
memcpy(pOut->data,prop->mData+4,pOut->length+1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -317,12 +317,12 @@ ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMa
|
||||||
{
|
{
|
||||||
ai_assert (pMat != NULL);
|
ai_assert (pMat != NULL);
|
||||||
|
|
||||||
/* Textures are always stored with ascending indices (ValidateDS provides a check, so we don't need to do it again) */
|
// Textures are always stored with ascending indices (ValidateDS provides a check, so we don't need to do it again)
|
||||||
unsigned int max = 0;
|
unsigned int max = 0;
|
||||||
for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
|
for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
|
||||||
aiMaterialProperty* prop = pMat->mProperties[i];
|
aiMaterialProperty* prop = pMat->mProperties[i];
|
||||||
|
|
||||||
if (prop /* just a sanity check ... */
|
if ( prop /* just a sanity check ... */
|
||||||
&& 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE )
|
&& 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE )
|
||||||
&& prop->mSemantic == type) {
|
&& prop->mSemantic == type) {
|
||||||
|
|
||||||
|
@ -381,14 +381,16 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
|
||||||
return AI_SUCCESS;
|
return AI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const unsigned int DefaultNumAllocated = 5;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Construction. Actually the one and only way to get an aiMaterial instance
|
// Construction. Actually the one and only way to get an aiMaterial instance
|
||||||
aiMaterial::aiMaterial()
|
aiMaterial::aiMaterial()
|
||||||
{
|
: mProperties( NULL )
|
||||||
|
, mNumProperties( 0 )
|
||||||
|
, mNumAllocated( DefaultNumAllocated ) {
|
||||||
// Allocate 5 entries by default
|
// Allocate 5 entries by default
|
||||||
mNumProperties = 0;
|
mProperties = new aiMaterialProperty*[ DefaultNumAllocated ];
|
||||||
mNumAllocated = 5;
|
|
||||||
mProperties = new aiMaterialProperty*[5];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -543,10 +545,10 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
uint32_t Assimp :: ComputeMaterialHash(const aiMaterial* mat, bool includeMatName /*= false*/)
|
uint32_t Assimp::ComputeMaterialHash(const aiMaterial* mat, bool includeMatName /*= false*/)
|
||||||
{
|
{
|
||||||
uint32_t hash = 1503; // magic start value, chosen to be my birthday :-)
|
uint32_t hash = 1503; // magic start value, chosen to be my birthday :-)
|
||||||
for (unsigned int i = 0; i < mat->mNumProperties;++i) {
|
for ( unsigned int i = 0; i < mat->mNumProperties; ++i ) {
|
||||||
aiMaterialProperty* prop;
|
aiMaterialProperty* prop;
|
||||||
|
|
||||||
// Exclude all properties whose first character is '?' from the hash
|
// Exclude all properties whose first character is '?' from the hash
|
||||||
|
@ -585,15 +587,16 @@ void aiMaterial::CopyPropertyList(aiMaterial* pcDest,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pcOld)
|
if ( pcOld ) {
|
||||||
delete[] pcOld;
|
delete[] pcOld;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = iOldNum; i< pcDest->mNumProperties;++i) {
|
for (unsigned int i = iOldNum; i< pcDest->mNumProperties;++i) {
|
||||||
aiMaterialProperty* propSrc = pcSrc->mProperties[i];
|
aiMaterialProperty* propSrc = pcSrc->mProperties[i];
|
||||||
|
|
||||||
// search whether we have already a property with this name -> if yes, overwrite it
|
// search whether we have already a property with this name -> if yes, overwrite it
|
||||||
aiMaterialProperty* prop;
|
aiMaterialProperty* prop;
|
||||||
for (unsigned int q = 0; q < iOldNum;++q) {
|
for ( unsigned int q = 0; q < iOldNum; ++q ) {
|
||||||
prop = pcDest->mProperties[q];
|
prop = pcDest->mProperties[q];
|
||||||
if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic
|
if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic
|
||||||
&& prop->mIndex == propSrc->mIndex) {
|
&& prop->mIndex == propSrc->mIndex) {
|
||||||
|
@ -617,5 +620,4 @@ void aiMaterial::CopyPropertyList(aiMaterial* pcDest,
|
||||||
prop->mData = new char[propSrc->mDataLength];
|
prop->mData = new char[propSrc->mDataLength];
|
||||||
memcpy(prop->mData,propSrc->mData,prop->mDataLength);
|
memcpy(prop->mData,propSrc->mData,prop->mDataLength);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,7 @@ void OFFImporter::InternReadFile( const std::string& pFile,
|
||||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
||||||
aiMaterial* pcMat = new aiMaterial();
|
aiMaterial* pcMat = new aiMaterial();
|
||||||
|
|
||||||
aiColor4D clr(0.6,0.6,0.6,1.0);
|
aiColor4D clr( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 1.0 ) );
|
||||||
pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
|
pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
pScene->mMaterials[0] = pcMat;
|
pScene->mMaterials[0] = pcMat;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
#ifndef OBJ_FILEDATA_H_INC
|
#ifndef OBJ_FILEDATA_H_INC
|
||||||
#define OBJ_FILEDATA_H_INC
|
#define OBJ_FILEDATA_H_INC
|
||||||
|
|
||||||
|
@ -56,59 +57,43 @@ struct Material;
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
//! \struct Face
|
//! \struct Face
|
||||||
//! \brief Data structure for a simple obj-face, describes discredit,l.ation and materials
|
//! \brief Data structure for a simple obj-face, describes discredit,l.ation and materials
|
||||||
struct Face
|
// ------------------------------------------------------------------------------------------------
|
||||||
{
|
struct Face {
|
||||||
typedef std::vector<unsigned int> IndexArray;
|
typedef std::vector<unsigned int> IndexArray;
|
||||||
|
|
||||||
//! Primitive type
|
//! Primitive type
|
||||||
aiPrimitiveType m_PrimitiveType;
|
aiPrimitiveType m_PrimitiveType;
|
||||||
//! Vertex indices
|
//! Vertex indices
|
||||||
IndexArray *m_pVertices;
|
IndexArray m_vertices;
|
||||||
//! Normal indices
|
//! Normal indices
|
||||||
IndexArray *m_pNormals;
|
IndexArray m_normals;
|
||||||
//! Texture coordinates indices
|
//! Texture coordinates indices
|
||||||
IndexArray *m_pTexturCoords;
|
IndexArray m_texturCoords;
|
||||||
//! Pointer to assigned material
|
//! Pointer to assigned material
|
||||||
Material *m_pMaterial;
|
Material *m_pMaterial;
|
||||||
|
|
||||||
//! \brief Default constructor
|
//! \brief Default constructor
|
||||||
//! \param pVertices Pointer to assigned vertex indexbuffer
|
Face( aiPrimitiveType pt = aiPrimitiveType_POLYGON)
|
||||||
//! \param pNormals Pointer to assigned normals indexbuffer
|
: m_PrimitiveType( pt )
|
||||||
//! \param pTexCoords Pointer to assigned texture indexbuffer
|
, m_vertices()
|
||||||
Face( std::vector<unsigned int> *pVertices,
|
, m_normals()
|
||||||
std::vector<unsigned int> *pNormals,
|
, m_texturCoords()
|
||||||
std::vector<unsigned int> *pTexCoords,
|
, m_pMaterial( 0L ) {
|
||||||
aiPrimitiveType pt = aiPrimitiveType_POLYGON) :
|
|
||||||
m_PrimitiveType( pt ),
|
|
||||||
m_pVertices( pVertices ),
|
|
||||||
m_pNormals( pNormals ),
|
|
||||||
m_pTexturCoords( pTexCoords ),
|
|
||||||
m_pMaterial( 0L )
|
|
||||||
{
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Destructor
|
//! \brief Destructor
|
||||||
~Face()
|
~Face() {
|
||||||
{
|
// empty
|
||||||
delete m_pVertices;
|
|
||||||
m_pVertices = NULL;
|
|
||||||
|
|
||||||
delete m_pNormals;
|
|
||||||
m_pNormals = NULL;
|
|
||||||
|
|
||||||
delete m_pTexturCoords;
|
|
||||||
m_pTexturCoords = NULL;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
//! \struct Object
|
//! \struct Object
|
||||||
//! \brief Stores all objects of an objfile object definition
|
//! \brief Stores all objects of an obj-file object definition
|
||||||
struct Object
|
// ------------------------------------------------------------------------------------------------
|
||||||
{
|
struct Object {
|
||||||
enum ObjectType
|
enum ObjectType {
|
||||||
{
|
|
||||||
ObjType,
|
ObjType,
|
||||||
GroupType
|
GroupType
|
||||||
};
|
};
|
||||||
|
@ -123,29 +108,24 @@ struct Object
|
||||||
std::vector<unsigned int> m_Meshes;
|
std::vector<unsigned int> m_Meshes;
|
||||||
|
|
||||||
//! \brief Default constructor
|
//! \brief Default constructor
|
||||||
Object() :
|
Object()
|
||||||
m_strObjName("")
|
: m_strObjName("") {
|
||||||
{
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Destructor
|
//! \brief Destructor
|
||||||
~Object()
|
~Object() {
|
||||||
{
|
for ( std::vector<Object*>::iterator it = m_SubObjects.begin(); it != m_SubObjects.end(); ++it) {
|
||||||
for (std::vector<Object*>::iterator it = m_SubObjects.begin();
|
|
||||||
it != m_SubObjects.end(); ++it)
|
|
||||||
{
|
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
m_SubObjects.clear();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
//! \struct Material
|
//! \struct Material
|
||||||
//! \brief Data structure to store all material specific data
|
//! \brief Data structure to store all material specific data
|
||||||
struct Material
|
// ------------------------------------------------------------------------------------------------
|
||||||
{
|
struct Material {
|
||||||
//! Name of material description
|
//! Name of material description
|
||||||
aiString MaterialName;
|
aiString MaterialName;
|
||||||
|
|
||||||
|
@ -160,8 +140,8 @@ struct Material
|
||||||
aiString textureSpecularity;
|
aiString textureSpecularity;
|
||||||
aiString textureOpacity;
|
aiString textureOpacity;
|
||||||
aiString textureDisp;
|
aiString textureDisp;
|
||||||
enum TextureType
|
|
||||||
{
|
enum TextureType {
|
||||||
TextureDiffuseType = 0,
|
TextureDiffuseType = 0,
|
||||||
TextureSpecularType,
|
TextureSpecularType,
|
||||||
TextureAmbientType,
|
TextureAmbientType,
|
||||||
|
@ -201,22 +181,19 @@ struct Material
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
Material()
|
Material()
|
||||||
: diffuse (0.6,0.6,0.6)
|
: diffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) )
|
||||||
, alpha (1.0)
|
, alpha (ai_real( 1.0 ) )
|
||||||
, shineness (0.0)
|
, shineness ( ai_real( 0.0) )
|
||||||
, illumination_model (1)
|
, illumination_model (1)
|
||||||
, ior (1.0)
|
, ior ( ai_real( 1.0 ) ) {
|
||||||
{
|
|
||||||
// empty
|
// empty
|
||||||
for (size_t i = 0; i < TextureTypeCount; ++i)
|
for (size_t i = 0; i < TextureTypeCount; ++i) {
|
||||||
{
|
clamp[ i ] = false;
|
||||||
clamp[i] = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
~Material()
|
~Material() {
|
||||||
{
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -224,6 +201,7 @@ struct Material
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
//! \struct Mesh
|
//! \struct Mesh
|
||||||
//! \brief Data structure to store a mesh
|
//! \brief Data structure to store a mesh
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
static const unsigned int NoMaterial = ~0u;
|
static const unsigned int NoMaterial = ~0u;
|
||||||
/// The name for the mesh
|
/// The name for the mesh
|
||||||
|
@ -254,8 +232,7 @@ struct Mesh {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~Mesh()
|
~Mesh() {
|
||||||
{
|
|
||||||
for (std::vector<Face*>::iterator it = m_Faces.begin();
|
for (std::vector<Face*>::iterator it = m_Faces.begin();
|
||||||
it != m_Faces.end(); ++it)
|
it != m_Faces.end(); ++it)
|
||||||
{
|
{
|
||||||
|
@ -267,8 +244,8 @@ struct Mesh {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
//! \struct Model
|
//! \struct Model
|
||||||
//! \brief Data structure to store all obj-specific model datas
|
//! \brief Data structure to store all obj-specific model datas
|
||||||
struct Model
|
// ------------------------------------------------------------------------------------------------
|
||||||
{
|
struct Model {
|
||||||
typedef std::map<std::string, std::vector<unsigned int>* > GroupMap;
|
typedef std::map<std::string, std::vector<unsigned int>* > GroupMap;
|
||||||
typedef std::map<std::string, std::vector<unsigned int>* >::iterator GroupMapIt;
|
typedef std::map<std::string, std::vector<unsigned int>* >::iterator GroupMapIt;
|
||||||
typedef std::map<std::string, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt;
|
typedef std::map<std::string, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt;
|
||||||
|
@ -320,8 +297,7 @@ struct Model
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief The class destructor
|
//! \brief The class destructor
|
||||||
~Model()
|
~Model() {
|
||||||
{
|
|
||||||
// Clear all stored object instances
|
// Clear all stored object instances
|
||||||
for (std::vector<Object*>::iterator it = m_Objects.begin();
|
for (std::vector<Object*>::iterator it = m_Objects.begin();
|
||||||
it != m_Objects.end(); ++it) {
|
it != m_Objects.end(); ++it) {
|
||||||
|
@ -352,4 +328,4 @@ struct Model
|
||||||
} // Namespace ObjFile
|
} // Namespace ObjFile
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
||||||
#endif
|
#endif // OBJ_FILEDATA_H_INC
|
||||||
|
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ObjFileImporter.h"
|
#include "ObjFileImporter.h"
|
||||||
#include "ObjFileParser.h"
|
#include "ObjFileParser.h"
|
||||||
#include "ObjFileData.h"
|
#include "ObjFileData.h"
|
||||||
|
#include "IOStreamBuffer.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
@ -126,8 +127,11 @@ void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene,
|
||||||
throw DeadlyImportError( "OBJ-file is too small.");
|
throw DeadlyImportError( "OBJ-file is too small.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IOStreamBuffer<char> streamedBuffer;
|
||||||
|
streamedBuffer.open( fileStream.get() );
|
||||||
|
|
||||||
// Allocate buffer and read file into it
|
// Allocate buffer and read file into it
|
||||||
TextFileToBuffer( fileStream.get(),m_Buffer);
|
//TextFileToBuffer( fileStream.get(),m_Buffer);
|
||||||
|
|
||||||
// Get the model name
|
// Get the model name
|
||||||
std::string modelName, folderName;
|
std::string modelName, folderName;
|
||||||
|
@ -150,7 +154,7 @@ void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene,
|
||||||
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
||||||
const unsigned int progressTotal = (3*m_Buffer.size()/updateProgressEveryBytes);
|
const unsigned int progressTotal = (3*m_Buffer.size()/updateProgressEveryBytes);
|
||||||
// process all '\'
|
// process all '\'
|
||||||
std::vector<char> ::iterator iter = m_Buffer.begin();
|
/*std::vector<char> ::iterator iter = m_Buffer.begin();
|
||||||
while (iter != m_Buffer.end())
|
while (iter != m_Buffer.end())
|
||||||
{
|
{
|
||||||
if (*iter == '\\')
|
if (*iter == '\\')
|
||||||
|
@ -169,17 +173,19 @@ void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene,
|
||||||
m_progress->UpdateFileRead(++progress, progressTotal);
|
m_progress->UpdateFileRead(++progress, progressTotal);
|
||||||
progressCounter = 0;
|
progressCounter = 0;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// 1/3rd progress
|
// 1/3rd progress
|
||||||
m_progress->UpdateFileRead(1, 3);
|
m_progress->UpdateFileRead(1, 3);
|
||||||
|
|
||||||
// parse the file into a temporary representation
|
// parse the file into a temporary representation
|
||||||
ObjFileParser parser(m_Buffer, modelName, pIOHandler, m_progress, file);
|
ObjFileParser parser( streamedBuffer, modelName, pIOHandler, m_progress, file);
|
||||||
|
|
||||||
// And create the proper return structures out of it
|
// And create the proper return structures out of it
|
||||||
CreateDataFromImport(parser.GetModel(), pScene);
|
CreateDataFromImport(parser.GetModel(), pScene);
|
||||||
|
|
||||||
|
streamedBuffer.close();
|
||||||
|
|
||||||
// Clean up allocated storage for the next import
|
// Clean up allocated storage for the next import
|
||||||
m_Buffer.clear();
|
m_Buffer.clear();
|
||||||
|
|
||||||
|
@ -291,9 +297,7 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Create topology data
|
// Create topology data
|
||||||
aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData, unsigned int meshIndex ) {
|
||||||
unsigned int meshIndex )
|
|
||||||
{
|
|
||||||
// Checking preconditions
|
// Checking preconditions
|
||||||
ai_assert( NULL != pModel );
|
ai_assert( NULL != pModel );
|
||||||
|
|
||||||
|
@ -322,14 +326,14 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
|
||||||
ai_assert( NULL != inp );
|
ai_assert( NULL != inp );
|
||||||
|
|
||||||
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||||
pMesh->mNumFaces += inp->m_pVertices->size() - 1;
|
pMesh->mNumFaces += inp->m_vertices.size() - 1;
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||||
} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
||||||
pMesh->mNumFaces += inp->m_pVertices->size();
|
pMesh->mNumFaces += inp->m_vertices.size();
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
||||||
} else {
|
} else {
|
||||||
++pMesh->mNumFaces;
|
++pMesh->mNumFaces;
|
||||||
if (inp->m_pVertices->size() > 3) {
|
if (inp->m_vertices.size() > 3) {
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
} else {
|
} else {
|
||||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
@ -350,7 +354,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
|
||||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) {
|
||||||
ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
|
ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
|
||||||
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||||
for(size_t i = 0; i < inp->m_pVertices->size() - 1; ++i) {
|
for(size_t i = 0; i < inp->m_vertices.size() - 1; ++i) {
|
||||||
aiFace& f = pMesh->mFaces[ outIndex++ ];
|
aiFace& f = pMesh->mFaces[ outIndex++ ];
|
||||||
uiIdxCount += f.mNumIndices = 2;
|
uiIdxCount += f.mNumIndices = 2;
|
||||||
f.mIndices = new unsigned int[2];
|
f.mIndices = new unsigned int[2];
|
||||||
|
@ -358,7 +362,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
||||||
for(size_t i = 0; i < inp->m_pVertices->size(); ++i) {
|
for(size_t i = 0; i < inp->m_vertices.size(); ++i) {
|
||||||
aiFace& f = pMesh->mFaces[ outIndex++ ];
|
aiFace& f = pMesh->mFaces[ outIndex++ ];
|
||||||
uiIdxCount += f.mNumIndices = 1;
|
uiIdxCount += f.mNumIndices = 1;
|
||||||
f.mIndices = new unsigned int[1];
|
f.mIndices = new unsigned int[1];
|
||||||
|
@ -367,7 +371,7 @@ aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const Obj
|
||||||
}
|
}
|
||||||
|
|
||||||
aiFace *pFace = &pMesh->mFaces[ outIndex++ ];
|
aiFace *pFace = &pMesh->mFaces[ outIndex++ ];
|
||||||
const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size();
|
const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_vertices.size();
|
||||||
uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices;
|
uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices;
|
||||||
if (pFace->mNumIndices > 0) {
|
if (pFace->mNumIndices > 0) {
|
||||||
pFace->mIndices = new unsigned int[ uiNumIndices ];
|
pFace->mIndices = new unsigned int[ uiNumIndices ];
|
||||||
|
@ -432,8 +436,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ];
|
ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ];
|
||||||
|
|
||||||
// Copy all index arrays
|
// Copy all index arrays
|
||||||
for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ ) {
|
for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_vertices.size(); vertexIndex++ ) {
|
||||||
const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex );
|
const unsigned int vertex = pSourceFace->m_vertices.at( vertexIndex );
|
||||||
if ( vertex >= pModel->m_Vertices.size() ) {
|
if ( vertex >= pModel->m_Vertices.size() ) {
|
||||||
throw DeadlyImportError( "OBJ: vertex index out of range" );
|
throw DeadlyImportError( "OBJ: vertex index out of range" );
|
||||||
}
|
}
|
||||||
|
@ -441,8 +445,8 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
|
pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
|
||||||
|
|
||||||
// Copy all normals
|
// Copy all normals
|
||||||
if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size()) {
|
if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) {
|
||||||
const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex );
|
const unsigned int normal = pSourceFace->m_normals.at( vertexIndex );
|
||||||
if ( normal >= pModel->m_Normals.size() ) {
|
if ( normal >= pModel->m_Normals.size() ) {
|
||||||
throw DeadlyImportError( "OBJ: vertex normal index out of range" );
|
throw DeadlyImportError( "OBJ: vertex normal index out of range" );
|
||||||
}
|
}
|
||||||
|
@ -457,9 +461,9 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy all texture coordinates
|
// Copy all texture coordinates
|
||||||
if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size())
|
if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_texturCoords.size())
|
||||||
{
|
{
|
||||||
const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
|
const unsigned int tex = pSourceFace->m_texturCoords.at( vertexIndex );
|
||||||
ai_assert( tex < pModel->m_TextureCoord.size() );
|
ai_assert( tex < pModel->m_TextureCoord.size() );
|
||||||
|
|
||||||
if ( tex >= pModel->m_TextureCoord.size() )
|
if ( tex >= pModel->m_TextureCoord.size() )
|
||||||
|
@ -476,20 +480,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
// Get destination face
|
// Get destination face
|
||||||
aiFace *pDestFace = &pMesh->mFaces[ outIndex ];
|
aiFace *pDestFace = &pMesh->mFaces[ outIndex ];
|
||||||
|
|
||||||
const bool last = ( vertexIndex == pSourceFace->m_pVertices->size() - 1 );
|
const bool last = ( vertexIndex == pSourceFace->m_vertices.size() - 1 );
|
||||||
if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last)
|
if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) {
|
||||||
{
|
|
||||||
pDestFace->mIndices[ outVertexIndex ] = newIndex;
|
pDestFace->mIndices[ outVertexIndex ] = newIndex;
|
||||||
outVertexIndex++;
|
outVertexIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT)
|
if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) {
|
||||||
{
|
|
||||||
outIndex++;
|
outIndex++;
|
||||||
outVertexIndex = 0;
|
outVertexIndex = 0;
|
||||||
}
|
} else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||||
else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE)
|
|
||||||
{
|
|
||||||
outVertexIndex = 0;
|
outVertexIndex = 0;
|
||||||
|
|
||||||
if(!last)
|
if(!last)
|
||||||
|
@ -498,7 +498,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||||
if (vertexIndex) {
|
if (vertexIndex) {
|
||||||
if(!last) {
|
if(!last) {
|
||||||
pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ];
|
pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ];
|
||||||
if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) {
|
if ( !pSourceFace->m_normals.empty() && !pModel->m_Normals.empty()) {
|
||||||
pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ];
|
pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ];
|
||||||
}
|
}
|
||||||
if ( !pModel->m_TextureCoord.empty() ) {
|
if ( !pModel->m_TextureCoord.empty() ) {
|
||||||
|
|
|
@ -50,8 +50,8 @@ struct aiNode;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
namespace ObjFile {
|
namespace ObjFile {
|
||||||
struct Object;
|
struct Object;
|
||||||
struct Model;
|
struct Model;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -38,8 +38,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
||||||
|
|
||||||
#include "ObjFileParser.h"
|
#include "ObjFileParser.h"
|
||||||
|
@ -54,16 +52,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Constructor with loaded data and directories.
|
// Constructor with loaded data and directories.
|
||||||
ObjFileParser::ObjFileParser(std::vector<char> &data, const std::string &modelName, IOSystem *io, ProgressHandler* progress, const std::string &originalObjFileName) :
|
ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
|
||||||
m_DataIt(data.begin()),
|
IOSystem *io, ProgressHandler* progress,
|
||||||
m_DataItEnd(data.end()),
|
const std::string &originalObjFileName) :
|
||||||
|
m_DataIt(),
|
||||||
|
m_DataItEnd(),
|
||||||
m_pModel(NULL),
|
m_pModel(NULL),
|
||||||
m_uiLine(0),
|
m_uiLine(0),
|
||||||
m_pIO( io ),
|
m_pIO( io ),
|
||||||
|
@ -83,55 +82,50 @@ ObjFileParser::ObjFileParser(std::vector<char> &data, const std::string &modelNa
|
||||||
m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
|
m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
|
||||||
|
|
||||||
// Start parsing the file
|
// Start parsing the file
|
||||||
parseFile();
|
parseFile( streamBuffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Destructor
|
// Destructor
|
||||||
ObjFileParser::~ObjFileParser()
|
ObjFileParser::~ObjFileParser() {
|
||||||
{
|
|
||||||
delete m_pModel;
|
delete m_pModel;
|
||||||
m_pModel = NULL;
|
m_pModel = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Returns a pointer to the model instance.
|
// Returns a pointer to the model instance.
|
||||||
ObjFile::Model *ObjFileParser::GetModel() const
|
ObjFile::Model *ObjFileParser::GetModel() const {
|
||||||
{
|
|
||||||
return m_pModel;
|
return m_pModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// File parsing method.
|
// File parsing method.
|
||||||
void ObjFileParser::parseFile()
|
void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
||||||
{
|
|
||||||
if (m_DataIt == m_DataItEnd)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// only update every 100KB or it'll be too slow
|
// only update every 100KB or it'll be too slow
|
||||||
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
const unsigned int updateProgressEveryBytes = 100 * 1024;
|
||||||
unsigned int progressCounter = 0;
|
unsigned int progressCounter = 0;
|
||||||
const unsigned int bytesToProcess = std::distance(m_DataIt, m_DataItEnd);
|
const unsigned int bytesToProcess = streamBuffer.size();
|
||||||
const unsigned int progressTotal = 3 * bytesToProcess;
|
const unsigned int progressTotal = 3 * bytesToProcess;
|
||||||
const unsigned int progressOffset = bytesToProcess;
|
const unsigned int progressOffset = bytesToProcess;
|
||||||
unsigned int processed = 0;
|
unsigned int processed = 0;
|
||||||
|
size_t lastFilePos( 0 );
|
||||||
|
|
||||||
DataArrayIt lastDataIt = m_DataIt;
|
std::vector<char> buffer;
|
||||||
|
while ( streamBuffer.getNextLine( buffer ) ) {
|
||||||
|
m_DataIt = buffer.begin();
|
||||||
|
m_DataItEnd = buffer.end();
|
||||||
|
|
||||||
while (m_DataIt != m_DataItEnd)
|
|
||||||
{
|
|
||||||
// Handle progress reporting
|
// Handle progress reporting
|
||||||
processed += std::distance(lastDataIt, m_DataIt);
|
const size_t filePos( streamBuffer.getFilePos() );
|
||||||
lastDataIt = m_DataIt;
|
if ( lastFilePos < filePos ) {
|
||||||
if (processed > (progressCounter * updateProgressEveryBytes))
|
processed += filePos;
|
||||||
{
|
lastFilePos = filePos;
|
||||||
progressCounter++;
|
progressCounter++;
|
||||||
m_progress->UpdateFileRead(progressOffset + processed*2, progressTotal);
|
m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse line
|
// parse line
|
||||||
switch (*m_DataIt)
|
switch (*m_DataIt) {
|
||||||
{
|
|
||||||
case 'v': // Parse a vertex texture coordinate
|
case 'v': // Parse a vertex texture coordinate
|
||||||
{
|
{
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
|
@ -149,8 +143,8 @@ void ObjFileParser::parseFile()
|
||||||
}
|
}
|
||||||
} else if (*m_DataIt == 't') {
|
} else if (*m_DataIt == 't') {
|
||||||
// read in texture coordinate ( 2D or 3D )
|
// read in texture coordinate ( 2D or 3D )
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
getVector( m_pModel->m_TextureCoord );
|
getVector( m_pModel->m_TextureCoord );
|
||||||
} else if (*m_DataIt == 'n') {
|
} else if (*m_DataIt == 'n') {
|
||||||
// Read in normal vector definition
|
// Read in normal vector definition
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
|
@ -184,7 +178,7 @@ void ObjFileParser::parseFile()
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
getName(m_DataIt, m_DataItEnd, name);
|
getNameNoSpace(m_DataIt, m_DataItEnd, name);
|
||||||
|
|
||||||
size_t nextSpace = name.find(" ");
|
size_t nextSpace = name.find(" ");
|
||||||
if (nextSpace != std::string::npos)
|
if (nextSpace != std::string::npos)
|
||||||
|
@ -230,8 +224,7 @@ pf_skip_line:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Copy the next word in a temporary buffer
|
// Copy the next word in a temporary buffer
|
||||||
void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
|
void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
|
||||||
{
|
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
|
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
|
||||||
|
@ -247,37 +240,6 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
|
||||||
pBuffer[index] = '\0';
|
pBuffer[index] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
// Copy the next line into a temporary buffer
|
|
||||||
void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
|
|
||||||
{
|
|
||||||
size_t index = 0u;
|
|
||||||
|
|
||||||
// some OBJ files have line continuations using \ (such as in C++ et al)
|
|
||||||
bool continuation = false;
|
|
||||||
for (;m_DataIt != m_DataItEnd && index < length-1; ++m_DataIt)
|
|
||||||
{
|
|
||||||
const char c = *m_DataIt;
|
|
||||||
if (c == '\\') {
|
|
||||||
continuation = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == '\n' || c == '\r') {
|
|
||||||
if(continuation) {
|
|
||||||
pBuffer[ index++ ] = ' ';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
continuation = false;
|
|
||||||
pBuffer[ index++ ] = c;
|
|
||||||
}
|
|
||||||
ai_assert(index < length);
|
|
||||||
pBuffer[ index ] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ObjFileParser::getNumComponentsInLine() {
|
size_t ObjFileParser::getNumComponentsInLine() {
|
||||||
size_t numComponents( 0 );
|
size_t numComponents( 0 );
|
||||||
const char* tmp( &m_DataIt[0] );
|
const char* tmp( &m_DataIt[0] );
|
||||||
|
@ -291,7 +253,6 @@ size_t ObjFileParser::getNumComponentsInLine() {
|
||||||
return numComponents;
|
return numComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
||||||
size_t numComponents = getNumComponentsInLine();
|
size_t numComponents = getNumComponentsInLine();
|
||||||
ai_real x, y, z;
|
ai_real x, y, z;
|
||||||
|
@ -403,18 +364,17 @@ static const std::string DefaultObjName = "defaultobject";
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get values for a new face instance
|
// Get values for a new face instance
|
||||||
void ObjFileParser::getFace(aiPrimitiveType type) {
|
void ObjFileParser::getFace( aiPrimitiveType type ) {
|
||||||
copyNextLine(m_buffer, Buffersize);
|
//copyNextLine(m_buffer, Buffersize);
|
||||||
char *pPtr = m_buffer;
|
//char *pPtr = m_DataIt;
|
||||||
char *pEnd = &pPtr[Buffersize];
|
//char *pPtr = m_buffer;
|
||||||
pPtr = getNextToken<char*>(pPtr, pEnd);
|
//char *pEnd = &pPtr[Buffersize];
|
||||||
if ( pPtr == pEnd || *pPtr == '\0' ) {
|
m_DataIt = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
|
||||||
|
if ( m_DataIt == m_DataItEnd || *m_DataIt == '\0' ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unsigned int> *pIndices = new std::vector<unsigned int>;
|
ObjFile::Face *face = new ObjFile::Face( type );
|
||||||
std::vector<unsigned int> *pTexID = new std::vector<unsigned int>;
|
|
||||||
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
|
|
||||||
bool hasNormal = false;
|
bool hasNormal = false;
|
||||||
|
|
||||||
const int vSize = m_pModel->m_Vertices.size();
|
const int vSize = m_pModel->m_Vertices.size();
|
||||||
|
@ -424,14 +384,14 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
const bool vt = (!m_pModel->m_TextureCoord.empty());
|
const bool vt = (!m_pModel->m_TextureCoord.empty());
|
||||||
const bool vn = (!m_pModel->m_Normals.empty());
|
const bool vn = (!m_pModel->m_Normals.empty());
|
||||||
int iStep = 0, iPos = 0;
|
int iStep = 0, iPos = 0;
|
||||||
while (pPtr != pEnd) {
|
while ( m_DataIt != m_DataItEnd ) {
|
||||||
iStep = 1;
|
iStep = 1;
|
||||||
|
|
||||||
if ( IsLineEnd( *pPtr ) ) {
|
if ( IsLineEnd( *m_DataIt ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*pPtr=='/' ) {
|
if ( *m_DataIt =='/' ) {
|
||||||
if (type == aiPrimitiveType_POINT) {
|
if (type == aiPrimitiveType_POINT) {
|
||||||
DefaultLogger::get()->error("Obj: Separator unexpected in point statement");
|
DefaultLogger::get()->error("Obj: Separator unexpected in point statement");
|
||||||
}
|
}
|
||||||
|
@ -443,11 +403,11 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iPos++;
|
iPos++;
|
||||||
} else if( IsSpaceOrNewLine( *pPtr ) ) {
|
} else if( IsSpaceOrNewLine( *m_DataIt ) ) {
|
||||||
iPos = 0;
|
iPos = 0;
|
||||||
} else {
|
} else {
|
||||||
//OBJ USES 1 Base ARRAYS!!!!
|
//OBJ USES 1 Base ARRAYS!!!!
|
||||||
const int iVal( ::atoi( pPtr ) );
|
const int iVal( ::atoi( & ( *m_DataIt ) ) );
|
||||||
|
|
||||||
// increment iStep position based off of the sign and # of digits
|
// increment iStep position based off of the sign and # of digits
|
||||||
int tmp = iVal;
|
int tmp = iVal;
|
||||||
|
@ -458,65 +418,42 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
++iStep;
|
++iStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( iVal > 0 )
|
if ( iVal > 0 ) {
|
||||||
{
|
|
||||||
// Store parsed index
|
// Store parsed index
|
||||||
if ( 0 == iPos )
|
if ( 0 == iPos ) {
|
||||||
{
|
face->m_vertices.push_back( iVal - 1 );
|
||||||
pIndices->push_back( iVal-1 );
|
} else if ( 1 == iPos ) {
|
||||||
}
|
face->m_texturCoords.push_back( iVal - 1 );
|
||||||
else if ( 1 == iPos )
|
} else if ( 2 == iPos ) {
|
||||||
{
|
face->m_normals.push_back( iVal - 1 );
|
||||||
pTexID->push_back( iVal-1 );
|
|
||||||
}
|
|
||||||
else if ( 2 == iPos )
|
|
||||||
{
|
|
||||||
pNormalID->push_back( iVal-1 );
|
|
||||||
hasNormal = true;
|
hasNormal = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
reportErrorTokenInFace();
|
reportErrorTokenInFace();
|
||||||
}
|
}
|
||||||
}
|
} else if ( iVal < 0 ) {
|
||||||
else if ( iVal < 0 )
|
|
||||||
{
|
|
||||||
// Store relatively index
|
// Store relatively index
|
||||||
if ( 0 == iPos )
|
if ( 0 == iPos ) {
|
||||||
{
|
face->m_vertices.push_back( vSize + iVal );
|
||||||
pIndices->push_back( vSize + iVal );
|
} else if ( 1 == iPos ) {
|
||||||
}
|
face->m_texturCoords.push_back( vtSize + iVal );
|
||||||
else if ( 1 == iPos )
|
} else if ( 2 == iPos ) {
|
||||||
{
|
face->m_normals.push_back( vnSize + iVal );
|
||||||
pTexID->push_back( vtSize + iVal );
|
|
||||||
}
|
|
||||||
else if ( 2 == iPos )
|
|
||||||
{
|
|
||||||
pNormalID->push_back( vnSize + iVal );
|
|
||||||
hasNormal = true;
|
hasNormal = true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
reportErrorTokenInFace();
|
reportErrorTokenInFace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pPtr += iStep;
|
m_DataIt += iStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pIndices->empty() ) {
|
if ( face->m_vertices.empty() ) {
|
||||||
DefaultLogger::get()->error("Obj: Ignoring empty face");
|
DefaultLogger::get()->error("Obj: Ignoring empty face");
|
||||||
// skip line and clean up
|
// skip line and clean up
|
||||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||||
delete pNormalID;
|
|
||||||
delete pTexID;
|
|
||||||
delete pIndices;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjFile::Face *face = new ObjFile::Face( pIndices, pNormalID, pTexID, type );
|
|
||||||
|
|
||||||
// Set active material, if one set
|
// Set active material, if one set
|
||||||
if( NULL != m_pModel->m_pCurrentMaterial ) {
|
if( NULL != m_pModel->m_pCurrentMaterial ) {
|
||||||
face->m_pMaterial = m_pModel->m_pCurrentMaterial;
|
face->m_pMaterial = m_pModel->m_pCurrentMaterial;
|
||||||
|
@ -536,8 +473,8 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
|
|
||||||
// Store the face
|
// Store the face
|
||||||
m_pModel->m_pCurrentMesh->m_Faces.push_back( face );
|
m_pModel->m_pCurrentMesh->m_Faces.push_back( face );
|
||||||
m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int)face->m_pVertices->size();
|
m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int) face->m_vertices.size();
|
||||||
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int)face->m_pTexturCoords[0].size();
|
m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int) face->m_texturCoords.size();
|
||||||
if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) {
|
if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) {
|
||||||
m_pModel->m_pCurrentMesh->m_hasNormals = true;
|
m_pModel->m_pCurrentMesh->m_hasNormals = true;
|
||||||
}
|
}
|
||||||
|
@ -547,8 +484,7 @@ void ObjFileParser::getFace(aiPrimitiveType type) {
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get values for a new material description
|
// Get values for a new material description
|
||||||
void ObjFileParser::getMaterialDesc()
|
void ObjFileParser::getMaterialDesc() {
|
||||||
{
|
|
||||||
// Get next data for material data
|
// Get next data for material data
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
if (m_DataIt == m_DataItEnd) {
|
if (m_DataIt == m_DataItEnd) {
|
||||||
|
@ -571,28 +507,26 @@ void ObjFileParser::getMaterialDesc()
|
||||||
|
|
||||||
// If the current mesh has the same material, we simply ignore that 'usemtl' command
|
// If the current mesh has the same material, we simply ignore that 'usemtl' command
|
||||||
// There is no need to create another object or even mesh here
|
// There is no need to create another object or even mesh here
|
||||||
if (m_pModel->m_pCurrentMaterial && m_pModel->m_pCurrentMaterial->MaterialName == aiString(strName))
|
if ( m_pModel->m_pCurrentMaterial && m_pModel->m_pCurrentMaterial->MaterialName == aiString( strName ) ) {
|
||||||
skip = true;
|
skip = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!skip)
|
if (!skip) {
|
||||||
{
|
|
||||||
// Search for material
|
// Search for material
|
||||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find(strName);
|
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find(strName);
|
||||||
if (it == m_pModel->m_MaterialMap.end())
|
if (it == m_pModel->m_MaterialMap.end()) {
|
||||||
{
|
|
||||||
// Not found, use default material
|
// Not found, use default material
|
||||||
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
|
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
|
||||||
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
|
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
|
||||||
strName = m_pModel->m_pDefaultMaterial->MaterialName.C_Str();
|
strName = m_pModel->m_pDefaultMaterial->MaterialName.C_Str();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Found, using detected material
|
// Found, using detected material
|
||||||
m_pModel->m_pCurrentMaterial = (*it).second;
|
m_pModel->m_pCurrentMaterial = (*it).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsNewMesh(strName))
|
if ( needsNewMesh( strName ) ) {
|
||||||
createMesh(strName);
|
createMesh( strName );
|
||||||
|
}
|
||||||
|
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
|
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
|
||||||
}
|
}
|
||||||
|
@ -603,17 +537,12 @@ void ObjFileParser::getMaterialDesc()
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get a comment, values will be skipped
|
// Get a comment, values will be skipped
|
||||||
void ObjFileParser::getComment()
|
void ObjFileParser::getComment() {
|
||||||
{
|
while (m_DataIt != m_DataItEnd) {
|
||||||
while (m_DataIt != m_DataItEnd)
|
if ( '\n' == (*m_DataIt)) {
|
||||||
{
|
|
||||||
if ( '\n' == (*m_DataIt))
|
|
||||||
{
|
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,8 +550,7 @@ void ObjFileParser::getComment()
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Get material library from file.
|
// Get material library from file.
|
||||||
void ObjFileParser::getMaterialLib()
|
void ObjFileParser::getMaterialLib() {
|
||||||
{
|
|
||||||
// Translate tuple
|
// Translate tuple
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
if( m_DataIt == m_DataItEnd ) {
|
if( m_DataIt == m_DataItEnd ) {
|
||||||
|
@ -678,8 +606,7 @@ void ObjFileParser::getMaterialLib()
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Set a new material definition as the current material.
|
// Set a new material definition as the current material.
|
||||||
void ObjFileParser::getNewMaterial()
|
void ObjFileParser::getNewMaterial() {
|
||||||
{
|
|
||||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||||
if( m_DataIt == m_DataItEnd ) {
|
if( m_DataIt == m_DataItEnd ) {
|
||||||
|
@ -692,17 +619,13 @@ void ObjFileParser::getNewMaterial()
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
}
|
}
|
||||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
|
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
|
||||||
if ( it == m_pModel->m_MaterialMap.end() )
|
if ( it == m_pModel->m_MaterialMap.end() ) {
|
||||||
{
|
|
||||||
// Show a warning, if material was not found
|
// Show a warning, if material was not found
|
||||||
DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat);
|
DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat);
|
||||||
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
|
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// Set new material
|
// Set new material
|
||||||
if ( needsNewMesh( strMat ) )
|
if ( needsNewMesh( strMat ) ) {
|
||||||
{
|
|
||||||
createMesh( strMat );
|
createMesh( strMat );
|
||||||
}
|
}
|
||||||
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat );
|
m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat );
|
||||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/vector2.h>
|
#include <assimp/vector2.h>
|
||||||
#include <assimp/vector3.h>
|
#include <assimp/vector3.h>
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
|
#include "IOStreamBuffer.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \brief Constructor with data array.
|
/// \brief Constructor with data array.
|
||||||
ObjFileParser(std::vector<char> &Data, const std::string &strModelName, IOSystem* io, ProgressHandler* progress, const std::string &originalObjFileName);
|
ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &strModelName, IOSystem* io, ProgressHandler* progress, const std::string &originalObjFileName);
|
||||||
/// \brief Destructor
|
/// \brief Destructor
|
||||||
~ObjFileParser();
|
~ObjFileParser();
|
||||||
/// \brief Model getter.
|
/// \brief Model getter.
|
||||||
|
@ -80,11 +81,11 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Parse the loaded file
|
/// Parse the loaded file
|
||||||
void parseFile();
|
void parseFile( IOStreamBuffer<char> &streamBuffer );
|
||||||
/// Method to copy the new delimited word in the current line.
|
/// Method to copy the new delimited word in the current line.
|
||||||
void copyNextWord(char *pBuffer, size_t length);
|
void copyNextWord(char *pBuffer, size_t length);
|
||||||
/// Method to copy the new line.
|
/// Method to copy the new line.
|
||||||
void copyNextLine(char *pBuffer, size_t length);
|
// void copyNextLine(char *pBuffer, size_t length);
|
||||||
/// Stores the vector
|
/// Stores the vector
|
||||||
void getVector( std::vector<aiVector3D> &point3d_array );
|
void getVector( std::vector<aiVector3D> &point3d_array );
|
||||||
/// Stores the following 3d vector.
|
/// Stores the following 3d vector.
|
||||||
|
|
|
@ -142,11 +142,52 @@ inline char_t getName( char_t it, char_t end, std::string &name )
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pStart = &( *it );
|
char *pStart = &( *it );
|
||||||
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
|
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) && !IsSpaceOrNewLine( *it ) ) {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( isEndOfBuffer( it, end ) || IsLineEnd( *it ) || IsSpaceOrNewLine( *it ) ) {
|
/*while( isEndOfBuffer( it, end ) || IsLineEnd( *it ) || IsSpaceOrNewLine( *it ) ) {
|
||||||
|
--it;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
*/
|
||||||
|
// Get name
|
||||||
|
// if there is no name, and the previous char is a separator, come back to start
|
||||||
|
while (&(*it) < pStart) {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
std::string strName( pStart, &(*it) );
|
||||||
|
if ( strName.empty() )
|
||||||
|
return it;
|
||||||
|
else
|
||||||
|
name = strName;
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Get a name from the current line. Do not preserve space
|
||||||
|
* in the middle, but trim it at the end.
|
||||||
|
* @param it set to current position
|
||||||
|
* @param end set to end of scratch buffer for readout
|
||||||
|
* @param name Separated name
|
||||||
|
* @return Current-iterator with new position
|
||||||
|
*/
|
||||||
|
template<class char_t>
|
||||||
|
inline char_t getNameNoSpace( char_t it, char_t end, std::string &name )
|
||||||
|
{
|
||||||
|
name = "";
|
||||||
|
if( isEndOfBuffer( it, end ) ) {
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *pStart = &( *it );
|
||||||
|
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it )
|
||||||
|
&& !IsSpaceOrNewLine( *it ) ) {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( isEndOfBuffer( it, end ) || IsLineEnd( *it )
|
||||||
|
|| IsSpaceOrNewLine( *it ) ) {
|
||||||
--it;
|
--it;
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
|
@ -246,6 +287,20 @@ string_type trim_whitespaces(string_type str)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool hasLineEnd( T it, T end ) {
|
||||||
|
bool hasLineEnd( false );
|
||||||
|
while ( !isEndOfBuffer( it, end ) ) {
|
||||||
|
it++;
|
||||||
|
if ( IsLineEnd( it ) ) {
|
||||||
|
hasLineEnd = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasLineEnd;
|
||||||
|
}
|
||||||
|
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
||||||
#endif // OBJ_TOOLS_H_INC
|
#endif // OBJ_TOOLS_H_INC
|
||||||
|
|
|
@ -93,7 +93,7 @@ void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIO
|
||||||
// Create materials that can be found and parsed via the IOSystem.
|
// Create materials that can be found and parsed via the IOSystem.
|
||||||
for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i)
|
for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i)
|
||||||
{
|
{
|
||||||
SubMeshXml *submesh = mesh->GetSubMesh(i);
|
SubMeshXml *submesh = mesh->GetSubMesh( static_cast<uint16_t>(i));
|
||||||
if (submesh && !submesh->materialRef.empty())
|
if (submesh && !submesh->materialRef.empty())
|
||||||
{
|
{
|
||||||
aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef);
|
aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef);
|
||||||
|
|
|
@ -690,7 +690,7 @@ void PretransformVertices::Execute( aiScene* pScene)
|
||||||
|
|
||||||
// find the dominant axis
|
// find the dominant axis
|
||||||
aiVector3D d = max-min;
|
aiVector3D d = max-min;
|
||||||
const ai_real div = std::max(d.x,std::max(d.y,d.z))*0.5;
|
const ai_real div = std::max(d.x,std::max(d.y,d.z))*ai_real( 0.5);
|
||||||
|
|
||||||
d = min + d * (ai_real)0.5;
|
d = min + d * (ai_real)0.5;
|
||||||
for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
|
for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
|
||||||
|
|
|
@ -77,8 +77,8 @@ void ConvertListToStrings(const std::string& in, std::list<std::string>& out)
|
||||||
void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max,
|
void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max,
|
||||||
const aiMatrix4x4& m)
|
const aiMatrix4x4& m)
|
||||||
{
|
{
|
||||||
min = aiVector3D (10e10, 10e10, 10e10);
|
min = aiVector3D ( ai_real( 10e10 ), ai_real( 10e10 ), ai_real( 10e10 ) );
|
||||||
max = aiVector3D (-10e10,-10e10,-10e10);
|
max = aiVector3D ( ai_real( -10e10 ), ai_real( -10e10 ), ai_real( -10e10 ) );
|
||||||
for (unsigned int i = 0;i < mesh->mNumVertices;++i)
|
for (unsigned int i = 0;i < mesh->mNumVertices;++i)
|
||||||
{
|
{
|
||||||
const aiVector3D v = m * mesh->mVertices[i];
|
const aiVector3D v = m * mesh->mVertices[i];
|
||||||
|
@ -144,7 +144,7 @@ void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
ai_real ComputePositionEpsilon(const aiMesh* pMesh)
|
ai_real ComputePositionEpsilon(const aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
const ai_real epsilon = 1e-4;
|
const ai_real epsilon = ai_real( 1e-4 );
|
||||||
|
|
||||||
// calculate the position bounds so we have a reliable epsilon to check position differences against
|
// calculate the position bounds so we have a reliable epsilon to check position differences against
|
||||||
aiVector3D minVec, maxVec;
|
aiVector3D minVec, maxVec;
|
||||||
|
@ -157,7 +157,7 @@ ai_real ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num)
|
||||||
{
|
{
|
||||||
ai_assert( NULL != pMeshes );
|
ai_assert( NULL != pMeshes );
|
||||||
|
|
||||||
const ai_real epsilon = 1e-4;
|
const ai_real epsilon = ai_real( 1e-4 );
|
||||||
|
|
||||||
// calculate the position bounds so we have a reliable epsilon to check position differences against
|
// calculate the position bounds so we have a reliable epsilon to check position differences against
|
||||||
aiVector3D minVec, maxVec, mi, ma;
|
aiVector3D minVec, maxVec, mi, ma;
|
||||||
|
|
|
@ -177,12 +177,14 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate new names for all modified materials
|
// generate new names for modified materials that had no names
|
||||||
const unsigned int idx = aiMappingTable[p];
|
const unsigned int idx = aiMappingTable[p];
|
||||||
if (ppcMaterials[idx]) {
|
if (ppcMaterials[idx]) {
|
||||||
aiString sz;
|
aiString sz;
|
||||||
sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p);
|
if( ppcMaterials[idx]->Get(AI_MATKEY_NAME, sz) != AI_SUCCESS ) {
|
||||||
((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
|
sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p);
|
||||||
|
((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ppcMaterials[idx] = pScene->mMaterials[p];
|
ppcMaterials[idx] = pScene->mMaterials[p];
|
||||||
}
|
}
|
||||||
|
|
|
@ -709,7 +709,7 @@ static void ReadLightInfo(aiLight* light, StreamReaderLE* stream)
|
||||||
// 99% and 1% percentiles.
|
// 99% and 1% percentiles.
|
||||||
// OpenGL: I = cos(angle)^E
|
// OpenGL: I = cos(angle)^E
|
||||||
// Solving: angle = acos(I^(1/E))
|
// Solving: angle = acos(I^(1/E))
|
||||||
ai_real E = 1.0 / std::max(spotExponent, (ai_real)0.00001);
|
ai_real E = ai_real( 1.0 ) / std::max(spotExponent, (ai_real)0.00001);
|
||||||
ai_real inner = std::acos(std::pow((ai_real)0.99, E));
|
ai_real inner = std::acos(std::pow((ai_real)0.99, E));
|
||||||
ai_real outer = std::acos(std::pow((ai_real)0.01, E));
|
ai_real outer = std::acos(std::pow((ai_real)0.01, E));
|
||||||
|
|
||||||
|
|
|
@ -168,8 +168,7 @@ void addFacesToMesh(aiMesh* pMesh)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void STLImporter::InternReadFile( const std::string& pFile,
|
void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
||||||
|
|
||||||
|
@ -189,7 +188,7 @@ void STLImporter::InternReadFile( const std::string& pFile,
|
||||||
this->mBuffer = &mBuffer2[0];
|
this->mBuffer = &mBuffer2[0];
|
||||||
|
|
||||||
// the default vertex color is light gray.
|
// the default vertex color is light gray.
|
||||||
clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 0.6;
|
clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = (ai_real) 0.6;
|
||||||
|
|
||||||
// allocate a single node
|
// allocate a single node
|
||||||
pScene->mRootNode = new aiNode();
|
pScene->mRootNode = new aiNode();
|
||||||
|
@ -217,13 +216,13 @@ void STLImporter::InternReadFile( const std::string& pFile,
|
||||||
s.Set(AI_DEFAULT_MATERIAL_NAME);
|
s.Set(AI_DEFAULT_MATERIAL_NAME);
|
||||||
pcMat->AddProperty(&s, AI_MATKEY_NAME);
|
pcMat->AddProperty(&s, AI_MATKEY_NAME);
|
||||||
|
|
||||||
aiColor4D clrDiffuse(0.6,0.6,0.6,1.0);
|
aiColor4D clrDiffuse(ai_real(0.6),ai_real(0.6),ai_real(0.6),ai_real(1.0));
|
||||||
if (bMatClr) {
|
if (bMatClr) {
|
||||||
clrDiffuse = clrColorDefault;
|
clrDiffuse = clrColorDefault;
|
||||||
}
|
}
|
||||||
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
|
||||||
clrDiffuse = aiColor4D(0.05,0.05,0.05,1.0);
|
clrDiffuse = aiColor4D( ai_real( 0.05), ai_real( 0.05), ai_real( 0.05), ai_real( 1.0));
|
||||||
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
pScene->mNumMaterials = 1;
|
pScene->mNumMaterials = 1;
|
||||||
|
@ -416,10 +415,11 @@ bool STLImporter::LoadBinaryFile()
|
||||||
// read the default vertex color for facets
|
// read the default vertex color for facets
|
||||||
bIsMaterialise = true;
|
bIsMaterialise = true;
|
||||||
DefaultLogger::get()->info("STL: Taking code path for Materialise files");
|
DefaultLogger::get()->info("STL: Taking code path for Materialise files");
|
||||||
clrColorDefault.r = (*sz2++) / 255.0;
|
const ai_real invByte = (ai_real)1.0 / ( ai_real )255.0;
|
||||||
clrColorDefault.g = (*sz2++) / 255.0;
|
clrColorDefault.r = (*sz2++) * invByte;
|
||||||
clrColorDefault.b = (*sz2++) / 255.0;
|
clrColorDefault.g = (*sz2++) * invByte;
|
||||||
clrColorDefault.a = (*sz2++) / 255.0;
|
clrColorDefault.b = (*sz2++) * invByte;
|
||||||
|
clrColorDefault.a = (*sz2++) * invByte;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,17 +481,18 @@ bool STLImporter::LoadBinaryFile()
|
||||||
}
|
}
|
||||||
aiColor4D* clr = &pMesh->mColors[0][i*3];
|
aiColor4D* clr = &pMesh->mColors[0][i*3];
|
||||||
clr->a = 1.0;
|
clr->a = 1.0;
|
||||||
|
const ai_real invVal( (ai_real)1.0 / ( ai_real )31.0 );
|
||||||
if (bIsMaterialise) // this is reversed
|
if (bIsMaterialise) // this is reversed
|
||||||
{
|
{
|
||||||
clr->r = (color & 0x31u) / 31.0;
|
clr->r = (color & 0x31u) *invVal;
|
||||||
clr->g = ((color & (0x31u<<5))>>5u) / 31.0;
|
clr->g = ((color & (0x31u<<5))>>5u) *invVal;
|
||||||
clr->b = ((color & (0x31u<<10))>>10u) / 31.0;
|
clr->b = ((color & (0x31u<<10))>>10u) *invVal;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
clr->b = (color & 0x31u) / 31.0;
|
clr->b = (color & 0x31u) *invVal;
|
||||||
clr->g = ((color & (0x31u<<5))>>5u) / 31.0;
|
clr->g = ((color & (0x31u<<5))>>5u) *invVal;
|
||||||
clr->r = ((color & (0x31u<<10))>>10u) / 31.0;
|
clr->r = ((color & (0x31u<<10))>>10u) *invVal;
|
||||||
}
|
}
|
||||||
// assign the color to all vertices of the face
|
// assign the color to all vertices of the face
|
||||||
*(clr+1) = *clr;
|
*(clr+1) = *clr;
|
||||||
|
|
|
@ -740,7 +740,7 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
|
||||||
aiVertexWeight* avw = pc->mWeights = new aiVertexWeight[pc->mNumWeights];
|
aiVertexWeight* avw = pc->mWeights = new aiVertexWeight[pc->mNumWeights];
|
||||||
|
|
||||||
// And copy the final weights - adjust the vertex IDs by the
|
// And copy the final weights - adjust the vertex IDs by the
|
||||||
// face index offset of the coresponding mesh.
|
// face index offset of the corresponding mesh.
|
||||||
for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) {
|
for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) {
|
||||||
aiBone* pip = (*wmit).first;
|
aiBone* pip = (*wmit).first;
|
||||||
for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) {
|
for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) {
|
||||||
|
|
|
@ -176,22 +176,22 @@ void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
|
||||||
if (anim->mDuration == -1.) {
|
if (anim->mDuration == -1.) {
|
||||||
|
|
||||||
// Position keys
|
// Position keys
|
||||||
for (unsigned int i = 0; i < channel->mNumPositionKeys;++i) {
|
for (unsigned int j = 0; j < channel->mNumPositionKeys;++j) {
|
||||||
aiVectorKey& key = channel->mPositionKeys[i];
|
aiVectorKey& key = channel->mPositionKeys[j];
|
||||||
first = std::min (first, key.mTime);
|
first = std::min (first, key.mTime);
|
||||||
last = std::max (last, key.mTime);
|
last = std::max (last, key.mTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scaling keys
|
// Scaling keys
|
||||||
for (unsigned int i = 0; i < channel->mNumScalingKeys;++i) {
|
for (unsigned int j = 0; j < channel->mNumScalingKeys;++j ) {
|
||||||
aiVectorKey& key = channel->mScalingKeys[i];
|
aiVectorKey& key = channel->mScalingKeys[j];
|
||||||
first = std::min (first, key.mTime);
|
first = std::min (first, key.mTime);
|
||||||
last = std::max (last, key.mTime);
|
last = std::max (last, key.mTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotation keys
|
// Rotation keys
|
||||||
for (unsigned int i = 0; i < channel->mNumRotationKeys;++i) {
|
for (unsigned int j = 0; j < channel->mNumRotationKeys;++j ) {
|
||||||
aiQuatKey& key = channel->mRotationKeys[i];
|
aiQuatKey& key = channel->mRotationKeys[ j ];
|
||||||
first = std::min (first, key.mTime);
|
first = std::min (first, key.mTime);
|
||||||
last = std::max (last, key.mTime);
|
last = std::max (last, key.mTime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ void SkeletonMeshBuilder::CreateGeometry( const aiNode* pNode)
|
||||||
{
|
{
|
||||||
// if the node has no children, it's an end node. Put a little knob there instead
|
// if the node has no children, it's an end node. Put a little knob there instead
|
||||||
aiVector3D ownpos( pNode->mTransformation.a4, pNode->mTransformation.b4, pNode->mTransformation.c4);
|
aiVector3D ownpos( pNode->mTransformation.a4, pNode->mTransformation.b4, pNode->mTransformation.c4);
|
||||||
ai_real sizeEstimate = ownpos.Length() * 0.18;
|
ai_real sizeEstimate = ownpos.Length() * ai_real( 0.18 );
|
||||||
|
|
||||||
mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0));
|
mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0));
|
||||||
mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0));
|
mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0));
|
||||||
|
|
|
@ -193,8 +193,8 @@ unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+60);
|
positions.reserve(positions.size()+60);
|
||||||
|
|
||||||
const ai_real t = (1.0 + 2.236067977)/2.0;
|
const ai_real t = ( ai_real( 1.0 )+ ai_real( 2.236067977 ) ) / ai_real( 2.0 );
|
||||||
const ai_real s = std::sqrt(1.0 + t*t);
|
const ai_real s = std::sqrt(ai_real(1.0) + t*t);
|
||||||
|
|
||||||
const aiVector3D v0 = aiVector3D(t,1.0, 0.0)/s;
|
const aiVector3D v0 = aiVector3D(t,1.0, 0.0)/s;
|
||||||
const aiVector3D v1 = aiVector3D(-t,1.0, 0.0)/s;
|
const aiVector3D v1 = aiVector3D(-t,1.0, 0.0)/s;
|
||||||
|
@ -243,9 +243,9 @@ unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+108);
|
positions.reserve(positions.size()+108);
|
||||||
|
|
||||||
const ai_real a = 1.0 / 1.7320508;
|
const ai_real a = ai_real( 1.0 ) / ai_real(1.7320508);
|
||||||
const ai_real b = std::sqrt((3.0-2.23606797f)/6.0);
|
const ai_real b = std::sqrt(( ai_real( 3.0 )- ai_real( 2.23606797))/ ai_real( 6.0) );
|
||||||
const ai_real c = std::sqrt((3.0+2.23606797f)/6.0);
|
const ai_real c = std::sqrt(( ai_real( 3.0 )+ ai_real( 2.23606797f))/ ai_real( 6.0) );
|
||||||
|
|
||||||
const aiVector3D v0 = aiVector3D(a,a,a);
|
const aiVector3D v0 = aiVector3D(a,a,a);
|
||||||
const aiVector3D v1 = aiVector3D(a,a,-a);
|
const aiVector3D v1 = aiVector3D(a,a,-a);
|
||||||
|
@ -315,13 +315,14 @@ unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions)
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+9);
|
positions.reserve(positions.size()+9);
|
||||||
|
|
||||||
const ai_real a = 1.41421/3.0;
|
const ai_real invThree = ai_real( 1.0 ) / ai_real( 3.0 );
|
||||||
const ai_real b = 2.4494/3.0;
|
const ai_real a = ai_real( 1.41421 ) * invThree;
|
||||||
|
const ai_real b = ai_real( 2.4494 ) * invThree;
|
||||||
|
|
||||||
const aiVector3D v0 = aiVector3D(0.0,0.0,1.0);
|
const aiVector3D v0 = aiVector3D(0.0,0.0,1.0);
|
||||||
const aiVector3D v1 = aiVector3D(2*a,0,-1.0/3.0);
|
const aiVector3D v1 = aiVector3D(2*a,0,-invThree );
|
||||||
const aiVector3D v2 = aiVector3D(-a,b,-1.0/3.0);
|
const aiVector3D v2 = aiVector3D(-a,b,-invThree );
|
||||||
const aiVector3D v3 = aiVector3D(-a,-b,-1.0/3.0);
|
const aiVector3D v3 = aiVector3D(-a,-b,-invThree );
|
||||||
|
|
||||||
ADD_TRIANGLE(v0,v1,v2);
|
ADD_TRIANGLE(v0,v1,v2);
|
||||||
ADD_TRIANGLE(v0,v2,v3);
|
ADD_TRIANGLE(v0,v2,v3);
|
||||||
|
@ -336,7 +337,7 @@ unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions,
|
||||||
bool polygons /*= false*/)
|
bool polygons /*= false*/)
|
||||||
{
|
{
|
||||||
positions.reserve(positions.size()+36);
|
positions.reserve(positions.size()+36);
|
||||||
const ai_real length = 1.0/1.73205080;
|
const ai_real length = ai_real(1.0)/ai_real(1.73205080);
|
||||||
|
|
||||||
const aiVector3D v0 = aiVector3D(-1.0,-1.0,-1.0)*length;
|
const aiVector3D v0 = aiVector3D(-1.0,-1.0,-1.0)*length;
|
||||||
const aiVector3D v1 = aiVector3D(1.0,-1.0,-1.0)*length;
|
const aiVector3D v1 = aiVector3D(1.0,-1.0,-1.0)*length;
|
||||||
|
@ -395,7 +396,7 @@ void StandardShapes::MakeCone(ai_real height,ai_real radius1,
|
||||||
radius1 = std::fabs(radius1);
|
radius1 = std::fabs(radius1);
|
||||||
radius2 = std::fabs(radius2);
|
radius2 = std::fabs(radius2);
|
||||||
|
|
||||||
ai_real halfHeight = height / 2.0;
|
ai_real halfHeight = height / ai_real(2.0);
|
||||||
|
|
||||||
// radius1 is always the smaller one
|
// radius1 is always the smaller one
|
||||||
if (radius2 > radius1)
|
if (radius2 > radius1)
|
||||||
|
|
|
@ -447,7 +447,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
|
||||||
|
|
||||||
unsigned int jointNamesIndex;
|
unsigned int jointNamesIndex;
|
||||||
bool addJointToJointNames = true;
|
bool addJointToJointNames = true;
|
||||||
for (int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
|
for ( unsigned int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
|
||||||
if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
|
if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
|
||||||
addJointToJointNames = false;
|
addJointToJointNames = false;
|
||||||
jointNamesIndex = idx_joint;
|
jointNamesIndex = idx_joint;
|
||||||
|
@ -732,7 +732,7 @@ void glTFExporter::ExportMeshes()
|
||||||
// Create the Accessor for skinRef->inverseBindMatrices
|
// Create the Accessor for skinRef->inverseBindMatrices
|
||||||
if (createSkin) {
|
if (createSkin) {
|
||||||
mat4* invBindMatrixData = new mat4[inverseBindMatricesData.size()];
|
mat4* invBindMatrixData = new mat4[inverseBindMatricesData.size()];
|
||||||
for (int idx_joint = 0; idx_joint < inverseBindMatricesData.size(); ++idx_joint) {
|
for ( unsigned int idx_joint = 0; idx_joint < inverseBindMatricesData.size(); ++idx_joint) {
|
||||||
CopyValue(inverseBindMatricesData[idx_joint], invBindMatrixData[idx_joint]);
|
CopyValue(inverseBindMatricesData[idx_joint], invBindMatrixData[idx_joint]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -376,7 +376,7 @@ namespace o3dgc
|
||||||
|
|
||||||
if (quantMode == O3DGC_SC3DMC_DIAG_BB)
|
if (quantMode == O3DGC_SC3DMC_DIAG_BB)
|
||||||
{
|
{
|
||||||
Real diag = 0.0;
|
Real diag = Real( 0.0 );
|
||||||
Real r;
|
Real r;
|
||||||
for(unsigned long d = 0; d < dim; ++d)
|
for(unsigned long d = 0; d < dim; ++d)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
#include "o3dgcCommon.h"
|
#include "o3dgcCommon.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
/* Thank you, Microsoft, for file WinDef.h with min/max redefinition. */
|
/* Thank you, Microsoft, for file WinDef.h with min/max redefinition. */
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -42,7 +42,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
namespace o3dgc
|
namespace o3dgc
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef _WIN32
|
||||||
class Timer
|
class Timer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -36,11 +36,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
// C4103: Packing was changed after the inclusion of the header, probably missing #pragma pop
|
// C4103: Packing was changed after the inclusion of the header, probably missing #pragma pop
|
||||||
# pragma warning (disable : 4103)
|
# pragma warning (disable : 4103)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define AI_PUSHPACK_IS_DEFINED
|
#define AI_PUSHPACK_IS_DEFINED
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -337,7 +337,7 @@ ASSIMP_API void aiReleaseImport(
|
||||||
* import process. NULL if there was no error. There can't be an error if you
|
* import process. NULL if there was no error. There can't be an error if you
|
||||||
* got a non-NULL #aiScene from #aiImportFile/#aiImportFileEx/#aiApplyPostProcessing.
|
* got a non-NULL #aiScene from #aiImportFile/#aiImportFileEx/#aiApplyPostProcessing.
|
||||||
*/
|
*/
|
||||||
ASSIMP_API const char* aiGetErrorString();
|
ASSIMP_API const char* aiGetErrorString(void);
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------
|
||||||
/** Returns whether a given file extension is supported by ASSIMP
|
/** Returns whether a given file extension is supported by ASSIMP
|
||||||
|
|
|
@ -92,14 +92,10 @@ struct aiMetadataEntry
|
||||||
void* mData;
|
void* mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Helper functions to get the aiType enum entry for a type
|
* Helper functions to get the aiType enum entry for a type
|
||||||
|
@ -113,11 +109,7 @@ inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; }
|
||||||
inline aiMetadataType GetAiType( aiString ) { return AI_AISTRING; }
|
inline aiMetadataType GetAiType( aiString ) { return AI_AISTRING; }
|
||||||
inline aiMetadataType GetAiType( aiVector3D ) { return AI_AIVECTOR3D; }
|
inline aiMetadataType GetAiType( aiVector3D ) { return AI_AIVECTOR3D; }
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -176,11 +176,7 @@ struct aiColor3D
|
||||||
/** Component-wise comparison */
|
/** Component-wise comparison */
|
||||||
// TODO: add epsilon?
|
// TODO: add epsilon?
|
||||||
bool operator < (const aiColor3D& other) const {
|
bool operator < (const aiColor3D& other) const {
|
||||||
return r < other.r || (
|
return r < other.r || ( r == other.r && (g < other.g || (g == other.g && b < other.b ) ) );
|
||||||
r == other.r && (g < other.g ||
|
|
||||||
(g == other.g && b < other.b)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Component-wise addition */
|
/** Component-wise addition */
|
||||||
|
@ -210,7 +206,14 @@ struct aiColor3D
|
||||||
|
|
||||||
/** Access a specific color component */
|
/** Access a specific color component */
|
||||||
ai_real& operator[](unsigned int i) {
|
ai_real& operator[](unsigned int i) {
|
||||||
return *(&r + i);
|
if ( 0 == i ) {
|
||||||
|
return r;
|
||||||
|
} else if ( 1 == i ) {
|
||||||
|
return g;
|
||||||
|
} else if ( 2 == i ) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check whether a color is black */
|
/** Check whether a color is black */
|
||||||
|
@ -223,7 +226,7 @@ struct aiColor3D
|
||||||
|
|
||||||
//! Red, green and blue color values
|
//! Red, green and blue color values
|
||||||
ai_real r, g, b;
|
ai_real r, g, b;
|
||||||
} PACK_STRUCT; // !struct aiColor3D
|
} /*PACK_STRUCT*/; // !struct aiColor3D
|
||||||
#include "./Compiler/poppack1.h"
|
#include "./Compiler/poppack1.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------
|
||||||
|
|
|
@ -55,7 +55,9 @@ SOURCE_GROUP( unit FILES
|
||||||
)
|
)
|
||||||
|
|
||||||
SET( TEST_SRCS
|
SET( TEST_SRCS
|
||||||
|
unit/TestIOSystem.h
|
||||||
unit/AssimpAPITest.cpp
|
unit/AssimpAPITest.cpp
|
||||||
|
unit/utBatchLoader.cpp
|
||||||
unit/utBlenderIntermediate.cpp
|
unit/utBlenderIntermediate.cpp
|
||||||
unit/utBlendImportAreaLight.cpp
|
unit/utBlendImportAreaLight.cpp
|
||||||
unit/utBlendImportMaterials.cpp
|
unit/utBlendImportMaterials.cpp
|
||||||
|
@ -70,6 +72,7 @@ SET( TEST_SRCS
|
||||||
unit/utImporter.cpp
|
unit/utImporter.cpp
|
||||||
unit/utImproveCacheLocality.cpp
|
unit/utImproveCacheLocality.cpp
|
||||||
unit/utIOSystem.cpp
|
unit/utIOSystem.cpp
|
||||||
|
unit/utIOStreamBuffer.cpp
|
||||||
unit/utIssues.cpp
|
unit/utIssues.cpp
|
||||||
unit/utJoinVertices.cpp
|
unit/utJoinVertices.cpp
|
||||||
unit/utLimitBoneWeights.cpp
|
unit/utLimitBoneWeights.cpp
|
||||||
|
@ -91,6 +94,7 @@ SET( TEST_SRCS
|
||||||
unit/utTargetAnimation.cpp
|
unit/utTargetAnimation.cpp
|
||||||
unit/utTextureTransform.cpp
|
unit/utTextureTransform.cpp
|
||||||
unit/utTriangulate.cpp
|
unit/utTriangulate.cpp
|
||||||
|
unit/utTypes.cpp
|
||||||
unit/utVertexTriangleAdjacency.cpp
|
unit/utVertexTriangleAdjacency.cpp
|
||||||
unit/utVersion.cpp
|
unit/utVersion.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DefaultIOStream.h"
|
||||||
|
|
||||||
|
using namespace ::Assimp;
|
||||||
|
|
||||||
|
class TestDefaultIOStream : public DefaultIOStream {
|
||||||
|
public:
|
||||||
|
TestDefaultIOStream()
|
||||||
|
: DefaultIOStream() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
TestDefaultIOStream( FILE* pFile, const std::string &strFilename )
|
||||||
|
: DefaultIOStream( pFile, strFilename ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~TestDefaultIOStream() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
static const string Sep = "/";
|
||||||
|
class TestIOSystem : public IOSystem {
|
||||||
|
public:
|
||||||
|
TestIOSystem() : IOSystem() {}
|
||||||
|
virtual ~TestIOSystem() {}
|
||||||
|
virtual bool Exists( const char* ) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
virtual char getOsSeparator() const {
|
||||||
|
return Sep[ 0 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual IOStream* Open( const char* pFile, const char* pMode = "rb" ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Close( IOStream* pFile ) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 "Importer.h"
|
||||||
|
#include "TestIOSystem.h"
|
||||||
|
|
||||||
|
using namespace ::Assimp;
|
||||||
|
|
||||||
|
class BatchLoaderTest : public ::testing::Test {
|
||||||
|
public:
|
||||||
|
virtual void SetUp() {
|
||||||
|
m_io = new TestIOSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() {
|
||||||
|
delete m_io;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TestIOSystem* m_io;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F( BatchLoaderTest, createTest ) {
|
||||||
|
bool ok( true );
|
||||||
|
try {
|
||||||
|
BatchLoader loader( m_io );
|
||||||
|
} catch ( ... ) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( BatchLoaderTest, validateAccessTest ) {
|
||||||
|
BatchLoader loader1( m_io );
|
||||||
|
EXPECT_FALSE( loader1.getValidation() );
|
||||||
|
loader1.setValidation( true );
|
||||||
|
EXPECT_TRUE( loader1.getValidation() );
|
||||||
|
|
||||||
|
BatchLoader loader2( m_io, true );
|
||||||
|
EXPECT_TRUE( loader2.getValidation() );
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
-------------------------------------------------------------------------*/
|
-------------------------------------------------------------------------*/
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include "DefaultIOStream.h"
|
#include "TestIOStream.h"
|
||||||
|
|
||||||
using namespace ::Assimp;
|
using namespace ::Assimp;
|
||||||
|
|
||||||
|
@ -45,23 +45,6 @@ class utDefaultIOStream : public ::testing::Test {
|
||||||
// empty
|
// empty
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestDefaultIOStream : public DefaultIOStream {
|
|
||||||
public:
|
|
||||||
TestDefaultIOStream()
|
|
||||||
: DefaultIOStream() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
TestDefaultIOStream( FILE* pFile, const std::string &strFilename )
|
|
||||||
: DefaultIOStream( pFile, strFilename ) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~TestDefaultIOStream() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F( utDefaultIOStream, FileSizeTest ) {
|
TEST_F( utDefaultIOStream, FileSizeTest ) {
|
||||||
char buffer[ L_tmpnam ];
|
char buffer[ L_tmpnam ];
|
||||||
tmpnam( buffer );
|
tmpnam( buffer );
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 "IOStreamBuffer.h"
|
||||||
|
#include "TestIOStream.h"
|
||||||
|
|
||||||
|
class IOStreamBufferTest : public ::testing::Test {
|
||||||
|
// empty
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, creationTest ) {
|
||||||
|
bool ok( true );
|
||||||
|
try {
|
||||||
|
IOStreamBuffer<char> myBuffer;
|
||||||
|
} catch ( ... ) {
|
||||||
|
ok = false;
|
||||||
|
}
|
||||||
|
EXPECT_TRUE( ok );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, accessCacheSizeTest ) {
|
||||||
|
IOStreamBuffer<char> myBuffer1;
|
||||||
|
EXPECT_NE( 0, myBuffer1.cacheSize() );
|
||||||
|
|
||||||
|
IOStreamBuffer<char> myBuffer2( 100 );
|
||||||
|
EXPECT_EQ( 100, myBuffer2.cacheSize() );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, open_close_Test ) {
|
||||||
|
IOStreamBuffer<char> myBuffer;
|
||||||
|
|
||||||
|
EXPECT_FALSE( myBuffer.open( nullptr ) );
|
||||||
|
EXPECT_FALSE( myBuffer.close() );
|
||||||
|
|
||||||
|
char buffer[ L_tmpnam ];
|
||||||
|
tmpnam( buffer );
|
||||||
|
std::FILE *fs( std::fopen( buffer, "w+" ) );
|
||||||
|
size_t written( std::fwrite( buffer, 1, sizeof( char ) * L_tmpnam, fs ) );
|
||||||
|
std::fflush( fs );
|
||||||
|
|
||||||
|
TestDefaultIOStream myStream( fs, buffer );
|
||||||
|
|
||||||
|
EXPECT_TRUE( myBuffer.open( &myStream ) );
|
||||||
|
EXPECT_FALSE( myBuffer.open( &myStream ) );
|
||||||
|
EXPECT_TRUE( myBuffer.close() );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, readlineTest ) {
|
||||||
|
char buffer[ L_tmpnam ];
|
||||||
|
tmpnam( buffer );
|
||||||
|
std::FILE *fs( std::fopen( buffer, "w+" ) );
|
||||||
|
size_t written( std::fwrite( buffer, 1, sizeof( char ) * L_tmpnam, fs ) );
|
||||||
|
std::fflush( fs );
|
||||||
|
|
||||||
|
IOStreamBuffer<char> myBuffer( 26 );
|
||||||
|
EXPECT_EQ( 26, myBuffer.cacheSize() );
|
||||||
|
|
||||||
|
TestDefaultIOStream myStream( fs, buffer );
|
||||||
|
size_t size( myStream.FileSize() );
|
||||||
|
size_t numBlocks( size / myBuffer.cacheSize() );
|
||||||
|
if ( size % myBuffer.cacheSize() > 0 ) {
|
||||||
|
numBlocks++;
|
||||||
|
}
|
||||||
|
EXPECT_TRUE( myBuffer.open( &myStream ) );
|
||||||
|
EXPECT_EQ( numBlocks, myBuffer.getNumBlocks() );
|
||||||
|
EXPECT_TRUE( myBuffer.close() );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( IOStreamBufferTest, accessBlockIndexTest ) {
|
||||||
|
|
||||||
|
}
|
|
@ -39,37 +39,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
#include "TestIOSystem.h"
|
||||||
|
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
static const string Sep = "/";
|
|
||||||
class TestIOSystem : public IOSystem {
|
|
||||||
public:
|
|
||||||
TestIOSystem() : IOSystem() {}
|
|
||||||
virtual ~TestIOSystem() {}
|
|
||||||
virtual bool Exists( const char* ) const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
virtual char getOsSeparator() const {
|
|
||||||
return Sep[ 0 ];
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual IOStream* Open(const char* pFile, const char* pMode = "rb") {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Close( IOStream* pFile) {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IOSystemTest : public ::testing::Test {
|
class IOSystemTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
virtual void SetUp() { pImp = new TestIOSystem(); }
|
virtual void SetUp() {
|
||||||
virtual void TearDown() { delete pImp; }
|
pImp = new TestIOSystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void TearDown() {
|
||||||
|
delete pImp;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TestIOSystem* pImp;
|
TestIOSystem* pImp;
|
||||||
|
|
|
@ -270,3 +270,5 @@ TEST_F(ImporterTest, testMultipleReads)
|
||||||
EXPECT_TRUE(pImp->ReadFile(ASSIMP_TEST_MODELS_DIR "/X/BCN_Epileptic.X",flags));
|
EXPECT_TRUE(pImp->ReadFile(ASSIMP_TEST_MODELS_DIR "/X/BCN_Epileptic.X",flags));
|
||||||
//EXPECT_TRUE(pImp->ReadFile(ASSIMP_TEST_MODELS_DIR "/X/dwarf.x",flags)); # is in nonbsd
|
//EXPECT_TRUE(pImp->ReadFile(ASSIMP_TEST_MODELS_DIR "/X/dwarf.x",flags)); # is in nonbsd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -47,21 +47,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
class TriangulateProcessTest : public ::testing::Test
|
class TriangulateProcessTest : public ::testing::Test {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void SetUp();
|
virtual void SetUp();
|
||||||
virtual void TearDown();
|
virtual void TearDown();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
aiMesh* pcMesh;
|
aiMesh* pcMesh;
|
||||||
TriangulateProcess* piProcess;
|
TriangulateProcess* piProcess;
|
||||||
};
|
};
|
||||||
|
|
||||||
void TriangulateProcessTest::SetUp()
|
void TriangulateProcessTest::SetUp() {
|
||||||
{
|
|
||||||
piProcess = new TriangulateProcess();
|
piProcess = new TriangulateProcess();
|
||||||
pcMesh = new aiMesh();
|
pcMesh = new aiMesh();
|
||||||
|
|
||||||
|
@ -72,24 +68,21 @@ void TriangulateProcessTest::SetUp()
|
||||||
pcMesh->mPrimitiveTypes = aiPrimitiveType_POINT | aiPrimitiveType_LINE |
|
pcMesh->mPrimitiveTypes = aiPrimitiveType_POINT | aiPrimitiveType_LINE |
|
||||||
aiPrimitiveType_LINE | aiPrimitiveType_POLYGON;
|
aiPrimitiveType_LINE | aiPrimitiveType_POLYGON;
|
||||||
|
|
||||||
for (unsigned int m = 0, t = 0, q = 4; m < 1000; ++m)
|
for (unsigned int m = 0, t = 0, q = 4; m < 1000; ++m) {
|
||||||
{
|
|
||||||
++t;
|
++t;
|
||||||
aiFace& face = pcMesh->mFaces[m];
|
aiFace& face = pcMesh->mFaces[m];
|
||||||
face.mNumIndices = t;
|
face.mNumIndices = t;
|
||||||
if (4 == t)
|
if (4 == t) {
|
||||||
{
|
|
||||||
face.mNumIndices = q++;
|
face.mNumIndices = q++;
|
||||||
t = 0;
|
t = 0;
|
||||||
|
|
||||||
if (10 == q)q = 4;
|
if (10 == q)q = 4;
|
||||||
}
|
}
|
||||||
face.mIndices = new unsigned int[face.mNumIndices];
|
face.mIndices = new unsigned int[face.mNumIndices];
|
||||||
for (unsigned int p = 0; p < face.mNumIndices; ++p)
|
for (unsigned int p = 0; p < face.mNumIndices; ++p) {
|
||||||
{
|
face.mIndices[ p ] = pcMesh->mNumVertices;
|
||||||
face.mIndices[p] = pcMesh->mNumVertices;
|
|
||||||
|
|
||||||
// construct fully convex input data in ccw winding, xy plane
|
// construct fully convex input data in ccw winding, xy plane
|
||||||
aiVector3D& v = pcMesh->mVertices[pcMesh->mNumVertices++];
|
aiVector3D& v = pcMesh->mVertices[pcMesh->mNumVertices++];
|
||||||
v.z = 0.f;
|
v.z = 0.f;
|
||||||
v.x = cos (p * (float)(AI_MATH_TWO_PI)/face.mNumIndices);
|
v.x = cos (p * (float)(AI_MATH_TWO_PI)/face.mNumIndices);
|
||||||
|
@ -98,51 +91,43 @@ void TriangulateProcessTest::SetUp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TriangulateProcessTest::TearDown()
|
void TriangulateProcessTest::TearDown() {
|
||||||
{
|
|
||||||
delete piProcess;
|
delete piProcess;
|
||||||
delete pcMesh;
|
delete pcMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TriangulateProcessTest, testTriangulation)
|
TEST_F(TriangulateProcessTest, testTriangulation) {
|
||||||
{
|
|
||||||
piProcess->TriangulateMesh(pcMesh);
|
piProcess->TriangulateMesh(pcMesh);
|
||||||
|
|
||||||
for (unsigned int m = 0, t = 0, q = 4, max = 1000, idx = 0; m < max;++m)
|
for (unsigned int m = 0, t = 0, q = 4, max = 1000, idx = 0; m < max;++m) {
|
||||||
{
|
|
||||||
++t;
|
++t;
|
||||||
aiFace& face = pcMesh->mFaces[m];
|
aiFace& face = pcMesh->mFaces[m];
|
||||||
if (4 == t)
|
if (4 == t) {
|
||||||
{
|
|
||||||
t = 0;
|
t = 0;
|
||||||
max += q-3;
|
max += q-3;
|
||||||
|
|
||||||
std::vector<bool> ait(q,false);
|
std::vector<bool> ait(q,false);
|
||||||
|
|
||||||
for (unsigned int i = 0, tt = q-2; i < tt; ++i,++m)
|
for (unsigned int i = 0, tt = q-2; i < tt; ++i,++m) {
|
||||||
{
|
|
||||||
aiFace& face = pcMesh->mFaces[m];
|
aiFace& face = pcMesh->mFaces[m];
|
||||||
EXPECT_EQ(3U, face.mNumIndices);
|
EXPECT_EQ(3U, face.mNumIndices);
|
||||||
|
|
||||||
for (unsigned int qqq = 0; qqq < face.mNumIndices; ++qqq)
|
for (unsigned int qqq = 0; qqq < face.mNumIndices; ++qqq) {
|
||||||
{
|
|
||||||
ait[face.mIndices[qqq]-idx] = true;
|
ait[face.mIndices[qqq]-idx] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (std::vector<bool>::const_iterator it = ait.begin(); it != ait.end(); ++it)
|
for (std::vector<bool>::const_iterator it = ait.begin(); it != ait.end(); ++it) {
|
||||||
{
|
|
||||||
EXPECT_TRUE(*it);
|
EXPECT_TRUE(*it);
|
||||||
}
|
}
|
||||||
--m;
|
--m;
|
||||||
idx+=q;
|
idx+=q;
|
||||||
if(++q == 10)q = 4;
|
if ( ++q == 10 ) {
|
||||||
}
|
q = 4;
|
||||||
else
|
}
|
||||||
{
|
} else {
|
||||||
EXPECT_EQ(t, face.mNumIndices);
|
EXPECT_EQ(t, face.mNumIndices);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < face.mNumIndices; ++i,++idx)
|
for (unsigned int i = 0; i < face.mNumIndices; ++i,++idx) {
|
||||||
{
|
|
||||||
EXPECT_EQ(idx, face.mIndices[i]);
|
EXPECT_EQ(idx, face.mIndices[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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/types.h>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class utTypes : public ::testing::Test {
|
||||||
|
// empty
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F( utTypes, Color3dCpmpareOpTest ) {
|
||||||
|
aiColor3D col1( 1, 2, 3 );
|
||||||
|
aiColor3D col2( 4, 5, 6 );
|
||||||
|
aiColor3D col3( col1 );
|
||||||
|
|
||||||
|
EXPECT_FALSE( col1 == col2 );
|
||||||
|
EXPECT_FALSE( col2 == col3 );
|
||||||
|
EXPECT_TRUE( col1 == col3 );
|
||||||
|
|
||||||
|
EXPECT_TRUE( col1 != col2 );
|
||||||
|
EXPECT_TRUE( col2 != col3 );
|
||||||
|
EXPECT_FALSE( col1 != col3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F( utTypes, Color3dIndexOpTest ) {
|
||||||
|
aiColor3D col( 1, 2, 3 );
|
||||||
|
const ai_real r = col[ 0 ];
|
||||||
|
EXPECT_FLOAT_EQ( 1, r );
|
||||||
|
|
||||||
|
const ai_real g = col[ 1 ];
|
||||||
|
EXPECT_FLOAT_EQ( 2, g );
|
||||||
|
|
||||||
|
const ai_real b = col[ 2 ];
|
||||||
|
EXPECT_FLOAT_EQ( 3, b );
|
||||||
|
}
|
|
@ -325,7 +325,7 @@ void CGLView::ImportTextures(const QString& pScenePath)
|
||||||
|
|
||||||
void CGLView::BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParent_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign)
|
void CGLView::BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParent_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign)
|
||||||
{
|
{
|
||||||
aiMatrix4x4 mat_trans = pParent_TransformationMatrix * pNode.mTransformation;
|
aiMatrix4x4 mat_trans = pParent_TransformationMatrix * pNode.mTransformation;
|
||||||
|
|
||||||
// Check if node has meshes
|
// Check if node has meshes
|
||||||
for(size_t idx_idx_mesh = 0; idx_idx_mesh < pNode.mNumMeshes; idx_idx_mesh++)
|
for(size_t idx_idx_mesh = 0; idx_idx_mesh < pNode.mNumMeshes; idx_idx_mesh++)
|
||||||
|
@ -437,7 +437,7 @@ void CGLView::LogError(const QString& pMessage)
|
||||||
|
|
||||||
void CGLView::Draw_Node(const aiNode* pNode)
|
void CGLView::Draw_Node(const aiNode* pNode)
|
||||||
{
|
{
|
||||||
aiMatrix4x4 mat_node = pNode->mTransformation;
|
aiMatrix4x4 mat_node = pNode->mTransformation;
|
||||||
|
|
||||||
// Apply node transformation matrix.
|
// Apply node transformation matrix.
|
||||||
mat_node.Transpose();
|
mat_node.Transpose();
|
||||||
|
@ -516,7 +516,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
|
||||||
|
|
||||||
void CGLView::Draw_BBox(const SBBox& pBBox)
|
void CGLView::Draw_BBox(const SBBox& pBBox)
|
||||||
{
|
{
|
||||||
aiVector3D vertex[8];
|
aiVector3D vertex[8];
|
||||||
|
|
||||||
BBox_GetVertices(pBBox, vertex);
|
BBox_GetVertices(pBBox, vertex);
|
||||||
// Draw
|
// Draw
|
||||||
|
@ -590,9 +590,27 @@ void CGLView::resizeGL(int pWidth, int pHeight)
|
||||||
gluPerspective(mCamera_FOVY, mCamera_Viewport_AspectRatio, 1.0, 100000.0);///TODO: znear/zfar depend on scene size.
|
gluPerspective(mCamera_FOVY, mCamera_Viewport_AspectRatio, 1.0, 100000.0);///TODO: znear/zfar depend on scene size.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGLView::drawCoordSystem() {
|
||||||
|
glBindTexture(GL_TEXTURE_1D, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_3D, 0);
|
||||||
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
// X, -X
|
||||||
|
qglColor(QColor(Qt::red)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0);
|
||||||
|
qglColor(QColor(Qt::cyan)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
|
||||||
|
// Y, -Y
|
||||||
|
qglColor(QColor(Qt::green)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 100000.0, 0.0);
|
||||||
|
qglColor(QColor(Qt::magenta)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, -100000.0, 0.0);
|
||||||
|
// Z, -Z
|
||||||
|
qglColor(QColor(Qt::blue)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0);
|
||||||
|
qglColor(QColor(Qt::yellow)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
void CGLView::paintGL()
|
void CGLView::paintGL()
|
||||||
{
|
{
|
||||||
QTime time_paintbegin;
|
QTime time_paintbegin;
|
||||||
|
|
||||||
time_paintbegin = QTime::currentTime();
|
time_paintbegin = QTime::currentTime();
|
||||||
|
|
||||||
|
@ -604,23 +622,11 @@ QTime time_paintbegin;
|
||||||
glTranslatef(-mHelper_Camera.Translation_ToScene.x, -mHelper_Camera.Translation_ToScene.y, -mHelper_Camera.Translation_ToScene.z);
|
glTranslatef(-mHelper_Camera.Translation_ToScene.x, -mHelper_Camera.Translation_ToScene.y, -mHelper_Camera.Translation_ToScene.z);
|
||||||
glMultMatrixf((GLfloat*)&mHelper_Camera.Rotation_Scene);
|
glMultMatrixf((GLfloat*)&mHelper_Camera.Rotation_Scene);
|
||||||
// Coordinate system
|
// Coordinate system
|
||||||
if(mLightingEnabled) glDisable(GL_LIGHTING);///TODO: display list
|
if ( mLightingEnabled ) {
|
||||||
|
glDisable( GL_LIGHTING );///TODO: display list
|
||||||
|
}
|
||||||
|
drawCoordSystem();
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_1D, 0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
glBindTexture(GL_TEXTURE_3D, 0);
|
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
|
||||||
glBegin(GL_LINES);
|
|
||||||
// X, -X
|
|
||||||
qglColor(QColor(Qt::red)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0);
|
|
||||||
qglColor(QColor(Qt::cyan)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
|
|
||||||
// Y, -Y
|
|
||||||
qglColor(QColor(Qt::green)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 100000.0, 0.0);
|
|
||||||
qglColor(QColor(Qt::magenta)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, -100000.0, 0.0);
|
|
||||||
// Z, -Z
|
|
||||||
qglColor(QColor(Qt::blue)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0);
|
|
||||||
qglColor(QColor(Qt::yellow)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0);
|
|
||||||
glEnd();
|
|
||||||
glDisable(GL_COLOR_MATERIAL);
|
glDisable(GL_COLOR_MATERIAL);
|
||||||
if(mLightingEnabled) glEnable(GL_LIGHTING);
|
if(mLightingEnabled) glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
|
@ -1015,8 +1021,8 @@ void CGLView::Lighting_DisableSource(const size_t pLightNumber)
|
||||||
|
|
||||||
void CGLView::Camera_Set(const size_t pCameraNumber)
|
void CGLView::Camera_Set(const size_t pCameraNumber)
|
||||||
{
|
{
|
||||||
SHelper_Camera& hcam = mHelper_Camera;// reference with short name for conveniance.
|
SHelper_Camera& hcam = mHelper_Camera;// reference with short name for conveniance.
|
||||||
aiVector3D up;
|
aiVector3D up;
|
||||||
|
|
||||||
if(mCamera_DefaultAdded || (pCameraNumber >= mScene->mNumCameras))// If default camera used then 'pCameraNumber' doesn't matter.
|
if(mCamera_DefaultAdded || (pCameraNumber >= mScene->mNumCameras))// If default camera used then 'pCameraNumber' doesn't matter.
|
||||||
{
|
{
|
||||||
|
|
|
@ -253,7 +253,7 @@ private:
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void drawCoordSystem();
|
||||||
/// \fn void initializeGL() override
|
/// \fn void initializeGL() override
|
||||||
/// Overrided function for initialise OpenGL.
|
/// Overrided function for initialise OpenGL.
|
||||||
void initializeGL() override;
|
void initializeGL() override;
|
||||||
|
|
Loading…
Reference in New Issue