Merge pull request #3 from migenius/master

merge master to RS build branch
pull/2158/head
Brendan Hack 2018-08-29 09:31:51 +10:00 committed by GitHub
commit 8518a5cda4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
92 changed files with 10536 additions and 1103 deletions

7
.gitignore vendored
View File

@ -21,6 +21,7 @@ revision.h
contrib/zlib/zconf.h contrib/zlib/zconf.h
contrib/zlib/zlib.pc contrib/zlib/zlib.pc
include/assimp/config.h include/assimp/config.h
unit.vcxproj.user
# CMake # CMake
CMakeCache.txt CMakeCache.txt
@ -87,3 +88,9 @@ lib64/assimp-vc120-mt.exp
xcuserdata xcuserdata
cmake-build-debug cmake-build-debug
install_manifest.txt
tools/assimp_qt_viewer/moc_glview.cpp
tools/assimp_qt_viewer/moc_glview.cpp_parameters
tools/assimp_qt_viewer/moc_mainwindow.cpp
tools/assimp_qt_viewer/moc_mainwindow.cpp_parameters
tools/assimp_qt_viewer/ui_mainwindow.h

View File

@ -39,10 +39,12 @@ CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
PROJECT( Assimp ) PROJECT( Assimp )
# All supported options ############################################### # All supported options ###############################################
OPTION( BUILD_SHARED_LIBS OPTION( BUILD_SHARED_LIBS
"Build package with shared libraries." "Build package with shared libraries."
ON ON
) )
OPTION( BUILD_FRAMEWORK OPTION( BUILD_FRAMEWORK
"Build package as Mac OS X Framework bundle." "Build package as Mac OS X Framework bundle."
OFF OFF
@ -103,6 +105,16 @@ OPTION ( BUILD_DOCS
"Build documentation using Doxygen." "Build documentation using Doxygen."
OFF OFF
) )
OPTION( INJECT_DEBUG_POSTFIX
"Inject debug postfix in .a/.so lib names"
ON
)
IF (IOS)
IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE "Release")
ENDIF (NOT CMAKE_BUILD_TYPE)
ENDIF (IOS)
# Use subset of Windows.h # Use subset of Windows.h
if (WIN32) if (WIN32)
@ -204,7 +216,7 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
ELSEIF(MSVC) ELSEIF(MSVC)
# enable multi-core compilation with MSVC # enable multi-core compilation with MSVC
ADD_COMPILE_OPTIONS(/MP) ADD_COMPILE_OPTIONS(/MP)
IF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)") if(CMAKE_SIZEOF_VOID_P EQUAL 8)
ADD_COMPILE_OPTIONS( /bigobj ) ADD_COMPILE_OPTIONS( /bigobj )
ENDIF() ENDIF()
# disable "elements of array '' will be default initialized" warning on MSVC2013 # disable "elements of array '' will be default initialized" warning on MSVC2013
@ -215,16 +227,23 @@ ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" ) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
ELSEIF( CMAKE_COMPILER_IS_MINGW ) ELSEIF( CMAKE_COMPILER_IS_MINGW )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" ) SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11 -Wa,-mbig-obj" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC ")
ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF() ENDIF()
IF (IOS) IF ( IOS )
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
ELSE()
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
ENDIF() ENDIF()
ENDIF( IOS )
IF (ASSIMP_COVERALLS) IF (ASSIMP_COVERALLS)
MESSAGE(STATUS "Coveralls enabled") MESSAGE(STATUS "Coveralls enabled")
INCLUDE(Coveralls) INCLUDE(Coveralls)
@ -329,9 +348,17 @@ ENDIF(NOT ZLIB_FOUND)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR}) INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
# Search for unzip # Search for unzip
IF( NOT ASSIMP_BUILD_MINIZIP ) IF ( NOT IOS )
IF( NOT ASSIMP_BUILD_MINIZIP )
use_pkgconfig(UNZIP minizip) use_pkgconfig(UNZIP minizip)
ENDIF( NOT ASSIMP_BUILD_MINIZIP ) ENDIF( NOT ASSIMP_BUILD_MINIZIP )
ELSE ( NOT IOS )
IF(NOT BUILD_SHARED_LIBS)
IF( NOT ASSIMP_BUILD_MINIZIP )
use_pkgconfig(UNZIP minizip)
ENDIF( NOT ASSIMP_BUILD_MINIZIP )
ENDIF (NOT BUILD_SHARED_LIBS)
ENDIF ( NOT IOS )
IF ( ASSIMP_NO_EXPORT ) IF ( ASSIMP_NO_EXPORT )
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT) ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT)
@ -416,7 +443,9 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY ) ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
ADD_SUBDIRECTORY( tools/assimp_cmd/ ) ADD_SUBDIRECTORY( tools/assimp_cmd/ )
IF (NOT IOS)
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ ) ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
ENDIF (NOT IOS)
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS ) ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
IF ( ASSIMP_BUILD_SAMPLES) IF ( ASSIMP_BUILD_SAMPLES)

View File

@ -30,6 +30,8 @@ One-off donations via PayPal:
Please check our Wiki as well: https://github.com/assimp/assimp/wiki Please check our Wiki as well: https://github.com/assimp/assimp/wiki
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
#### Supported file formats #### #### Supported file formats ####
__Importers__: __Importers__:

View File

@ -272,6 +272,8 @@ void aiReleaseImport( const aiScene* pScene)
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
// find the importer associated with this data // find the importer associated with this data
const ScenePrivateData* priv = ScenePriv(pScene); const ScenePrivateData* priv = ScenePriv(pScene);
if( !priv || !priv->mOrigImporter) { if( !priv || !priv->mOrigImporter) {

View File

@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <map>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
@ -461,6 +462,13 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
aiNodeAnim* nodeAnim = new aiNodeAnim; aiNodeAnim* nodeAnim = new aiNodeAnim;
anim->mChannels[a] = nodeAnim; anim->mChannels[a] = nodeAnim;
nodeAnim->mNodeName.Set( nodeName); nodeAnim->mNodeName.Set( nodeName);
std::map<BVHLoader::ChannelType, int> channelMap;
//Build map of channels
for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel)
{
channelMap[node.mChannels[channel]] = channel;
}
// translational part, if given // translational part, if given
if( node.mChannels.size() == 6) if( node.mChannels.size() == 6)
@ -472,15 +480,31 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{ {
poskey->mTime = double( fr); poskey->mTime = double( fr);
// Now compute all translations in the right order // Now compute all translations
for( unsigned int channel = 0; channel < 3; ++channel) for(BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel +1))
{ {
switch( node.mChannels[channel]) //Find channel in node
{ std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break; if (mapIter == channelMap.end())
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break; throw DeadlyImportError("Missing position channel in node " + nodeName);
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName ); else {
int channelIdx = mapIter->second;
switch (channel) {
case Channel_PositionX:
poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
case Channel_PositionY:
poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
case Channel_PositionZ:
poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channelIdx];
break;
default:
break;
}
} }
} }
++poskey; ++poskey;
@ -497,12 +521,6 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
// rotation part. Always present. First find value offsets // rotation part. Always present. First find value offsets
{ {
unsigned int rotOffset = 0;
if( node.mChannels.size() == 6)
{
// Offset all further calculations
rotOffset = 3;
}
// Then create the number of rotation keys // Then create the number of rotation keys
nodeAnim->mNumRotationKeys = mAnimNumFrames; nodeAnim->mNumRotationKeys = mAnimNumFrames;
@ -512,19 +530,32 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{ {
aiMatrix4x4 temp; aiMatrix4x4 temp;
aiMatrix3x3 rotMatrix; aiMatrix3x3 rotMatrix;
for (BVHLoader::ChannelType channel = Channel_RotationX; channel <= Channel_RotationZ; channel = (BVHLoader::ChannelType)(channel + 1))
for( unsigned int channel = 0; channel < 3; ++channel)
{ {
//Find channel in node
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
if (mapIter == channelMap.end())
throw DeadlyImportError("Missing rotation channel in node " + nodeName);
else {
int channelIdx = mapIter->second;
// translate ZXY euler angels into a quaternion // translate ZXY euler angels into a quaternion
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f; const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
// Compute rotation transformations in the right order // Compute rotation transformations in the right order
switch (node.mChannels[rotOffset+channel]) switch (channel)
{ {
case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; case Channel_RotationX:
case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp);
case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break; break;
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName ); case Channel_RotationY:
aiMatrix4x4::RotationY(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
case Channel_RotationZ: aiMatrix4x4::RotationZ(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
default:
break;
}
} }
} }

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <assimp/BaseImporter.h> #include <assimp/BaseImporter.h>
#include <assimp/ParsingUtils.h>
#include "FileSystemFilter.h" #include "FileSystemFilter.h"
#include "Importer.h" #include "Importer.h"
#include <assimp/ByteSwapper.h> #include <assimp/ByteSwapper.h>
@ -53,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <ios> #include <ios>
#include <list> #include <list>
#include <memory> #include <memory>
@ -158,15 +160,14 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
if (pStream.get() ) { if (pStream.get() ) {
// read 200 characters from the file // read 200 characters from the file
std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]); std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
char* buffer = _buffer.get(); char *buffer( _buffer.get() );
const size_t read( pStream->Read(buffer,1,searchBytes) );
const size_t read = pStream->Read(buffer,1,searchBytes); if( 0 == read ) {
if( !read ) {
return false; return false;
} }
for( size_t i = 0; i < read; ++i ) { for( size_t i = 0; i < read; ++i ) {
buffer[ i ] = ::tolower( buffer[ i ] ); buffer[ i ] = static_cast<char>( ::tolower( buffer[ i ] ) );
} }
// It is not a proper handling of unicode files here ... // It is not a proper handling of unicode files here ...
@ -187,7 +188,7 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
token.clear(); token.clear();
const char *ptr( tokens[ i ] ); const char *ptr( tokens[ i ] );
for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) { for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) {
token.push_back( tolower( *ptr ) ); token.push_back( static_cast<char>( tolower( *ptr ) ) );
++ptr; ++ptr;
} }
const char* r = strstr( buffer, token.c_str() ); const char* r = strstr( buffer, token.c_str() );
@ -240,16 +241,19 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get file extension from path // Get file extension from path
/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile) std::string BaseImporter::GetExtension( const std::string& file ) {
{ std::string::size_type pos = file.find_last_of('.');
std::string::size_type pos = pFile.find_last_of('.');
// no file extension at all // no file extension at all
if( pos == std::string::npos) if (pos == std::string::npos) {
return ""; return "";
}
// thanks to Andy Maloney for the hint
std::string ret = file.substr( pos + 1 );
std::transform( ret.begin(), ret.end(), ret.begin(), ToLower<char>);
std::string ret = pFile.substr(pos+1);
std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
return ret; return ret;
} }

View File

@ -911,6 +911,12 @@ ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
ADD_LIBRARY( assimp ${assimp_src} ) ADD_LIBRARY( assimp ${assimp_src} )
TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
)
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} ${IRRXML_LIBRARY} ) TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} ${IRRXML_LIBRARY} )
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM) if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)

View File

@ -59,6 +59,25 @@ using namespace Assimp;
#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS #ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
namespace {
template <typename aiMeshType>
void flipUVs(aiMeshType* pMesh) {
if (pMesh == nullptr) { return; }
// mirror texture y coordinate
for (unsigned int tcIdx = 0; tcIdx < AI_MAX_NUMBER_OF_TEXTURECOORDS; tcIdx++) {
if (!pMesh->HasTextureCoords(tcIdx)) {
break;
}
for (unsigned int vIdx = 0; vIdx < pMesh->mNumVertices; vIdx++) {
pMesh->mTextureCoords[tcIdx][vIdx].y = 1.0f - pMesh->mTextureCoords[tcIdx][vIdx].y;
}
}
}
} // namespace
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MakeLeftHandedProcess::MakeLeftHandedProcess() MakeLeftHandedProcess::MakeLeftHandedProcess()
@ -282,15 +301,9 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
// Converts a single mesh // Converts a single mesh
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh) void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
{ {
// mirror texture y coordinate flipUVs(pMesh);
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { for (unsigned int idx = 0; idx < pMesh->mNumAnimMeshes; idx++) {
if( !pMesh->HasTextureCoords( a ) ) { flipUVs(pMesh->mAnimMeshes[idx]);
break;
}
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
}
} }
} }

View File

@ -73,11 +73,7 @@ using namespace Util;
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
// XXX vc9's debugger won't step into anonymous namespaces FBXConverter::FBXConverter( aiScene* out, const Document& doc )
//namespace {
Converter::Converter( aiScene* out, const Document& doc )
: defaultMaterialIndex() : defaultMaterialIndex()
, out( out ) , out( out )
, doc( doc ) { , doc( doc ) {
@ -118,7 +114,7 @@ Converter::Converter( aiScene* out, const Document& doc )
} }
Converter::~Converter() { FBXConverter::~FBXConverter() {
std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() ); std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() );
std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() ); std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() );
std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() ); std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() );
@ -127,7 +123,7 @@ Converter::~Converter() {
std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() ); std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() );
} }
void Converter::ConvertRootNode() { void FBXConverter::ConvertRootNode() {
out->mRootNode = new aiNode(); out->mRootNode = new aiNode();
out->mRootNode->mName.Set( "RootNode" ); out->mRootNode->mName.Set( "RootNode" );
@ -135,7 +131,7 @@ void Converter::ConvertRootNode() {
ConvertNodes( 0L, *out->mRootNode ); ConvertNodes( 0L, *out->mRootNode );
} }
void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) { void FBXConverter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" ); const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" );
std::vector<aiNode*> nodes; std::vector<aiNode*> nodes;
@ -189,12 +185,12 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
} }
if ( !name_carrier ) { if ( !name_carrier ) {
NodeNameCache::const_iterator it( std::find( mNodeNames.begin(), mNodeNames.end(), original_name ) ); NodeNameCache::const_iterator it = mNodeNames.find(original_name);
if ( it != mNodeNames.end() ) { if ( it != mNodeNames.end() ) {
original_name = original_name + std::string( "001" ); original_name = original_name + std::string( "001" );
} }
mNodeNames.push_back( original_name ); mNodeNames.insert( original_name );
nodes_chain.push_back( new aiNode( original_name ) ); nodes_chain.push_back( new aiNode( original_name ) );
} else { } else {
original_name = nodes_chain.back()->mName.C_Str(); original_name = nodes_chain.back()->mName.C_Str();
@ -286,7 +282,7 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
} }
void Converter::ConvertLights( const Model& model, const std::string &orig_name ) { void FBXConverter::ConvertLights( const Model& model, const std::string &orig_name ) {
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
for( const NodeAttribute* attr : node_attrs ) { for( const NodeAttribute* attr : node_attrs ) {
const Light* const light = dynamic_cast<const Light*>( attr ); const Light* const light = dynamic_cast<const Light*>( attr );
@ -296,7 +292,7 @@ void Converter::ConvertLights( const Model& model, const std::string &orig_name
} }
} }
void Converter::ConvertCameras( const Model& model, const std::string &orig_name ) { void FBXConverter::ConvertCameras( const Model& model, const std::string &orig_name ) {
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
for( const NodeAttribute* attr : node_attrs ) { for( const NodeAttribute* attr : node_attrs ) {
const Camera* const cam = dynamic_cast<const Camera*>( attr ); const Camera* const cam = dynamic_cast<const Camera*>( attr );
@ -306,7 +302,7 @@ void Converter::ConvertCameras( const Model& model, const std::string &orig_name
} }
} }
void Converter::ConvertLight( const Light& light, const std::string &orig_name ) { void FBXConverter::ConvertLight( const Light& light, const std::string &orig_name ) {
lights.push_back( new aiLight() ); lights.push_back( new aiLight() );
aiLight* const out_light = lights.back(); aiLight* const out_light = lights.back();
@ -383,7 +379,7 @@ void Converter::ConvertLight( const Light& light, const std::string &orig_name )
} }
} }
void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name ) void FBXConverter::ConvertCamera( const Camera& cam, const std::string &orig_name )
{ {
cameras.push_back( new aiCamera() ); cameras.push_back( new aiCamera() );
aiCamera* const out_camera = cameras.back(); aiCamera* const out_camera = cameras.back();
@ -402,36 +398,23 @@ void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name )
out_camera->mClipPlaneFar = cam.FarPlane(); out_camera->mClipPlaneFar = cam.FarPlane();
} }
static bool HasName( NodeNameCache &cache, const std::string &name ) { void FBXConverter::GetUniqueName( const std::string &name, std::string &uniqueName )
NodeNameCache::const_iterator it( std::find( cache.begin(), cache.end(), name ) );
return it != cache.end();
}
void Converter::GetUniqueName( const std::string &name, std::string uniqueName ) {
if ( !HasName( mNodeNames, name ) ) {
uniqueName = name;
return;
}
int i( 0 );
std::string newName;
while ( HasName( mNodeNames, newName ) ) {
++i;
newName.clear();
newName += name;
std::stringstream ext;
ext << std::setfill( '0' ) << std::setw( 3 ) << i;
newName += ext.str();
}
uniqueName = newName;
mNodeNames.push_back( uniqueName );
}
const char* Converter::NameTransformationComp( TransformationComp comp )
{ {
switch ( comp ) int i = 0;
uniqueName = name;
while (mNodeNames.find(uniqueName) != mNodeNames.end())
{ {
++i;
std::stringstream ext;
ext << name << std::setfill('0') << std::setw(3) << i;
uniqueName = ext.str();
}
mNodeNames.insert(uniqueName);
}
const char* FBXConverter::NameTransformationComp( TransformationComp comp ) {
switch ( comp ) {
case TransformationComp_Translation: case TransformationComp_Translation:
return "Translation"; return "Translation";
case TransformationComp_RotationOffset: case TransformationComp_RotationOffset:
@ -472,13 +455,12 @@ const char* Converter::NameTransformationComp( TransformationComp comp )
} }
ai_assert( false ); ai_assert( false );
return NULL;
return nullptr;
} }
const char* Converter::NameTransformationCompProperty( TransformationComp comp ) const char* FBXConverter::NameTransformationCompProperty( TransformationComp comp ) {
{ switch ( comp ) {
switch ( comp )
{
case TransformationComp_Translation: case TransformationComp_Translation:
return "Lcl Translation"; return "Lcl Translation";
case TransformationComp_RotationOffset: case TransformationComp_RotationOffset:
@ -518,17 +500,18 @@ const char* Converter::NameTransformationCompProperty( TransformationComp comp )
} }
ai_assert( false ); ai_assert( false );
return NULL;
return nullptr;
} }
aiVector3D Converter::TransformationCompDefaultValue( TransformationComp comp ) aiVector3D FBXConverter::TransformationCompDefaultValue( TransformationComp comp )
{ {
// XXX a neat way to solve the never-ending special cases for scaling // XXX a neat way to solve the never-ending special cases for scaling
// would be to do everything in log space! // would be to do everything in log space!
return comp == TransformationComp_Scaling ? aiVector3D( 1.f, 1.f, 1.f ) : aiVector3D(); return comp == TransformationComp_Scaling ? aiVector3D( 1.f, 1.f, 1.f ) : aiVector3D();
} }
void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out ) void FBXConverter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out )
{ {
if ( mode == Model::RotOrder_SphericXYZ ) { if ( mode == Model::RotOrder_SphericXYZ ) {
FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" ); FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" );
@ -599,11 +582,15 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
default: default:
ai_assert( false ); ai_assert( false );
break;
} }
ai_assert( ( order[ 0 ] >= 0 ) && ( order[ 0 ] <= 2 ) ); ai_assert( order[ 0 ] >= 0 );
ai_assert( ( order[ 1 ] >= 0 ) && ( order[ 1 ] <= 2 ) ); ai_assert( order[ 0 ] <= 2 );
ai_assert( ( order[ 2 ] >= 0 ) && ( order[ 2 ] <= 2 ) ); ai_assert( order[ 1 ] >= 0 );
ai_assert( order[ 1 ] <= 2 );
ai_assert( order[ 2 ] >= 0 );
ai_assert( order[ 2 ] <= 2 );
if ( !is_id[ order[ 0 ] ] ) { if ( !is_id[ order[ 0 ] ] ) {
out = temp[ order[ 0 ] ]; out = temp[ order[ 0 ] ];
@ -618,7 +605,7 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
} }
} }
bool Converter::NeedsComplexTransformationChain( const Model& model ) bool FBXConverter::NeedsComplexTransformationChain( const Model& model )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
bool ok; bool ok;
@ -649,13 +636,13 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
return false; return false;
} }
std::string Converter::NameTransformationChainNode( const std::string& name, TransformationComp comp ) std::string FBXConverter::NameTransformationChainNode( const std::string& name, TransformationComp comp )
{ {
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp ); return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
} }
void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes ) void FBXConverter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes,
{ std::vector<aiNode*>& post_output_nodes ) {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
const Model::RotOrder rot = model.RotationOrder(); const Model::RotOrder rot = model.RotationOrder();
@ -826,7 +813,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
} }
} }
void Converter::SetupNodeMetadata( const Model& model, aiNode& nd ) void FBXConverter::SetupNodeMetadata( const Model& model, aiNode& nd )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties(); DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
@ -863,7 +850,7 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
} }
} }
void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform ) void FBXConverter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform )
{ {
const std::vector<const Geometry*>& geos = model.GetGeometry(); const std::vector<const Geometry*>& geos = model.GetGeometry();
@ -890,7 +877,7 @@ void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4&
} }
} }
std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> FBXConverter::ConvertMesh( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
std::vector<unsigned int> temp; std::vector<unsigned int> temp;
@ -925,7 +912,7 @@ std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, cons
return temp; return temp;
} }
aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd) aiMesh* FBXConverter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
{ {
aiMesh* const out_mesh = new aiMesh(); aiMesh* const out_mesh = new aiMesh();
meshes.push_back( out_mesh ); meshes.push_back( out_mesh );
@ -948,7 +935,7 @@ aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
return out_mesh; return out_mesh;
} }
unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model, unsigned int FBXConverter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
@ -1075,7 +1062,7 @@ unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, con
return static_cast<unsigned int>( meshes.size() - 1 ); return static_cast<unsigned int>( meshes.size() - 1 );
} }
std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
@ -1095,7 +1082,7 @@ std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometr
return indices; return indices;
} }
unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model, unsigned int FBXConverter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
MatIndexArray::value_type index, MatIndexArray::value_type index,
const aiMatrix4x4& node_global_transform, const aiMatrix4x4& node_global_transform,
aiNode& nd) aiNode& nd)
@ -1271,7 +1258,7 @@ unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, cons
return static_cast<unsigned int>( meshes.size() - 1 ); return static_cast<unsigned int>( meshes.size() - 1 );
} }
void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo, void FBXConverter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
const aiMatrix4x4& node_global_transform , const aiMatrix4x4& node_global_transform ,
unsigned int materialIndex, unsigned int materialIndex,
std::vector<unsigned int>* outputVertStartIndices ) std::vector<unsigned int>* outputVertStartIndices )
@ -1376,7 +1363,7 @@ void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeome
std::swap_ranges( bones.begin(), bones.end(), out->mBones ); std::swap_ranges( bones.begin(), bones.end(), out->mBones );
} }
void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl, void FBXConverter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
std::vector<size_t>& out_indices, std::vector<size_t>& out_indices,
std::vector<size_t>& index_out_indices, std::vector<size_t>& index_out_indices,
std::vector<size_t>& count_out_indices, std::vector<size_t>& count_out_indices,
@ -1417,7 +1404,7 @@ void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*mode
} }
} }
void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo, void FBXConverter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
MatIndexArray::value_type materialIndex ) MatIndexArray::value_type materialIndex )
{ {
// locate source materials for this mesh // locate source materials for this mesh
@ -1439,7 +1426,7 @@ void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const M
materials_converted[ mat ] = out->mMaterialIndex; materials_converted[ mat ] = out->mMaterialIndex;
} }
unsigned int Converter::GetDefaultMaterial() unsigned int FBXConverter::GetDefaultMaterial()
{ {
if ( defaultMaterialIndex ) { if ( defaultMaterialIndex ) {
return defaultMaterialIndex - 1; return defaultMaterialIndex - 1;
@ -1461,7 +1448,7 @@ unsigned int Converter::GetDefaultMaterial()
} }
unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh ) unsigned int FBXConverter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh )
{ {
const PropertyTable& props = material.Props(); const PropertyTable& props = material.Props();
@ -1496,7 +1483,7 @@ unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeo
return static_cast<unsigned int>( materials.size() - 1 ); return static_cast<unsigned int>( materials.size() - 1 );
} }
unsigned int Converter::ConvertVideo( const Video& video ) unsigned int FBXConverter::ConvertVideo( const Video& video )
{ {
// generate empty output texture // generate empty output texture
aiTexture* out_tex = new aiTexture(); aiTexture* out_tex = new aiTexture();
@ -1526,7 +1513,7 @@ unsigned int Converter::ConvertVideo( const Video& video )
return static_cast<unsigned int>( textures.size() - 1 ); return static_cast<unsigned int>( textures.size() - 1 );
} }
aiString Converter::GetTexturePath(const Texture* tex) aiString FBXConverter::GetTexturePath(const Texture* tex)
{ {
aiString path; aiString path;
path.Set(tex->RelativeFilename()); path.Set(tex->RelativeFilename());
@ -1566,7 +1553,7 @@ aiString Converter::GetTexturePath(const Texture* tex)
return path; return path;
} }
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
const std::string& propName, const std::string& propName,
aiTextureType target, const MeshGeometry* const mesh ) aiTextureType target, const MeshGeometry* const mesh )
{ {
@ -1684,7 +1671,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
} }
} }
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
const std::string& propName, const std::string& propName,
aiTextureType target, const MeshGeometry* const mesh ) { aiTextureType target, const MeshGeometry* const mesh ) {
LayeredTextureMap::const_iterator it = layeredTextures.find( propName ); LayeredTextureMap::const_iterator it = layeredTextures.find( propName );
@ -1807,7 +1794,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextu
} }
} }
void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh ) void FBXConverter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh )
{ {
TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh ); TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh ); TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh );
@ -1822,7 +1809,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& tex
TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh ); TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh );
} }
void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh ) void FBXConverter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh )
{ {
TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh );
@ -1837,7 +1824,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureM
TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh );
} }
aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName, aiColor3D FBXConverter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName,
const std::string& factorName, bool& result, bool useTemplate ) const std::string& factorName, bool& result, bool useTemplate )
{ {
result = true; result = true;
@ -1862,13 +1849,13 @@ aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const
return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z ); return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z );
} }
aiColor3D Converter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName, aiColor3D FBXConverter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
bool& result ) bool& result )
{ {
return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true ); return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true );
} }
aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::string& colorName, aiColor3D FBXConverter::GetColorProperty( const PropertyTable& props, const std::string& colorName,
bool& result, bool useTemplate ) bool& result, bool useTemplate )
{ {
result = true; result = true;
@ -1881,7 +1868,7 @@ aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::st
return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z ); return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z );
} }
void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props ) void FBXConverter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props )
{ {
// Set shading properties. // Set shading properties.
// Modern FBX Files have two separate systems for defining these, // Modern FBX Files have two separate systems for defining these,
@ -1980,8 +1967,7 @@ void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyT
} }
double Converter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal ) double FBXConverter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal ) {
{
switch ( fp ) { switch ( fp ) {
case FileGlobalSettings::FrameRate_DEFAULT: case FileGlobalSettings::FrameRate_DEFAULT:
return 1.0; return 1.0;
@ -2029,11 +2015,12 @@ double Converter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double cu
} }
ai_assert( false ); ai_assert( false );
return -1.0f; return -1.0f;
} }
void Converter::ConvertAnimations() void FBXConverter::ConvertAnimations()
{ {
// first of all determine framerate // first of all determine framerate
const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode(); const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode();
@ -2046,7 +2033,7 @@ void Converter::ConvertAnimations()
} }
} }
std::string Converter::FixNodeName( const std::string& name ) { std::string FBXConverter::FixNodeName( const std::string& name ) {
// strip Model:: prefix, avoiding ambiguities (i.e. don't strip if // strip Model:: prefix, avoiding ambiguities (i.e. don't strip if
// this causes ambiguities, well possible between empty identifiers, // this causes ambiguities, well possible between empty identifiers,
// such as "Model::" and ""). Make sure the behaviour is consistent // such as "Model::" and ""). Make sure the behaviour is consistent
@ -2059,7 +2046,7 @@ std::string Converter::FixNodeName( const std::string& name ) {
return name; return name;
} }
void Converter::ConvertAnimationStack( const AnimationStack& st ) void FBXConverter::ConvertAnimationStack( const AnimationStack& st )
{ {
const AnimationLayerList& layers = st.Layers(); const AnimationLayerList& layers = st.Layers();
if ( layers.empty() ) { if ( layers.empty() ) {
@ -2201,7 +2188,7 @@ static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>
#endif // ASSIMP_BUILD_DEBUG #endif // ASSIMP_BUILD_DEBUG
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims, void FBXConverter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
const std::string& fixed_name, const std::string& fixed_name,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2435,10 +2422,9 @@ void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
node_anim_chain_bits[ fixed_name ] = flags; node_anim_chain_bits[ fixed_name ] = flags;
} }
bool Converter::IsRedundantAnimationData( const Model& target, bool FBXConverter::IsRedundantAnimationData( const Model& target,
TransformationComp comp, TransformationComp comp,
const std::vector<const AnimationCurveNode*>& curves ) const std::vector<const AnimationCurveNode*>& curves ) {
{
ai_assert( curves.size() ); ai_assert( curves.size() );
// look for animation nodes with // look for animation nodes with
@ -2481,7 +2467,7 @@ bool Converter::IsRedundantAnimationData( const Model& target,
} }
aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateRotationNodeAnim( const std::string& name,
const Model& target, const Model& target,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2511,7 +2497,7 @@ aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateScalingNodeAnim( const std::string& name,
const Model& /*target*/, const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2541,16 +2527,14 @@ aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* FBXConverter::GenerateTranslationNodeAnim( const std::string& name,
aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
const Model& /*target*/, const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& max_time, double& max_time,
double& min_time, double& min_time,
bool inverse ) bool inverse ) {
{
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() ); std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
na->mNodeName.Set( name ); na->mNodeName.Set( name );
@ -2579,7 +2563,7 @@ aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim( const std::string& name,
const Model& target, const Model& target,
NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ], NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
NodeMap::const_iterator iter_end, NodeMap::const_iterator iter_end,
@ -2715,7 +2699,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop ) FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop )
{ {
KeyFrameListList inputs; KeyFrameListList inputs;
inputs.reserve( nodes.size() * 3 ); inputs.reserve( nodes.size() * 3 );
@ -2771,12 +2755,11 @@ Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const
} }
KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs ) KeyTimeList FBXConverter::GetKeyTimeList( const KeyFrameListList& inputs ) {
{ ai_assert( !inputs.empty() );
ai_assert( inputs.size() );
// reserve some space upfront - it is likely that the keyframe lists // reserve some space upfront - it is likely that the key-frame lists
// have matching time values, so max(of all keyframe lists) should // have matching time values, so max(of all key-frame lists) should
// be a good estimate. // be a good estimate.
KeyTimeList keys; KeyTimeList keys;
@ -2820,17 +2803,15 @@ KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs )
return keys; return keys;
} }
void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, void FBXConverter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
const aiVector3D& def_value, const aiVector3D& def_value,
double& max_time, double& max_time,
double& min_time ) double& min_time ) {
ai_assert( !keys.empty() );
{ ai_assert( nullptr != valOut );
ai_assert( keys.size() );
ai_assert( valOut );
std::vector<unsigned int> next_pos; std::vector<unsigned int> next_pos;
const size_t count = inputs.size(); const size_t count( inputs.size() );
next_pos.resize( inputs.size(), 0 ); next_pos.resize( inputs.size(), 0 );
@ -2841,6 +2822,9 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
const KeyFrameList& kfl = inputs[ i ]; const KeyFrameList& kfl = inputs[ i ];
const size_t ksize = std::get<0>(kfl)->size(); const size_t ksize = std::get<0>(kfl)->size();
if (ksize == 0) {
continue;
}
if ( ksize > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == time ) { if ( ksize > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == time ) {
++next_pos[ i ]; ++next_pos[ i ];
} }
@ -2875,14 +2859,14 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
} }
} }
void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, void FBXConverter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
const aiVector3D& def_value, const aiVector3D& def_value,
double& maxTime, double& maxTime,
double& minTime, double& minTime,
Model::RotOrder order ) Model::RotOrder order )
{ {
ai_assert( keys.size() ); ai_assert( !keys.empty() );
ai_assert( valOut ); ai_assert( nullptr != valOut );
std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] ); std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] );
InterpolateKeys( temp.get(), keys, inputs, def_value, maxTime, minTime ); InterpolateKeys( temp.get(), keys, inputs, def_value, maxTime, minTime );
@ -2913,7 +2897,7 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
} }
} }
void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale, void FBXConverter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
aiVectorKey* out_translation, aiVectorKey* out_translation,
const KeyFrameListList& scaling, const KeyFrameListList& scaling,
const KeyFrameListList& translation, const KeyFrameListList& translation,
@ -2971,7 +2955,7 @@ void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey
} }
} }
aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order ) aiQuaternion FBXConverter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
{ {
aiMatrix4x4 m; aiMatrix4x4 m;
GetRotationMatrix( order, rot, m ); GetRotationMatrix( order, rot, m );
@ -2979,7 +2963,7 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde
return aiQuaternion( aiMatrix3x3( m ) ); return aiQuaternion( aiMatrix3x3( m ) );
} }
void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/, void FBXConverter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
double& minTime ) double& minTime )
@ -2999,7 +2983,7 @@ void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const Animat
InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime ); InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
} }
void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, void FBXConverter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& /*layers*/, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
@ -3017,7 +3001,7 @@ void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const
InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime ); InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
} }
void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, void FBXConverter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& /*layers*/, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
@ -3037,7 +3021,7 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
} }
} }
void Converter::ConvertGlobalSettings() { void FBXConverter::ConvertGlobalSettings() {
if (nullptr == out) { if (nullptr == out) {
return; return;
} }
@ -3048,7 +3032,7 @@ void Converter::ConvertGlobalSettings() {
out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor); out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor);
} }
void Converter::TransferDataToScene() void FBXConverter::TransferDataToScene()
{ {
ai_assert( !out->mMeshes ); ai_assert( !out->mMeshes );
ai_assert( !out->mNumMeshes ); ai_assert( !out->mNumMeshes );
@ -3100,12 +3084,10 @@ void Converter::TransferDataToScene()
} }
} }
//} // !anon
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc) void ConvertToAssimpScene(aiScene* out, const Document& doc)
{ {
Converter converter(out,doc); FBXConverter converter(out,doc);
} }
} // !FBX } // !FBX

View File

@ -68,7 +68,7 @@ namespace FBX {
class Document; class Document;
using NodeNameCache = std::vector<std::string>; using NodeNameCache = std::set<std::string>;
/** /**
* Convert a FBX #Document to #aiScene * Convert a FBX #Document to #aiScene
@ -78,7 +78,7 @@ using NodeNameCache = std::vector<std::string>;
void ConvertToAssimpScene(aiScene* out, const Document& doc); void ConvertToAssimpScene(aiScene* out, const Document& doc);
/** Dummy class to encapsulate the conversion process */ /** Dummy class to encapsulate the conversion process */
class Converter { class FBXConverter {
public: public:
/** /**
* The different parts that make up the final local transformation of a fbx-node * The different parts that make up the final local transformation of a fbx-node
@ -106,8 +106,8 @@ public:
}; };
public: public:
Converter(aiScene* out, const Document& doc); FBXConverter(aiScene* out, const Document& doc);
~Converter(); ~FBXConverter();
private: private:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -131,7 +131,7 @@ private:
void ConvertCamera( const Camera& cam, const std::string &orig_name ); void ConvertCamera( const Camera& cam, const std::string &orig_name );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void GetUniqueName( const std::string &name, std::string uniqueName ); void GetUniqueName( const std::string &name, std::string& uniqueName );
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// this returns unified names usable within assimp identifiers (i.e. no space characters - // this returns unified names usable within assimp identifiers (i.e. no space characters -

View File

@ -67,7 +67,7 @@ public:
FileSystemFilter(const std::string& file, IOSystem* old) FileSystemFilter(const std::string& file, IOSystem* old)
: mWrapped (old) : mWrapped (old)
, mSrc_file(file) , mSrc_file(file)
, sep(mWrapped->getOsSeparator()) { , mSep(mWrapped->getOsSeparator()) {
ai_assert(nullptr != mWrapped); ai_assert(nullptr != mWrapped);
// Determine base directory // Determine base directory
@ -116,7 +116,7 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns the directory separator. */ /** Returns the directory separator. */
char getOsSeparator() const { char getOsSeparator() const {
return sep; return mSep;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -256,7 +256,7 @@ private:
while(true) { while(true) {
tmp = mBase; tmp = mBase;
tmp += sep; tmp += mSep;
std::string::size_type dirsep = in.rfind('/', last_dirsep); std::string::size_type dirsep = in.rfind('/', last_dirsep);
if (std::string::npos == dirsep) { if (std::string::npos == dirsep) {
@ -298,7 +298,7 @@ private:
in.erase(in.begin(),it+1); in.erase(in.begin(),it+1);
} }
const char sep = getOsSeparator(); const char separator = getOsSeparator();
for (it = in.begin(); it != in.end(); ++it) { for (it = in.begin(); it != in.end(); ++it) {
// Exclude :// and \\, which remain untouched. // Exclude :// and \\, which remain untouched.
// https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632 // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
@ -313,7 +313,7 @@ private:
// Cleanup path delimiters // Cleanup path delimiters
if (*it == '/' || (*it) == '\\') { if (*it == '/' || (*it) == '\\') {
*it = sep; *it = separator;
// And we're removing double delimiters, frequent issue with // And we're removing double delimiters, frequent issue with
// incorrectly composited paths ... // incorrectly composited paths ...
@ -337,7 +337,7 @@ private:
private: private:
IOSystem *mWrapped; IOSystem *mWrapped;
std::string mSrc_file, mBase; std::string mSrc_file, mBase;
char sep; char mSep;
}; };
} //!ns Assimp } //!ns Assimp

View File

@ -178,6 +178,7 @@ Importer::~Importer()
{ {
// Delete all import plugins // Delete all import plugins
DeleteImporterInstanceList(pimpl->mImporter); DeleteImporterInstanceList(pimpl->mImporter);
aiReleaseDefaultMaterial();
// Delete all post-processing plug-ins // Delete all post-processing plug-ins
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
@ -383,6 +384,8 @@ bool _ValidateFlags(unsigned int pFlags)
void Importer::FreeScene( ) void Importer::FreeScene( )
{ {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
delete pimpl->mScene; delete pimpl->mScene;
pimpl->mScene = NULL; pimpl->mScene = NULL;
@ -490,9 +493,9 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength)); SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
// read the file and recover the previous IOSystem // read the file and recover the previous IOSystem
static const size_t BufferSize(Importer::MaxLenHint + 28); static const size_t BufSize(Importer::MaxLenHint + 28);
char fbuff[ BufferSize ]; char fbuff[BufSize];
ai_snprintf(fbuff, BufferSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint); ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
ReadFile(fbuff,pFlags); ReadFile(fbuff,pFlags);
SetIOHandler(io); SetIOHandler(io);
@ -930,20 +933,19 @@ BaseImporter* Importer::GetImporter (const char* szExtension) const
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Find a loader plugin for a given file extension // Find a loader plugin for a given file extension
size_t Importer::GetImporterIndex (const char* szExtension) const size_t Importer::GetImporterIndex (const char* szExtension) const {
{ ai_assert(nullptr != szExtension);
ai_assert(szExtension);
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
// skip over wildcard and dot characters at string head -- // skip over wildcard and dot characters at string head --
for(;*szExtension == '*' || *szExtension == '.'; ++szExtension); for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension );
std::string ext(szExtension); std::string ext(szExtension);
if (ext.empty()) { if (ext.empty()) {
return static_cast<size_t>(-1); return static_cast<size_t>(-1);
} }
std::transform(ext.begin(),ext.end(), ext.begin(), tolower); std::transform( ext.begin(), ext.end(), ext.begin(), ToLower<char> );
std::set<std::string> str; std::set<std::string> str;
for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {

View File

@ -317,7 +317,7 @@ void ProcessRevolvedAreaSolid(const Schema_2x3::IfcRevolvedAreaSolid& solid, Tem
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid solid, TempMesh& result, ConversionData& conv) void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh& result, ConversionData& conv)
{ {
const Curve* const curve = Curve::Convert(*solid.Directrix, conv); const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
if(!curve) { if(!curve) {

View File

@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Vertex.h> #include <assimp/Vertex.h>
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <stdio.h> #include <stdio.h>
#include <unordered_set>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -239,6 +240,19 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
return 0; return 0;
} }
// We should care only about used vertices, not all of them
// (this can happen due to original file vertices buffer being used by
// multiple meshes)
std::unordered_set<unsigned int> usedVertexIndices;
usedVertexIndices.reserve(pMesh->mNumVertices);
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{
aiFace& face = pMesh->mFaces[a];
for( unsigned int b = 0; b < face.mNumIndices; b++) {
usedVertexIndices.insert(face.mIndices[b]);
}
}
// We'll never have more vertices afterwards. // We'll never have more vertices afterwards.
std::vector<Vertex> uniqueVertices; std::vector<Vertex> uniqueVertices;
uniqueVertices.reserve( pMesh->mNumVertices); uniqueVertices.reserve( pMesh->mNumVertices);
@ -292,6 +306,10 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// Now check each vertex if it brings something new to the table // Now check each vertex if it brings something new to the table
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) { for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
if (usedVertexIndices.find(a) == usedVertexIndices.end()) {
continue;
}
// collect the vertex data // collect the vertex data
Vertex v(pMesh,a); Vertex v(pMesh,a);

View File

@ -41,6 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <utility> #include <utility>
#include "MMDPmxParser.h" #include "MMDPmxParser.h"
#include <assimp/StringUtils.h>
#include "../contrib/utf8cpp/source/utf8.h" #include "../contrib/utf8cpp/source/utf8.h"
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
@ -118,7 +119,7 @@ namespace pmx
stream->read((char*) &count, sizeof(uint8_t)); stream->read((char*) &count, sizeof(uint8_t));
if (count < 8) if (count < 8)
{ {
throw; throw DeadlyImportError("MMD: invalid size");
} }
stream->read((char*) &encoding, sizeof(uint8_t)); stream->read((char*) &encoding, sizeof(uint8_t));
stream->read((char*) &uv, sizeof(uint8_t)); stream->read((char*) &uv, sizeof(uint8_t));
@ -395,7 +396,7 @@ namespace pmx
} }
break; break;
default: default:
throw; throw DeadlyImportError("MMD: unknown morth type");
} }
} }
@ -476,7 +477,7 @@ namespace pmx
{ {
// 未実装 // 未実装
std::cerr << "Not Implemented Exception" << std::endl; std::cerr << "Not Implemented Exception" << std::endl;
throw; throw DeadlyImportError("MMD: Not Implemented Exception");
} }
void PmxModel::Init() void PmxModel::Init()
@ -516,14 +517,14 @@ namespace pmx
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20) if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
{ {
std::cerr << "invalid magic number." << std::endl; std::cerr << "invalid magic number." << std::endl;
throw; throw DeadlyImportError("MMD: invalid magic number.");
} }
// バージョン // バージョン
stream->read((char*) &version, sizeof(float)); stream->read((char*) &version, sizeof(float));
if (version != 2.0f && version != 2.1f) if (version != 2.0f && version != 2.1f)
{ {
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl; std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
throw; throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version));
} }
// ファイル設定 // ファイル設定
this->setting.Read(stream); this->setting.Read(stream);
@ -605,34 +606,5 @@ namespace pmx
{ {
this->joints[i].Read(stream, &setting); this->joints[i].Read(stream, &setting);
} }
//if (this->version == 2.1f)
//{
// stream->read((char*) &this->soft_body_count, sizeof(int));
// this->soft_bodies = mmd::make_unique<PmxSoftBody []>(this->soft_body_count);
// for (int i = 0; i < this->soft_body_count; i++)
// {
// this->soft_bodies[i].Read(stream, &setting);
// }
//}
} }
//std::unique_ptr<PmxModel> ReadFromFile(const char *filename)
//{
// auto stream = std::ifstream(filename, std::ios_base::binary);
// auto pmx = PmxModel::ReadFromStream(&stream);
// if (!stream.eof())
// {
// std::cerr << "don't reach the end of file." << std::endl;
// }
// stream.close();
// return pmx;
//}
//std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream)
//{
// auto pmx = mmd::make_unique<PmxModel>();
// pmx->Read(stream);
// return pmx;
//}
} }

View File

@ -63,9 +63,9 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
unsigned int index, unsigned int index,
const aiMaterialProperty** pPropOut) const aiMaterialProperty** pPropOut)
{ {
ai_assert (pMat != NULL); ai_assert( pMat != NULL );
ai_assert (pKey != NULL); ai_assert( pKey != NULL );
ai_assert (pPropOut != NULL); ai_assert( pPropOut != NULL );
/* Just search for a property with exactly this name .. /* Just search for a property with exactly this name ..
* could be improved by hashing, but it's possibly * could be improved by hashing, but it's possibly
@ -76,7 +76,7 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
if (prop /* just for safety ... */ if (prop /* just for safety ... */
&& 0 == strcmp( prop->mKey.data, pKey ) && 0 == strcmp( prop->mKey.data, pKey )
&& (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wildcard, but this is undocumented :-) */ && (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wild-card, but this is undocumented :-) */
&& (UINT_MAX == index || prop->mIndex == index)) && (UINT_MAX == index || prop->mIndex == index))
{ {
*pPropOut = pMat->mProperties[i]; *pPropOut = pMat->mProperties[i];
@ -96,8 +96,8 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
ai_real* pOut, ai_real* pOut,
unsigned int* pMax) unsigned int* pMax)
{ {
ai_assert (pOut != NULL); ai_assert( pOut != NULL );
ai_assert (pMat != NULL); ai_assert( pMat != NULL );
const aiMaterialProperty* prop; const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop); aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
@ -182,8 +182,8 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
int* pOut, int* pOut,
unsigned int* pMax) unsigned int* pMax)
{ {
ai_assert (pOut != NULL); ai_assert( pOut != NULL );
ai_assert (pMat != NULL); ai_assert( pMat != NULL );
const aiMaterialProperty* prop; const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop); aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
@ -314,7 +314,7 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Get the number of textures on a particular texture stack // Get the number of textures on a particular texture stack
ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat, unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
C_ENUM aiTextureType type) C_ENUM aiTextureType type)
{ {
ai_assert (pMat != NULL); ai_assert (pMat != NULL);
@ -347,12 +347,14 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/ unsigned int* flags /*= NULL*/
) )
{ {
ai_assert(NULL != mat && NULL != path); ai_assert( NULL != mat );
ai_assert( NULL != path );
// Get the path to the texture // Get the path to the texture
if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) { if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) {
return AI_FAILURE; return AI_FAILURE;
} }
// Determine mapping type // Determine mapping type
int mapping_ = static_cast<int>(aiTextureMapping_UV); int mapping_ = static_cast<int>(aiTextureMapping_UV);
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_); aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_);
@ -381,15 +383,37 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
if (flags){ if (flags){
aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags); aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
} }
return AI_SUCCESS; return AI_SUCCESS;
} }
static aiMaterial *DefaultMaterial = nullptr;
// ------------------------------------------------------------------------------------------------
// Will return the default material.
aiMaterial *aiCreateAndRegisterDefaultMaterial() {
if (nullptr == DefaultMaterial) {
DefaultMaterial = new aiMaterial;
aiString s;
s.Set(AI_DEFAULT_MATERIAL_NAME);
DefaultMaterial->AddProperty(&s, AI_MATKEY_NAME);
}
return DefaultMaterial;
}
// ------------------------------------------------------------------------------------------------
// Will return the default material.
void aiReleaseDefaultMaterial() {
DefaultMaterial = nullptr;
}
static const unsigned int DefaultNumAllocated = 5; 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 ) : mProperties( nullptr )
, mNumProperties( 0 ) , mNumProperties( 0 )
, mNumAllocated( DefaultNumAllocated ) { , mNumAllocated( DefaultNumAllocated ) {
// Allocate 5 entries by default // Allocate 5 entries by default
@ -404,12 +428,20 @@ aiMaterial::~aiMaterial()
delete[] mProperties; delete[] mProperties;
} }
// ------------------------------------------------------------------------------------------------
aiString aiMaterial::GetName() {
aiString name;
Get(AI_MATKEY_NAME, name);
return name;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void aiMaterial::Clear() void aiMaterial::Clear()
{ {
for (unsigned int i = 0; i < mNumProperties;++i) { for ( unsigned int i = 0; i < mNumProperties; ++i ) {
// delete this entry // delete this entry
delete mProperties[i]; delete mProperties[ i ];
AI_DEBUG_INVALIDATE_PTR(mProperties[i]); AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
} }
mNumProperties = 0; mNumProperties = 0;
@ -418,11 +450,9 @@ void aiMaterial::Clear()
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiReturn aiMaterial::RemoveProperty (const char* pKey,unsigned int type, aiReturn aiMaterial::RemoveProperty ( const char* pKey,unsigned int type, unsigned int index )
unsigned int index
)
{ {
ai_assert(NULL != pKey); ai_assert( nullptr != pKey );
for (unsigned int i = 0; i < mNumProperties;++i) { for (unsigned int i = 0; i < mNumProperties;++i) {
aiMaterialProperty* prop = mProperties[i]; aiMaterialProperty* prop = mProperties[i];
@ -454,17 +484,18 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
aiPropertyTypeInfo pType aiPropertyTypeInfo pType
) )
{ {
ai_assert (pInput != NULL); ai_assert( pInput != NULL );
ai_assert (pKey != NULL); ai_assert( pKey != NULL );
ai_assert (0 != pSizeInBytes); ai_assert( 0 != pSizeInBytes );
if ( 0 == pSizeInBytes ) { if ( 0 == pSizeInBytes ) {
} }
// first search the list whether there is already an entry with this key // first search the list whether there is already an entry with this key
unsigned int iOutIndex = UINT_MAX; unsigned int iOutIndex( UINT_MAX );
for (unsigned int i = 0; i < mNumProperties;++i) { for ( unsigned int i = 0; i < mNumProperties; ++i ) {
aiMaterialProperty* prop = mProperties[i]; aiMaterialProperty *prop( mProperties[ i ] );
if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) && if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
prop->mSemantic == type && prop->mIndex == index){ prop->mSemantic == type && prop->mIndex == index){
@ -516,6 +547,7 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
} }
// push back ... // push back ...
mProperties[mNumProperties++] = pcNew; mProperties[mNumProperties++] = pcNew;
return AI_SUCCESS; return AI_SUCCESS;
} }

View File

@ -210,22 +210,63 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
ai_assert(false); ai_assert(false);
} }
if (pModel->m_Objects.size() > 0) {
// Create nodes for the whole scene // Create nodes for the whole scene
std::vector<aiMesh*> MeshArray; std::vector<aiMesh*> MeshArray;
for (size_t index = 0; index < pModel->m_Objects.size(); ++index ) { for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray); createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
} }
// Create mesh pointer buffer for this scene // Create mesh pointer buffer for this scene
if (pScene->mNumMeshes > 0) { if (pScene->mNumMeshes > 0) {
pScene->mMeshes = new aiMesh*[ MeshArray.size() ]; pScene->mMeshes = new aiMesh*[MeshArray.size()];
for (size_t index =0; index < MeshArray.size(); ++index ) { for (size_t index = 0; index < MeshArray.size(); ++index) {
pScene->mMeshes[ index ] = MeshArray[ index ]; pScene->mMeshes[index] = MeshArray[index];
} }
} }
// Create all materials // Create all materials
createMaterials( pModel, pScene ); createMaterials(pModel, pScene);
}else {
if (pModel->m_Vertices.empty()){
return;
}
std::unique_ptr<aiMesh> mesh( new aiMesh );
mesh->mPrimitiveTypes = aiPrimitiveType_POINT;
unsigned int n = pModel->m_Vertices.size();
mesh->mNumVertices = n;
mesh->mVertices = new aiVector3D[n];
memcpy(mesh->mVertices, pModel->m_Vertices.data(), n*sizeof(aiVector3D) );
if ( !pModel->m_Normals.empty() ) {
mesh->mNormals = new aiVector3D[n];
if (pModel->m_Normals.size() < n) {
throw DeadlyImportError("OBJ: vertex normal index out of range");
}
memcpy(mesh->mNormals, pModel->m_Normals.data(), n*sizeof(aiVector3D));
}
if ( !pModel->m_VertexColors.empty() ){
mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
for (unsigned int i = 0; i < n; ++i) {
if (i < pModel->m_VertexColors.size() ) {
const aiVector3D& color = pModel->m_VertexColors[i];
mesh->mColors[0][i] = aiColor4D(color.x, color.y, color.z, 1.0);
}else {
throw DeadlyImportError("OBJ: vertex color index out of range");
}
}
}
pScene->mRootNode->mNumMeshes = 1;
pScene->mRootNode->mMeshes = new unsigned int[1];
pScene->mRootNode->mMeshes[0] = 0;
pScene->mMeshes = new aiMesh*[1];
pScene->mNumMeshes = 1;
pScene->mMeshes[0] = mesh.release();
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -452,7 +493,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// Copy all vertex colors // Copy all vertex colors
if ( !pModel->m_VertexColors.empty()) if ( !pModel->m_VertexColors.empty())
{ {
const aiVector3D color = pModel->m_VertexColors[ vertex ]; const aiVector3D& color = pModel->m_VertexColors[ vertex ];
pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0); pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0);
} }

View File

@ -84,8 +84,6 @@ static const std::string BumpOption = "-bm";
static const std::string ChannelOption = "-imfchan"; static const std::string ChannelOption = "-imfchan";
static const std::string TypeOption = "-type"; static const std::string TypeOption = "-type";
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Constructor // Constructor
ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer, ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
@ -334,6 +332,11 @@ void ObjFileMtlImporter::getTexture() {
// Specular texture // Specular texture
out = & m_pModel->m_pCurrentMaterial->textureSpecular; out = & m_pModel->m_pCurrentMaterial->textureSpecular;
clampIndex = ObjFile::Material::TextureSpecularType; clampIndex = ObjFile::Material::TextureSpecularType;
} else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) ||
!ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) {
// Displacement texture
out = &m_pModel->m_pCurrentMaterial->textureDisp;
clampIndex = ObjFile::Material::TextureDispType;
} else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()) ) ) { } else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()) ) ) {
// Opacity texture // Opacity texture
out = & m_pModel->m_pCurrentMaterial->textureOpacity; out = & m_pModel->m_pCurrentMaterial->textureOpacity;
@ -356,11 +359,6 @@ void ObjFileMtlImporter::getTexture() {
// Reflection texture(s) // Reflection texture(s)
//Do nothing here //Do nothing here
return; return;
} else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) ||
!ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) {
// Displacement texture
out = &m_pModel->m_pCurrentMaterial->textureDisp;
clampIndex = ObjFile::Material::TextureDispType;
} else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) { } else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) {
// Specularity scaling (glossiness) // Specularity scaling (glossiness)
out = & m_pModel->m_pCurrentMaterial->textureSpecularity; out = & m_pModel->m_pCurrentMaterial->textureSpecularity;

View File

@ -90,6 +90,9 @@ static bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
return expectedBinaryFileSize == fileSize; return expectedBinaryFileSize == fileSize;
} }
static const size_t BufferSize = 500;
static const char UnicodeBoundary = 127;
// An ascii STL buffer will begin with "solid NAME", where NAME is optional. // An ascii STL buffer will begin with "solid NAME", where NAME is optional.
// Note: The "solid NAME" check is necessary, but not sufficient, to determine // Note: The "solid NAME" check is necessary, but not sufficient, to determine
// if the buffer is ASCII; a binary header could also begin with "solid NAME". // if the buffer is ASCII; a binary header could also begin with "solid NAME".
@ -108,10 +111,10 @@ static bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
bool isASCII( strncmp( buffer, "solid", 5 ) == 0 ); bool isASCII( strncmp( buffer, "solid", 5 ) == 0 );
if( isASCII ) { if( isASCII ) {
// A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters. // A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters.
if( fileSize >= 500 ) { if( fileSize >= BufferSize) {
isASCII = true; isASCII = true;
for( unsigned int i = 0; i < 500; i++ ) { for( unsigned int i = 0; i < BufferSize; i++ ) {
if( buffer[ i ] > 127 ) { if( buffer[ i ] > UnicodeBoundary) {
isASCII = false; isASCII = false;
break; break;
} }
@ -211,10 +214,11 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// create a single default material, using a white diffuse color for consistency with // create a single default material, using a white diffuse color for consistency with
// other geometric types (e.g., PLY). // other geometric types (e.g., PLY).
aiMaterial* pcMat = new aiMaterial(); aiMaterial* pcMat = aiCreateAndRegisterDefaultMaterial();
/*aiMaterial* pcMat = new aiMaterial();
aiString s; aiString s;
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(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0)); aiColor4D clrDiffuse(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0));
if (bMatClr) { if (bMatClr) {
@ -535,11 +539,21 @@ bool STLImporter::LoadBinaryFile()
// now copy faces // now copy faces
addFacesToMesh(pMesh); addFacesToMesh(pMesh);
aiNode* root = pScene->mRootNode;
// allocate one node
aiNode* node = new aiNode();
node->mParent = root;
root->mNumChildren = 1u;
root->mChildren = new aiNode*[root->mNumChildren];
root->mChildren[0] = node;
// add all created meshes to the single node // add all created meshes to the single node
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; node->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes]; node->mMeshes = new unsigned int[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes; i++) for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
pScene->mRootNode->mMeshes[i] = i; node->mMeshes[i] = i;
if (bIsMaterialise && !pMesh->mColors[0]) if (bIsMaterialise && !pMesh->mColors[0])
{ {

View File

@ -707,30 +707,30 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
// we work with hashes to make the comparisons MUCH faster, // we work with hashes to make the comparisons MUCH faster,
// at least if we have many bones. // at least if we have many bones.
std::list<BoneWithHash> asBones; std::list<BoneWithHash> asBones;
BuildUniqueBoneList(asBones, it,end); BuildUniqueBoneList( asBones, it, end );
// now create the output bones // now create the output bones
out->mNumBones = 0; out->mNumBones = 0;
out->mBones = new aiBone*[asBones.size()]; out->mBones = new aiBone*[asBones.size()];
for (std::list<BoneWithHash>::const_iterator it = asBones.begin(),end = asBones.end(); it != end;++it) { for (std::list<BoneWithHash>::const_iterator boneIt = asBones.begin(),boneEnd = asBones.end(); boneIt != boneEnd; ++boneIt ) {
// Allocate a bone and setup it's name // Allocate a bone and setup it's name
aiBone* pc = out->mBones[out->mNumBones++] = new aiBone(); aiBone* pc = out->mBones[out->mNumBones++] = new aiBone();
pc->mName = aiString( *((*it).second )); pc->mName = aiString( *( boneIt->second ));
std::vector< BoneSrcIndex >::const_iterator wend = (*it).pSrcBones.end(); std::vector< BoneSrcIndex >::const_iterator wend = boneIt->pSrcBones.end();
// Loop through all bones to be joined for this bone // Loop through all bones to be joined for this bone
for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) { for (std::vector< BoneSrcIndex >::const_iterator wmit = boneIt->pSrcBones.begin(); wmit != wend; ++wmit) {
pc->mNumWeights += (*wmit).first->mNumWeights; pc->mNumWeights += (*wmit).first->mNumWeights;
// NOTE: different offset matrices for bones with equal names // NOTE: different offset matrices for bones with equal names
// are - at the moment - not handled correctly. // are - at the moment - not handled correctly.
if (wmit != (*it).pSrcBones.begin() && pc->mOffsetMatrix != (*wmit).first->mOffsetMatrix) { if (wmit != boneIt->pSrcBones.begin() && pc->mOffsetMatrix != wmit->first->mOffsetMatrix) {
ASSIMP_LOG_WARN("Bones with equal names but different offset matrices can't be joined at the moment"); ASSIMP_LOG_WARN("Bones with equal names but different offset matrices can't be joined at the moment");
continue; continue;
} }
pc->mOffsetMatrix = (*wmit).first->mOffsetMatrix; pc->mOffsetMatrix = wmit->first->mOffsetMatrix;
} }
// Allocate the vertex weight array // Allocate the vertex weight array
@ -738,7 +738,7 @@ void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator
// 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 corresponding 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 = (*boneIt).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) {
const aiVertexWeight& vfi = pip->mWeights[mp]; const aiVertexWeight& vfi = pip->mWeights[mp];
@ -849,14 +849,14 @@ void SceneCombiner::MergeMeshes(aiMesh** _out, unsigned int /*flags*/,
// copy vertex colors // copy vertex colors
n = 0; n = 0;
while ((**begin).HasVertexColors(n)) { while ((**begin).HasVertexColors(n)) {
aiColor4D* pv2 = out->mColors[n] = new aiColor4D[out->mNumVertices]; aiColor4D *pVec2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) { for ( std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it ) {
if ((*it)->mColors[n]) { if ((*it)->mColors[n]) {
::memcpy(pv2,(*it)->mColors[n],(*it)->mNumVertices*sizeof(aiColor4D)); ::memcpy( pVec2, (*it)->mColors[ n ], (*it)->mNumVertices * sizeof( aiColor4D ) ) ;
} else { } else {
ASSIMP_LOG_WARN( "JoinMeshes: VCs expected but input mesh contains no VCs" ); ASSIMP_LOG_WARN( "JoinMeshes: VCs expected but input mesh contains no VCs" );
} }
pv2 += (*it)->mNumVertices; pVec2 += (*it)->mNumVertices;
} }
++n; ++n;
} }

View File

@ -55,12 +55,8 @@ namespace Assimp {
class Importer; class Importer;
struct ScenePrivateData { struct ScenePrivateData {
ScenePrivateData() // The struct constructor.
: mOrigImporter( nullptr ) ScenePrivateData();
, mPPStepsApplied( 0 )
, mIsCopy( false ) {
// empty
}
// Importer that originally loaded the scene though the C-API // Importer that originally loaded the scene though the C-API
// If set, this object is owned by this private data instance. // If set, this object is owned by this private data instance.
@ -77,6 +73,14 @@ struct ScenePrivateData {
bool mIsCopy; bool mIsCopy;
}; };
inline
ScenePrivateData::ScenePrivateData()
: mOrigImporter( nullptr )
, mPPStepsApplied( 0 )
, mIsCopy( false ) {
// empty
}
// Access private data stored in the scene // Access private data stored in the scene
inline inline
ScenePrivateData* ScenePriv(aiScene* in) { ScenePrivateData* ScenePriv(aiScene* in) {

View File

@ -223,7 +223,7 @@ namespace {
if( (-42 == (~42 + 1)) && (binValue & 0x80000000)) if( (-42 == (~42 + 1)) && (binValue & 0x80000000))
return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue; return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
// One's complement? // One's complement?
else if( (-42 == ~42) && (binValue & 0x80000000)) else if ( (-42 == ~42) && (binValue & 0x80000000))
return BinFloat(-0) - binValue; return BinFloat(-0) - binValue;
// Sign-magnitude? // Sign-magnitude?
else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary

View File

@ -393,7 +393,7 @@ void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end()); newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
} }
delete pNode->mMeshes; delete [] pNode->mMeshes;
pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size()); pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes); std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);

View File

@ -105,10 +105,12 @@ void TriangulateProcess::Execute( aiScene* pScene)
bool bHas = false; bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
{ {
if (pScene->mMeshes[ a ]) {
if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) { if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) {
bHas = true; bHas = true;
} }
} }
}
if ( bHas ) { if ( bHas ) {
ASSIMP_LOG_INFO( "TriangulateProcess finished. All polygons have been triangulated." ); ASSIMP_LOG_INFO( "TriangulateProcess finished. All polygons have been triangulated." );
} else { } else {

View File

@ -150,9 +150,11 @@ ASSIMP_API aiScene::~aiScene() {
delete mMeshes[a]; delete mMeshes[a];
delete [] mMeshes; delete [] mMeshes;
if (mNumMaterials && mMaterials) if (mNumMaterials && mMaterials) {
for( unsigned int a = 0; a < mNumMaterials; a++) for (unsigned int a = 0; a < mNumMaterials; ++a ) {
delete mMaterials[a]; delete mMaterials[ a ];
}
}
delete [] mMaterials; delete [] mMaterials;
if (mNumAnimations && mAnimations) if (mNumAnimations && mAnimations)

View File

@ -766,10 +766,17 @@ namespace glTF2
Ref<Accessor> indices; Ref<Accessor> indices;
Ref<Material> material; Ref<Material> material;
struct Target {
AccessorList position, normal, tangent;
};
std::vector<Target> targets;
}; };
std::vector<Primitive> primitives; std::vector<Primitive> primitives;
std::vector<float> weights;
Mesh() {} Mesh() {}
/// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root) /// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)

View File

@ -931,6 +931,21 @@ namespace {
else return false; else return false;
return true; return true;
} }
inline bool GetAttribTargetVector(Mesh::Primitive& p, const int targetIndex, const char* attr, Mesh::AccessorList*& v, int& pos)
{
if ((pos = Compare(attr, "POSITION"))) {
v = &(p.targets[targetIndex].position);
}
else if ((pos = Compare(attr, "NORMAL"))) {
v = &(p.targets[targetIndex].normal);
}
else if ((pos = Compare(attr, "TANGENT"))) {
v = &(p.targets[targetIndex].tangent);
}
else return false;
return true;
}
} }
inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root) inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
@ -965,6 +980,26 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
} }
} }
if (Value* targetsArray = FindArray(primitive, "targets")) {
prim.targets.resize(targetsArray->Size());
for (unsigned int i = 0; i < targetsArray->Size(); ++i) {
Value& target = (*targetsArray)[i];
if (!target.IsObject()) continue;
for (Value::MemberIterator it = target.MemberBegin(); it != target.MemberEnd(); ++it) {
if (!it->value.IsUint()) continue;
const char* attr = it->name.GetString();
// Valid attribute semantics include POSITION, NORMAL, TANGENT
int undPos = 0;
Mesh::AccessorList* vec = 0;
if (GetAttribTargetVector(prim, i, attr, vec, undPos)) {
size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
if ((*vec).size() <= idx) (*vec).resize(idx + 1);
(*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
}
}
}
}
if (Value* indices = FindUInt(primitive, "indices")) { if (Value* indices = FindUInt(primitive, "indices")) {
prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint()); prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint());
} }
@ -974,6 +1009,16 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
} }
} }
} }
if (Value* weights = FindArray(pJSON_Object, "weights")) {
this->weights.resize(weights->Size());
for (unsigned int i = 0; i < weights->Size(); ++i) {
Value& weightValue = (*weights)[i];
if (weightValue.IsNumber()) {
this->weights[i] = weightValue.GetFloat();
}
}
}
} }
inline void Camera::Read(Value& obj, Asset& /*r*/) inline void Camera::Read(Value& obj, Asset& /*r*/)

View File

@ -94,19 +94,7 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
, mIOSystem(pIOSystem) , mIOSystem(pIOSystem)
, mProperties(pProperties) , mProperties(pProperties)
{ {
aiScene* sceneCopy_tmp; mScene = pScene;
SceneCombiner::CopyScene(&sceneCopy_tmp, pScene);
std::unique_ptr<aiScene> sceneCopy(sceneCopy_tmp);
SplitLargeMeshesProcess_Triangle tri_splitter;
tri_splitter.SetLimit(0xffff);
tri_splitter.Execute(sceneCopy.get());
SplitLargeMeshesProcess_Vertex vert_splitter;
vert_splitter.SetLimit(0xffff);
vert_splitter.Execute(sceneCopy.get());
mScene = sceneCopy.get();
mAsset.reset( new Asset( pIOSystem ) ); mAsset.reset( new Asset( pIOSystem ) );
@ -681,12 +669,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
void glTF2Exporter::ExportMeshes() void glTF2Exporter::ExportMeshes()
{ {
// Not for typedef decltype(aiFace::mNumIndices) IndicesType;
// using IndicesType = decltype(aiFace::mNumIndices);
// But yes for
// using IndicesType = unsigned short;
// because "ComponentType_UNSIGNED_SHORT" used for indices. And it's a maximal type according to glTF specification.
typedef unsigned short IndicesType;
std::string fname = std::string(mFilename); std::string fname = std::string(mFilename);
std::string bufferIdPrefix = fname.substr(0, fname.rfind(".gltf")); std::string bufferIdPrefix = fname.substr(0, fname.rfind(".gltf"));
@ -778,11 +761,11 @@ void glTF2Exporter::ExportMeshes()
indices.resize(aim->mNumFaces * nIndicesPerFace); indices.resize(aim->mNumFaces * nIndicesPerFace);
for (size_t i = 0; i < aim->mNumFaces; ++i) { for (size_t i = 0; i < aim->mNumFaces; ++i) {
for (size_t j = 0; j < nIndicesPerFace; ++j) { for (size_t j = 0; j < nIndicesPerFace; ++j) {
indices[i*nIndicesPerFace + j] = uint16_t(aim->mFaces[i].mIndices[j]); indices[i*nIndicesPerFace + j] = IndicesType(aim->mFaces[i].mIndices[j]);
} }
} }
p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_SHORT, true); p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_INT, true);
} }
switch (aim->mPrimitiveTypes) { switch (aim->mPrimitiveTypes) {

173
code/glTF2Importer.cpp 100644 → 100755
View File

@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h> #include <assimp/importerdesc.h>
#include <assimp/CreateAnimMesh.h>
#include <memory> #include <memory>
@ -65,6 +66,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp; using namespace Assimp;
using namespace glTF2; using namespace glTF2;
namespace {
// generate bitangents from normals and tangents according to spec
struct Tangent {
aiVector3D xyz;
ai_real w;
};
} // namespace
// //
// glTF2Importer // glTF2Importer
@ -109,13 +117,9 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
if (pIOHandler) { if (pIOHandler) {
glTF2::Asset asset(pIOHandler); glTF2::Asset asset(pIOHandler);
try {
asset.Load(pFile, extension == "glb"); asset.Load(pFile, extension == "glb");
std::string version = asset.asset.version; std::string version = asset.asset.version;
return !version.empty() && version[0] == '2'; return !version.empty() && version[0] == '2';
} catch (...) {
return false;
}
} }
return false; return false;
@ -416,10 +420,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
// only extract tangents if normals are present // only extract tangents if normals are present
if (attr.tangent.size() > 0 && attr.tangent[0]) { if (attr.tangent.size() > 0 && attr.tangent[0]) {
// generate bitangents from normals and tangents according to spec // generate bitangents from normals and tangents according to spec
struct Tangent { Tangent *tangents = nullptr;
aiVector3D xyz;
ai_real w;
} *tangents = nullptr;
attr.tangent[0]->ExtractData(tangents); attr.tangent[0]->ExtractData(tangents);
@ -436,6 +437,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
} }
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) { for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
if (attr.texcoord[tc]->count != aim->mNumVertices) {
DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name +
"\" does not match the vertex count");
continue;
}
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]); attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents(); aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
@ -445,11 +452,57 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
} }
} }
std::vector<Mesh::Primitive::Target>& targets = prim.targets;
if (targets.size() > 0) {
aim->mNumAnimMeshes = targets.size();
aim->mAnimMeshes = new aiAnimMesh*[aim->mNumAnimMeshes];
for (size_t i = 0; i < targets.size(); i++) {
aim->mAnimMeshes[i] = aiCreateAnimMesh(aim);
aiAnimMesh& aiAnimMesh = *(aim->mAnimMeshes[i]);
Mesh::Primitive::Target& target = targets[i];
if (target.position.size() > 0) {
aiVector3D *positionDiff = nullptr;
target.position[0]->ExtractData(positionDiff);
for(unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
aiAnimMesh.mVertices[vertexId] += positionDiff[vertexId];
}
delete [] positionDiff;
}
if (target.normal.size() > 0) {
aiVector3D *normalDiff = nullptr;
target.normal[0]->ExtractData(normalDiff);
for(unsigned int vertexId = 0; vertexId < aim->mNumVertices; vertexId++) {
aiAnimMesh.mNormals[vertexId] += normalDiff[vertexId];
}
delete [] normalDiff;
}
if (target.tangent.size() > 0) {
Tangent *tangent = nullptr;
attr.tangent[0]->ExtractData(tangent);
aiVector3D *tangentDiff = nullptr;
target.tangent[0]->ExtractData(tangentDiff);
for (unsigned int vertexId = 0; vertexId < aim->mNumVertices; ++vertexId) {
tangent[vertexId].xyz += tangentDiff[vertexId];
aiAnimMesh.mTangents[vertexId] = tangent[vertexId].xyz;
aiAnimMesh.mBitangents[vertexId] = (aiAnimMesh.mNormals[vertexId] ^ tangent[vertexId].xyz) * tangent[vertexId].w;
}
delete [] tangent;
delete [] tangentDiff;
}
if (mesh.weights.size() > i) {
aiAnimMesh.mWeight = mesh.weights[i];
}
}
}
if (prim.indices) {
aiFace* faces = 0; aiFace* faces = 0;
unsigned int nFaces = 0; unsigned int nFaces = 0;
if (prim.indices) {
unsigned int count = prim.indices->count; unsigned int count = prim.indices->count;
Accessor::Indexer data = prim.indices->GetIndexer(); Accessor::Indexer data = prim.indices->GetIndexer();
@ -499,9 +552,18 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_TRIANGLE_STRIP: { case PrimitiveMode_TRIANGLE_STRIP: {
nFaces = count - 2; nFaces = count - 2;
faces = new aiFace[nFaces]; faces = new aiFace[nFaces];
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2)); for (unsigned int i = 0; i < nFaces; ++i) {
for (unsigned int i = 3; i < count; ++i) { //The ordering is to ensure that the triangles are all drawn with the same orientation
SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i)); if ((i + 1) % 2 == 0)
{
//For even n, vertices n + 1, n, and n + 2 define triangle n
SetFace(faces[i], data.GetUInt(i + 1), data.GetUInt(i), data.GetUInt(i + 2));
}
else
{
//For odd n, vertices n, n+1, and n+2 define triangle n
SetFace(faces[i], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
}
} }
break; break;
} }
@ -509,19 +571,92 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
nFaces = count - 2; nFaces = count - 2;
faces = new aiFace[nFaces]; faces = new aiFace[nFaces];
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2)); SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
for (unsigned int i = 3; i < count; ++i) { for (unsigned int i = 1; i < nFaces; ++i) {
SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i)); SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i + 2));
} }
break; break;
} }
}
else { // no indices provided so directly generate from counts
// use the already determined count as it includes checks
unsigned int count = aim->mNumVertices;
switch (prim.mode) {
case PrimitiveMode_POINTS: {
nFaces = count;
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; ++i) {
SetFace(faces[i], i);
}
break;
}
case PrimitiveMode_LINES: {
nFaces = count / 2;
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], i, i + 1);
}
break;
}
case PrimitiveMode_LINE_LOOP:
case PrimitiveMode_LINE_STRIP: {
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
faces = new aiFace[nFaces];
SetFace(faces[0], 0, 1);
for (unsigned int i = 2; i < count; ++i) {
SetFace(faces[i - 1], faces[i - 2].mIndices[1], i);
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
}
break;
}
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], i, i + 1, i + 2);
}
break;
}
case PrimitiveMode_TRIANGLE_STRIP: {
nFaces = count - 2;
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < nFaces; ++i) {
//The ordering is to ensure that the triangles are all drawn with the same orientation
if ((i+1) % 2 == 0)
{
//For even n, vertices n + 1, n, and n + 2 define triangle n
SetFace(faces[i], i+1, i, i+2);
}
else
{
//For odd n, vertices n, n+1, and n+2 define triangle n
SetFace(faces[i], i, i+1, i+2);
}
}
break;
}
case PrimitiveMode_TRIANGLE_FAN:
nFaces = count - 2;
faces = new aiFace[nFaces];
SetFace(faces[0], 0, 1, 2);
for (unsigned int i = 1; i < nFaces; ++i) {
SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], i + 2);
}
break;
}
}
if (faces) { if (faces) {
aim->mFaces = faces; aim->mFaces = faces;
aim->mNumFaces = nFaces; aim->mNumFaces = nFaces;
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices)); ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
} }
}
if (prim.material) { if (prim.material) {
aim->mMaterialIndex = prim.material.GetIndex(); aim->mMaterialIndex = prim.material.GetIndex();
@ -733,12 +868,6 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO
ImportNodes(asset); ImportNodes(asset);
// TODO: it does not split the loaded vertices, should it?
//pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
MakeVerboseFormatProcess process;
process.Execute(pScene);
if (pScene->mNumMeshes == 0) { if (pScene->mNumMeshes == 0) {
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
} }

75
code/glTFImporter.cpp 100644 → 100755
View File

@ -351,10 +351,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
} }
if (prim.indices) {
aiFace* faces = 0; aiFace* faces = 0;
unsigned int nFaces = 0; unsigned int nFaces = 0;
if (prim.indices) {
unsigned int count = prim.indices->count; unsigned int count = prim.indices->count;
Accessor::Indexer data = prim.indices->GetIndexer(); Accessor::Indexer data = prim.indices->GetIndexer();
@ -419,14 +419,78 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
} }
break; break;
} }
}
else { // no indices provided so directly generate from counts
// use the already determined count as it includes checks
unsigned int count = aim->mNumVertices;
switch (prim.mode) {
case PrimitiveMode_POINTS: {
nFaces = count;
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; ++i) {
SetFace(faces[i], i);
}
break;
}
case PrimitiveMode_LINES: {
nFaces = count / 2;
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 2) {
SetFace(faces[i / 2], i, i + 1);
}
break;
}
case PrimitiveMode_LINE_LOOP:
case PrimitiveMode_LINE_STRIP: {
nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
faces = new aiFace[nFaces];
SetFace(faces[0], 0, 1);
for (unsigned int i = 2; i < count; ++i) {
SetFace(faces[i - 1], faces[i - 2].mIndices[1], i);
}
if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
}
break;
}
case PrimitiveMode_TRIANGLES: {
nFaces = count / 3;
faces = new aiFace[nFaces];
for (unsigned int i = 0; i < count; i += 3) {
SetFace(faces[i / 3], i, i + 1, i + 2);
}
break;
}
case PrimitiveMode_TRIANGLE_STRIP: {
nFaces = count - 2;
faces = new aiFace[nFaces];
SetFace(faces[0], 0, 1, 2);
for (unsigned int i = 3; i < count; ++i) {
SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], i);
}
break;
}
case PrimitiveMode_TRIANGLE_FAN:
nFaces = count - 2;
faces = new aiFace[nFaces];
SetFace(faces[0], 0, 1, 2);
for (unsigned int i = 3; i < count; ++i) {
SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], i);
}
break;
}
}
if (faces) { if (faces) {
aim->mFaces = faces; aim->mFaces = faces;
aim->mNumFaces = nFaces; aim->mNumFaces = nFaces;
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices)); ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
} }
}
if (prim.material) { if (prim.material) {
aim->mMaterialIndex = prim.material.GetIndex(); aim->mMaterialIndex = prim.material.GetIndex();
@ -676,11 +740,6 @@ void glTFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOS
ImportNodes(asset); ImportNodes(asset);
// TODO: it does not split the loaded vertices, should it?
//pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
MakeVerboseFormatProcess process;
process.Execute(pScene);
if (pScene->mNumMeshes == 0) { if (pScene->mNumMeshes == 0) {
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;

View File

@ -100,10 +100,16 @@ static bool isUnsignedIntegerType( Value::ValueType integerType ) {
} }
static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) { static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
// Basic checks
if( ddl_nullptr == id || ddl_nullptr == parser ) { if( ddl_nullptr == id || ddl_nullptr == parser ) {
return ddl_nullptr; return ddl_nullptr;
} }
// If the buffer is empty ( an empty node ) return nullptr
if ( ddl_nullptr == id->m_buffer ) {
return ddl_nullptr;
}
const std::string type( id->m_buffer ); const std::string type( id->m_buffer );
DDLNode *parent( parser->top() ); DDLNode *parent( parser->top() );
DDLNode *node = DDLNode::create( type, "", parent ); DDLNode *node = DDLNode::create( type, "", parent );

View File

@ -3,7 +3,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team Copyright (c) 2006-2018, assimp team
All rights reserved. All rights reserved.

View File

@ -79,26 +79,27 @@ struct aiVectorKey
/// @brief Construction from a given time and key value. /// @brief Construction from a given time and key value.
aiVectorKey(double time, const aiVector3D& value) aiVectorKey(double time, const aiVector3D& value)
: mTime (time) : mTime( time )
, mValue (value) , mValue( value ) {
{} // empty
}
typedef aiVector3D elem_type; typedef aiVector3D elem_type;
// Comparison operators. For use with std::find(); // Comparison operators. For use with std::find();
bool operator == (const aiVectorKey& o) const { bool operator == (const aiVectorKey& rhs) const {
return o.mValue == this->mValue; return rhs.mValue == this->mValue;
} }
bool operator != (const aiVectorKey& o) const { bool operator != (const aiVectorKey& rhs ) const {
return o.mValue != this->mValue; return rhs.mValue != this->mValue;
} }
// Relational operators. For use with std::sort(); // Relational operators. For use with std::sort();
bool operator < (const aiVectorKey& o) const { bool operator < (const aiVectorKey& rhs ) const {
return mTime < o.mTime; return mTime < rhs.mTime;
} }
bool operator > (const aiVectorKey& o) const { bool operator > (const aiVectorKey& rhs ) const {
return mTime > o.mTime; return mTime > rhs.mTime;
} }
#endif // __cplusplus #endif // __cplusplus
}; };
@ -130,25 +131,25 @@ struct aiQuatKey
typedef aiQuaternion elem_type; typedef aiQuaternion elem_type;
// Comparison operators. For use with std::find(); // Comparison operators. For use with std::find();
bool operator == (const aiQuatKey& o) const { bool operator == (const aiQuatKey& rhs ) const {
return o.mValue == this->mValue; return rhs.mValue == this->mValue;
} }
bool operator != (const aiQuatKey& o) const { bool operator != (const aiQuatKey& rhs ) const {
return o.mValue != this->mValue; return rhs.mValue != this->mValue;
} }
// Relational operators. For use with std::sort(); // Relational operators. For use with std::sort();
bool operator < (const aiQuatKey& o) const { bool operator < (const aiQuatKey& rhs ) const {
return mTime < o.mTime; return mTime < rhs.mTime;
} }
bool operator > (const aiQuatKey& o) const { bool operator > (const aiQuatKey& rhs ) const {
return mTime > o.mTime; return mTime > rhs.mTime;
} }
#endif #endif
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Binds a anim mesh to a specific point in time. */ /** Binds a anim-mesh to a specific point in time. */
struct aiMeshKey struct aiMeshKey
{ {
/** The time of this key */ /** The time of this key */

View File

@ -612,12 +612,13 @@ struct aiMaterialProperty
, mIndex( 0 ) , mIndex( 0 )
, mDataLength( 0 ) , mDataLength( 0 )
, mType( aiPTI_Float ) , mType( aiPTI_Float )
, mData( NULL ) , mData(nullptr) {
{ // empty
} }
~aiMaterialProperty() { ~aiMaterialProperty() {
delete[] mData; delete[] mData;
mData = nullptr;
} }
#endif #endif
@ -651,6 +652,14 @@ public:
aiMaterial(); aiMaterial();
~aiMaterial(); ~aiMaterial();
// -------------------------------------------------------------------
/**
* @brief Returns the name of the material.
* @return The name of the material.
*/
// -------------------------------------------------------------------
aiString GetName();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Retrieve an array of Type values with a specific key /** @brief Retrieve an array of Type values with a specific key
* from the material * from the material
@ -1556,10 +1565,32 @@ C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/); unsigned int* flags /*= NULL*/);
#endif // !#ifdef __cplusplus #endif // !#ifdef __cplusplus
// ---------------------------------------------------------------------------
/** @brief Helper function to get all values pertaining to a particular
* texture slot from a material structure.
*
* @return Pointer showing to the default material.
*/
// ---------------------------------------------------------------------------
#ifdef __cplusplus
ASSIMP_API aiMaterial *aiCreateAndRegisterDefaultMaterial(void);
#else
C_STRUCT aiMaterial *aiCreateAndRegisterDefaultMaterial(void);
#endif // !#ifdef __cplusplus
// ---------------------------------------------------------------------------
/**
* @brief Helper function to release the default material instance, the
* instance will not be destroyed.
*/
// ---------------------------------------------------------------------------
ASSIMP_API void aiReleaseDefaultMaterial();
#ifdef __cplusplus #ifdef __cplusplus
} }
#include "material.inl" #include "material.inl"
#endif //!__cplusplus #endif //!__cplusplus
#endif //!!AI_MATERIAL_H_INC #endif //!!AI_MATERIAL_H_INC

View File

@ -130,7 +130,7 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
return AI_FAILURE; return AI_FAILURE;
} }
::memcpy(&pOut,prop->mData,sizeof(Type)); ::memcpy( &pOut, prop->mData, sizeof( Type ) );
} }
return ret; return ret;
} }

View File

@ -124,8 +124,8 @@ def _init(self, target = None, parent = None):
except: except:
uni = str(obj.data, errors='ignore') uni = str(obj.data, errors='ignore')
target.name = str( uni ) target.name = str( uni )
target.__class__.__repr__ = lambda x: str(x.__class__) + "(" + x.name + ")" target.__class__.__repr__ = lambda x: str(x.__class__) + "(" + getattr(x, 'name','') + ")"
target.__class__.__str__ = lambda x: x.name target.__class__.__str__ = lambda x: getattr(x, 'name', '')
continue continue
name = m[1:].lower() name = m[1:].lower()

View File

@ -214,6 +214,41 @@ class MeshKey(Structure):
("mValue", c_uint), ("mValue", c_uint),
] ]
class MetadataEntry(Structure):
"""
See 'metadata.h' for details
"""
AI_BOOL = 0
AI_INT32 = 1
AI_UINT64 = 2
AI_FLOAT = 3
AI_DOUBLE = 4
AI_AISTRING = 5
AI_AIVECTOR3D = 6
AI_META_MAX = 7
_fields_ = [
# The type field uniquely identifies the underlying type of the data field
("mType", c_uint),
("mData", c_void_p),
]
class Metadata(Structure):
"""
See 'metadata.h' for details
"""
_fields_ = [
# Length of the mKeys and mValues arrays, respectively
("mNumProperties", c_uint),
# Arrays of keys, may not be NULL. Entries in this array may not be NULL
# as well.
("mKeys", POINTER(String)),
# Arrays of values, may not be NULL. Entries in this array may be NULL
# if the corresponding property key has no assigned value.
("mValues", POINTER(MetadataEntry)),
]
class Node(Structure): class Node(Structure):
""" """
See 'aiScene.h' for details. See 'aiScene.h' for details.
@ -253,6 +288,10 @@ Node._fields_ = [
# The meshes of this node. Each entry is an index into the mesh # The meshes of this node. Each entry is an index into the mesh
("mMeshes", POINTER(c_uint)), ("mMeshes", POINTER(c_uint)),
# Metadata associated with this node or NULL if there is no metadata.
# Whether any metadata is generated depends on the source file format.
("mMetadata", POINTER(POINTER(Metadata))),
] ]
class Light(Structure): class Light(Structure):
@ -896,6 +935,11 @@ class Scene(Structure):
# array (if existing) is the default camera view into # array (if existing) is the default camera view into
# the scene. # the scene.
("mCameras", POINTER(POINTER(Camera))), ("mCameras", POINTER(POINTER(Camera))),
# This data contains global metadata which belongs to the scene like
# unit-conversions, versions, vendors or other model-specific data. This
# can be used to store format-specific metadata as well.
("mMetadata", POINTER(POINTER(Metadata))),
] ]
assimp_structs_as_tuple = (Matrix4x4, assimp_structs_as_tuple = (Matrix4x4,

View File

@ -3,15 +3,13 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE) SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin") SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "arm64") SET (CMAKE_SYSTEM_PROCESSOR "arm64")
SET (IOS TRUE)
SET (SDKVER "7.1") SET (IOS_SDK_DEVICE iPhoneOS)
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain")
SET (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDKVER}.sdk") SET (SDKVER "${IOS_SDK_VERSION}")
SET (CC "${DEVROOT}/usr/bin/clang") SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
SET (CXX "${DEVROOT}/usr/bin/clang++")
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}") SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

View File

@ -3,15 +3,13 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE) SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin") SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "armv6") SET (CMAKE_SYSTEM_PROCESSOR "armv6")
SET (IOS TRUE)
SET (SDKVER "7.1") SET (IOS_SDK_DEVICE iPhoneOS)
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain")
SET (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDKVER}.sdk") SET (SDKVER "${IOS_SDK_VERSION}")
SET (CC "${DEVROOT}/usr/bin/clang") SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
SET (CXX "${DEVROOT}/usr/bin/clang++")
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}") SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

View File

@ -3,15 +3,13 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE) SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin") SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "armv7s") SET (CMAKE_SYSTEM_PROCESSOR "armv7s")
SET (IOS TRUE)
SET (SDKVER "7.1") SET (IOS_SDK_DEVICE iPhoneOS)
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain")
SET (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDKVER}.sdk") SET (SDKVER "${IOS_SDK_VERSION}")
SET (CC "${DEVROOT}/usr/bin/clang") SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
SET (CXX "${DEVROOT}/usr/bin/clang++")
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}") SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

View File

@ -3,15 +3,13 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE) SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin") SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "armv7") SET (CMAKE_SYSTEM_PROCESSOR "armv7")
SET (IOS TRUE)
SET (SDKVER "7.1") SET (IOS_SDK_DEVICE iPhoneOS)
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain")
SET (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDKVER}.sdk") SET (SDKVER "${IOS_SDK_VERSION}")
SET (CC "${DEVROOT}/usr/bin/clang") SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
SET (CXX "${DEVROOT}/usr/bin/clang++")
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}") SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

View File

@ -3,16 +3,13 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE) SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin") SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "i386") SET (CMAKE_SYSTEM_PROCESSOR "i386")
SET (IOS TRUE)
SET (SDKVER "7.1") SET (IOS_SDK_DEVICE iPhoneSimulator)
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain") SET (SDKVER "${IOS_SDK_VERSION}")
SET (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDKVER}.sdk") SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
SET (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}") SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

View File

@ -3,16 +3,13 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE) SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin") SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "x86_64") SET (CMAKE_SYSTEM_PROCESSOR "x86_64")
SET (IOS TRUE)
SET (SDKVER "7.1") SET (IOS_SDK_DEVICE iPhoneSimulator)
SET (DEVROOT "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain") SET (SDKVER "${IOS_SDK_VERSION}")
SET (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDKVER}.sdk") SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
SET (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}") SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

View File

@ -6,24 +6,41 @@
BUILD_DIR="./lib/iOS" BUILD_DIR="./lib/iOS"
IOS_SDK_VERSION= ###################################
IOS_SDK_TARGET=6.0 # SDK Version
#(iPhoneOS iPhoneSimulator) -- determined from arch ###################################
IOS_SDK_DEVICE= IOS_SDK_VERSION=$(xcodebuild -version -sdk iphoneos | grep SDKVersion | cut -f2 -d ':' | tr -d '[[:space:]]')
###################################
XCODE_ROOT_DIR=/Applications/Xcode.app/Contents ###################################
TOOLCHAIN=$XCODE_ROOT_DIR//Developer/Toolchains/XcodeDefault.xctoolchain # BUILD Configuration
###################################
BUILD_ARCHS_DEVICE="armv7 armv7s arm64" BUILD_SHARED_LIBS=OFF
BUILD_ARCHS_SIMULATOR="i386 x86_64" BUILD_TYPE=Release
BUILD_ARCHS_ALL=(armv7 armv7s arm64 i386 x86_64)
################################################
# Minimum iOS deployment target version
################################################
MIN_IOS_VERSION="6.0"
IOS_SDK_TARGET=$MIN_IOS_VERSION
XCODE_ROOT_DIR=$(xcode-select --print-path)
TOOLCHAIN=$XCODE_ROOT_DIR/Toolchains/XcodeDefault.xctoolchain
CMAKE_C_COMPILER=$(xcrun -find cc)
CMAKE_CXX_COMPILER=$(xcrun -find c++)
BUILD_ARCHS_DEVICE="arm64 armv7s armv7"
BUILD_ARCHS_SIMULATOR="x86_64 i386"
BUILD_ARCHS_ALL=($BUILD_ARCHS_DEVICE $BUILD_ARCHS_SIMULATOR)
CPP_DEV_TARGET_LIST=(miphoneos-version-min mios-simulator-version-min) CPP_DEV_TARGET_LIST=(miphoneos-version-min mios-simulator-version-min)
CPP_DEV_TARGET= CPP_DEV_TARGET=
CPP_STD_LIB_LIST=(libc++ libstdc++) CPP_STD_LIB_LIST=(libc++ libstdc++)
CPP_STD_LIB= CPP_STD_LIB=
CPP_STD_LIST=(c++11 c++14) CPP_STD_LIST=(c++11 c++14)
CPP_STD= CPP_STD=c++11
function join { local IFS="$1"; shift; echo "$*"; } function join { local IFS="$1"; shift; echo "$*"; }
@ -41,26 +58,41 @@ build_arch()
echo '[!] Target SDK set to DEVICE.' echo '[!] Target SDK set to DEVICE.'
fi fi
unset DEVROOT SDKROOT CFLAGS LDFLAGS CPPFLAGS CXXFLAGS unset DEVROOT SDKROOT CFLAGS LDFLAGS CPPFLAGS CXXFLAGS CMAKE_CLI_INPUT
export DEVROOT=$XCODE_ROOT_DIR/Developer/Platforms/$IOS_SDK_DEVICE.platform/Developer #export CC="$(xcrun -sdk iphoneos -find clang)"
#export CPP="$CC -E"
export DEVROOT=$XCODE_ROOT_DIR/Platforms/$IOS_SDK_DEVICE.platform/Developer
export SDKROOT=$DEVROOT/SDKs/$IOS_SDK_DEVICE$IOS_SDK_VERSION.sdk export SDKROOT=$DEVROOT/SDKs/$IOS_SDK_DEVICE$IOS_SDK_VERSION.sdk
export CFLAGS="-arch $1 -pipe -no-cpp-precomp -stdlib=$CPP_STD_LIB -isysroot $SDKROOT -$CPP_DEV_TARGET=$IOS_SDK_TARGET -I$SDKROOT/usr/include/" export CFLAGS="-arch $1 -pipe -no-cpp-precomp -stdlib=$CPP_STD_LIB -isysroot $SDKROOT -I$SDKROOT/usr/include/ -miphoneos-version-min=$IOS_SDK_TARGET"
export LDFLAGS="-L$SDKROOT/usr/lib/" if [[ "$BUILD_TYPE" =~ "Debug" ]]; then
export CPPFLAGS=$CFLAGS export CFLAGS="$CFLAGS -Og"
else
export CFLAGS="$CFLAGS -O3"
fi
export LDFLAGS="-arch $1 -isysroot $SDKROOT -L$SDKROOT/usr/lib/"
export CPPFLAGS="$CFLAGS"
export CXXFLAGS="$CFLAGS -std=$CPP_STD" export CXXFLAGS="$CFLAGS -std=$CPP_STD"
rm CMakeCache.txt rm CMakeCache.txt
cmake -G 'Unix Makefiles' -DCMAKE_TOOLCHAIN_FILE=./port/iOS/IPHONEOS_$(echo $1 | tr '[:lower:]' '[:upper:]')_TOOLCHAIN.cmake -DENABLE_BOOST_WORKAROUND=ON -DBUILD_SHARED_LIBS=OFF CMAKE_CLI_INPUT="-DCMAKE_C_COMPILER=$CMAKE_C_COMPILER -DCMAKE_CXX_COMPILER=$CMAKE_CXX_COMPILER -DCMAKE_TOOLCHAIN_FILE=./port/iOS/IPHONEOS_$(echo $1 | tr '[:lower:]' '[:upper:]')_TOOLCHAIN.cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DENABLE_BOOST_WORKAROUND=ON -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS"
echo "[!] Running CMake with -G 'Unix Makefiles' $CMAKE_CLI_INPUT"
cmake -G 'Unix Makefiles' ${CMAKE_CLI_INPUT}
echo "[!] Building $1 library" echo "[!] Building $1 library"
$XCODE_ROOT_DIR/Developer/usr/bin/make clean xcrun -run make clean
$XCODE_ROOT_DIR/Developer/usr/bin/make assimp -j 8 -l xcrun -run make assimp -j 8 -l
echo "[!] Moving built libraries into: $BUILD_DIR/$1/" if [[ "$BUILD_SHARED_LIBS" =~ "ON" ]]; then
echo "[!] Moving built dynamic libraries into: $BUILD_DIR/$1/"
mv ./lib/*.dylib $BUILD_DIR/$1/
fi
echo "[!] Moving built static libraries into: $BUILD_DIR/$1/"
mv ./lib/*.a $BUILD_DIR/$1/ mv ./lib/*.a $BUILD_DIR/$1/
} }
@ -85,12 +117,22 @@ for i in "$@"; do
DEPLOY_ARCHS=`echo $i | sed 's/[-a-zA-Z0-9]*=//'` DEPLOY_ARCHS=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
echo "[!] Selecting architectures: $DEPLOY_ARCHS" echo "[!] Selecting architectures: $DEPLOY_ARCHS"
;; ;;
--debug)
BUILD_TYPE=Debug
echo "[!] Selecting build type: Debug"
;;
--shared-lib)
BUILD_SHARED_LIBS=ON
echo "[!] Will generate dynamic libraries"
;;
-n|--no-fat) -n|--no-fat)
DEPLOY_FAT=0 DEPLOY_FAT=0
echo "[!] Fat binary will not be created." echo "[!] Fat binary will not be created."
;; ;;
-h|--help) -h|--help)
echo " - don't build fat library (--no-fat)." echo " - don't build fat library (--no-fat)."
echo " - Include debug information and symbols, no compiler optimizations (--debug)."
echo " - generate dynamic libraries rather than static ones (--shared-lib)."
echo " - supported architectures (--archs): $(echo $(join , ${BUILD_ARCHS_ALL[*]}) | sed 's/,/, /g')" echo " - supported architectures (--archs): $(echo $(join , ${BUILD_ARCHS_ALL[*]}) | sed 's/,/, /g')"
echo " - supported C++ STD libs (--stdlib): $(echo $(join , ${CPP_STD_LIB_LIST[*]}) | sed 's/,/, /g')" echo " - supported C++ STD libs (--stdlib): $(echo $(join , ${CPP_STD_LIB_LIST[*]}) | sed 's/,/, /g')"
echo " - supported C++ standards (--std): $(echo $(join , ${CPP_STD_LIST[*]}) | sed 's/,/, /g')" echo " - supported C++ standards (--std): $(echo $(join , ${CPP_STD_LIST[*]}) | sed 's/,/, /g')"
@ -105,29 +147,56 @@ cd ../../
rm -rf $BUILD_DIR rm -rf $BUILD_DIR
for ARCH_TARGET in $DEPLOY_ARCHS; do for ARCH_TARGET in $DEPLOY_ARCHS; do
echo "Creating folder: $BUILD_DIR/$ARCH_TARGET"
mkdir -p $BUILD_DIR/$ARCH_TARGET mkdir -p $BUILD_DIR/$ARCH_TARGET
echo "Building for arc: $ARCH_TARGET"
build_arch $ARCH_TARGET build_arch $ARCH_TARGET
#rm ./lib/libassimp.a #rm ./lib/libassimp.a
done done
make_fat_binary() make_fat_static_or_shared_binary()
{
LIB_NAME=$1
LIPO_ARGS=''
for ARCH_TARGET in $DEPLOY_ARCHS; do
if [[ "$BUILD_SHARED_LIBS" =~ "ON" ]]; then
LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.dylib "
else
LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.a "
fi
done
if [[ "$BUILD_SHARED_LIBS" =~ "ON" ]]; then
LIPO_ARGS="$LIPO_ARGS -create -output $BUILD_DIR/$LIB_NAME-fat.dylib"
else
LIPO_ARGS="$LIPO_ARGS -create -output $BUILD_DIR/$LIB_NAME-fat.a"
fi
lipo $LIPO_ARGS
}
make_fat_static_binary()
{ {
LIB_NAME=$1 LIB_NAME=$1
LIPO_ARGS='' LIPO_ARGS=''
for ARCH_TARGET in $DEPLOY_ARCHS; do for ARCH_TARGET in $DEPLOY_ARCHS; do
LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.a " LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.a "
done done
LIPO_ARGS="$LIPO_ARGS-create -output $BUILD_DIR/$LIB_NAME-fat.a" LIPO_ARGS="$LIPO_ARGS -create -output $BUILD_DIR/$LIB_NAME-fat.a"
lipo $LIPO_ARGS lipo $LIPO_ARGS
} }
if [[ "$DEPLOY_FAT" -eq 1 ]]; then if [[ "$DEPLOY_FAT" -eq 1 ]]; then
echo '[+] Creating fat binaries ...' echo '[+] Creating fat binaries ...'
make_fat_binary 'libassimp' if [[ "$BUILD_TYPE" =~ "Debug" ]]; then
make_fat_binary 'libIrrXML' make_fat_static_or_shared_binary 'libassimpd'
make_fat_binary 'libzlibstatic' make_fat_static_binary 'libIrrXMLd'
make_fat_static_binary 'libzlibstaticd'
else
make_fat_static_or_shared_binary 'libassimp'
make_fat_static_binary 'libIrrXML'
make_fat_static_binary 'libzlibstatic'
fi
echo "[!] Done! The fat binaries can be found at $BUILD_DIR" echo "[!] Done! The fat binaries can be found at $BUILD_DIR"
fi fi

View File

@ -0,0 +1,7 @@
CameraObject {
Param (attrib = "fov") { float { 0.97 } }
Param (attrib = "near") { float { 1.5 } }
Param (attrib = "far") { float { 150.0 } }
}
CameraObject {}

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Gary Hsu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,63 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 1024,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_00.bin",
"byteLength": 12288
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 12288,
"name": "Positions"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"mode": 0
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,63 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 8,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_01.bin",
"byteLength": 96
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 96,
"name": "Positions"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"mode": 1
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,63 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_02.bin",
"byteLength": 48
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"mode": 2
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,63 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 5,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_03.bin",
"byteLength": 60
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 60,
"name": "Positions"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"mode": 3
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,63 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_04.bin",
"byteLength": 48
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"mode": 5
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,63 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_05.bin",
"byteLength": 48
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"mode": 6
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,62 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 6,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_06.bin",
"byteLength": 72
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 72,
"name": "Positions"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
}
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,77 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 1024,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5125,
"count": 1024,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_07.bin",
"byteLength": 16384
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 12288,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 12288,
"byteLength": 4096,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1,
"mode": 0
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,77 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5125,
"count": 8,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_08.bin",
"byteLength": 80
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 48,
"byteLength": 32,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1,
"mode": 1
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,77 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5125,
"count": 4,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_09.bin",
"byteLength": 64
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 48,
"byteLength": 16,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1,
"mode": 2
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,77 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5125,
"count": 5,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_10.bin",
"byteLength": 68
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 48,
"byteLength": 20,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1,
"mode": 3
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,77 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5125,
"count": 4,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_11.bin",
"byteLength": 64
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 48,
"byteLength": 16,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1,
"mode": 5
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,77 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5125,
"count": 4,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_12.bin",
"byteLength": 64
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 48,
"byteLength": 16,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1,
"mode": 6
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,76 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5125,
"count": 6,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_13.bin",
"byteLength": 72
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 48,
"byteLength": 24,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,76 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5121,
"count": 6,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_14.bin",
"byteLength": 54
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 48,
"byteLength": 6,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,76 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 4,
"type": "VEC3",
"max": [
0.5,
0.5,
0.0
],
"min": [
-0.5,
-0.5,
0.0
],
"name": "Positions Accessor"
},
{
"bufferView": 1,
"componentType": 5123,
"count": 6,
"type": "SCALAR",
"name": "Indices Accessor"
}
],
"asset": {
"generator": "glTF Asset Generator",
"version": "2.0"
},
"buffers": [
{
"uri": "Mesh_PrimitiveMode_15.bin",
"byteLength": 60
}
],
"bufferViews": [
{
"buffer": 0,
"byteLength": 48,
"name": "Positions"
},
{
"buffer": 0,
"byteOffset": 48,
"byteLength": 12,
"name": "Indices"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"POSITION": 0
},
"indices": 1
}
]
}
],
"nodes": [
{
"mesh": 0
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
]
}

View File

@ -0,0 +1,33 @@
These models are intended to test indices, vertexes without indices, and using mode to render different primitive types.
All values of Byte, Short, and Int are unsigned.
All model indices relate to vertices as shown by the Indices figure below, except for models using Points Mode:
| Indices | Indices (For Points Mode) |
| :---: | :---: |
| <img src="Figures/Indices.png" height="144" width="144" align="middle"> | <img src="Figures/Indices_Points.png" height="144" width="144" align="middle"> |
<br>
The following table shows the properties that are set for a given model.
| | Sample Image | Mode | Indices Values | Indices Component Type |
| :---: | :---: | :---: | :---: | :---: |
| [00](Mesh_PrimitiveMode_00.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=0) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_00.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_00.png) | Points | | |
| [01](Mesh_PrimitiveMode_01.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=1) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_01.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_01.png) | Lines | | |
| [02](Mesh_PrimitiveMode_02.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=2) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_02.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_02.png) | Line Loop | | |
| [03](Mesh_PrimitiveMode_03.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=3) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_03.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_03.png) | Line Strip | | |
| [04](Mesh_PrimitiveMode_04.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=4) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_04.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_04.png) | Triangle Strip | | |
| [05](Mesh_PrimitiveMode_05.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=5) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_05.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_05.png) | Triangle Fan | | |
| [06](Mesh_PrimitiveMode_06.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=6) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_06.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_06.png) | Triangles | | |
| [07](Mesh_PrimitiveMode_07.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=7) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_07.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_07.png) | Points | [0 - 1023] | Int |
| [08](Mesh_PrimitiveMode_08.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=8) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_08.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_08.png) | Lines | [0, 3, 3, 2, 2, 1, 1, 0] | Int |
| [09](Mesh_PrimitiveMode_09.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=9) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_09.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_09.png) | Line Loop | [0, 3, 2, 1] | Int |
| [10](Mesh_PrimitiveMode_10.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=10) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_10.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_10.png) | Line Strip | [0, 3, 2, 1, 0] | Int |
| [11](Mesh_PrimitiveMode_11.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=11) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_11.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_11.png) | Triangle Strip | [0, 3, 1, 2] | Int |
| [12](Mesh_PrimitiveMode_12.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=12) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_12.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_12.png) | Triangle Fan | [0, 3, 2, 1] | Int |
| [13](Mesh_PrimitiveMode_13.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=13) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_13.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_13.png) | Triangles | [1, 0, 3, 1, 3, 2] | Int |
| [14](Mesh_PrimitiveMode_14.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=14) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_14.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_14.png) | Triangles | [1, 0, 3, 1, 3, 2] | Byte |
| [15](Mesh_PrimitiveMode_15.gltf)<br>[View](https://bghgary.github.io/glTF-Assets-Viewer/?folder=12&model=15) | [<img src="Figures/Thumbnails/Mesh_PrimitiveMode_15.png" align="middle">](Figures/SampleImages/Mesh_PrimitiveMode_15.png) | Triangles | [1, 0, 3, 1, 3, 2] | Short |

View File

@ -120,8 +120,7 @@ TEST_F(MaterialSystemTest, testColorProperty)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testStringProperty) TEST_F(MaterialSystemTest, testStringProperty) {
{
aiString s; aiString s;
s.Set("Hello, this is a small test"); s.Set("Hello, this is a small test");
this->pcMat->AddProperty(&s,"testKey6"); this->pcMat->AddProperty(&s,"testKey6");
@ -129,3 +128,24 @@ TEST_F(MaterialSystemTest, testStringProperty)
EXPECT_EQ(AI_SUCCESS, pcMat->Get("testKey6",0,0,s)); EXPECT_EQ(AI_SUCCESS, pcMat->Get("testKey6",0,0,s));
EXPECT_STREQ("Hello, this is a small test", s.data); EXPECT_STREQ("Hello, this is a small test", s.data);
} }
// ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testDefaultMaterialAccess) {
aiMaterial *mat = aiCreateAndRegisterDefaultMaterial();
EXPECT_NE(nullptr, mat);
aiReleaseDefaultMaterial();
delete mat;
}
// ------------------------------------------------------------------------------------------------
TEST_F(MaterialSystemTest, testMaterialNameAccess) {
aiMaterial *mat = aiCreateAndRegisterDefaultMaterial();
EXPECT_NE(nullptr, mat);
aiString name = mat->GetName();
const int retValue(strncmp(name.C_Str(), AI_DEFAULT_MATERIAL_NAME, name.length));
EXPECT_EQ(0, retValue );
delete mat;
}

View File

@ -68,3 +68,9 @@ TEST_F( utOpenGEXImportExport, Importissue1262_NoCrash ) {
EXPECT_NE( nullptr, scene ); EXPECT_NE( nullptr, scene );
} }
TEST_F(utOpenGEXImportExport, Importissue1340_EmptyCameraObject) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OpenGEX/empty_camera.ogex", 0);
EXPECT_NE(nullptr, scene);
}

View File

@ -63,7 +63,7 @@ public:
} }
}; };
TEST_F( utSTLImporterExporter, importXFromFileTest ) { TEST_F( utSTLImporterExporter, importSTLFromFileTest ) {
EXPECT_TRUE( importerTest() ); EXPECT_TRUE( importerTest() );
} }

View File

@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exporter.hpp> #include <assimp/Exporter.hpp>
#include <assimp/postprocess.h> #include <assimp/postprocess.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <array>
using namespace Assimp; using namespace Assimp;
@ -100,6 +101,234 @@ TEST_F( utglTF2ImportExport, importBinaryglTF2FromFileTest ) {
EXPECT_TRUE( binaryImporterTest() ); EXPECT_TRUE( binaryImporterTest() );
} }
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModePointsWithoutIndices) {
Assimp::Importer importer;
//Points without indices
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_00.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 1024);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mNumIndices, 1);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], i);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLinesWithoutIndices) {
Assimp::Importer importer;
//Lines without indices
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_01.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 8);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mNumIndices, 2);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], i*2);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[1], i*2 + 1);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLinesLoopWithoutIndices) {
Assimp::Importer importer;
//Lines loop without indices
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_02.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4);
std::array<int, 5> l1 = {{ 0, 1, 2, 3, 0 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mNumIndices, 2);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[1], l1[i + 1]);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLinesStripWithoutIndices) {
Assimp::Importer importer;
//Lines strip without indices
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_03.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 5);
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mNumIndices, 2);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], i);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[1], i + 1);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesStripWithoutIndices) {
Assimp::Importer importer;
//Triangles strip without indices
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_04.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4);
std::array<int, 3> f1 = {{ 0, 1, 2 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]);
}
std::array<int, 3> f2 = {{ 2, 1, 3 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesFanWithoutIndices) {
Assimp::Importer importer;
//Triangles fan without indices
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_05.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4);
std::array<int, 3> f1 = {{ 0, 1, 2 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]);
}
std::array<int, 3> f2 = {{ 0, 2, 3 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesWithoutIndices) {
Assimp::Importer importer;
//Triangles without indices
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_06.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 6);
std::array<int, 3> f1 = {{ 0, 1, 2 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]);
}
std::array<int, 3> f2 = {{ 3, 4, 5 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModePoints) {
Assimp::Importer importer;
//Line loop
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_07.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 1024);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mNumIndices, 1);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], i);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLines) {
Assimp::Importer importer;
//Lines
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_08.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4);
std::array<int, 5> l1 = {{ 0, 3, 2, 1, 0 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[1], l1[i + 1]);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLineLoop) {
Assimp::Importer importer;
//Line loop
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_09.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4);
std::array<int, 5> l1 = {{ 0, 3, 2, 1, 0 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[1], l1[i+1]);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeLineStrip) {
Assimp::Importer importer;
//Lines Strip
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_10.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4);
std::array<int, 5> l1 = {{ 0, 3, 2, 1, 0 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 2);
for (unsigned int i = 0; i < scene->mMeshes[0]->mNumFaces; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[0], l1[i]);
EXPECT_EQ(scene->mMeshes[0]->mFaces[i].mIndices[1], l1[i + 1]);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesStrip) {
Assimp::Importer importer;
//Triangles strip
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_11.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4);
std::array<int, 3> f1 = {{ 0, 3, 1 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]);
}
std::array<int, 3> f2 = {{ 1, 3, 2 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]);
}
}
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModeTrianglesFan) {
Assimp::Importer importer;
//Triangles fan
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/glTF-Asset-Generator/Mesh_PrimitiveMode/Mesh_PrimitiveMode_12.gltf", aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mMeshes[0]->mNumVertices, 4);
EXPECT_EQ(scene->mMeshes[0]->mNumFaces, 2);
std::array<int, 3> f1 = {{ 0, 3, 2 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[0].mIndices[i], f1[i]);
}
std::array<int, 3> f2 = {{ 0, 2, 1 }};
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mNumIndices, 3);
for (int i = 0; i < 3; ++i)
{
EXPECT_EQ(scene->mMeshes[0]->mFaces[1].mIndices[i], f2[i]);
}
}
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) { TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
EXPECT_TRUE( exporterTest() ); EXPECT_TRUE( exporterTest() );

View File

@ -3,52 +3,28 @@ project(assimp_qt_viewer)
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
OPTION( ASSIMP_QT4_VIEWER
"Set to ON to enable Qt4 against Qt5 for assimp_qt_viewer"
OFF
)
FIND_PACKAGE(DevIL QUIET)
FIND_PACKAGE(OpenGL QUIET) FIND_PACKAGE(OpenGL QUIET)
IF(ASSIMP_QT4_VIEWER) # Qt5 version
# Qt4 version FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
FIND_PACKAGE(Qt4 QUIET)
ELSE(ASSIMP_QT4_VIEWER)
# Qt5 version
FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
ENDIF(ASSIMP_QT4_VIEWER)
SET(VIEWER_BUILD:BOOL FALSE) SET(VIEWER_BUILD:BOOL FALSE)
IF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) IF( Qt5Widgets_FOUND AND OPENGL_FOUND)
SET(VIEWER_BUILD TRUE) SET(VIEWER_BUILD TRUE)
ELSE( Qt5Widgets_FOUND AND OPENGL_FOUND)
ELSE((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "") SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
IF(ASSIMP_QT4_VIEWER)
IF (NOT Qt4_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt4")
ENDIF (NOT Qt4_FOUND)
ELSE(ASSIMP_QT4_VIEWER)
IF (NOT Qt5_FOUND) IF (NOT Qt5_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5") SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
ENDIF (NOT Qt5_FOUND) ENDIF (NOT Qt5_FOUND)
ENDIF(ASSIMP_QT4_VIEWER)
IF (NOT IL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL")
ENDIF (NOT IL_FOUND)
IF (NOT OPENGL_FOUND) IF (NOT OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL") SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
ENDIF (NOT OPENGL_FOUND) ENDIF (NOT OPENGL_FOUND)
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}") MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
ENDIF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND) ENDIF( Qt5Widgets_FOUND AND OPENGL_FOUND)
IF(VIEWER_BUILD) IF(VIEWER_BUILD)
INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
@ -63,28 +39,23 @@ IF(VIEWER_BUILD)
LINK_DIRECTORIES(${Assimp_BINARY_DIR}) LINK_DIRECTORIES(${Assimp_BINARY_DIR})
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
SET(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp) SET(assimp_qt_viewer_SRCS
main.cpp
loggerview.hpp
loggerview.cpp
glview.hpp
glview.cpp
mainwindow.hpp
mainwindow.cpp
)
IF(ASSIMP_QT4_VIEWER)
MESSAGE("assimp_qt_viewer use Qt4")
ADD_DEFINITIONS( -DASSIMP_QT4_VIEWER )
INCLUDE_DIRECTORIES(${QT_INCLUDES})
qt4_wrap_ui(UISrcs mainwindow.ui)
qt4_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
ELSE()
MESSAGE("assimp_qt_viewer use Qt5") MESSAGE("assimp_qt_viewer use Qt5")
INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES}) INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
qt5_wrap_ui(UISrcs mainwindow.ui) qt5_wrap_ui(UISrcs mainwindow.ui)
qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp) qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
ENDIF()
add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs}) add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
IF(ASSIMP_QT4_VIEWER)
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
ELSE()
target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp) target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
ENDIF()
IF(WIN32) # Check if we are on Windows IF(WIN32) # Check if we are on Windows
IF(MSVC) # Check if we are using the Visual Studio compiler IF(MSVC) # Check if we are using the Visual Studio compiler

View File

@ -1,8 +1,45 @@
/// \file glview.cpp /*
/// \brief OpenGL visualisation. Implementation file. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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 "glview.hpp" #include "glview.hpp"
// Header files, Qt. // Header files, Qt.
@ -16,40 +53,30 @@
#endif #endif
// Header files, DevIL. // Header files, DevIL.
#include <il.h>
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#ifndef __unused #define STB_IMAGE_IMPLEMENTATION
#define __unused __attribute__((unused)) #include "stb_image.h"
#endif // __unused
/**********************************/
/********** SHelper_Mesh **********/
/**********************************/
CGLView::SHelper_Mesh::SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox) CGLView::SHelper_Mesh::SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox)
: Quantity_Point(pQuantity_Point), Quantity_Line(pQuantity_Line), Quantity_Triangle(pQuantity_Triangle), BBox(pBBox) : Quantity_Point(pQuantity_Point)
{ , Quantity_Line(pQuantity_Line)
, Quantity_Triangle(pQuantity_Triangle)
, BBox(pBBox) {
Index_Point = pQuantity_Point ? new GLuint[pQuantity_Point * 1] : nullptr; Index_Point = pQuantity_Point ? new GLuint[pQuantity_Point * 1] : nullptr;
Index_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr; Index_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr;
Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr; Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr;
} }
CGLView::SHelper_Mesh::~SHelper_Mesh() CGLView::SHelper_Mesh::~SHelper_Mesh() {
{ delete [] Index_Point;
if(Index_Point != nullptr) delete [] Index_Point; delete [] Index_Line;
if(Index_Line != nullptr) delete [] Index_Line; delete [] Index_Triangle;
if(Index_Triangle != nullptr) delete [] Index_Triangle;
} }
/**********************************/ void CGLView::SHelper_Camera::SetDefault() {
/********** SHelper_Mesh **********/
/**********************************/
void CGLView::SHelper_Camera::SetDefault()
{
Position.Set(0, 0, 0); Position.Set(0, 0, 0);
Target.Set(0, 0, -1); Target.Set(0, 0, -1);
Rotation_AroundCamera = aiMatrix4x4(); Rotation_AroundCamera = aiMatrix4x4();
@ -57,39 +84,21 @@ void CGLView::SHelper_Camera::SetDefault()
Translation_ToScene.Set(0, 0, 2); Translation_ToScene.Set(0, 0, 2);
} }
/**********************************/ static void set_float4(float f[4], float a, float b, float c, float d) {
/************ CGLView *************/ f[0] = a;
/**********************************/ f[1] = b;
f[2] = c;
f[3] = d;
}
#if !ASSIMP_QT4_VIEWER static void color4_to_float4(const aiColor4D *c, float f[4]) {
# define ConditionalContextControl_Begin \ f[0] = c->r;
bool ContextEnabledHere; \ f[1] = c->g;
\ f[2] = c->b;
if(mGLContext_Current) \ f[3] = c->a;
{ \ }
ContextEnabledHere = false; \
} \
else \
{ \
makeCurrent(); \
mGLContext_Current = true; \
ContextEnabledHere = true; \
} \
\
do {} while(false)
# define ConditionalContextControl_End \ void CGLView::Material_Apply(const aiMaterial* pMaterial) {
if(ContextEnabledHere) \
{ \
doneCurrent(); \
mGLContext_Current = false; \
} \
\
do {} while(false)
#endif // ASSIMP_QT4_VIEWER
void CGLView::Material_Apply(const aiMaterial* pMaterial)
{
GLfloat tcol[4]; GLfloat tcol[4];
aiColor4D taicol; aiColor4D taicol;
unsigned int max; unsigned int max;
@ -97,15 +106,12 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
int texture_index = 0; int texture_index = 0;
aiString texture_path; aiString texture_path;
auto set_float4 = [](float f[4], float a, float b, float c, float d) { f[0] = a, f[1] = b, f[2] = c, f[3] = d; };
auto color4_to_float4 = [](const aiColor4D *c, float f[4]) { f[0] = c->r, f[1] = c->g, f[2] = c->b, f[3] = c->a; };
///TODO: cache materials ///TODO: cache materials
// Disable color material because glMaterial is used. // Disable color material because glMaterial is used.
glDisable(GL_COLOR_MATERIAL);///TODO: cache glDisable(GL_COLOR_MATERIAL);///TODO: cache
// Set texture. If assigned. // Set texture. If assigned.
if(AI_SUCCESS == pMaterial->GetTexture(aiTextureType_DIFFUSE, texture_index, &texture_path)) if(AI_SUCCESS == pMaterial->GetTexture(aiTextureType_DIFFUSE, texture_index, &texture_path)) {
{
//bind texture //bind texture
unsigned int texture_ID = mTexture_IDMap.value(texture_path.data, 0); unsigned int texture_ID = mTexture_IDMap.value(texture_path.data, 0);
@ -116,19 +122,26 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
// //
// Diffuse // Diffuse
set_float4(tcol, 0.8f, 0.8f, 0.8f, 1.0f); set_float4(tcol, 0.8f, 0.8f, 0.8f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_DIFFUSE, &taicol)) color4_to_float4(&taicol, tcol); if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_DIFFUSE, &taicol )) {
color4_to_float4( &taicol, tcol );
}
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, tcol);
// Specular // Specular
set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f); set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_SPECULAR, &taicol)) color4_to_float4(&taicol, tcol); if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_SPECULAR, &taicol )) {
color4_to_float4( &taicol, tcol );
}
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol);
// Ambient // Ambient
set_float4(tcol, 0.2f, 0.2f, 0.2f, 1.0f); set_float4(tcol, 0.2f, 0.2f, 0.2f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_AMBIENT, &taicol)) color4_to_float4(&taicol, tcol); if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_AMBIENT, &taicol )) {
color4_to_float4( &taicol, tcol );
}
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, tcol);
// Emission // Emission
set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f); set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f);
if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_EMISSIVE, &taicol)) color4_to_float4(&taicol, tcol); if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_EMISSIVE, &taicol)) color4_to_float4(&taicol, tcol);
@ -142,12 +155,9 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
// Shininess strength // Shininess strength
max = 1; max = 1;
ret2 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); ret2 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) {
{
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);///TODO: cache glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);///TODO: cache
} } else {
else
{
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);///TODO: cache glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);///TODO: cache
set_float4(tcol, 0.0f, 0.0f, 0.0f, 0.0f); set_float4(tcol, 0.0f, 0.0f, 0.0f, 0.0f);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol);
@ -199,38 +209,26 @@ void CGLView::Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix)
} }
} }
void CGLView::ImportTextures(const QString& pScenePath) void CGLView::ImportTextures(const QString& scenePath) {
{
auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation. auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation.
{ {
ILboolean success;
GLuint id_ogl_texture;// OpenGL texture ID. GLuint id_ogl_texture;// OpenGL texture ID.
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX)) if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
{ {
ILuint id_image;// DevIL image ID. QString basepath = scenePath.left(scenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString fileloc = (basepath + pFileName); QString fileloc = (basepath + pFileName);
fileloc.replace('\\', "/"); fileloc.replace('\\', "/");
ilGenImages(1, &id_image);// Generate DevIL image ID. int x, y, n;
ilBindImage(id_image); unsigned char *data = stbi_load(fileloc.toLocal8Bit(), &x, &y, &n, STBI_rgb_alpha );
success = ilLoadImage(fileloc.toLocal8Bit()); if ( nullptr == data ) {
if(!success)
{
LogError(QString("Couldn't load Image: %1").arg(fileloc)); LogError(QString("Couldn't load Image: %1").arg(fileloc));
return false; return false;
} }
// Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA. // Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA.
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
if(!success)
{
LogError("Couldn't convert image.");
return false;
}
glGenTextures(1, &id_ogl_texture);// Texture ID generation. glGenTextures(1, &id_ogl_texture);// Texture ID generation.
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
@ -238,11 +236,9 @@ void CGLView::ImportTextures(const QString& pScenePath)
// Redefine standard texture values // Redefine standard texture values
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0, glTexImage2D(GL_TEXTURE_2D, 0, n, x, y, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, data );// Texture specification.
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
//Cleanup // Cleanup
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
} }
else else
{ {
@ -321,27 +317,18 @@ void CGLView::ImportTextures(const QString& pScenePath)
return; return;
} }
// Before calling ilInit() version should be checked.
if(ilGetInteger(IL_VERSION_NUM) < IL_VERSION)
{
LogError("Wrong DevIL version.");
return;
}
ilInit();// Initialization of DevIL.
// //
// Load textures. // Load textures.
// //
// Get textures file names and number of textures. // Get textures file names and number of textures.
for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) {
{
int idx_texture = 0; int idx_texture = 0;
aiString path; aiString path;
do do {
{ if (mScene->mMaterials[ idx_material ]->GetTexture( aiTextureType_DIFFUSE, idx_texture, &path ) != AI_SUCCESS) {
if(mScene->mMaterials[idx_material]->GetTexture(aiTextureType_DIFFUSE, idx_texture, &path) != AI_SUCCESS) break; break;
}
LoadTexture(QString(path.C_Str())); LoadTexture(QString(path.C_Str()));
idx_texture++; idx_texture++;
@ -349,11 +336,8 @@ void CGLView::ImportTextures(const QString& pScenePath)
}// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) }// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++)
// Textures list is empty, exit. // Textures list is empty, exit.
if(mTexture_IDMap.size() == 0) if(mTexture_IDMap.empty()) {
{
LogInfo("No textures for import."); LogInfo("No textures for import.");
return;
} }
} }
@ -451,32 +435,21 @@ void CGLView::BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVe
} }
} }
/********************************************************************/ void CGLView::LogInfo(const QString& pMessage) {
/************************ Logging functions *************************/
/********************************************************************/
void CGLView::LogInfo(const QString& pMessage)
{
Assimp::DefaultLogger::get()->info(pMessage.toStdString()); Assimp::DefaultLogger::get()->info(pMessage.toStdString());
} }
void CGLView::LogError(const QString& pMessage) void CGLView::LogError(const QString& pMessage) {
{
Assimp::DefaultLogger::get()->error(pMessage.toStdString()); Assimp::DefaultLogger::get()->error(pMessage.toStdString());
} }
/********************************************************************/ void CGLView::Draw_Node(const aiNode* pNode) {
/************************** Draw functions **************************/
/********************************************************************/
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();
glPushMatrix(); glPushMatrix();
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)mat_node[0]); glMultMatrixd((GLdouble*)mat_node[0]);
#else #else
glMultMatrixf((GLfloat*)&mat_node); glMultMatrixf((GLfloat*)&mat_node);
@ -518,7 +491,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
{ {
glEnable(GL_COLOR_MATERIAL);///TODO: cache glEnable(GL_COLOR_MATERIAL);///TODO: cache
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]); glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]);
#else #else
glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]); glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]);
@ -531,7 +504,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
if(mesh_cur.HasTextureCoords(0)) if(mesh_cur.HasTextureCoords(0))
{ {
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]); glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
#else #else
glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]); glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
@ -544,7 +517,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
if(mesh_cur.HasNormals()) if(mesh_cur.HasNormals())
{ {
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
#if ASSIMP_DOUBLE_PRECISION #ifdef ASSIMP_DOUBLE_PRECISION
glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals); glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals);
#else #else
glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals); glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals);
@ -581,16 +554,12 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
glBindTexture(GL_TEXTURE_1D, 0); glBindTexture(GL_TEXTURE_1D, 0);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
glBindTexture(GL_TEXTURE_3D, 0); glBindTexture(GL_TEXTURE_3D, 0);
#if ASSIMP_QT4_VIEWER
qglColor(QColor(Qt::white));
#else
const QColor c_w(Qt::white); const QColor c_w(Qt::white);
glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF()); glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF());
#endif // ASSIMP_QT4_VIEWER
glBegin(GL_LINE_STRIP); glBegin(GL_LINE_STRIP);
# if ASSIMP_DOUBLE_PRECISION # ifdef ASSIMP_DOUBLE_PRECISION
glVertex3dv(&vertex[0][0]), glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[0][0]);// "Minimum" side. glVertex3dv(&vertex[0][0]), glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[0][0]);// "Minimum" side.
glVertex3dv(&vertex[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side. glVertex3dv(&vertex[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side.
# else # else
@ -600,7 +569,7 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
glEnd(); glEnd();
glBegin(GL_LINES); glBegin(GL_LINES);
# if ASSIMP_DOUBLE_PRECISION # ifdef ASSIMP_DOUBLE_PRECISION
glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]); glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]);
glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]); glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]);
glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]); glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]);
@ -615,48 +584,28 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
} }
void CGLView::Enable_Textures(const bool pEnable) void CGLView::Enable_Textures(const bool pEnable) {
{ if(pEnable) {
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
if(pEnable)
{
glEnable(GL_TEXTURE_1D); glEnable(GL_TEXTURE_1D);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_3D); glEnable(GL_TEXTURE_3D);
} } else {
else
{
glDisable(GL_TEXTURE_1D); glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D); glDisable(GL_TEXTURE_3D);
} }
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
/********************************************************************/ void CGLView::initializeGL() {
/*********************** Override functions ************************/
/********************************************************************/
void CGLView::initializeGL()
{
#if ASSIMP_QT4_VIEWER
qglClearColor(Qt::gray);
#else
mGLContext_Current = true; mGLContext_Current = true;
initializeOpenGLFunctions(); initializeOpenGLFunctions();
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
#endif // ASSIMP_QT4_VIEWER
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE); glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glEnable( GL_MULTISAMPLE );
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
@ -668,25 +617,14 @@ void CGLView::initializeGL()
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CCW); glFrontFace(GL_CCW);
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::resizeGL(int pWidth, int pHeight) void CGLView::resizeGL(int width, int height) {
{ mCamera_Viewport_AspectRatio = (GLdouble)width / height;
#if !ASSIMP_QT4_VIEWER glViewport(0, 0, width, height);
mGLContext_Current = true;
#endif // ASSIMP_QT4_VIEWER
mCamera_Viewport_AspectRatio = (GLdouble)pWidth / pHeight;
glViewport(0, 0, pWidth, pHeight);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
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.
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::drawCoordSystem() { void CGLView::drawCoordSystem() {
@ -699,18 +637,7 @@ void CGLView::drawCoordSystem() {
glBindTexture(GL_TEXTURE_3D, 0); glBindTexture(GL_TEXTURE_3D, 0);
glEnable(GL_COLOR_MATERIAL); glEnable(GL_COLOR_MATERIAL);
glBegin(GL_LINES); glBegin(GL_LINES);
#if ASSIMP_QT4_VIEWER
// 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);
qglColor(QColor(Qt::white));
#else
// X, -X // X, -X
glColor3f(1.0f, 0.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0); glColor3f(1.0f, 0.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0);
glColor3f(0.5f, 0.5f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0); glColor3f(0.5f, 0.5f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
@ -721,19 +648,15 @@ void CGLView::drawCoordSystem() {
glColor3f(0.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0); glColor3f(0.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0);
glColor3f(1.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0); glColor3f(1.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0);
glColor3f(1.0f, 1.0f, 1.0f); glColor3f(1.0f, 1.0f, 1.0f);
#endif // ASSIMP_QT4_VIEWER
glEnd(); glEnd();
// Restore previous state of lighting. // Restore previous state of lighting.
if(mLightingEnabled) glEnable(GL_LIGHTING); if (mLightingEnabled) {
glEnable( GL_LIGHTING );
}
} }
void CGLView::paintGL() void CGLView::paintGL() {
{
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = true;
#endif // ASSIMP_QT4_VIEWER
QTime time_paintbegin; QTime time_paintbegin;
time_paintbegin = QTime::currentTime(); time_paintbegin = QTime::currentTime();
@ -741,6 +664,7 @@ void CGLView::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
// Apply current camera transformations. // Apply current camera transformations.
#if ASSIMP_DOUBLE_PRECISION #if ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera); glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera);
@ -753,58 +677,38 @@ void CGLView::paintGL()
#endif // ASSIMP_DOUBLE_PRECISION #endif // ASSIMP_DOUBLE_PRECISION
// Coordinate system // Coordinate system
if (mScene_AxesEnabled == true) if ( mScene_AxesEnabled ) {
{
drawCoordSystem(); drawCoordSystem();
} }
glDisable(GL_COLOR_MATERIAL); glDisable(GL_COLOR_MATERIAL);
// Scene // Scene
if(mScene != nullptr) if(mScene != nullptr) {
{
Draw_Node(mScene->mRootNode); Draw_Node(mScene->mRootNode);
// Scene BBox // Scene BBox
if(mScene_DrawBBox) Draw_BBox(mScene_BBox); if (mScene_DrawBBox) {
Draw_BBox( mScene_BBox );
}
} }
emit Paint_Finished((size_t)time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length()); emit Paint_Finished((size_t) time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length());
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
} }
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
CGLView::CGLView(QWidget *pParent) CGLView::CGLView( QWidget *pParent )
#if ASSIMP_QT4_VIEWER : QOpenGLWidget( pParent )
: QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer), pParent) , mGLContext_Current( false ) {
#else
: QOpenGLWidget(pParent), mGLContext_Current(false)
#endif // ASSIMP_QT4_VIEWER
{
// set initial view // set initial view
mHelper_CameraDefault.SetDefault(); mHelper_CameraDefault.SetDefault();
Camera_Set(0); Camera_Set( 0 );
} }
CGLView::~CGLView() CGLView::~CGLView() {
{
FreeScene(); FreeScene();
} }
/********************************************************************/ void CGLView::FreeScene() {
/********************* Scene control functions **********************/
/********************************************************************/
void CGLView::FreeScene()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
// Set scene to null and after that \ref paintGL will not try to render it. // Set scene to null and after that \ref paintGL will not try to render it.
mScene = nullptr; mScene = nullptr;
// Clean helper objects. // Clean helper objects.
@ -834,21 +738,14 @@ void CGLView::FreeScene()
mTexture_IDMap.clear(); mTexture_IDMap.clear();
delete [] id_tex; delete [] id_tex;
} }
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) {
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
FreeScene();// Clear old data FreeScene();// Clear old data
// Why checking here, not at begin of function. Because old scene may not exist at know. So, need cleanup. // Why checking here, not at begin of function. Because old scene may not exist at know. So, need cleanup.
if(pScene == nullptr) return; if (pScene == nullptr) {
return;
}
mScene = pScene;// Copy pointer of new scene. mScene = pScene;// Copy pointer of new scene.
@ -874,7 +771,7 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
BBox_GetFromVertices(mesh_cur.mVertices, mesh_cur.mNumVertices, mesh_bbox); BBox_GetFromVertices(mesh_cur.mVertices, mesh_cur.mNumVertices, mesh_bbox);
// //
// Create vertices indices arrays splited by primitive type. // Create vertices indices arrays splitted by primitive type.
// //
size_t indcnt_p = 0;// points quantity size_t indcnt_p = 0;// points quantity
size_t indcnt_l = 0;// lines quantity size_t indcnt_l = 0;// lines quantity
@ -1039,7 +936,10 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
}// switch(light_cur.mType) }// switch(light_cur.mType)
// Add light source // Add light source
if(name.isEmpty()) name += QString("%1").arg(idx_light);// Use index if name is empty. // Use index if name is empty.
if (name.isEmpty()) {
name += QString( "%1" ).arg( idx_light );
}
Lighting_EditSource(idx_light, lp); Lighting_EditSource(idx_light, lp);
emit SceneObject_LightSource(name);// Light source will be enabled in signal handler. emit SceneObject_LightSource(name);// Light source will be enabled in signal handler.
@ -1072,65 +972,47 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str()); emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str());
} }
}// if(!mScene->HasCameras()) else }// if(!mScene->HasCameras()) else
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
/********************************************************************/ void CGLView::Lighting_Enable() {
/******************** Lighting control functions ********************/
/********************************************************************/
void CGLView::Lighting_Enable()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
mLightingEnabled = true; mLightingEnabled = true;
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::Lighting_Disable() void CGLView::Lighting_Disable() {
{ glDisable( GL_LIGHTING );
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
glDisable(GL_LIGHTING);
mLightingEnabled = false; mLightingEnabled = false;
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters) void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
{ {
#if !ASSIMP_QT4_VIEWER const size_t light_num = GL_LIGHT0 + pLightNumber;
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
const size_t light_num = GL_LIGHT0 + pLightNumber; GLfloat farr[4];
GLfloat farr[4];
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
// Ambient color // Ambient color
farr[0] = pLightParameters.Ambient.r, farr[1] = pLightParameters.Ambient.g; farr[2] = pLightParameters.Ambient.b; farr[3] = pLightParameters.Ambient.a; farr[0] = pLightParameters.Ambient.r;
farr[1] = pLightParameters.Ambient.g;
farr[2] = pLightParameters.Ambient.b;
farr[3] = pLightParameters.Ambient.a;
glLightfv(light_num, GL_AMBIENT, farr); glLightfv(light_num, GL_AMBIENT, farr);
// Diffuse color // Diffuse color
farr[0] = pLightParameters.Diffuse.r, farr[1] = pLightParameters.Diffuse.g; farr[2] = pLightParameters.Diffuse.b; farr[3] = pLightParameters.Diffuse.a; farr[0] = pLightParameters.Diffuse.r;
farr[1] = pLightParameters.Diffuse.g;
farr[2] = pLightParameters.Diffuse.b;
farr[3] = pLightParameters.Diffuse.a;
glLightfv(light_num, GL_DIFFUSE, farr); glLightfv(light_num, GL_DIFFUSE, farr);
// Specular color // Specular color
farr[0] = pLightParameters.Specular.r, farr[1] = pLightParameters.Specular.g; farr[2] = pLightParameters.Specular.b; farr[3] = pLightParameters.Specular.a; farr[0] = pLightParameters.Specular.r;
farr[1] = pLightParameters.Specular.g;
farr[2] = pLightParameters.Specular.b;
farr[3] = pLightParameters.Specular.a;
glLightfv(light_num, GL_SPECULAR, farr); glLightfv(light_num, GL_SPECULAR, farr);
// Other parameters // Other parameters
switch(pLightParameters.Type) switch(pLightParameters.Type)
{ {
@ -1176,46 +1058,21 @@ GLfloat farr[4];
glLightf(light_num, GL_SPOT_CUTOFF, 180.0); glLightf(light_num, GL_SPOT_CUTOFF, 180.0);
break; break;
}// switch(pLightParameters.Type) }// switch(pLightParameters.Type)
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::Lighting_EnableSource(const size_t pLightNumber) void CGLView::Lighting_EnableSource(const size_t pLightNumber) {
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
glEnable(GL_LIGHT0 + pLightNumber); glEnable(GL_LIGHT0 + pLightNumber);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
void CGLView::Lighting_DisableSource(const size_t pLightNumber) void CGLView::Lighting_DisableSource(const size_t pLightNumber)
{ {
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value; if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
glDisable(GL_LIGHT0 + pLightNumber); glDisable(GL_LIGHT0 + pLightNumber);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
} }
/********************************************************************/
/******************** Cameras control functions *********************/
/********************************************************************/
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.
@ -1263,7 +1120,7 @@ void CGLView::Camera_Set(const size_t pCameraNumber)
void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) { void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) {
auto deg2rad = [](const GLfloat pDegree) -> GLfloat { auto deg2rad = [](const GLfloat pDegree) -> GLfloat {
return pDegree * AI_MATH_PI / 180.0; return pDegree * AI_MATH_PI / 180.0f;
}; };
aiMatrix4x4 mat_rot; aiMatrix4x4 mat_rot;

View File

@ -1,7 +1,45 @@
/// \file glview.hpp /*
/// \brief OpenGL visualisation. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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 #pragma once

View File

@ -1,19 +1,64 @@
/// \file loggerview.cpp /*
/// \brief Stream for Assimp logging subsystem. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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 "loggerview.hpp" #include "loggerview.hpp"
// Header files, Qt. // Header files, Qt.
#include <QTime> #include <QTime>
#include <QTextBrowser>
CLoggerView::CLoggerView(QTextBrowser* pOutputWidget) CLoggerView::CLoggerView(QTextBrowser* pOutputWidget)
: mOutputWidget(pOutputWidget) : mOutputWidget(pOutputWidget) {
{ // empty
} }
void CLoggerView::write(const char *pMessage) CLoggerView::~CLoggerView() {
{ mOutputWidget = nullptr;
}
void CLoggerView::write(const char *pMessage) {
if (nullptr == mOutputWidget) {
return;
}
mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage)); mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage));
} }

View File

@ -1,33 +1,67 @@
/// \file loggerview.hpp /*
/// \brief Stream for Assimp logging subsystem. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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 #pragma once
// Header files, Qt.
#include <QTextBrowser>
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
/// \class CLoggerView class QTextBrowser;
/// GUI-stream for Assimp logging subsytem. Get data for logging and write it to output widget.
class CLoggerView final : public Assimp::LogStream
{
private:
QTextBrowser* mOutputWidget;///< Widget for displaying messages.
/// @class CLoggerView
/// @brief GUI-stream for Assimp logging sub-sytem. Get data for logging and write it to output widget.
class CLoggerView final : public ::Assimp::LogStream {
public: public:
/// @brief The class constructor.
/// @param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView( QTextBrowser* pOutputWidget );
/// \fn explicit CLoggerView(QTextBrowser* pOutputWidget) /// @brief The class destructor.
/// Constructor. virtual ~CLoggerView();
/// \param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView(QTextBrowser* pOutputWidget);
/// \fn virtual void write(const char *pMessage)
/// Write message to output widget. Used by Assimp. /// Write message to output widget. Used by Assimp.
/// \param [in] pMessage - message for displaying. /// \param [in] pMessage - message for displaying.
virtual void write(const char *pMessage); virtual void write(const char *pMessage);
private:
QTextBrowser * mOutputWidget; ///< Widget for displaying messages.
}; };

View File

@ -1,7 +1,46 @@
/// \file main.cpp /*
/// \brief Start-up file which contain function "main". ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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.
---------------------------------------------------------------------------
*/
// Thanks to acorn89 for support. // Thanks to acorn89 for support.
// Header files, project. // Header files, project.
@ -11,9 +50,9 @@
#include <QApplication> #include <QApplication>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QApplication a(argc, argv); QApplication app(argc, argv);
MainWindow w; MainWindow win;
w.show(); win.show();
return a.exec(); return app.exec();
} }

View File

@ -1,7 +1,45 @@
/// \file mainwindow.hpp /*
/// \brief Main window and algorhytms. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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 "mainwindow.hpp" #include "mainwindow.hpp"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
@ -14,22 +52,13 @@
#define __unused __attribute__((unused)) #define __unused __attribute__((unused))
#endif // __unused #endif // __unused
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
void MainWindow::ImportFile(const QString &pFileName)
{
using namespace Assimp; using namespace Assimp;
QTime time_begin = QTime::currentTime();
if(mScene != nullptr) void MainWindow::ImportFile(const QString &pFileName) {
{ QTime time_begin = QTime::currentTime();
if ( mScene != nullptr ) {
mImporter.FreeScene(); mImporter.FreeScene();
mGLView->FreeScene(); mGLView->FreeScene();
} }
@ -37,8 +66,7 @@ QTime time_begin = QTime::currentTime();
// Try to import scene. // Try to import scene.
mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \ mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs); aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
if(mScene != nullptr) if ( mScene != nullptr ) {
{
ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime()))); ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
LogInfo("Import done: " + pFileName); LogInfo("Import done: " + pFileName);
// Prepare widgets for new scene. // Prepare widgets for new scene.
@ -60,8 +88,7 @@ QTime time_begin = QTime::currentTime();
size_t qty_face = 0; size_t qty_face = 0;
size_t qty_vert = 0; size_t qty_vert = 0;
for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) {
{
qty_face += mScene->mMeshes[idx_mesh]->mNumFaces; qty_face += mScene->mMeshes[idx_mesh]->mNumFaces;
qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices; qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices;
} }
@ -241,7 +268,6 @@ MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow), : QMainWindow(parent), ui(new Ui::MainWindow),
mScene(nullptr) mScene(nullptr)
{ {
using namespace Assimp;
// other variables // other variables
mMouse_Transformation.Position_Pressed_Valid = false; mMouse_Transformation.Position_Pressed_Valid = false;

View File

@ -1,7 +1,45 @@
/// \file mainwindow.hpp /*
/// \brief Main window and algorhytms. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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 #pragma once
@ -20,125 +58,64 @@
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
namespace Ui { class MainWindow; } namespace Ui {
class MainWindow;
}
/// \class MainWindow /// \class MainWindow
/// Main window and algorhytms. /// Main window and algorithms.
class MainWindow : public QMainWindow class MainWindow : public QMainWindow {
{
Q_OBJECT Q_OBJECT
/**********************************/ struct SMouse_Transformation;
/************ Variables ***********/
/**********************************/
private: public:
/// @brief The class constructor.
/// \param [in] pParent - pointer to parent widget.
explicit MainWindow( QWidget* pParent = 0 );
Ui::MainWindow *ui; /// @brief The class destructor.
~MainWindow();
CGLView* mGLView;///< Pointer to OpenGL render.
CLoggerView* mLoggerView;///< Pointer to logging object.
Assimp::Importer mImporter;///< Assimp importer.
const aiScene* mScene;///< Pointer to loaded scene (\ref aiScene).
/// \struct SMouse_Transformation
/// Holds data about transformation of the scene/camera when mouse us used.
struct SMouse_Transformation
{
bool Position_Pressed_Valid;///< Mouse button pressed on GLView.
QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button.
QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button.
aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
} mMouse_Transformation;
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
/// \fn void ImportFile(const QString& pFileName)
/// Import scene from file. /// Import scene from file.
/// \param [in] pFileName - path and name of the file. /// \param [in] pFileName - path and name of the file.
void ImportFile(const QString& pFileName); void ImportFile(const QString& pFileName);
/// \fn void ResetSceneInfos()
/// Reset informations about the scene /// Reset informations about the scene
void ResetSceneInfos(); void ResetSceneInfos();
/********************************************************************/
/************************ Logging functions *************************/
/********************************************************************/
/// \fn void LogInfo(const QString& pMessage)
/// Add message with severity "Warning" to log. /// Add message with severity "Warning" to log.
void LogInfo(const QString& pMessage); void LogInfo(const QString& pMessage);
/// \fn void LogError(const QString& pMessage)
/// Add message with severity "Error" to log. /// Add message with severity "Error" to log.
void LogError(const QString& pMessage); void LogError(const QString& pMessage);
/********************************************************************/
/*********************** Override functions ************************/
/********************************************************************/
protected: protected:
/// \fn void mousePressEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "button pressed". /// Override function which handles mouse event "button pressed".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mousePressEvent(QMouseEvent* pEvent) override; void mousePressEvent(QMouseEvent* pEvent) override;
/// \fn void mouseReleaseEvent(QMouseEvent *pEvent) override
/// Override function which handles mouse event "button released". /// Override function which handles mouse event "button released".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mouseReleaseEvent(QMouseEvent *pEvent) override; void mouseReleaseEvent(QMouseEvent *pEvent) override;
/// \fn void mouseMoveEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "move". /// Override function which handles mouse event "move".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mouseMoveEvent(QMouseEvent* pEvent) override; void mouseMoveEvent(QMouseEvent* pEvent) override;
/// \fn void keyPressEvent(QKeyEvent* pEvent) override
/// Override function which handles key event "key pressed". /// Override function which handles key event "key pressed".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void keyPressEvent(QKeyEvent* pEvent) override; void keyPressEvent(QKeyEvent* pEvent) override;
public:
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
/// \fn explicit MainWindow(QWidget* pParent = 0)
/// \param [in] pParent - pointer to parent widget.
explicit MainWindow(QWidget* pParent = 0);
/// \fn ~MainWindow()
/// Destructor.
~MainWindow();
/********************************************************************/
/****************************** Slots *******************************/
/********************************************************************/
private slots: private slots:
/// \fn void Paint_Finished(const int pPaintTime)
/// Show paint/render time and distance between camera and center of the scene. /// Show paint/render time and distance between camera and center of the scene.
/// \param [in] pPaintTime_ms - paint time in milliseconds. /// \param [in] pPaintTime_ms - paint time in milliseconds.
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance); void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
/// \fn void SceneObject_Camera(const QString& pName)
/// Add camera name to list. /// Add camera name to list.
/// \param [in] pName - name of the camera. /// \param [in] pName - name of the camera.
void SceneObject_Camera(const QString& pName); void SceneObject_Camera(const QString& pName);
/// \fn void SceneObject_LightSource(const QString& pName)
/// Add lighting source name to list. /// Add lighting source name to list.
/// \param [in] pName - name of the light source, /// \param [in] pName - name of the light source,
void SceneObject_LightSource(const QString& pName); void SceneObject_LightSource(const QString& pName);
@ -151,4 +128,21 @@ private slots:
void on_cbxBBox_clicked(bool checked); void on_cbxBBox_clicked(bool checked);
void on_cbxTextures_clicked(bool checked); void on_cbxTextures_clicked(bool checked);
void on_cbxDrawAxes_clicked(bool checked); void on_cbxDrawAxes_clicked(bool checked);
private:
Ui::MainWindow *ui;
CGLView *mGLView;///< Pointer to OpenGL render.
CLoggerView *mLoggerView;///< Pointer to logging object.
Assimp::Importer mImporter;///< Assimp importer.
const aiScene* mScene;///< Pointer to loaded scene (\ref aiScene).
/// \struct SMouse_Transformation
/// Holds data about transformation of the scene/camera when mouse us used.
struct SMouse_Transformation {
bool Position_Pressed_Valid;///< Mouse button pressed on GLView.
QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button.
QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button.
aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
} mMouse_Transformation;
}; };

File diff suppressed because it is too large Load Diff