Merge branch 'master' into assimpviewer_dev
commit
1b71c2fd34
|
@ -38,6 +38,7 @@ tools/assimp_cmd/Makefile
|
|||
|
||||
# Tests
|
||||
test/results
|
||||
test/readlinetest*
|
||||
|
||||
# Python
|
||||
__pycache__
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#How to contribute
|
||||
|
||||
If you want to contribute you can follow these setps:
|
||||
- Fist create your own clone of assimp
|
||||
- When you want to fix a bug or add a new feature create a branch on your own fork ( just follow https://help.github.com/articles/creating-a-pull-request-from-a-fork/ )
|
||||
- Push it to the repo and open a pull request
|
||||
- A pull request will start our CI-service, which checks if the build works for linux and windows.
|
||||
It will check for memory leaks, compiler warnings and memory alignment issues. If any of these tests fails: fix it and the tests will be reastarted automatically
|
||||
- At the end we will perform a code review and merge your branch to the master branch.
|
||||
|
||||
|
|
@ -208,8 +208,15 @@ OPTION(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT "default value of all ASSIMP_BUILD_
|
|||
# macro to add the CMake Option ADD_ASSIMP_IMPORTER_<name> which enables compile of loader
|
||||
# this way selective loaders can be compiled (reduces filesize + compile time)
|
||||
MACRO(ADD_ASSIMP_IMPORTER name)
|
||||
OPTION(ASSIMP_BUILD_${name}_IMPORTER "build the ${name} importer" ${ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT})
|
||||
IF(ASSIMP_BUILD_${name}_IMPORTER)
|
||||
IF (ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT)
|
||||
set(ASSIMP_IMPORTER_ENABLED TRUE)
|
||||
IF (DEFINED ASSIMP_BUILD_${name}_IMPORTER AND NOT ASSIMP_BUILD_${name}_IMPORTER)
|
||||
set(ASSIMP_IMPORTER_ENABLED FALSE)
|
||||
ENDIF ()
|
||||
ELSE ()
|
||||
set(ASSIMP_IMPORTER_ENABLED ${ASSIMP_BUILD_${name}_IMPORTER})
|
||||
ENDIF ()
|
||||
IF (ASSIMP_IMPORTER_ENABLED)
|
||||
LIST(APPEND ASSIMP_LOADER_SRCS ${ARGN})
|
||||
SET(ASSIMP_IMPORTERS_ENABLED "${ASSIMP_IMPORTERS_ENABLED} ${name}")
|
||||
SET(${name}_SRCS ${ARGN})
|
||||
|
|
|
@ -1819,9 +1819,12 @@ void ColladaLoader::ConvertPath (aiString& ss)
|
|||
|
||||
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
|
||||
// I need to filter it without destroying linux paths starting with "/somewhere"
|
||||
if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' )
|
||||
{
|
||||
ss.length--;
|
||||
#if defined( _MSC_VER )
|
||||
if( ss.data[0] == '/' && isalpha( (unsigned char) ss.data[1]) && ss.data[2] == ':' ) {
|
||||
#else
|
||||
if (ss.data[ 0 ] == '/' && isalpha( ss.data[ 1 ] ) && ss.data[ 2 ] == ':') {
|
||||
#endif
|
||||
--ss.length;
|
||||
::memmove( ss.data, ss.data+1, ss.length);
|
||||
ss.data[ss.length] = 0;
|
||||
}
|
||||
|
|
|
@ -115,10 +115,10 @@ public:
|
|||
// import the metadata
|
||||
if ( !mMetaData.empty() ) {
|
||||
const size_t numMeta( mMetaData.size() );
|
||||
scene->mMetaData = aiMetadata::Alloc( numMeta );
|
||||
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>( numMeta ) );
|
||||
for ( size_t i = 0; i < numMeta; ++i ) {
|
||||
aiString val( mMetaData[ i ].value );
|
||||
scene->mMetaData->Set( i, mMetaData[ i ].name, val );
|
||||
scene->mMetaData->Set(static_cast<unsigned int>( i ), mMetaData[ i ].name, val );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
|
|||
|
||||
if ( extension.empty() || checkSig ) {
|
||||
static const char *pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
|
||||
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 4 );
|
||||
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 4, 32 );
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -76,11 +76,11 @@ bool DefaultIOSystem::Exists( const char* pFile) const
|
|||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
|
||||
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL);
|
||||
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
|
||||
struct _stat64 filestat;
|
||||
struct __stat64 filestat;
|
||||
if (0 != _wstat64(fileName16, &filestat)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
|
|||
FILE* file;
|
||||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL );
|
||||
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
|
||||
std::string mode8(strMode);
|
||||
|
@ -158,7 +158,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
|
|||
{
|
||||
ai_assert(in && _out);
|
||||
#if defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL);
|
||||
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
wchar_t out16[PATHLIMIT];
|
||||
wchar_t in16[PATHLIMIT];
|
||||
|
|
|
@ -154,9 +154,9 @@ Exporter::ExportFormatEntry gExporters[] =
|
|||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
|
||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb2", &ExportSceneGLB2,
|
||||
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
#endif
|
||||
|
||||
|
|
|
@ -448,8 +448,8 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
|||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
const uint32_t version = ReadWord(input, cursor, input + length);
|
||||
const bool is64bits = version >= 7500;
|
||||
while (cursor < input + length)
|
||||
{
|
||||
const char *end = input + length;
|
||||
while (cursor < end ) {
|
||||
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -108,6 +108,125 @@ void JoinVerticesProcess::Execute( aiScene* pScene)
|
|||
pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex)
|
||||
{
|
||||
// A little helper to find locally close vertices faster.
|
||||
// Try to reuse the lookup table from the last step.
|
||||
const static float epsilon = 1e-5f;
|
||||
// Squared because we check against squared length of the vector difference
|
||||
static const float squareEpsilon = epsilon * epsilon;
|
||||
|
||||
// Square compare is useful for animeshes vertexes compare
|
||||
if ((lhs.position - rhs.position).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We just test the other attributes even if they're not present in the mesh.
|
||||
// In this case they're initialized to 0 so the comparison succeeds.
|
||||
// By this method the non-present attributes are effectively ignored in the comparison.
|
||||
if ((lhs.normal - rhs.normal).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((lhs.texcoords[0] - rhs.texcoords[0]).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((lhs.tangent - rhs.tangent).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((lhs.bitangent - rhs.bitangent).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Usually we won't have vertex colors or multiple UVs, so we can skip from here
|
||||
// Actually this increases runtime performance slightly, at least if branch
|
||||
// prediction is on our side.
|
||||
if (complex) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i > 0 && (lhs.texcoords[i] - rhs.texcoords[i]).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
if (GetColorDifference(lhs.colors[i], rhs.colors[i]) > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class XMesh>
|
||||
void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
|
||||
// replace vertex data with the unique data sets
|
||||
pMesh->mNumVertices = (unsigned int)uniqueVertices.size();
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// NOTE - we're *not* calling Vertex::SortBack() because it would check for
|
||||
// presence of every single vertex component once PER VERTEX. And our CPU
|
||||
// dislikes branches, even if they're easily predictable.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Position, if present (check made for aiAnimMesh)
|
||||
if (pMesh->mVertices)
|
||||
{
|
||||
delete [] pMesh->mVertices;
|
||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||
for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
pMesh->mVertices[a] = uniqueVertices[a].position;
|
||||
}
|
||||
}
|
||||
|
||||
// Normals, if present
|
||||
if (pMesh->mNormals)
|
||||
{
|
||||
delete [] pMesh->mNormals;
|
||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
pMesh->mNormals[a] = uniqueVertices[a].normal;
|
||||
}
|
||||
}
|
||||
// Tangents, if present
|
||||
if (pMesh->mTangents)
|
||||
{
|
||||
delete [] pMesh->mTangents;
|
||||
pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
|
||||
for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
pMesh->mTangents[a] = uniqueVertices[a].tangent;
|
||||
}
|
||||
}
|
||||
// Bitangents as well
|
||||
if (pMesh->mBitangents)
|
||||
{
|
||||
delete [] pMesh->mBitangents;
|
||||
pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
|
||||
for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
pMesh->mBitangents[a] = uniqueVertices[a].bitangent;
|
||||
}
|
||||
}
|
||||
// Vertex colors
|
||||
for (unsigned int a = 0; pMesh->HasVertexColors(a); a++)
|
||||
{
|
||||
delete [] pMesh->mColors[a];
|
||||
pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices];
|
||||
for( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
|
||||
pMesh->mColors[a][b] = uniqueVertices[b].colors[a];
|
||||
}
|
||||
}
|
||||
// Texture coords
|
||||
for (unsigned int a = 0; pMesh->HasTextureCoords(a); a++)
|
||||
{
|
||||
delete [] pMesh->mTextureCoords[a];
|
||||
pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices];
|
||||
for (unsigned int b = 0; b < pMesh->mNumVertices; b++) {
|
||||
pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a];
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Unites identical vertices in the given mesh
|
||||
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
||||
|
@ -132,9 +251,6 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
|
||||
std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
|
||||
|
||||
// A little helper to find locally close vertices faster.
|
||||
// Try to reuse the lookup table from the last step.
|
||||
const static float epsilon = 1e-5f;
|
||||
// float posEpsilonSqr;
|
||||
SpatialSort* vertexFinder = NULL;
|
||||
SpatialSort _vertexFinder;
|
||||
|
@ -156,9 +272,6 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
// posEpsilonSqr = ComputePositionEpsilon(pMesh);
|
||||
}
|
||||
|
||||
// Squared because we check against squared length of the vector difference
|
||||
static const float squareEpsilon = epsilon * epsilon;
|
||||
|
||||
// Again, better waste some bytes than a realloc ...
|
||||
std::vector<unsigned int> verticesFound;
|
||||
verticesFound.reserve(10);
|
||||
|
@ -166,6 +279,16 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
// Run an optimized code path if we don't have multiple UVs or vertex colors.
|
||||
// This should yield false in more than 99% of all imports ...
|
||||
const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);
|
||||
const bool hasAnimMeshes = pMesh->mNumAnimMeshes > 0;
|
||||
|
||||
// We'll never have more vertices afterwards.
|
||||
std::vector<std::vector<Vertex>> uniqueAnimatedVertices;
|
||||
if (hasAnimMeshes) {
|
||||
uniqueAnimatedVertices.resize(pMesh->mNumAnimMeshes);
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices);
|
||||
}
|
||||
}
|
||||
|
||||
// Now check each vertex if it brings something new to the table
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
|
@ -178,74 +301,32 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
|
||||
// check all unique vertices close to the position if this vertex is already present among them
|
||||
for( unsigned int b = 0; b < verticesFound.size(); b++) {
|
||||
|
||||
const unsigned int vidx = verticesFound[b];
|
||||
const unsigned int uidx = replaceIndex[ vidx];
|
||||
if( uidx & 0x80000000)
|
||||
continue;
|
||||
|
||||
const Vertex& uv = uniqueVertices[ uidx];
|
||||
// Position mismatch is impossible - the vertex finder already discarded all non-matching positions
|
||||
|
||||
// We just test the other attributes even if they're not present in the mesh.
|
||||
// In this case they're initialized to 0 so the comparison succeeds.
|
||||
// By this method the non-present attributes are effectively ignored in the comparison.
|
||||
if( (uv.normal - v.normal).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( (uv.texcoords[0] - v.texcoords[0]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( (uv.tangent - v.tangent).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( (uv.bitangent - v.bitangent).SquareLength() > squareEpsilon)
|
||||
if (!areVerticesEqual(v, uv, complex)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Usually we won't have vertex colors or multiple UVs, so we can skip from here
|
||||
// Actually this increases runtime performance slightly, at least if branch
|
||||
// prediction is on our side.
|
||||
if (complex){
|
||||
// manually unrolled because continue wouldn't work as desired in an inner loop,
|
||||
// also because some compilers seem to fail the task. Colors and UV coords
|
||||
// are interleaved since the higher entries are most likely to be
|
||||
// zero and thus useless. By interleaving the arrays, vertices are,
|
||||
// on average, rejected earlier.
|
||||
|
||||
if( (uv.texcoords[1] - v.texcoords[1]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[0], v.colors[0]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[2] - v.texcoords[2]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[1], v.colors[1]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[3] - v.texcoords[3]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[2], v.colors[2]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[4] - v.texcoords[4]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[3], v.colors[3]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[5] - v.texcoords[5]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[4], v.colors[4]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[6] - v.texcoords[6]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[5], v.colors[5]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[7] - v.texcoords[7]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[6], v.colors[6]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( GetColorDifference( uv.colors[7], v.colors[7]) > squareEpsilon)
|
||||
if (hasAnimMeshes) {
|
||||
// If given vertex is animated, then it has to be preserver 1 to 1 (base mesh and animated mesh require same topology)
|
||||
// NOTE: not doing this totaly breaks anim meshes as they don't have their own faces (they use pMesh->mFaces)
|
||||
bool breaksAnimMesh = false;
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
const Vertex& animatedUV = uniqueAnimatedVertices[animMeshIndex][ uidx];
|
||||
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
|
||||
if (!areVerticesEqual(aniMeshVertex, animatedUV, complex)) {
|
||||
breaksAnimMesh = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (breaksAnimMesh) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// we're still here -> this vertex perfectly matches our given vertex
|
||||
|
@ -264,6 +345,12 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
// no unique vertex matches it up to now -> so add it
|
||||
replaceIndex[a] = (unsigned int)uniqueVertices.size();
|
||||
uniqueVertices.push_back( v);
|
||||
if (hasAnimMeshes) {
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
|
||||
uniqueAnimatedVertices[animMeshIndex].push_back(aniMeshVertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,64 +368,10 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
);
|
||||
}
|
||||
|
||||
// replace vertex data with the unique data sets
|
||||
pMesh->mNumVertices = (unsigned int)uniqueVertices.size();
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// NOTE - we're *not* calling Vertex::SortBack() because it would check for
|
||||
// presence of every single vertex component once PER VERTEX. And our CPU
|
||||
// dislikes branches, even if they're easily predictable.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Position
|
||||
delete [] pMesh->mVertices;
|
||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
|
||||
pMesh->mVertices[a] = uniqueVertices[a].position;
|
||||
|
||||
// Normals, if present
|
||||
if( pMesh->mNormals)
|
||||
{
|
||||
delete [] pMesh->mNormals;
|
||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
pMesh->mNormals[a] = uniqueVertices[a].normal;
|
||||
}
|
||||
}
|
||||
// Tangents, if present
|
||||
if( pMesh->mTangents)
|
||||
{
|
||||
delete [] pMesh->mTangents;
|
||||
pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
pMesh->mTangents[a] = uniqueVertices[a].tangent;
|
||||
}
|
||||
}
|
||||
// Bitangents as well
|
||||
if( pMesh->mBitangents)
|
||||
{
|
||||
delete [] pMesh->mBitangents;
|
||||
pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
pMesh->mBitangents[a] = uniqueVertices[a].bitangent;
|
||||
}
|
||||
}
|
||||
// Vertex colors
|
||||
for( unsigned int a = 0; pMesh->HasVertexColors(a); a++)
|
||||
{
|
||||
delete [] pMesh->mColors[a];
|
||||
pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices];
|
||||
for( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
|
||||
pMesh->mColors[a][b] = uniqueVertices[b].colors[a];
|
||||
}
|
||||
}
|
||||
// Texture coords
|
||||
for( unsigned int a = 0; pMesh->HasTextureCoords(a); a++)
|
||||
{
|
||||
delete [] pMesh->mTextureCoords[a];
|
||||
pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices];
|
||||
for( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
|
||||
pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a];
|
||||
updateXMeshVertices(pMesh, uniqueVertices);
|
||||
if (hasAnimMeshes) {
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
updateXMeshVertices(pMesh->mAnimMeshes[animMeshIndex], uniqueAnimatedVertices[animMeshIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -138,28 +138,29 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
|
|||
}
|
||||
}
|
||||
|
||||
glTF2Exporter::~glTF2Exporter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a 4x4 matrix from struct aiMatrix to typedef mat4.
|
||||
* Also converts from row-major to column-major storage.
|
||||
*/
|
||||
static void CopyValue(const aiMatrix4x4& v, mat4& o)
|
||||
{
|
||||
static void CopyValue(const aiMatrix4x4& v, mat4& o) {
|
||||
o[ 0] = v.a1; o[ 1] = v.b1; o[ 2] = v.c1; o[ 3] = v.d1;
|
||||
o[ 4] = v.a2; o[ 5] = v.b2; o[ 6] = v.c2; o[ 7] = v.d2;
|
||||
o[ 8] = v.a3; o[ 9] = v.b3; o[10] = v.c3; o[11] = v.d3;
|
||||
o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4;
|
||||
}
|
||||
|
||||
static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o)
|
||||
{
|
||||
static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o) {
|
||||
o.a1 = v.a1; o.a2 = v.a2; o.a3 = v.a3; o.a4 = v.a4;
|
||||
o.b1 = v.b1; o.b2 = v.b2; o.b3 = v.b3; o.b4 = v.b4;
|
||||
o.c1 = v.c1; o.c2 = v.c2; o.c3 = v.c3; o.c4 = v.c4;
|
||||
o.d1 = v.d1; o.d2 = v.d2; o.d3 = v.d3; o.d4 = v.d4;
|
||||
}
|
||||
|
||||
static void IdentityMatrix4(mat4& o)
|
||||
{
|
||||
static void IdentityMatrix4(mat4& o) {
|
||||
o[ 0] = 1; o[ 1] = 0; o[ 2] = 0; o[ 3] = 0;
|
||||
o[ 4] = 0; o[ 5] = 1; o[ 6] = 0; o[ 7] = 0;
|
||||
o[ 8] = 0; o[ 9] = 0; o[10] = 1; o[11] = 0;
|
||||
|
@ -169,7 +170,9 @@ static void IdentityMatrix4(mat4& o)
|
|||
inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer,
|
||||
unsigned int count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, bool isIndices = false)
|
||||
{
|
||||
if (!count || !data) return Ref<Accessor>();
|
||||
if (!count || !data) {
|
||||
return Ref<Accessor>();
|
||||
}
|
||||
|
||||
unsigned int numCompsIn = AttribType::GetNumComponents(typeIn);
|
||||
unsigned int numCompsOut = AttribType::GetNumComponents(typeOut);
|
||||
|
@ -638,11 +641,11 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
|
|||
Mesh::Primitive& p = meshRef->primitives.back();
|
||||
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
if ( vertexJointAccessor ) {
|
||||
unsigned int offset = vertexJointAccessor->bufferView->byteOffset;
|
||||
unsigned int bytesLen = vertexJointAccessor->bufferView->byteLength;
|
||||
size_t offset = vertexJointAccessor->bufferView->byteOffset;
|
||||
size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
|
||||
unsigned int s_bytesPerComp= ComponentTypeSize(ComponentType_UNSIGNED_SHORT);
|
||||
unsigned int bytesPerComp = ComponentTypeSize(vertexJointAccessor->componentType);
|
||||
unsigned int s_bytesLen = bytesLen * s_bytesPerComp / bytesPerComp;
|
||||
size_t s_bytesLen = bytesLen * s_bytesPerComp / bytesPerComp;
|
||||
Ref<Buffer> buf = vertexJointAccessor->bufferView->buffer;
|
||||
uint8_t* arrys = new uint8_t[s_bytesLen];
|
||||
unsigned int i = 0;
|
||||
|
@ -728,8 +731,10 @@ void glTF2Exporter::ExportMeshes()
|
|||
|
||||
/******************** Normals ********************/
|
||||
// Normalize all normals as the validator can emit a warning otherwise
|
||||
for (auto i = 0u; i < aim->mNumVertices; ++i) {
|
||||
aim->mNormals[i].Normalize();
|
||||
if ( nullptr != aim->mNormals) {
|
||||
for ( auto i = 0u; i < aim->mNumVertices; ++i ) {
|
||||
aim->mNormals[ i ].Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
||||
|
@ -759,7 +764,7 @@ void glTF2Exporter::ExportMeshes()
|
|||
if (c)
|
||||
p.attributes.color.push_back(c);
|
||||
}
|
||||
|
||||
|
||||
/*************** Vertices indices ****************/
|
||||
if (aim->mNumFaces > 0) {
|
||||
std::vector<IndicesType> indices;
|
||||
|
@ -891,6 +896,8 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode* n)
|
|||
{
|
||||
Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
|
||||
|
||||
node->name = n->mName.C_Str();
|
||||
|
||||
if (!n->mTransformation.IsIdentity()) {
|
||||
node->matrix.isPresent = true;
|
||||
CopyValue(n->mTransformation, node->matrix.value);
|
||||
|
|
|
@ -87,28 +87,15 @@ namespace Assimp
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
/** Helper class to export a given scene to an glTF file. */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class glTF2Exporter
|
||||
{
|
||||
class glTF2Exporter {
|
||||
public:
|
||||
/// Constructor for a specific scene to export
|
||||
glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
|
||||
const ExportProperties* pProperties, bool binary);
|
||||
~glTF2Exporter();
|
||||
|
||||
private:
|
||||
|
||||
const char* mFilename;
|
||||
IOSystem* mIOSystem;
|
||||
const aiScene* mScene;
|
||||
const ExportProperties* mProperties;
|
||||
|
||||
std::map<std::string, unsigned int> mTexturesByPath;
|
||||
|
||||
std::shared_ptr<glTF2::Asset> mAsset;
|
||||
|
||||
std::vector<unsigned char> mBodyData;
|
||||
|
||||
protected:
|
||||
void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
|
||||
|
||||
void GetTexSampler(const aiMaterial* mat, glTF2::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||
void GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||
|
@ -126,6 +113,15 @@ namespace Assimp
|
|||
unsigned int ExportNode(const aiNode* node, glTF2::Ref<glTF2::Node>& parent);
|
||||
void ExportScene();
|
||||
void ExportAnimations();
|
||||
|
||||
private:
|
||||
const char* mFilename;
|
||||
IOSystem* mIOSystem;
|
||||
const aiScene* mScene;
|
||||
const ExportProperties* mProperties;
|
||||
std::map<std::string, unsigned int> mTexturesByPath;
|
||||
std::shared_ptr<glTF2::Asset> mAsset;
|
||||
std::vector<unsigned char> mBodyData;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -134,6 +134,30 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Extract a particular vertex from a anim mesh and interleave all components */
|
||||
explicit Vertex(const aiAnimMesh* msh, unsigned int idx) {
|
||||
ai_assert(idx < msh->mNumVertices);
|
||||
position = msh->mVertices[idx];
|
||||
|
||||
if (msh->HasNormals()) {
|
||||
normal = msh->mNormals[idx];
|
||||
}
|
||||
|
||||
if (msh->HasTangentsAndBitangents()) {
|
||||
tangent = msh->mTangents[idx];
|
||||
bitangent = msh->mBitangents[idx];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) {
|
||||
texcoords[i] = msh->mTextureCoords[i][idx];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; msh->HasVertexColors(i); ++i) {
|
||||
colors[i] = msh->mColors[i][idx];
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Vertex& operator += (const Vertex& v) {
|
||||
|
|
|
@ -149,7 +149,8 @@ struct aiMetadata {
|
|||
mValues[ i ].mType = rhs.mValues[ i ].mType;
|
||||
switch ( rhs.mValues[ i ].mType ) {
|
||||
case AI_BOOL:
|
||||
mValues[ i ].mData = new bool( rhs.mValues[i].mData );
|
||||
mValues[ i ].mData = new bool;
|
||||
::memcpy( mValues[ i ].mData, rhs.mValues[ i ].mData, sizeof(bool) );
|
||||
break;
|
||||
case AI_INT32: {
|
||||
int32_t v;
|
||||
|
|
|
@ -89,4 +89,5 @@ TEST_F( utglTF2ImportExport, importBinaryglTF2FromFileTest ) {
|
|||
TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
|
||||
EXPECT_TRUE( exporterTest() );
|
||||
}
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
|
|
|
@ -106,7 +106,8 @@ int Assimp_Export(const char* const* params, unsigned int num)
|
|||
continue;
|
||||
}
|
||||
if (!strncmp( params[i], "-f",2)) {
|
||||
outf = std::string(params[i]+2);
|
||||
if ( strncmp( params[ i ], "-fi",3 ))
|
||||
outf = std::string(params[i]+2);
|
||||
}
|
||||
else if ( !strncmp( params[i], "--format=",9)) {
|
||||
outf = std::string(params[i]+9);
|
||||
|
|
|
@ -261,7 +261,6 @@ void PrintHorBar()
|
|||
printf("-----------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Import a specific file
|
||||
const aiScene* ImportModel(
|
||||
|
@ -390,105 +389,101 @@ int ProcessStandardArguments(
|
|||
|
||||
for (unsigned int i = 0; i < num;++i)
|
||||
{
|
||||
if (! strcmp(params[i], "-ptv") || ! strcmp(params[i], "--pretransform-vertices")) {
|
||||
const char *param = params[ i ];
|
||||
printf( "param = %s\n", param );
|
||||
if (! strcmp( param, "-ptv") || ! strcmp( param, "--pretransform-vertices")) {
|
||||
fill.ppFlags |= aiProcess_PreTransformVertices;
|
||||
}
|
||||
else if (! strcmp(params[i], "-gsn") || ! strcmp(params[i], "--gen-smooth-normals")) {
|
||||
else if (! strcmp( param, "-gsn") || ! strcmp( param, "--gen-smooth-normals")) {
|
||||
fill.ppFlags |= aiProcess_GenSmoothNormals;
|
||||
}
|
||||
else if (! strcmp(params[i], "-gn") || ! strcmp(params[i], "--gen-normals")) {
|
||||
else if (! strcmp( param, "-gn") || ! strcmp( param, "--gen-normals")) {
|
||||
fill.ppFlags |= aiProcess_GenNormals;
|
||||
}
|
||||
else if (! strcmp(params[i], "-jiv") || ! strcmp(params[i], "--join-identical-vertices")) {
|
||||
else if (! strcmp( param, "-jiv") || ! strcmp( param, "--join-identical-vertices")) {
|
||||
fill.ppFlags |= aiProcess_JoinIdenticalVertices;
|
||||
}
|
||||
else if (! strcmp(params[i], "-rrm") || ! strcmp(params[i], "--remove-redundant-materials")) {
|
||||
else if (! strcmp( param, "-rrm") || ! strcmp( param, "--remove-redundant-materials")) {
|
||||
fill.ppFlags |= aiProcess_RemoveRedundantMaterials;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fd") || ! strcmp(params[i], "--find-degenerates")) {
|
||||
else if (! strcmp( param, "-fd") || ! strcmp( param, "--find-degenerates")) {
|
||||
fill.ppFlags |= aiProcess_FindDegenerates;
|
||||
}
|
||||
else if (! strcmp(params[i], "-slm") || ! strcmp(params[i], "--split-large-meshes")) {
|
||||
else if (! strcmp( param, "-slm") || ! strcmp( param, "--split-large-meshes")) {
|
||||
fill.ppFlags |= aiProcess_SplitLargeMeshes;
|
||||
}
|
||||
else if (! strcmp(params[i], "-lbw") || ! strcmp(params[i], "--limit-bone-weights")) {
|
||||
else if (! strcmp( param, "-lbw") || ! strcmp( param, "--limit-bone-weights")) {
|
||||
fill.ppFlags |= aiProcess_LimitBoneWeights;
|
||||
}
|
||||
else if (! strcmp(params[i], "-vds") || ! strcmp(params[i], "--validate-data-structure")) {
|
||||
else if (! strcmp( param, "-vds") || ! strcmp( param, "--validate-data-structure")) {
|
||||
fill.ppFlags |= aiProcess_ValidateDataStructure;
|
||||
}
|
||||
else if (! strcmp(params[i], "-icl") || ! strcmp(params[i], "--improve-cache-locality")) {
|
||||
else if (! strcmp( param, "-icl") || ! strcmp( param, "--improve-cache-locality")) {
|
||||
fill.ppFlags |= aiProcess_ImproveCacheLocality;
|
||||
}
|
||||
else if (! strcmp(params[i], "-sbpt") || ! strcmp(params[i], "--sort-by-ptype")) {
|
||||
else if (! strcmp( param, "-sbpt") || ! strcmp( param, "--sort-by-ptype")) {
|
||||
fill.ppFlags |= aiProcess_SortByPType;
|
||||
}
|
||||
else if (! strcmp(params[i], "-lh") || ! strcmp(params[i], "--left-handed")) {
|
||||
else if (! strcmp( param, "-lh") || ! strcmp( param, "--left-handed")) {
|
||||
fill.ppFlags |= aiProcess_ConvertToLeftHanded;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fuv") || ! strcmp(params[i], "--flip-uv")) {
|
||||
else if (! strcmp( param, "-fuv") || ! strcmp( param, "--flip-uv")) {
|
||||
fill.ppFlags |= aiProcess_FlipUVs;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fwo") || ! strcmp(params[i], "--flip-winding-order")) {
|
||||
else if (! strcmp( param, "-fwo") || ! strcmp( param, "--flip-winding-order")) {
|
||||
fill.ppFlags |= aiProcess_FlipWindingOrder;
|
||||
}
|
||||
else if (! strcmp(params[i], "-tuv") || ! strcmp(params[i], "--transform-uv-coords")) {
|
||||
else if (! strcmp( param, "-tuv") || ! strcmp( param, "--transform-uv-coords")) {
|
||||
fill.ppFlags |= aiProcess_TransformUVCoords;
|
||||
}
|
||||
else if (! strcmp(params[i], "-guv") || ! strcmp(params[i], "--gen-uvcoords")) {
|
||||
else if (! strcmp( param, "-guv") || ! strcmp( param, "--gen-uvcoords")) {
|
||||
fill.ppFlags |= aiProcess_GenUVCoords;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fid") || ! strcmp(params[i], "--find-invalid-data")) {
|
||||
else if (! strcmp( param, "-fid") || ! strcmp( param, "--find-invalid-data")) {
|
||||
fill.ppFlags |= aiProcess_FindInvalidData;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fixn") || ! strcmp(params[i], "--fix-normals")) {
|
||||
else if (! strcmp( param, "-fixn") || ! strcmp( param, "--fix-normals")) {
|
||||
fill.ppFlags |= aiProcess_FixInfacingNormals;
|
||||
}
|
||||
else if (! strcmp(params[i], "-tri") || ! strcmp(params[i], "--triangulate")) {
|
||||
else if (! strcmp( param, "-tri") || ! strcmp( param, "--triangulate")) {
|
||||
fill.ppFlags |= aiProcess_Triangulate;
|
||||
}
|
||||
else if (! strcmp(params[i], "-cts") || ! strcmp(params[i], "--calc-tangent-space")) {
|
||||
else if (! strcmp( param, "-cts") || ! strcmp( param, "--calc-tangent-space")) {
|
||||
fill.ppFlags |= aiProcess_CalcTangentSpace;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fi") || ! strcmp(params[i], "--find-instances")) {
|
||||
else if (! strcmp( param, "-fi") || ! strcmp( param, "--find-instances")) {
|
||||
fill.ppFlags |= aiProcess_FindInstances;
|
||||
}
|
||||
else if (! strcmp(params[i], "-og") || ! strcmp(params[i], "--optimize-graph")) {
|
||||
else if (! strcmp( param, "-og") || ! strcmp( param, "--optimize-graph")) {
|
||||
fill.ppFlags |= aiProcess_OptimizeGraph;
|
||||
}
|
||||
else if (! strcmp(params[i], "-om") || ! strcmp(params[i], "--optimize-meshes")) {
|
||||
else if (! strcmp( param, "-om") || ! strcmp( param, "--optimize-meshes")) {
|
||||
fill.ppFlags |= aiProcess_OptimizeMeshes;
|
||||
}
|
||||
else if (! strcmp(params[i], "-db") || ! strcmp(params[i], "--debone")) {
|
||||
else if (! strcmp( param, "-db") || ! strcmp( param, "--debone")) {
|
||||
fill.ppFlags |= aiProcess_Debone;
|
||||
}
|
||||
else if (! strcmp(params[i], "-sbc") || ! strcmp(params[i], "--split-by-bone-count")) {
|
||||
else if (! strcmp( param, "-sbc") || ! strcmp( param, "--split-by-bone-count")) {
|
||||
fill.ppFlags |= aiProcess_SplitByBoneCount;
|
||||
}
|
||||
|
||||
|
||||
else if (! strncmp(params[i], "-c",2) || ! strncmp(params[i], "--config=",9)) {
|
||||
|
||||
else if (! strncmp( param, "-c",2) || ! strncmp( param, "--config=",9)) {
|
||||
const unsigned int ofs = (params[i][1] == '-' ? 9 : 2);
|
||||
|
||||
// use default configurations
|
||||
if (! strncmp(params[i]+ofs,"full",4)) {
|
||||
fill.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
|
||||
}
|
||||
else if (! strncmp(params[i]+ofs,"default",7)) {
|
||||
if (!strncmp( param + ofs, "full", 4 )) {
|
||||
fill.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
|
||||
} else if (!strncmp( param + ofs, "default", 7 )) {
|
||||
fill.ppFlags |= aiProcessPreset_TargetRealtime_Quality;
|
||||
}
|
||||
else if (! strncmp(params[i]+ofs,"fast",4)) {
|
||||
} else if (! strncmp( param +ofs,"fast",4)) {
|
||||
fill.ppFlags |= aiProcessPreset_TargetRealtime_Fast;
|
||||
}
|
||||
}
|
||||
else if (! strcmp(params[i], "-l") || ! strcmp(params[i], "--show-log")) {
|
||||
} else if (! strcmp( param, "-l") || ! strcmp( param, "--show-log")) {
|
||||
fill.showLog = true;
|
||||
}
|
||||
else if (! strcmp(params[i], "-v") || ! strcmp(params[i], "--verbose")) {
|
||||
else if (! strcmp( param, "-v") || ! strcmp( param, "--verbose")) {
|
||||
fill.verbose = true;
|
||||
}
|
||||
else if (! strncmp(params[i], "--log-out=",10) || ! strncmp(params[i], "-lo",3)) {
|
||||
else if (! strncmp( param, "--log-out=",10) || ! strncmp( param, "-lo",3)) {
|
||||
fill.logFile = std::string(params[i]+(params[i][1] == '-' ? 10 : 3));
|
||||
if (!fill.logFile.length()) {
|
||||
fill.logFile = "assimp-log.txt";
|
||||
|
|
|
@ -2259,7 +2259,7 @@ int CDisplay::RenderTextureView()
|
|||
const float ny = (float)sRect.bottom;
|
||||
const float x = (float)sDesc.Width;
|
||||
const float y = (float)sDesc.Height;
|
||||
float f = min((nx-30) / x,(ny-30) / y) * (m_fTextureZoom/1000.0f);
|
||||
float f = std::min((nx-30) / x,(ny-30) / y) * (m_fTextureZoom/1000.0f);
|
||||
|
||||
float fHalfX = (nx - (f * x)) / 2.0f;
|
||||
float fHalfY = (ny - (f * y)) / 2.0f;
|
||||
|
|
|
@ -275,7 +275,7 @@ bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString)
|
|||
for (unsigned int i = 0; i < iSizeFound;++i)
|
||||
info.cFileName[i] = (CHAR)tolower(info.cFileName[i]);
|
||||
|
||||
if (0 == memcmp(info.cFileName,szFile2, min(iSizeFound,iSize)))
|
||||
if (0 == memcmp(info.cFileName,szFile2, std::min(iSizeFound,iSize)))
|
||||
{
|
||||
// we have it. Build the full path ...
|
||||
char* sz = strrchr(szTempB,'*');
|
||||
|
|
|
@ -45,7 +45,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <windowsx.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <mmsystem.h>
|
||||
#else
|
||||
#include <timeapi.h>
|
||||
#endif
|
||||
|
||||
namespace AssimpView {
|
||||
|
||||
|
@ -1049,9 +1054,9 @@ void DoExport(size_t formatId)
|
|||
ai_assert(strlen(szFileName) <= MAX_PATH);
|
||||
|
||||
// invent a nice default file name
|
||||
char* sz = max(strrchr(szFileName,'\\'),strrchr(szFileName,'/'));
|
||||
char* sz = std::max(strrchr(szFileName,'\\'),strrchr(szFileName,'/'));
|
||||
if (sz) {
|
||||
strncpy(sz,max(strrchr(g_szFileName,'\\'),strrchr(g_szFileName,'/')),MAX_PATH);
|
||||
strncpy(sz,std::max(strrchr(g_szFileName,'\\'),strrchr(g_szFileName,'/')),MAX_PATH);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -43,10 +43,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
|
||||
#include "assimp_view.h"
|
||||
#include <timeapi.h>
|
||||
#include <assimp/StringUtils.h>
|
||||
#include <map>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <mmsystem.h>
|
||||
#else
|
||||
#include <timeapi.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace AssimpView {
|
||||
|
|
|
@ -46,6 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#define AI_SHADER_COMPILE_FLAGS D3DXSHADER_USE_LEGACY_D3DX9_31_DLL
|
||||
|
||||
// Because Dx headers include windef.h with min/max redefinition
|
||||
#define NOMINMAX
|
||||
|
||||
// include resource definitions
|
||||
#include "resource.h"
|
||||
|
||||
|
@ -177,7 +180,7 @@ type clamp(intype in)
|
|||
{
|
||||
// for unsigned types only ...
|
||||
intype mask = (0x1u << (sizeof(type)*8))-1;
|
||||
return (type)max((intype)0,min(in,mask));
|
||||
return (type)std::max((intype)0,std::min(in,mask));
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue