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/zlib.pc
include/assimp/config.h
unit.vcxproj.user
# CMake
CMakeCache.txt
@ -87,3 +88,9 @@ lib64/assimp-vc120-mt.exp
xcuserdata
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 )
# All supported options ###############################################
OPTION( BUILD_SHARED_LIBS
"Build package with shared libraries."
ON
)
OPTION( BUILD_FRAMEWORK
"Build package as Mac OS X Framework bundle."
OFF
@ -103,6 +105,16 @@ OPTION ( BUILD_DOCS
"Build documentation using Doxygen."
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
if (WIN32)
@ -204,7 +216,7 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
ELSEIF(MSVC)
# enable multi-core compilation with MSVC
ADD_COMPILE_OPTIONS(/MP)
IF("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
ADD_COMPILE_OPTIONS( /bigobj )
ENDIF()
# 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_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
ELSEIF( CMAKE_COMPILER_IS_MINGW )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
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 ")
ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF()
IF (IOS)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
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_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
ENDIF()
ENDIF( IOS )
IF (ASSIMP_COVERALLS)
MESSAGE(STATUS "Coveralls enabled")
INCLUDE(Coveralls)
@ -329,9 +348,17 @@ ENDIF(NOT ZLIB_FOUND)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
# Search for unzip
IF( NOT ASSIMP_BUILD_MINIZIP )
use_pkgconfig(UNZIP minizip)
ENDIF( NOT ASSIMP_BUILD_MINIZIP )
IF ( NOT IOS )
IF( NOT ASSIMP_BUILD_MINIZIP )
use_pkgconfig(UNZIP 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 )
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT)
@ -416,7 +443,9 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
IF (NOT IOS)
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
ENDIF (NOT IOS)
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
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
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
#### Supported file formats ####
__Importers__:

View File

@ -272,6 +272,8 @@ void aiReleaseImport( const aiScene* pScene)
ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
// find the importer associated with this data
const ScenePrivateData* priv = ScenePriv(pScene);
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/scene.h>
#include <assimp/importerdesc.h>
#include <map>
using namespace Assimp;
using namespace Assimp::Formatter;
@ -461,6 +462,13 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
aiNodeAnim* nodeAnim = new aiNodeAnim;
anim->mChannels[a] = nodeAnim;
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
if( node.mChannels.size() == 6)
@ -472,16 +480,32 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{
poskey->mTime = double( fr);
// Now compute all translations in the right order
for( unsigned int channel = 0; channel < 3; ++channel)
// Now compute all translations
for(BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel +1))
{
switch( node.mChannels[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;
case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
}
//Find channel in node
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
if (mapIter == channelMap.end())
throw DeadlyImportError("Missing position channel in 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;
}
@ -497,12 +521,6 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
// 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
nodeAnim->mNumRotationKeys = mAnimNumFrames;
@ -512,20 +530,33 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
{
aiMatrix4x4 temp;
aiMatrix3x3 rotMatrix;
for (BVHLoader::ChannelType channel = Channel_RotationX; channel <= Channel_RotationZ; channel = (BVHLoader::ChannelType)(channel + 1))
{
//Find channel in node
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
for( unsigned int channel = 0; channel < 3; ++channel)
{
// translate ZXY euler angels into a quaternion
const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
if (mapIter == channelMap.end())
throw DeadlyImportError("Missing rotation channel in node " + nodeName);
else {
int channelIdx = mapIter->second;
// translate ZXY euler angels into a quaternion
const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
// Compute rotation transformations in the right order
switch (node.mChannels[rotOffset+channel])
{
case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
}
// Compute rotation transformations in the right order
switch (channel)
{
case Channel_RotationX:
aiMatrix4x4::RotationX(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
case Channel_RotationY:
aiMatrix4x4::RotationY(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
case Channel_RotationZ: aiMatrix4x4::RotationZ(angle, temp); rotMatrix *= aiMatrix3x3(temp);
break;
default:
break;
}
}
}
rotkey->mTime = double( fr);

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assimp/BaseImporter.h>
#include <assimp/ParsingUtils.h>
#include "FileSystemFilter.h"
#include "Importer.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/postprocess.h>
#include <assimp/importerdesc.h>
#include <ios>
#include <list>
#include <memory>
@ -158,15 +160,14 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
if (pStream.get() ) {
// read 200 characters from the file
std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
char* buffer = _buffer.get();
const size_t read = pStream->Read(buffer,1,searchBytes);
if( !read ) {
char *buffer( _buffer.get() );
const size_t read( pStream->Read(buffer,1,searchBytes) );
if( 0 == read ) {
return false;
}
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 ...
@ -187,7 +188,7 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
token.clear();
const char *ptr( tokens[ i ] );
for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) {
token.push_back( tolower( *ptr ) );
token.push_back( static_cast<char>( tolower( *ptr ) ) );
++ptr;
}
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
/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
{
std::string::size_type pos = pFile.find_last_of('.');
std::string BaseImporter::GetExtension( const std::string& file ) {
std::string::size_type pos = file.find_last_of('.');
// no file extension at all
if( pos == std::string::npos)
if (pos == std::string::npos) {
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;
}

View File

@ -911,6 +911,12 @@ ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
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} )
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)

View File

@ -59,6 +59,25 @@ using namespace Assimp;
#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
MakeLeftHandedProcess::MakeLeftHandedProcess()
@ -282,15 +301,9 @@ void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
// Converts a single mesh
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
{
// mirror texture y coordinate
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
if( !pMesh->HasTextureCoords( a ) ) {
break;
}
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
}
flipUVs(pMesh);
for (unsigned int idx = 0; idx < pMesh->mNumAnimMeshes; idx++) {
flipUVs(pMesh->mAnimMeshes[idx]);
}
}

View File

@ -73,11 +73,7 @@ using namespace Util;
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
// XXX vc9's debugger won't step into anonymous namespaces
//namespace {
Converter::Converter( aiScene* out, const Document& doc )
FBXConverter::FBXConverter( aiScene* out, const Document& doc )
: defaultMaterialIndex()
, out( out )
, 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( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() );
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>() );
}
void Converter::ConvertRootNode() {
void FBXConverter::ConvertRootNode() {
out->mRootNode = new aiNode();
out->mRootNode->mName.Set( "RootNode" );
@ -135,7 +131,7 @@ void Converter::ConvertRootNode() {
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" );
std::vector<aiNode*> nodes;
@ -189,12 +185,12 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
}
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() ) {
original_name = original_name + std::string( "001" );
}
mNodeNames.push_back( original_name );
mNodeNames.insert( original_name );
nodes_chain.push_back( new aiNode( original_name ) );
} else {
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();
for( const NodeAttribute* attr : node_attrs ) {
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();
for( const NodeAttribute* attr : node_attrs ) {
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() );
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() );
aiCamera* const out_camera = cameras.back();
@ -402,133 +398,120 @@ void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name )
out_camera->mClipPlaneFar = cam.FarPlane();
}
static bool HasName( NodeNameCache &cache, const std::string &name ) {
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 ) ) {
void FBXConverter::GetUniqueName( const std::string &name, std::string &uniqueName )
{
int i = 0;
uniqueName = name;
while (mNodeNames.find(uniqueName) != mNodeNames.end())
{
++i;
newName.clear();
newName += name;
std::stringstream ext;
ext << std::setfill( '0' ) << std::setw( 3 ) << i;
newName += ext.str();
ext << name << std::setfill('0') << std::setw(3) << i;
uniqueName = ext.str();
}
uniqueName = newName;
mNodeNames.push_back( uniqueName );
mNodeNames.insert(uniqueName);
}
const char* Converter::NameTransformationComp( TransformationComp comp )
{
switch ( comp )
{
case TransformationComp_Translation:
return "Translation";
case TransformationComp_RotationOffset:
return "RotationOffset";
case TransformationComp_RotationPivot:
return "RotationPivot";
case TransformationComp_PreRotation:
return "PreRotation";
case TransformationComp_Rotation:
return "Rotation";
case TransformationComp_PostRotation:
return "PostRotation";
case TransformationComp_RotationPivotInverse:
return "RotationPivotInverse";
case TransformationComp_ScalingOffset:
return "ScalingOffset";
case TransformationComp_ScalingPivot:
return "ScalingPivot";
case TransformationComp_Scaling:
return "Scaling";
case TransformationComp_ScalingPivotInverse:
return "ScalingPivotInverse";
case TransformationComp_GeometricScaling:
return "GeometricScaling";
case TransformationComp_GeometricRotation:
return "GeometricRotation";
case TransformationComp_GeometricTranslation:
return "GeometricTranslation";
case TransformationComp_GeometricScalingInverse:
return "GeometricScalingInverse";
case TransformationComp_GeometricRotationInverse:
return "GeometricRotationInverse";
case TransformationComp_GeometricTranslationInverse:
return "GeometricTranslationInverse";
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
default:
break;
const char* FBXConverter::NameTransformationComp( TransformationComp comp ) {
switch ( comp ) {
case TransformationComp_Translation:
return "Translation";
case TransformationComp_RotationOffset:
return "RotationOffset";
case TransformationComp_RotationPivot:
return "RotationPivot";
case TransformationComp_PreRotation:
return "PreRotation";
case TransformationComp_Rotation:
return "Rotation";
case TransformationComp_PostRotation:
return "PostRotation";
case TransformationComp_RotationPivotInverse:
return "RotationPivotInverse";
case TransformationComp_ScalingOffset:
return "ScalingOffset";
case TransformationComp_ScalingPivot:
return "ScalingPivot";
case TransformationComp_Scaling:
return "Scaling";
case TransformationComp_ScalingPivotInverse:
return "ScalingPivotInverse";
case TransformationComp_GeometricScaling:
return "GeometricScaling";
case TransformationComp_GeometricRotation:
return "GeometricRotation";
case TransformationComp_GeometricTranslation:
return "GeometricTranslation";
case TransformationComp_GeometricScalingInverse:
return "GeometricScalingInverse";
case TransformationComp_GeometricRotationInverse:
return "GeometricRotationInverse";
case TransformationComp_GeometricTranslationInverse:
return "GeometricTranslationInverse";
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
default:
break;
}
ai_assert( false );
return NULL;
return nullptr;
}
const char* Converter::NameTransformationCompProperty( TransformationComp comp )
{
switch ( comp )
{
case TransformationComp_Translation:
return "Lcl Translation";
case TransformationComp_RotationOffset:
return "RotationOffset";
case TransformationComp_RotationPivot:
return "RotationPivot";
case TransformationComp_PreRotation:
return "PreRotation";
case TransformationComp_Rotation:
return "Lcl Rotation";
case TransformationComp_PostRotation:
return "PostRotation";
case TransformationComp_RotationPivotInverse:
return "RotationPivotInverse";
case TransformationComp_ScalingOffset:
return "ScalingOffset";
case TransformationComp_ScalingPivot:
return "ScalingPivot";
case TransformationComp_Scaling:
return "Lcl Scaling";
case TransformationComp_ScalingPivotInverse:
return "ScalingPivotInverse";
case TransformationComp_GeometricScaling:
return "GeometricScaling";
case TransformationComp_GeometricRotation:
return "GeometricRotation";
case TransformationComp_GeometricTranslation:
return "GeometricTranslation";
case TransformationComp_GeometricScalingInverse:
return "GeometricScalingInverse";
case TransformationComp_GeometricRotationInverse:
return "GeometricRotationInverse";
case TransformationComp_GeometricTranslationInverse:
return "GeometricTranslationInverse";
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
break;
const char* FBXConverter::NameTransformationCompProperty( TransformationComp comp ) {
switch ( comp ) {
case TransformationComp_Translation:
return "Lcl Translation";
case TransformationComp_RotationOffset:
return "RotationOffset";
case TransformationComp_RotationPivot:
return "RotationPivot";
case TransformationComp_PreRotation:
return "PreRotation";
case TransformationComp_Rotation:
return "Lcl Rotation";
case TransformationComp_PostRotation:
return "PostRotation";
case TransformationComp_RotationPivotInverse:
return "RotationPivotInverse";
case TransformationComp_ScalingOffset:
return "ScalingOffset";
case TransformationComp_ScalingPivot:
return "ScalingPivot";
case TransformationComp_Scaling:
return "Lcl Scaling";
case TransformationComp_ScalingPivotInverse:
return "ScalingPivotInverse";
case TransformationComp_GeometricScaling:
return "GeometricScaling";
case TransformationComp_GeometricRotation:
return "GeometricRotation";
case TransformationComp_GeometricTranslation:
return "GeometricTranslation";
case TransformationComp_GeometricScalingInverse:
return "GeometricScalingInverse";
case TransformationComp_GeometricRotationInverse:
return "GeometricRotationInverse";
case TransformationComp_GeometricTranslationInverse:
return "GeometricTranslationInverse";
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
break;
}
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
// would be to do everything in log space!
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 ) {
FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" );
@ -599,11 +582,15 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
default:
ai_assert( false );
break;
}
ai_assert( ( order[ 0 ] >= 0 ) && ( order[ 0 ] <= 2 ) );
ai_assert( ( order[ 1 ] >= 0 ) && ( order[ 1 ] <= 2 ) );
ai_assert( ( order[ 2 ] >= 0 ) && ( order[ 2 ] <= 2 ) );
ai_assert( order[ 0 ] >= 0 );
ai_assert( order[ 0 ] <= 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 ] ] ) {
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();
bool ok;
@ -649,13 +636,13 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
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 );
}
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 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();
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();
@ -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)
{
std::vector<unsigned int> temp;
@ -925,7 +912,7 @@ std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, cons
return temp;
}
aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
aiMesh* FBXConverter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
{
aiMesh* const out_mesh = new aiMesh();
meshes.push_back( out_mesh );
@ -948,7 +935,7 @@ aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
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 MatIndexArray& mindices = mesh.GetMaterialIndices();
@ -1075,7 +1062,7 @@ unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, con
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 MatIndexArray& mindices = mesh.GetMaterialIndices();
@ -1095,7 +1082,7 @@ std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometr
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,
const aiMatrix4x4& node_global_transform,
aiNode& nd)
@ -1271,7 +1258,7 @@ unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, cons
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 ,
unsigned int materialIndex,
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 );
}
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>& index_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 )
{
// 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;
}
unsigned int Converter::GetDefaultMaterial()
unsigned int FBXConverter::GetDefaultMaterial()
{
if ( defaultMaterialIndex ) {
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();
@ -1496,7 +1483,7 @@ unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeo
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
aiTexture* out_tex = new aiTexture();
@ -1526,7 +1513,7 @@ unsigned int Converter::ConvertVideo( const Video& video )
return static_cast<unsigned int>( textures.size() - 1 );
}
aiString Converter::GetTexturePath(const Texture* tex)
aiString FBXConverter::GetTexturePath(const Texture* tex)
{
aiString path;
path.Set(tex->RelativeFilename());
@ -1566,7 +1553,7 @@ aiString Converter::GetTexturePath(const Texture* tex)
return path;
}
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
const std::string& propName,
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,
aiTextureType target, const MeshGeometry* const mesh ) {
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, "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 );
}
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, "AmbientColor", aiTextureType_AMBIENT, mesh );
@ -1837,7 +1824,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureM
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 )
{
result = true;
@ -1862,13 +1849,13 @@ aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const
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 )
{
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 )
{
result = true;
@ -1881,7 +1868,7 @@ aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::st
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.
// Modern FBX Files have two separate systems for defining these,
@ -1980,60 +1967,60 @@ 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 ) {
case FileGlobalSettings::FrameRate_DEFAULT:
return 1.0;
case FileGlobalSettings::FrameRate_DEFAULT:
return 1.0;
case FileGlobalSettings::FrameRate_120:
return 120.0;
case FileGlobalSettings::FrameRate_120:
return 120.0;
case FileGlobalSettings::FrameRate_100:
return 100.0;
case FileGlobalSettings::FrameRate_100:
return 100.0;
case FileGlobalSettings::FrameRate_60:
return 60.0;
case FileGlobalSettings::FrameRate_60:
return 60.0;
case FileGlobalSettings::FrameRate_50:
return 50.0;
case FileGlobalSettings::FrameRate_50:
return 50.0;
case FileGlobalSettings::FrameRate_48:
return 48.0;
case FileGlobalSettings::FrameRate_48:
return 48.0;
case FileGlobalSettings::FrameRate_30:
case FileGlobalSettings::FrameRate_30_DROP:
return 30.0;
case FileGlobalSettings::FrameRate_30:
case FileGlobalSettings::FrameRate_30_DROP:
return 30.0;
case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
return 29.9700262;
case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
return 29.9700262;
case FileGlobalSettings::FrameRate_PAL:
return 25.0;
case FileGlobalSettings::FrameRate_PAL:
return 25.0;
case FileGlobalSettings::FrameRate_CINEMA:
return 24.0;
case FileGlobalSettings::FrameRate_CINEMA:
return 24.0;
case FileGlobalSettings::FrameRate_1000:
return 1000.0;
case FileGlobalSettings::FrameRate_1000:
return 1000.0;
case FileGlobalSettings::FrameRate_CINEMA_ND:
return 23.976;
case FileGlobalSettings::FrameRate_CINEMA_ND:
return 23.976;
case FileGlobalSettings::FrameRate_CUSTOM:
return customFPSVal;
case FileGlobalSettings::FrameRate_CUSTOM:
return customFPSVal;
case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings
break;
case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings
break;
}
ai_assert( false );
return -1.0f;
}
void Converter::ConvertAnimations()
void FBXConverter::ConvertAnimations()
{
// first of all determine framerate
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
// this causes ambiguities, well possible between empty identifiers,
// such as "Model::" and ""). Make sure the behaviour is consistent
@ -2059,7 +2046,7 @@ std::string Converter::FixNodeName( const std::string& name ) {
return name;
}
void Converter::ConvertAnimationStack( const AnimationStack& st )
void FBXConverter::ConvertAnimationStack( const AnimationStack& st )
{
const AnimationLayerList& layers = st.Layers();
if ( layers.empty() ) {
@ -2201,7 +2188,7 @@ static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>
#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::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map,
@ -2435,10 +2422,9 @@ void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
node_anim_chain_bits[ fixed_name ] = flags;
}
bool Converter::IsRedundantAnimationData( const Model& target,
TransformationComp comp,
const std::vector<const AnimationCurveNode*>& curves )
{
bool FBXConverter::IsRedundantAnimationData( const Model& target,
TransformationComp comp,
const std::vector<const AnimationCurveNode*>& curves ) {
ai_assert( curves.size() );
// 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 std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map,
@ -2511,7 +2497,7 @@ aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name,
return na.release();
}
aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
aiNodeAnim* FBXConverter::GenerateScalingNodeAnim( const std::string& name,
const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map,
@ -2541,16 +2527,14 @@ aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
return na.release();
}
aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map,
int64_t start, int64_t stop,
double& max_time,
double& min_time,
bool inverse )
{
aiNodeAnim* FBXConverter::GenerateTranslationNodeAnim( const std::string& name,
const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map,
int64_t start, int64_t stop,
double& max_time,
double& min_time,
bool inverse ) {
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
na->mNodeName.Set( name );
@ -2579,7 +2563,7 @@ aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
return na.release();
}
aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim( const std::string& name,
const Model& target,
NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
NodeMap::const_iterator iter_end,
@ -2715,7 +2699,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
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;
inputs.reserve( nodes.size() * 3 );
@ -2771,12 +2755,11 @@ Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const
}
KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs )
{
ai_assert( inputs.size() );
KeyTimeList FBXConverter::GetKeyTimeList( const KeyFrameListList& inputs ) {
ai_assert( !inputs.empty() );
// reserve some space upfront - it is likely that the keyframe lists
// have matching time values, so max(of all keyframe lists) should
// reserve some space upfront - it is likely that the key-frame lists
// have matching time values, so max(of all key-frame lists) should
// be a good estimate.
KeyTimeList keys;
@ -2820,17 +2803,15 @@ KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs )
return keys;
}
void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
const aiVector3D& def_value,
double& max_time,
double& min_time )
{
ai_assert( keys.size() );
ai_assert( valOut );
void FBXConverter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
const aiVector3D& def_value,
double& max_time,
double& min_time ) {
ai_assert( !keys.empty() );
ai_assert( nullptr != valOut );
std::vector<unsigned int> next_pos;
const size_t count = inputs.size();
const size_t count( inputs.size() );
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 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 ) {
++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,
double& maxTime,
double& minTime,
Model::RotOrder order )
{
ai_assert( keys.size() );
ai_assert( valOut );
ai_assert( !keys.empty() );
ai_assert( nullptr != valOut );
std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] );
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,
const KeyFrameListList& scaling,
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;
GetRotationMatrix( order, rot, m );
@ -2979,7 +2963,7 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde
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,
double& maxTime,
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 );
}
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*/,
int64_t start, int64_t stop,
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 );
}
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*/,
int64_t start, int64_t stop,
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) {
return;
}
@ -3048,7 +3032,7 @@ void Converter::ConvertGlobalSettings() {
out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor);
}
void Converter::TransferDataToScene()
void FBXConverter::TransferDataToScene()
{
ai_assert( !out->mMeshes );
ai_assert( !out->mNumMeshes );
@ -3100,12 +3084,10 @@ void Converter::TransferDataToScene()
}
}
//} // !anon
// ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc)
{
Converter converter(out,doc);
FBXConverter converter(out,doc);
}
} // !FBX

View File

@ -68,7 +68,7 @@ namespace FBX {
class Document;
using NodeNameCache = std::vector<std::string>;
using NodeNameCache = std::set<std::string>;
/**
* Convert a FBX #Document to #aiScene
@ -78,7 +78,7 @@ using NodeNameCache = std::vector<std::string>;
void ConvertToAssimpScene(aiScene* out, const Document& doc);
/** Dummy class to encapsulate the conversion process */
class Converter {
class FBXConverter {
public:
/**
* The different parts that make up the final local transformation of a fbx-node
@ -106,8 +106,8 @@ public:
};
public:
Converter(aiScene* out, const Document& doc);
~Converter();
FBXConverter(aiScene* out, const Document& doc);
~FBXConverter();
private:
// ------------------------------------------------------------------------------------------------
@ -131,7 +131,7 @@ private:
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 -

View File

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

View File

@ -178,6 +178,7 @@ Importer::~Importer()
{
// Delete all import plugins
DeleteImporterInstanceList(pimpl->mImporter);
aiReleaseDefaultMaterial();
// Delete all post-processing plug-ins
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
@ -383,6 +384,8 @@ bool _ValidateFlags(unsigned int pFlags)
void Importer::FreeScene( )
{
ASSIMP_BEGIN_EXCEPTION_REGION();
aiReleaseDefaultMaterial();
delete pimpl->mScene;
pimpl->mScene = NULL;
@ -490,9 +493,9 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
// read the file and recover the previous IOSystem
static const size_t BufferSize(Importer::MaxLenHint + 28);
char fbuff[ BufferSize ];
ai_snprintf(fbuff, BufferSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
static const size_t BufSize(Importer::MaxLenHint + 28);
char fbuff[BufSize];
ai_snprintf(fbuff, BufSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
ReadFile(fbuff,pFlags);
SetIOHandler(io);
@ -930,20 +933,19 @@ BaseImporter* Importer::GetImporter (const char* szExtension) const
// ------------------------------------------------------------------------------------------------
// Find a loader plugin for a given file extension
size_t Importer::GetImporterIndex (const char* szExtension) const
{
ai_assert(szExtension);
size_t Importer::GetImporterIndex (const char* szExtension) const {
ai_assert(nullptr != szExtension);
ASSIMP_BEGIN_EXCEPTION_REGION();
// skip over wildcard and dot characters at string head --
for(;*szExtension == '*' || *szExtension == '.'; ++szExtension);
for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension );
std::string ext(szExtension);
if (ext.empty()) {
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;
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);
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/TinyFormatter.h>
#include <stdio.h>
#include <unordered_set>
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
@ -239,6 +240,19 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
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.
std::vector<Vertex> uniqueVertices;
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
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
if (usedVertexIndices.find(a) == usedVertexIndices.end()) {
continue;
}
// collect the vertex data
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 "MMDPmxParser.h"
#include <assimp/StringUtils.h>
#include "../contrib/utf8cpp/source/utf8.h"
#include <assimp/Exceptional.h>
@ -118,7 +119,7 @@ namespace pmx
stream->read((char*) &count, sizeof(uint8_t));
if (count < 8)
{
throw;
throw DeadlyImportError("MMD: invalid size");
}
stream->read((char*) &encoding, sizeof(uint8_t));
stream->read((char*) &uv, sizeof(uint8_t));
@ -395,7 +396,7 @@ namespace pmx
}
break;
default:
throw;
throw DeadlyImportError("MMD: unknown morth type");
}
}
@ -476,8 +477,8 @@ namespace pmx
{
// 未実装
std::cerr << "Not Implemented Exception" << std::endl;
throw;
}
throw DeadlyImportError("MMD: Not Implemented Exception");
}
void PmxModel::Init()
{
@ -516,15 +517,15 @@ namespace pmx
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
{
std::cerr << "invalid magic number." << std::endl;
throw;
}
throw DeadlyImportError("MMD: invalid magic number.");
}
// バージョン
stream->read((char*) &version, sizeof(float));
if (version != 2.0f && version != 2.1f)
{
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);
@ -605,34 +606,5 @@ namespace pmx
{
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,
const aiMaterialProperty** pPropOut)
{
ai_assert (pMat != NULL);
ai_assert (pKey != NULL);
ai_assert (pPropOut != NULL);
ai_assert( pMat != NULL );
ai_assert( pKey != NULL );
ai_assert( pPropOut != NULL );
/* Just search for a property with exactly this name ..
* could be improved by hashing, but it's possibly
@ -76,7 +76,7 @@ aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
if (prop /* just for safety ... */
&& 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))
{
*pPropOut = pMat->mProperties[i];
@ -96,8 +96,8 @@ aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
ai_real* pOut,
unsigned int* pMax)
{
ai_assert (pOut != NULL);
ai_assert (pMat != NULL);
ai_assert( pOut != NULL );
ai_assert( pMat != NULL );
const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
@ -182,8 +182,8 @@ aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
int* pOut,
unsigned int* pMax)
{
ai_assert (pOut != NULL);
ai_assert (pMat != NULL);
ai_assert( pOut != NULL );
ai_assert( pMat != NULL );
const aiMaterialProperty* prop;
aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
@ -274,7 +274,7 @@ aiReturn aiGetMaterialUVTransform(const aiMaterial* pMat,
aiUVTransform* pOut)
{
unsigned int iMax = 4;
return aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax);
return aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax);
}
// ------------------------------------------------------------------------------------------------
@ -314,7 +314,7 @@ aiReturn aiGetMaterialString(const aiMaterial* pMat,
// ------------------------------------------------------------------------------------------------
// 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)
{
ai_assert (pMat != NULL);
@ -347,12 +347,14 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/
)
{
ai_assert(NULL != mat && NULL != path);
ai_assert( NULL != mat );
ai_assert( NULL != path );
// Get the path to the texture
if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) {
return AI_FAILURE;
}
// Determine mapping type
int mapping_ = static_cast<int>(aiTextureMapping_UV);
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_);
@ -381,15 +383,37 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
if (flags){
aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
}
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;
// ------------------------------------------------------------------------------------------------
// Construction. Actually the one and only way to get an aiMaterial instance
aiMaterial::aiMaterial()
: mProperties( NULL )
: mProperties( nullptr )
, mNumProperties( 0 )
, mNumAllocated( DefaultNumAllocated ) {
// Allocate 5 entries by default
@ -404,12 +428,20 @@ aiMaterial::~aiMaterial()
delete[] mProperties;
}
// ------------------------------------------------------------------------------------------------
aiString aiMaterial::GetName() {
aiString name;
Get(AI_MATKEY_NAME, name);
return name;
}
// ------------------------------------------------------------------------------------------------
void aiMaterial::Clear()
{
for (unsigned int i = 0; i < mNumProperties;++i) {
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
// delete this entry
delete mProperties[i];
delete mProperties[ i ];
AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
}
mNumProperties = 0;
@ -418,11 +450,9 @@ void aiMaterial::Clear()
}
// ------------------------------------------------------------------------------------------------
aiReturn aiMaterial::RemoveProperty (const char* pKey,unsigned int type,
unsigned int index
)
aiReturn aiMaterial::RemoveProperty ( const char* pKey,unsigned int type, unsigned int index )
{
ai_assert(NULL != pKey);
ai_assert( nullptr != pKey );
for (unsigned int i = 0; i < mNumProperties;++i) {
aiMaterialProperty* prop = mProperties[i];
@ -454,17 +484,18 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
aiPropertyTypeInfo pType
)
{
ai_assert (pInput != NULL);
ai_assert (pKey != NULL);
ai_assert (0 != pSizeInBytes);
ai_assert( pInput != NULL );
ai_assert( pKey != NULL );
ai_assert( 0 != pSizeInBytes );
if ( 0 == pSizeInBytes ) {
}
// first search the list whether there is already an entry with this key
unsigned int iOutIndex = UINT_MAX;
for (unsigned int i = 0; i < mNumProperties;++i) {
aiMaterialProperty* prop = mProperties[i];
unsigned int iOutIndex( UINT_MAX );
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
aiMaterialProperty *prop( mProperties[ i ] );
if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
prop->mSemantic == type && prop->mIndex == index){
@ -516,6 +547,7 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
}
// push back ...
mProperties[mNumProperties++] = pcNew;
return AI_SUCCESS;
}

View File

@ -210,22 +210,63 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
ai_assert(false);
}
// Create nodes for the whole scene
std::vector<aiMesh*> MeshArray;
for (size_t index = 0; index < pModel->m_Objects.size(); ++index ) {
createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, MeshArray);
}
// Create mesh pointer buffer for this scene
if (pScene->mNumMeshes > 0) {
pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
for (size_t index =0; index < MeshArray.size(); ++index ) {
pScene->mMeshes[ index ] = MeshArray[ index ];
if (pModel->m_Objects.size() > 0) {
// Create nodes for the whole scene
std::vector<aiMesh*> MeshArray;
for (size_t index = 0; index < pModel->m_Objects.size(); ++index) {
createNodes(pModel, pModel->m_Objects[index], pScene->mRootNode, pScene, MeshArray);
}
}
// Create all materials
createMaterials( pModel, pScene );
// Create mesh pointer buffer for this scene
if (pScene->mNumMeshes > 0) {
pScene->mMeshes = new aiMesh*[MeshArray.size()];
for (size_t index = 0; index < MeshArray.size(); ++index) {
pScene->mMeshes[index] = MeshArray[index];
}
}
// Create all materials
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
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);
}

View File

@ -84,8 +84,6 @@ static const std::string BumpOption = "-bm";
static const std::string ChannelOption = "-imfchan";
static const std::string TypeOption = "-type";
// -------------------------------------------------------------------
// Constructor
ObjFileMtlImporter::ObjFileMtlImporter( std::vector<char> &buffer,
@ -334,6 +332,11 @@ void ObjFileMtlImporter::getTexture() {
// Specular texture
out = & m_pModel->m_pCurrentMaterial->textureSpecular;
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()) ) ) {
// Opacity texture
out = & m_pModel->m_pCurrentMaterial->textureOpacity;
@ -356,11 +359,6 @@ void ObjFileMtlImporter::getTexture() {
// Reflection texture(s)
//Do nothing here
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()) ) ) {
// Specularity scaling (glossiness)
out = & m_pModel->m_pCurrentMaterial->textureSpecularity;

View File

@ -90,6 +90,9 @@ static bool IsBinarySTL(const char* buffer, unsigned int 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.
// 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".
@ -108,10 +111,10 @@ static bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
bool isASCII( strncmp( buffer, "solid", 5 ) == 0 );
if( isASCII ) {
// 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;
for( unsigned int i = 0; i < 500; i++ ) {
if( buffer[ i ] > 127 ) {
for( unsigned int i = 0; i < BufferSize; i++ ) {
if( buffer[ i ] > UnicodeBoundary) {
isASCII = false;
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
// other geometric types (e.g., PLY).
aiMaterial* pcMat = new aiMaterial();
aiMaterial* pcMat = aiCreateAndRegisterDefaultMaterial();
/*aiMaterial* pcMat = new aiMaterial();
aiString s;
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));
if (bMatClr) {
@ -535,11 +539,21 @@ bool STLImporter::LoadBinaryFile()
// now copy faces
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
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
node->mNumMeshes = pScene->mNumMeshes;
node->mMeshes = new unsigned int[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
pScene->mRootNode->mMeshes[i] = i;
node->mMeshes[i] = i;
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,
// at least if we have many bones.
std::list<BoneWithHash> asBones;
BuildUniqueBoneList(asBones, it,end);
BuildUniqueBoneList( asBones, it, end );
// now create the output bones
out->mNumBones = 0;
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
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
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;
// NOTE: different offset matrices for bones with equal names
// 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");
continue;
}
pc->mOffsetMatrix = (*wmit).first->mOffsetMatrix;
pc->mOffsetMatrix = wmit->first->mOffsetMatrix;
}
// 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
// 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;
for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) {
const aiVertexWeight& vfi = pip->mWeights[mp];
@ -849,14 +849,14 @@ void SceneCombiner::MergeMeshes(aiMesh** _out, unsigned int /*flags*/,
// copy vertex colors
n = 0;
while ((**begin).HasVertexColors(n)) {
aiColor4D* pv2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
aiColor4D *pVec2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
for ( std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it ) {
if ((*it)->mColors[n]) {
::memcpy(pv2,(*it)->mColors[n],(*it)->mNumVertices*sizeof(aiColor4D));
::memcpy( pVec2, (*it)->mColors[ n ], (*it)->mNumVertices * sizeof( aiColor4D ) ) ;
} else {
ASSIMP_LOG_WARN( "JoinMeshes: VCs expected but input mesh contains no VCs" );
}
pv2 += (*it)->mNumVertices;
pVec2 += (*it)->mNumVertices;
}
++n;
}

View File

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

View File

@ -223,7 +223,7 @@ namespace {
if( (-42 == (~42 + 1)) && (binValue & 0x80000000))
return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
// One's complement?
else if( (-42 == ~42) && (binValue & 0x80000000))
else if ( (-42 == ~42) && (binValue & 0x80000000))
return BinFloat(-0) - binValue;
// Sign-magnitude?
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());
}
delete pNode->mMeshes;
delete [] pNode->mMeshes;
pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);

View File

@ -105,8 +105,10 @@ void TriangulateProcess::Execute( aiScene* pScene)
bool bHas = false;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
{
if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) {
bHas = true;
if (pScene->mMeshes[ a ]) {
if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) {
bHas = true;
}
}
}
if ( bHas ) {
@ -285,7 +287,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
// We project it onto a plane to get a 2d triangle.
// Collect all vertices of of the polygon.
for (tmp = 0; tmp < max; ++tmp) {
for (tmp = 0; tmp < max; ++tmp) {
temp_verts3d[tmp] = verts[idx[tmp]];
}

View File

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

View File

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

View File

@ -931,6 +931,21 @@ namespace {
else return false;
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)
@ -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")) {
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*/)

View File

@ -94,19 +94,7 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
, mIOSystem(pIOSystem)
, mProperties(pProperties)
{
aiScene* sceneCopy_tmp;
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();
mScene = pScene;
mAsset.reset( new Asset( pIOSystem ) );
@ -681,12 +669,7 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
void glTF2Exporter::ExportMeshes()
{
// Not for
// 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;
typedef decltype(aiFace::mNumIndices) IndicesType;
std::string fname = std::string(mFilename);
std::string bufferIdPrefix = fname.substr(0, fname.rfind(".gltf"));
@ -778,11 +761,11 @@ void glTF2Exporter::ExportMeshes()
indices.resize(aim->mNumFaces * nIndicesPerFace);
for (size_t i = 0; i < aim->mNumFaces; ++i) {
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) {

187
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/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include <assimp/CreateAnimMesh.h>
#include <memory>
@ -65,6 +66,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
using namespace glTF2;
namespace {
// generate bitangents from normals and tangents according to spec
struct Tangent {
aiVector3D xyz;
ai_real w;
};
} // namespace
//
// glTF2Importer
@ -109,13 +117,9 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
if (pIOHandler) {
glTF2::Asset asset(pIOHandler);
try {
asset.Load(pFile, extension == "glb");
std::string version = asset.asset.version;
return !version.empty() && version[0] == '2';
} catch (...) {
return false;
}
asset.Load(pFile, extension == "glb");
std::string version = asset.asset.version;
return !version.empty() && version[0] == '2';
}
return false;
@ -416,10 +420,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
// only extract tangents if normals are present
if (attr.tangent.size() > 0 && attr.tangent[0]) {
// generate bitangents from normals and tangents according to spec
struct Tangent {
aiVector3D xyz;
ai_real w;
} *tangents = nullptr;
Tangent *tangents = nullptr;
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) {
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]);
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];
}
}
}
aiFace* faces = 0;
unsigned int nFaces = 0;
if (prim.indices) {
aiFace* faces = 0;
unsigned int nFaces = 0;
unsigned int count = prim.indices->count;
Accessor::Indexer data = prim.indices->GetIndexer();
@ -499,9 +552,18 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
case PrimitiveMode_TRIANGLE_STRIP: {
nFaces = count - 2;
faces = new aiFace[nFaces];
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
for (unsigned int i = 3; i < count; ++i) {
SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i));
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], 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;
}
@ -509,19 +571,92 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
nFaces = count - 2;
faces = new aiFace[nFaces];
SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
for (unsigned int i = 3; i < count; ++i) {
SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i));
for (unsigned int i = 1; i < nFaces; ++i) {
SetFace(faces[i], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i + 2));
}
break;
}
}
else { // no indices provided so directly generate from counts
if (faces) {
aim->mFaces = faces;
aim->mNumFaces = nFaces;
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
// 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) {
aim->mFaces = faces;
aim->mNumFaces = nFaces;
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
}
if (prim.material) {
aim->mMaterialIndex = prim.material.GetIndex();
@ -733,12 +868,6 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO
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) {
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
}

83
code/glTFImporter.cpp 100644 → 100755
View File

@ -351,10 +351,10 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
}
if (prim.indices) {
aiFace* faces = 0;
unsigned int nFaces = 0;
aiFace* faces = 0;
unsigned int nFaces = 0;
if (prim.indices) {
unsigned int count = prim.indices->count;
Accessor::Indexer data = prim.indices->GetIndexer();
@ -419,14 +419,78 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
}
break;
}
}
else { // no indices provided so directly generate from counts
if (faces) {
aim->mFaces = faces;
aim->mNumFaces = nFaces;
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
// 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) {
aim->mFaces = faces;
aim->mNumFaces = nFaces;
ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
}
if (prim.material) {
aim->mMaterialIndex = prim.material.GetIndex();
@ -676,11 +740,6 @@ void glTFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOS
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) {
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;

View File

@ -100,9 +100,15 @@ static bool isUnsignedIntegerType( Value::ValueType integerType ) {
}
static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
// Basic checks
if( ddl_nullptr == id || ddl_nullptr == parser ) {
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 );
DDLNode *parent( parser->top() );

View File

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

View File

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

View File

@ -608,16 +608,17 @@ struct aiMaterialProperty
#ifdef __cplusplus
aiMaterialProperty()
: mSemantic( 0 )
, mIndex( 0 )
, mDataLength( 0 )
, mType( aiPTI_Float )
, mData( NULL )
{
: mSemantic( 0 )
, mIndex( 0 )
, mDataLength( 0 )
, mType( aiPTI_Float )
, mData(nullptr) {
// empty
}
~aiMaterialProperty() {
delete[] mData;
mData = nullptr;
}
#endif
@ -651,6 +652,14 @@ public:
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
* from the material
@ -1556,10 +1565,32 @@ C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
unsigned int* flags /*= NULL*/);
#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
}
#include "material.inl"
#endif //!__cplusplus
#endif //!!AI_MATERIAL_H_INC

View File

@ -120,7 +120,7 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
const aiMaterialProperty* prop;
const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
(const aiMaterialProperty**)&prop);
if ( AI_SUCCESS == ret ) {
if ( AI_SUCCESS == ret ) {
if (prop->mDataLength < sizeof(Type)) {
return AI_FAILURE;
@ -130,7 +130,7 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
return AI_FAILURE;
}
::memcpy(&pOut,prop->mData,sizeof(Type));
::memcpy( &pOut, prop->mData, sizeof( Type ) );
}
return ret;
}

View File

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

View File

@ -214,6 +214,41 @@ class MeshKey(Structure):
("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):
"""
See 'aiScene.h' for details.
@ -253,6 +288,10 @@ Node._fields_ = [
# The meshes of this node. Each entry is an index into the mesh
("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):
@ -896,6 +935,11 @@ class Scene(Structure):
# array (if existing) is the default camera view into
# the scene.
("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,

View File

@ -3,17 +3,15 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "arm64")
SET (IOS TRUE)
SET (SDKVER "7.1")
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 (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
SET (IOS_SDK_DEVICE iPhoneOS)
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (SDKVER "${IOS_SDK_VERSION}")
SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
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_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -3,17 +3,15 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "armv6")
SET (IOS TRUE)
SET (SDKVER "7.1")
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 (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
SET (IOS_SDK_DEVICE iPhoneOS)
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (SDKVER "${IOS_SDK_VERSION}")
SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
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_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -3,17 +3,15 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "armv7s")
SET (IOS TRUE)
SET (SDKVER "7.1")
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 (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
SET (IOS_SDK_DEVICE iPhoneOS)
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (SDKVER "${IOS_SDK_VERSION}")
SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
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_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -3,17 +3,15 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "armv7")
SET (IOS TRUE)
SET (SDKVER "7.1")
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 (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
SET (IOS_SDK_DEVICE iPhoneOS)
CMAKE_FORCE_C_COMPILER (${CC} LLVM)
CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
SET (SDKVER "${IOS_SDK_VERSION}")
SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
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_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -3,18 +3,15 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin")
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 (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDKVER}.sdk")
SET (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
SET (SDKVER "${IOS_SDK_VERSION}")
SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
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_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -3,18 +3,15 @@ INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin")
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 (SDKROOT "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${SDKVER}.sdk")
SET (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
SET (SDKVER "${IOS_SDK_VERSION}")
SET (DEVROOT "${XCODE_ROOT_DIR}/Platforms/${IOS_SDK_DEVICE}.platform/Developer")
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_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -6,24 +6,41 @@
BUILD_DIR="./lib/iOS"
IOS_SDK_VERSION=
IOS_SDK_TARGET=6.0
#(iPhoneOS iPhoneSimulator) -- determined from arch
IOS_SDK_DEVICE=
###################################
# SDK Version
###################################
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_ARCHS_SIMULATOR="i386 x86_64"
BUILD_ARCHS_ALL=(armv7 armv7s arm64 i386 x86_64)
BUILD_SHARED_LIBS=OFF
BUILD_TYPE=Release
################################################
# 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=
CPP_STD_LIB_LIST=(libc++ libstdc++)
CPP_STD_LIB=
CPP_STD_LIST=(c++11 c++14)
CPP_STD=
CPP_STD=c++11
function join { local IFS="$1"; shift; echo "$*"; }
@ -41,27 +58,42 @@ build_arch()
echo '[!] Target SDK set to DEVICE.'
fi
unset DEVROOT SDKROOT CFLAGS LDFLAGS CPPFLAGS CXXFLAGS
export DEVROOT=$XCODE_ROOT_DIR/Developer/Platforms/$IOS_SDK_DEVICE.platform/Developer
unset DEVROOT SDKROOT CFLAGS LDFLAGS CPPFLAGS CXXFLAGS CMAKE_CLI_INPUT
#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 CFLAGS="-arch $1 -pipe -no-cpp-precomp -stdlib=$CPP_STD_LIB -isysroot $SDKROOT -$CPP_DEV_TARGET=$IOS_SDK_TARGET -I$SDKROOT/usr/include/"
export LDFLAGS="-L$SDKROOT/usr/lib/"
export CPPFLAGS=$CFLAGS
export CFLAGS="-arch $1 -pipe -no-cpp-precomp -stdlib=$CPP_STD_LIB -isysroot $SDKROOT -I$SDKROOT/usr/include/ -miphoneos-version-min=$IOS_SDK_TARGET"
if [[ "$BUILD_TYPE" =~ "Debug" ]]; then
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"
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"
$XCODE_ROOT_DIR/Developer/usr/bin/make clean
$XCODE_ROOT_DIR/Developer/usr/bin/make assimp -j 8 -l
echo "[!] Moving built libraries into: $BUILD_DIR/$1/"
mv ./lib/*.a $BUILD_DIR/$1/
xcrun -run make clean
xcrun -run make assimp -j 8 -l
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/
}
echo "[!] $0 - assimp iOS build script"
@ -85,12 +117,22 @@ for i in "$@"; do
DEPLOY_ARCHS=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
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)
DEPLOY_FAT=0
echo "[!] Fat binary will not be created."
;;
-h|--help)
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 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')"
@ -105,29 +147,56 @@ cd ../../
rm -rf $BUILD_DIR
for ARCH_TARGET in $DEPLOY_ARCHS; do
echo "Creating folder: $BUILD_DIR/$ARCH_TARGET"
mkdir -p $BUILD_DIR/$ARCH_TARGET
echo "Building for arc: $ARCH_TARGET"
build_arch $ARCH_TARGET
#rm ./lib/libassimp.a
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
LIPO_ARGS=''
for ARCH_TARGET in $DEPLOY_ARCHS; do
LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.a "
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
}
if [[ "$DEPLOY_FAT" -eq 1 ]]; then
echo '[+] Creating fat binaries ...'
make_fat_binary 'libassimp'
make_fat_binary 'libIrrXML'
make_fat_binary 'libzlibstatic'
if [[ "$BUILD_TYPE" =~ "Debug" ]]; then
make_fat_static_or_shared_binary 'libassimpd'
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"
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;
s.Set("Hello, this is a small test");
this->pcMat->AddProperty(&s,"testKey6");
@ -129,3 +128,24 @@ TEST_F(MaterialSystemTest, testStringProperty)
EXPECT_EQ(AI_SUCCESS, pcMat->Get("testKey6",0,0,s));
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 );
}
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() );
}

View File

@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exporter.hpp>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <array>
using namespace Assimp;
@ -100,6 +101,234 @@ TEST_F( utglTF2ImportExport, importBinaryglTF2FromFileTest ) {
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
TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
EXPECT_TRUE( exporterTest() );

View File

@ -3,52 +3,28 @@ project(assimp_qt_viewer)
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)
IF(ASSIMP_QT4_VIEWER)
# Qt4 version
FIND_PACKAGE(Qt4 QUIET)
ELSE(ASSIMP_QT4_VIEWER)
# Qt5 version
FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
ENDIF(ASSIMP_QT4_VIEWER)
# Qt5 version
FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
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)
ELSE((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND)
ELSE( Qt5Widgets_FOUND AND OPENGL_FOUND)
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)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
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 Qt5_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
ENDIF (NOT Qt5_FOUND)
IF (NOT OPENGL_FOUND)
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
ENDIF (NOT OPENGL_FOUND)
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)
INCLUDE_DIRECTORIES(
@ -63,28 +39,23 @@ IF(VIEWER_BUILD)
LINK_DIRECTORIES(${Assimp_BINARY_DIR})
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")
INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
qt5_wrap_ui(UISrcs mainwindow.ui)
qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
ENDIF()
MESSAGE("assimp_qt_viewer use Qt5")
INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
qt5_wrap_ui(UISrcs mainwindow.ui)
qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
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)
ENDIF()
target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
IF(WIN32) # Check if we are on Windows
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
/// \date 2016
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
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"
// Header files, Qt.
@ -16,40 +53,30 @@
#endif
// Header files, DevIL.
#include <il.h>
// Header files, Assimp.
#include <assimp/DefaultLogger.hpp>
#ifndef __unused
#define __unused __attribute__((unused))
#endif // __unused
/**********************************/
/********** SHelper_Mesh **********/
/**********************************/
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
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_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr;
Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr;
}
CGLView::SHelper_Mesh::~SHelper_Mesh()
{
if(Index_Point != nullptr) delete [] Index_Point;
if(Index_Line != nullptr) delete [] Index_Line;
if(Index_Triangle != nullptr) delete [] Index_Triangle;
CGLView::SHelper_Mesh::~SHelper_Mesh() {
delete [] Index_Point;
delete [] Index_Line;
delete [] Index_Triangle;
}
/**********************************/
/********** SHelper_Mesh **********/
/**********************************/
void CGLView::SHelper_Camera::SetDefault()
{
void CGLView::SHelper_Camera::SetDefault() {
Position.Set(0, 0, 0);
Target.Set(0, 0, -1);
Rotation_AroundCamera = aiMatrix4x4();
@ -57,39 +84,21 @@ void CGLView::SHelper_Camera::SetDefault()
Translation_ToScene.Set(0, 0, 2);
}
/**********************************/
/************ CGLView *************/
/**********************************/
static void 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;
}
#if !ASSIMP_QT4_VIEWER
# define ConditionalContextControl_Begin \
bool ContextEnabledHere; \
\
if(mGLContext_Current) \
{ \
ContextEnabledHere = false; \
} \
else \
{ \
makeCurrent(); \
mGLContext_Current = true; \
ContextEnabledHere = true; \
} \
\
do {} while(false)
static void 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;
}
# define ConditionalContextControl_End \
if(ContextEnabledHere) \
{ \
doneCurrent(); \
mGLContext_Current = false; \
} \
\
do {} while(false)
#endif // ASSIMP_QT4_VIEWER
void CGLView::Material_Apply(const aiMaterial* pMaterial)
{
void CGLView::Material_Apply(const aiMaterial* pMaterial) {
GLfloat tcol[4];
aiColor4D taicol;
unsigned int max;
@ -97,15 +106,12 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
int texture_index = 0;
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
// Disable color material because glMaterial is used.
glDisable(GL_COLOR_MATERIAL);///TODO: cache
// Set texture. If assigned.
if(AI_SUCCESS == pMaterial->GetTexture(aiTextureType_DIFFUSE, texture_index, &texture_path))
{
// Set texture. If assigned.
if(AI_SUCCESS == pMaterial->GetTexture(aiTextureType_DIFFUSE, texture_index, &texture_path)) {
//bind texture
unsigned int texture_ID = mTexture_IDMap.value(texture_path.data, 0);
@ -116,20 +122,27 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
//
// Diffuse
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);
// Specular
// Specular
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);
// Ambient
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);
// Emission
// Emission
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);
@ -142,12 +155,9 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
// Shininess strength
max = 1;
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
}
else
{
} else {
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);///TODO: cache
set_float4(tcol, 0.0f, 0.0f, 0.0f, 0.0f);
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.
{
ILboolean success;
GLuint id_ogl_texture;// OpenGL texture ID.
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
{
ILuint id_image;// DevIL image ID.
QString basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString basepath = scenePath.left(scenePath.lastIndexOf('/') + 1);// path with '/' at the end.
QString fileloc = (basepath + pFileName);
fileloc.replace('\\', "/");
ilGenImages(1, &id_image);// Generate DevIL image ID.
ilBindImage(id_image);
success = ilLoadImage(fileloc.toLocal8Bit());
if(!success)
{
int x, y, n;
unsigned char *data = stbi_load(fileloc.toLocal8Bit(), &x, &y, &n, STBI_rgb_alpha );
if ( nullptr == data ) {
LogError(QString("Couldn't load Image: %1").arg(fileloc));
return false;
}
// 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.
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
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.
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0,
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
glTexImage2D(GL_TEXTURE_2D, 0, n, x, y, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, data );// Texture specification.
//Cleanup
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
// Cleanup
}
else
{
@ -321,27 +317,18 @@ void CGLView::ImportTextures(const QString& pScenePath)
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.
//
// 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;
aiString path;
do
{
if(mScene->mMaterials[idx_material]->GetTexture(aiTextureType_DIFFUSE, idx_texture, &path) != AI_SUCCESS) break;
do {
if (mScene->mMaterials[ idx_material ]->GetTexture( aiTextureType_DIFFUSE, idx_texture, &path ) != AI_SUCCESS) {
break;
}
LoadTexture(QString(path.C_Str()));
idx_texture++;
@ -349,11 +336,8 @@ void CGLView::ImportTextures(const QString& pScenePath)
}// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++)
// Textures list is empty, exit.
if(mTexture_IDMap.size() == 0)
{
if(mTexture_IDMap.empty()) {
LogInfo("No textures for import.");
return;
}
}
@ -451,32 +435,21 @@ void CGLView::BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVe
}
}
/********************************************************************/
/************************ Logging functions *************************/
/********************************************************************/
void CGLView::LogInfo(const QString& pMessage)
{
void CGLView::LogInfo(const QString& pMessage) {
Assimp::DefaultLogger::get()->info(pMessage.toStdString());
}
void CGLView::LogError(const QString& pMessage)
{
void CGLView::LogError(const QString& pMessage) {
Assimp::DefaultLogger::get()->error(pMessage.toStdString());
}
/********************************************************************/
/************************** Draw functions **************************/
/********************************************************************/
void CGLView::Draw_Node(const aiNode* pNode)
{
void CGLView::Draw_Node(const aiNode* pNode) {
aiMatrix4x4 mat_node = pNode->mTransformation;
// Apply node transformation matrix.
mat_node.Transpose();
glPushMatrix();
#if ASSIMP_DOUBLE_PRECISION
#ifdef ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)mat_node[0]);
#else
glMultMatrixf((GLfloat*)&mat_node);
@ -518,7 +491,7 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
{
glEnable(GL_COLOR_MATERIAL);///TODO: cache
glEnableClientState(GL_COLOR_ARRAY);
#if ASSIMP_DOUBLE_PRECISION
#ifdef ASSIMP_DOUBLE_PRECISION
glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]);
#else
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))
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
#if ASSIMP_DOUBLE_PRECISION
#ifdef ASSIMP_DOUBLE_PRECISION
glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
#else
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())
{
glEnableClientState(GL_NORMAL_ARRAY);
#if ASSIMP_DOUBLE_PRECISION
#ifdef ASSIMP_DOUBLE_PRECISION
glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals);
#else
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_2D, 0);
glBindTexture(GL_TEXTURE_3D, 0);
#if ASSIMP_QT4_VIEWER
qglColor(QColor(Qt::white));
#else
const QColor c_w(Qt::white);
glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF());
#endif // ASSIMP_QT4_VIEWER
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[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side.
# else
@ -600,7 +569,7 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
glEnd();
glBegin(GL_LINES);
# if ASSIMP_DOUBLE_PRECISION
# ifdef ASSIMP_DOUBLE_PRECISION
glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]);
glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][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)
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
if(pEnable)
{
void CGLView::Enable_Textures(const bool pEnable) {
if(pEnable) {
glEnable(GL_TEXTURE_1D);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_3D);
}
else
{
} else {
glDisable(GL_TEXTURE_1D);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_3D);
}
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
/********************************************************************/
/*********************** Override functions ************************/
/********************************************************************/
void CGLView::initializeGL()
{
#if ASSIMP_QT4_VIEWER
qglClearColor(Qt::gray);
#else
void CGLView::initializeGL() {
mGLContext_Current = true;
initializeOpenGLFunctions();
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
#endif // ASSIMP_QT4_VIEWER
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glEnable(GL_TEXTURE_2D);
glEnable( GL_MULTISAMPLE );
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
@ -668,25 +617,14 @@ void CGLView::initializeGL()
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::resizeGL(int pWidth, int pHeight)
{
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = true;
#endif // ASSIMP_QT4_VIEWER
mCamera_Viewport_AspectRatio = (GLdouble)pWidth / pHeight;
glViewport(0, 0, pWidth, pHeight);
void CGLView::resizeGL(int width, int height) {
mCamera_Viewport_AspectRatio = (GLdouble)width / height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
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() {
@ -699,19 +637,8 @@ void CGLView::drawCoordSystem() {
glBindTexture(GL_TEXTURE_3D, 0);
glEnable(GL_COLOR_MATERIAL);
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(0.5f, 0.5f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
// Y, -Y
@ -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(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);
#endif // ASSIMP_QT4_VIEWER
glEnd();
// Restore previous state of lighting.
if(mLightingEnabled) glEnable(GL_LIGHTING);
glEnd();
// Restore previous state of lighting.
if (mLightingEnabled) {
glEnable( GL_LIGHTING );
}
}
void CGLView::paintGL()
{
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = true;
#endif // ASSIMP_QT4_VIEWER
void CGLView::paintGL() {
QTime time_paintbegin;
time_paintbegin = QTime::currentTime();
@ -741,6 +664,7 @@ void CGLView::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Apply current camera transformations.
#if ASSIMP_DOUBLE_PRECISION
glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera);
@ -753,58 +677,38 @@ void CGLView::paintGL()
#endif // ASSIMP_DOUBLE_PRECISION
// Coordinate system
if (mScene_AxesEnabled == true)
{
if ( mScene_AxesEnabled ) {
drawCoordSystem();
}
glDisable(GL_COLOR_MATERIAL);
// Scene
if(mScene != nullptr)
{
// Scene
if(mScene != nullptr) {
Draw_Node(mScene->mRootNode);
// 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());
#if !ASSIMP_QT4_VIEWER
mGLContext_Current = false;
#endif // ASSIMP_QT4_VIEWER
emit Paint_Finished((size_t) time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length());
}
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
CGLView::CGLView(QWidget *pParent)
#if ASSIMP_QT4_VIEWER
: QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer), pParent)
#else
: QOpenGLWidget(pParent), mGLContext_Current(false)
#endif // ASSIMP_QT4_VIEWER
{
// set initial view
mHelper_CameraDefault.SetDefault();
Camera_Set(0);
CGLView::CGLView( QWidget *pParent )
: QOpenGLWidget( pParent )
, mGLContext_Current( false ) {
// set initial view
mHelper_CameraDefault.SetDefault();
Camera_Set( 0 );
}
CGLView::~CGLView()
{
CGLView::~CGLView() {
FreeScene();
}
/********************************************************************/
/********************* Scene control functions **********************/
/********************************************************************/
void CGLView::FreeScene()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
void CGLView::FreeScene() {
// Set scene to null and after that \ref paintGL will not try to render it.
mScene = nullptr;
// Clean helper objects.
@ -834,21 +738,14 @@ void CGLView::FreeScene()
mTexture_IDMap.clear();
delete [] id_tex;
}
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
FreeScene();// Clear old data
void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) {
FreeScene();// Clear old data
// 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.
@ -874,7 +771,7 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
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_l = 0;// lines quantity
@ -1039,7 +936,10 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
}// switch(light_cur.mType)
// 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);
emit SceneObject_LightSource(name);// Light source will be enabled in signal handler.
@ -1072,66 +972,48 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str());
}
}// if(!mScene->HasCameras()) else
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
/********************************************************************/
/******************** Lighting control functions ********************/
/********************************************************************/
void CGLView::Lighting_Enable()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
void CGLView::Lighting_Enable() {
mLightingEnabled = true;
glEnable(GL_LIGHTING);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::Lighting_Disable()
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
glDisable(GL_LIGHTING);
void CGLView::Lighting_Disable() {
glDisable( GL_LIGHTING );
mLightingEnabled = false;
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
const size_t light_num = GL_LIGHT0 + pLightNumber;
const size_t light_num = GL_LIGHT0 + pLightNumber;
GLfloat farr[4];
GLfloat farr[4];
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
// 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);
// Diffuse color
farr[0] = pLightParameters.Diffuse.r, farr[1] = pLightParameters.Diffuse.g; farr[2] = pLightParameters.Diffuse.b; farr[3] = pLightParameters.Diffuse.a;
// Diffuse color
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);
// Specular color
farr[0] = pLightParameters.Specular.r, farr[1] = pLightParameters.Specular.g; farr[2] = pLightParameters.Specular.b; farr[3] = pLightParameters.Specular.a;
// Specular color
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);
// Other parameters
// Other parameters
switch(pLightParameters.Type)
{
case aiLightSource_DIRECTIONAL:
@ -1176,46 +1058,21 @@ GLfloat farr[4];
glLightf(light_num, GL_SPOT_CUTOFF, 180.0);
break;
}// switch(pLightParameters.Type)
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
void CGLView::Lighting_EnableSource(const size_t pLightNumber)
{
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_Begin;
#endif // ASSIMP_QT4_VIEWER
void CGLView::Lighting_EnableSource(const size_t pLightNumber) {
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
glEnable(GL_LIGHT0 + pLightNumber);
#if !ASSIMP_QT4_VIEWER
ConditionalContextControl_End;
#endif // ASSIMP_QT4_VIEWER
}
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;
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)
{
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) {
auto deg2rad = [](const GLfloat pDegree) -> GLfloat {
return pDegree * AI_MATH_PI / 180.0;
return pDegree * AI_MATH_PI / 180.0f;
};
aiMatrix4x4 mat_rot;

View File

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

View File

@ -1,19 +1,64 @@
/// \file loggerview.cpp
/// \brief Stream for Assimp logging subsystem.
/// \author smal.root@gmail.com
/// \date 2016
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
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"
// Header files, Qt.
#include <QTime>
#include <QTextBrowser>
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));
}

View File

@ -1,33 +1,67 @@
/// \file loggerview.hpp
/// \brief Stream for Assimp logging subsystem.
/// \author smal.root@gmail.com
/// \date 2016
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
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
// Header files, Qt.
#include <QTextBrowser>
// Header files, Assimp.
#include <assimp/DefaultLogger.hpp>
/// \class CLoggerView
/// 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 QTextBrowser;
/// @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:
/// @brief The class constructor.
/// @param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView( QTextBrowser* pOutputWidget );
/// \fn explicit CLoggerView(QTextBrowser* pOutputWidget)
/// Constructor.
/// \param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView(QTextBrowser* pOutputWidget);
/// @brief The class destructor.
virtual ~CLoggerView();
/// \fn virtual void write(const char *pMessage)
/// Write message to output widget. Used by Assimp.
/// \param [in] pMessage - message for displaying.
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
/// \date 2016
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
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.
// Header files, project.
@ -11,9 +50,9 @@
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
QApplication app(argc, argv);
MainWindow win;
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
/// \date 2016
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
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 "ui_mainwindow.h"
@ -14,22 +52,13 @@
#define __unused __attribute__((unused))
#endif // __unused
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
void MainWindow::ImportFile(const QString &pFileName)
{
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();
mGLView->FreeScene();
}
@ -37,8 +66,7 @@ QTime time_begin = QTime::currentTime();
// Try to import scene.
mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
if(mScene != nullptr)
{
if ( mScene != nullptr ) {
ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
LogInfo("Import done: " + pFileName);
// Prepare widgets for new scene.
@ -60,8 +88,7 @@ QTime time_begin = QTime::currentTime();
size_t qty_face = 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_vert += mScene->mMeshes[idx_mesh]->mNumVertices;
}
@ -241,7 +268,6 @@ MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow),
mScene(nullptr)
{
using namespace Assimp;
// other variables
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
/// \date 2016
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
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
@ -20,125 +58,64 @@
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
namespace Ui { class MainWindow; }
namespace Ui {
class MainWindow;
}
/// \class MainWindow
/// Main window and algorhytms.
class MainWindow : public QMainWindow
{
Q_OBJECT
/// Main window and algorithms.
class MainWindow : public QMainWindow {
Q_OBJECT
/**********************************/
/************ Variables ***********/
/**********************************/
struct SMouse_Transformation;
private:
public:
/// @brief The class constructor.
/// \param [in] pParent - pointer to parent widget.
explicit MainWindow( QWidget* pParent = 0 );
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;
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
/// \fn void ImportFile(const QString& pFileName)
/// Import scene from file.
/// @brief The class destructor.
~MainWindow();
/// Import scene from file.
/// \param [in] pFileName - path and name of the file.
void ImportFile(const QString& pFileName);
/// \fn void ResetSceneInfos()
/// Reset informations about the scene
void ResetSceneInfos();
/********************************************************************/
/************************ Logging functions *************************/
/********************************************************************/
/// \fn void LogInfo(const QString& pMessage)
/// Add message with severity "Warning" to log.
void LogInfo(const QString& pMessage);
/// \fn void LogError(const QString& pMessage)
/// Add message with severity "Error" to log.
void LogError(const QString& pMessage);
/********************************************************************/
/*********************** Override functions ************************/
/********************************************************************/
protected:
/// \fn void mousePressEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "button pressed".
/// \param [in] pEvent - pointer to event data.
void mousePressEvent(QMouseEvent* pEvent) override;
/// \fn void mouseReleaseEvent(QMouseEvent *pEvent) override
/// Override function which handles mouse event "button released".
/// \param [in] pEvent - pointer to event data.
void mouseReleaseEvent(QMouseEvent *pEvent) override;
/// \fn void mouseMoveEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "move".
/// \param [in] pEvent - pointer to event data.
void mouseMoveEvent(QMouseEvent* pEvent) override;
/// \fn void keyPressEvent(QKeyEvent* pEvent) override
/// Override function which handles key event "key pressed".
/// \param [in] pEvent - pointer to event data.
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:
/// \fn void Paint_Finished(const int pPaintTime)
/// Show paint/render time and distance between camera and center of the scene.
/// \param [in] pPaintTime_ms - paint time in milliseconds.
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
/// \fn void SceneObject_Camera(const QString& pName)
/// Add camera name to list.
/// \param [in] pName - name of the camera.
void SceneObject_Camera(const QString& pName);
/// \fn void SceneObject_LightSource(const QString& pName)
/// Add lighting source name to list.
/// \param [in] pName - name of the light source,
void SceneObject_LightSource(const QString& pName);
@ -151,4 +128,21 @@ private slots:
void on_cbxBBox_clicked(bool checked);
void on_cbxTextures_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