Merge branch 'master' into issue_1451

pull/2105/head
Kim Kulling 2018-08-28 19:44:46 +02:00 committed by GitHub
commit dcfc505c4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 8369 additions and 780 deletions

1
.gitignore vendored
View File

@ -21,6 +21,7 @@ revision.h
contrib/zlib/zconf.h contrib/zlib/zconf.h
contrib/zlib/zlib.pc contrib/zlib/zlib.pc
include/assimp/config.h include/assimp/config.h
unit.vcxproj.user
# CMake # CMake
CMakeCache.txt CMakeCache.txt

View File

@ -227,8 +227,8 @@ ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" ) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -fPIC -Wall -Wno-long-long -std=c++11" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
ELSEIF( CMAKE_COMPILER_IS_MINGW ) ELSEIF( CMAKE_COMPILER_IS_MINGW )
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11" ) SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -std=c++11 -Wa,-mbig-obj" )
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC ")
ADD_DEFINITIONS( -U__STRICT_ANSI__ ) ADD_DEFINITIONS( -U__STRICT_ANSI__ )
ENDIF() ENDIF()

View File

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

View File

@ -73,7 +73,7 @@ using namespace Util;
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
Converter::Converter( aiScene* out, const Document& doc ) FBXConverter::FBXConverter( aiScene* out, const Document& doc )
: defaultMaterialIndex() : defaultMaterialIndex()
, out( out ) , out( out )
, doc( doc ) { , doc( doc ) {
@ -114,7 +114,7 @@ Converter::Converter( aiScene* out, const Document& doc )
} }
Converter::~Converter() { FBXConverter::~FBXConverter() {
std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() ); std::for_each( meshes.begin(), meshes.end(), Util::delete_fun<aiMesh>() );
std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() ); std::for_each( materials.begin(), materials.end(), Util::delete_fun<aiMaterial>() );
std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() ); std::for_each( animations.begin(), animations.end(), Util::delete_fun<aiAnimation>() );
@ -123,7 +123,7 @@ Converter::~Converter() {
std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() ); std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() );
} }
void Converter::ConvertRootNode() { void FBXConverter::ConvertRootNode() {
out->mRootNode = new aiNode(); out->mRootNode = new aiNode();
out->mRootNode->mName.Set( "RootNode" ); out->mRootNode->mName.Set( "RootNode" );
@ -131,7 +131,7 @@ void Converter::ConvertRootNode() {
ConvertNodes( 0L, *out->mRootNode ); ConvertNodes( 0L, *out->mRootNode );
} }
void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) { void FBXConverter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform ) {
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" ); const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" );
std::vector<aiNode*> nodes; std::vector<aiNode*> nodes;
@ -282,7 +282,7 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
} }
void Converter::ConvertLights( const Model& model, const std::string &orig_name ) { void FBXConverter::ConvertLights( const Model& model, const std::string &orig_name ) {
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
for( const NodeAttribute* attr : node_attrs ) { for( const NodeAttribute* attr : node_attrs ) {
const Light* const light = dynamic_cast<const Light*>( attr ); const Light* const light = dynamic_cast<const Light*>( attr );
@ -292,7 +292,7 @@ void Converter::ConvertLights( const Model& model, const std::string &orig_name
} }
} }
void Converter::ConvertCameras( const Model& model, const std::string &orig_name ) { void FBXConverter::ConvertCameras( const Model& model, const std::string &orig_name ) {
const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes(); const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
for( const NodeAttribute* attr : node_attrs ) { for( const NodeAttribute* attr : node_attrs ) {
const Camera* const cam = dynamic_cast<const Camera*>( attr ); const Camera* const cam = dynamic_cast<const Camera*>( attr );
@ -302,7 +302,7 @@ void Converter::ConvertCameras( const Model& model, const std::string &orig_name
} }
} }
void Converter::ConvertLight( const Light& light, const std::string &orig_name ) { void FBXConverter::ConvertLight( const Light& light, const std::string &orig_name ) {
lights.push_back( new aiLight() ); lights.push_back( new aiLight() );
aiLight* const out_light = lights.back(); aiLight* const out_light = lights.back();
@ -379,7 +379,7 @@ void Converter::ConvertLight( const Light& light, const std::string &orig_name )
} }
} }
void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name ) void FBXConverter::ConvertCamera( const Camera& cam, const std::string &orig_name )
{ {
cameras.push_back( new aiCamera() ); cameras.push_back( new aiCamera() );
aiCamera* const out_camera = cameras.back(); aiCamera* const out_camera = cameras.back();
@ -398,7 +398,7 @@ void Converter::ConvertCamera( const Camera& cam, const std::string &orig_name )
out_camera->mClipPlaneFar = cam.FarPlane(); out_camera->mClipPlaneFar = cam.FarPlane();
} }
void Converter::GetUniqueName( const std::string &name, std::string &uniqueName ) void FBXConverter::GetUniqueName( const std::string &name, std::string &uniqueName )
{ {
int i = 0; int i = 0;
uniqueName = name; uniqueName = name;
@ -413,107 +413,105 @@ void Converter::GetUniqueName( const std::string &name, std::string &uniqueName
} }
const char* Converter::NameTransformationComp( TransformationComp comp ) const char* FBXConverter::NameTransformationComp( TransformationComp comp ) {
{ switch ( comp ) {
switch ( comp ) case TransformationComp_Translation:
{ return "Translation";
case TransformationComp_Translation: case TransformationComp_RotationOffset:
return "Translation"; return "RotationOffset";
case TransformationComp_RotationOffset: case TransformationComp_RotationPivot:
return "RotationOffset"; return "RotationPivot";
case TransformationComp_RotationPivot: case TransformationComp_PreRotation:
return "RotationPivot"; return "PreRotation";
case TransformationComp_PreRotation: case TransformationComp_Rotation:
return "PreRotation"; return "Rotation";
case TransformationComp_Rotation: case TransformationComp_PostRotation:
return "Rotation"; return "PostRotation";
case TransformationComp_PostRotation: case TransformationComp_RotationPivotInverse:
return "PostRotation"; return "RotationPivotInverse";
case TransformationComp_RotationPivotInverse: case TransformationComp_ScalingOffset:
return "RotationPivotInverse"; return "ScalingOffset";
case TransformationComp_ScalingOffset: case TransformationComp_ScalingPivot:
return "ScalingOffset"; return "ScalingPivot";
case TransformationComp_ScalingPivot: case TransformationComp_Scaling:
return "ScalingPivot"; return "Scaling";
case TransformationComp_Scaling: case TransformationComp_ScalingPivotInverse:
return "Scaling"; return "ScalingPivotInverse";
case TransformationComp_ScalingPivotInverse: case TransformationComp_GeometricScaling:
return "ScalingPivotInverse"; return "GeometricScaling";
case TransformationComp_GeometricScaling: case TransformationComp_GeometricRotation:
return "GeometricScaling"; return "GeometricRotation";
case TransformationComp_GeometricRotation: case TransformationComp_GeometricTranslation:
return "GeometricRotation"; return "GeometricTranslation";
case TransformationComp_GeometricTranslation: case TransformationComp_GeometricScalingInverse:
return "GeometricTranslation"; return "GeometricScalingInverse";
case TransformationComp_GeometricScalingInverse: case TransformationComp_GeometricRotationInverse:
return "GeometricScalingInverse"; return "GeometricRotationInverse";
case TransformationComp_GeometricRotationInverse: case TransformationComp_GeometricTranslationInverse:
return "GeometricRotationInverse"; return "GeometricTranslationInverse";
case TransformationComp_GeometricTranslationInverse: case TransformationComp_MAXIMUM: // this is to silence compiler warnings
return "GeometricTranslationInverse"; default:
case TransformationComp_MAXIMUM: // this is to silence compiler warnings break;
default:
break;
} }
ai_assert( false ); ai_assert( false );
return NULL;
return nullptr;
} }
const char* Converter::NameTransformationCompProperty( TransformationComp comp ) const char* FBXConverter::NameTransformationCompProperty( TransformationComp comp ) {
{ switch ( comp ) {
switch ( comp ) case TransformationComp_Translation:
{ return "Lcl Translation";
case TransformationComp_Translation: case TransformationComp_RotationOffset:
return "Lcl Translation"; return "RotationOffset";
case TransformationComp_RotationOffset: case TransformationComp_RotationPivot:
return "RotationOffset"; return "RotationPivot";
case TransformationComp_RotationPivot: case TransformationComp_PreRotation:
return "RotationPivot"; return "PreRotation";
case TransformationComp_PreRotation: case TransformationComp_Rotation:
return "PreRotation"; return "Lcl Rotation";
case TransformationComp_Rotation: case TransformationComp_PostRotation:
return "Lcl Rotation"; return "PostRotation";
case TransformationComp_PostRotation: case TransformationComp_RotationPivotInverse:
return "PostRotation"; return "RotationPivotInverse";
case TransformationComp_RotationPivotInverse: case TransformationComp_ScalingOffset:
return "RotationPivotInverse"; return "ScalingOffset";
case TransformationComp_ScalingOffset: case TransformationComp_ScalingPivot:
return "ScalingOffset"; return "ScalingPivot";
case TransformationComp_ScalingPivot: case TransformationComp_Scaling:
return "ScalingPivot"; return "Lcl Scaling";
case TransformationComp_Scaling: case TransformationComp_ScalingPivotInverse:
return "Lcl Scaling"; return "ScalingPivotInverse";
case TransformationComp_ScalingPivotInverse: case TransformationComp_GeometricScaling:
return "ScalingPivotInverse"; return "GeometricScaling";
case TransformationComp_GeometricScaling: case TransformationComp_GeometricRotation:
return "GeometricScaling"; return "GeometricRotation";
case TransformationComp_GeometricRotation: case TransformationComp_GeometricTranslation:
return "GeometricRotation"; return "GeometricTranslation";
case TransformationComp_GeometricTranslation: case TransformationComp_GeometricScalingInverse:
return "GeometricTranslation"; return "GeometricScalingInverse";
case TransformationComp_GeometricScalingInverse: case TransformationComp_GeometricRotationInverse:
return "GeometricScalingInverse"; return "GeometricRotationInverse";
case TransformationComp_GeometricRotationInverse: case TransformationComp_GeometricTranslationInverse:
return "GeometricRotationInverse"; return "GeometricTranslationInverse";
case TransformationComp_GeometricTranslationInverse: case TransformationComp_MAXIMUM: // this is to silence compiler warnings
return "GeometricTranslationInverse"; break;
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
break;
} }
ai_assert( false ); ai_assert( false );
return NULL;
return nullptr;
} }
aiVector3D Converter::TransformationCompDefaultValue( TransformationComp comp ) aiVector3D FBXConverter::TransformationCompDefaultValue( TransformationComp comp )
{ {
// XXX a neat way to solve the never-ending special cases for scaling // XXX a neat way to solve the never-ending special cases for scaling
// would be to do everything in log space! // would be to do everything in log space!
return comp == TransformationComp_Scaling ? aiVector3D( 1.f, 1.f, 1.f ) : aiVector3D(); return comp == TransformationComp_Scaling ? aiVector3D( 1.f, 1.f, 1.f ) : aiVector3D();
} }
void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out ) void FBXConverter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out )
{ {
if ( mode == Model::RotOrder_SphericXYZ ) { if ( mode == Model::RotOrder_SphericXYZ ) {
FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" ); FBXImporter::LogError( "Unsupported RotationMode: SphericXYZ" );
@ -584,11 +582,15 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
default: default:
ai_assert( false ); ai_assert( false );
break;
} }
ai_assert( ( order[ 0 ] >= 0 ) && ( order[ 0 ] <= 2 ) ); ai_assert( order[ 0 ] >= 0 );
ai_assert( ( order[ 1 ] >= 0 ) && ( order[ 1 ] <= 2 ) ); ai_assert( order[ 0 ] <= 2 );
ai_assert( ( order[ 2 ] >= 0 ) && ( order[ 2 ] <= 2 ) ); ai_assert( order[ 1 ] >= 0 );
ai_assert( order[ 1 ] <= 2 );
ai_assert( order[ 2 ] >= 0 );
ai_assert( order[ 2 ] <= 2 );
if ( !is_id[ order[ 0 ] ] ) { if ( !is_id[ order[ 0 ] ] ) {
out = temp[ order[ 0 ] ]; out = temp[ order[ 0 ] ];
@ -603,7 +605,7 @@ void Converter::GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotat
} }
} }
bool Converter::NeedsComplexTransformationChain( const Model& model ) bool FBXConverter::NeedsComplexTransformationChain( const Model& model )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
bool ok; bool ok;
@ -634,13 +636,13 @@ bool Converter::NeedsComplexTransformationChain( const Model& model )
return false; return false;
} }
std::string Converter::NameTransformationChainNode( const std::string& name, TransformationComp comp ) std::string FBXConverter::NameTransformationChainNode( const std::string& name, TransformationComp comp )
{ {
return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp ); return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
} }
void Converter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes ) void FBXConverter::GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes,
{ std::vector<aiNode*>& post_output_nodes ) {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
const Model::RotOrder rot = model.RotationOrder(); const Model::RotOrder rot = model.RotationOrder();
@ -811,7 +813,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
} }
} }
void Converter::SetupNodeMetadata( const Model& model, aiNode& nd ) void FBXConverter::SetupNodeMetadata( const Model& model, aiNode& nd )
{ {
const PropertyTable& props = model.Props(); const PropertyTable& props = model.Props();
DirectPropertyMap unparsedProperties = props.GetUnparsedProperties(); DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
@ -848,7 +850,7 @@ void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
} }
} }
void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform ) void FBXConverter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform )
{ {
const std::vector<const Geometry*>& geos = model.GetGeometry(); const std::vector<const Geometry*>& geos = model.GetGeometry();
@ -875,7 +877,7 @@ void Converter::ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4&
} }
} }
std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> FBXConverter::ConvertMesh( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
std::vector<unsigned int> temp; std::vector<unsigned int> temp;
@ -910,7 +912,7 @@ std::vector<unsigned int> Converter::ConvertMesh( const MeshGeometry& mesh, cons
return temp; return temp;
} }
aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd) aiMesh* FBXConverter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
{ {
aiMesh* const out_mesh = new aiMesh(); aiMesh* const out_mesh = new aiMesh();
meshes.push_back( out_mesh ); meshes.push_back( out_mesh );
@ -933,7 +935,7 @@ aiMesh* Converter::SetupEmptyMesh( const MeshGeometry& mesh, aiNode& nd)
return out_mesh; return out_mesh;
} }
unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model, unsigned int FBXConverter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
@ -1060,7 +1062,7 @@ unsigned int Converter::ConvertMeshSingleMaterial( const MeshGeometry& mesh, con
return static_cast<unsigned int>( meshes.size() - 1 ); return static_cast<unsigned int>( meshes.size() - 1 );
} }
std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model, std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
const aiMatrix4x4& node_global_transform, aiNode& nd) const aiMatrix4x4& node_global_transform, aiNode& nd)
{ {
const MatIndexArray& mindices = mesh.GetMaterialIndices(); const MatIndexArray& mindices = mesh.GetMaterialIndices();
@ -1080,7 +1082,7 @@ std::vector<unsigned int> Converter::ConvertMeshMultiMaterial( const MeshGeometr
return indices; return indices;
} }
unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model, unsigned int FBXConverter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
MatIndexArray::value_type index, MatIndexArray::value_type index,
const aiMatrix4x4& node_global_transform, const aiMatrix4x4& node_global_transform,
aiNode& nd) aiNode& nd)
@ -1256,7 +1258,7 @@ unsigned int Converter::ConvertMeshMultiMaterial( const MeshGeometry& mesh, cons
return static_cast<unsigned int>( meshes.size() - 1 ); return static_cast<unsigned int>( meshes.size() - 1 );
} }
void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo, void FBXConverter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
const aiMatrix4x4& node_global_transform , const aiMatrix4x4& node_global_transform ,
unsigned int materialIndex, unsigned int materialIndex,
std::vector<unsigned int>* outputVertStartIndices ) std::vector<unsigned int>* outputVertStartIndices )
@ -1361,7 +1363,7 @@ void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeome
std::swap_ranges( bones.begin(), bones.end(), out->mBones ); std::swap_ranges( bones.begin(), bones.end(), out->mBones );
} }
void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl, void FBXConverter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
std::vector<size_t>& out_indices, std::vector<size_t>& out_indices,
std::vector<size_t>& index_out_indices, std::vector<size_t>& index_out_indices,
std::vector<size_t>& count_out_indices, std::vector<size_t>& count_out_indices,
@ -1402,7 +1404,7 @@ void Converter::ConvertCluster( std::vector<aiBone*>& bones, const Model& /*mode
} }
} }
void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo, void FBXConverter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
MatIndexArray::value_type materialIndex ) MatIndexArray::value_type materialIndex )
{ {
// locate source materials for this mesh // locate source materials for this mesh
@ -1424,7 +1426,7 @@ void Converter::ConvertMaterialForMesh( aiMesh* out, const Model& model, const M
materials_converted[ mat ] = out->mMaterialIndex; materials_converted[ mat ] = out->mMaterialIndex;
} }
unsigned int Converter::GetDefaultMaterial() unsigned int FBXConverter::GetDefaultMaterial()
{ {
if ( defaultMaterialIndex ) { if ( defaultMaterialIndex ) {
return defaultMaterialIndex - 1; return defaultMaterialIndex - 1;
@ -1446,7 +1448,7 @@ unsigned int Converter::GetDefaultMaterial()
} }
unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh ) unsigned int FBXConverter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh )
{ {
const PropertyTable& props = material.Props(); const PropertyTable& props = material.Props();
@ -1481,7 +1483,7 @@ unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeo
return static_cast<unsigned int>( materials.size() - 1 ); return static_cast<unsigned int>( materials.size() - 1 );
} }
unsigned int Converter::ConvertVideo( const Video& video ) unsigned int FBXConverter::ConvertVideo( const Video& video )
{ {
// generate empty output texture // generate empty output texture
aiTexture* out_tex = new aiTexture(); aiTexture* out_tex = new aiTexture();
@ -1511,7 +1513,7 @@ unsigned int Converter::ConvertVideo( const Video& video )
return static_cast<unsigned int>( textures.size() - 1 ); return static_cast<unsigned int>( textures.size() - 1 );
} }
aiString Converter::GetTexturePath(const Texture* tex) aiString FBXConverter::GetTexturePath(const Texture* tex)
{ {
aiString path; aiString path;
path.Set(tex->RelativeFilename()); path.Set(tex->RelativeFilename());
@ -1551,7 +1553,7 @@ aiString Converter::GetTexturePath(const Texture* tex)
return path; return path;
} }
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
const std::string& propName, const std::string& propName,
aiTextureType target, const MeshGeometry* const mesh ) aiTextureType target, const MeshGeometry* const mesh )
{ {
@ -1669,7 +1671,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
} }
} }
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, void FBXConverter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
const std::string& propName, const std::string& propName,
aiTextureType target, const MeshGeometry* const mesh ) { aiTextureType target, const MeshGeometry* const mesh ) {
LayeredTextureMap::const_iterator it = layeredTextures.find( propName ); LayeredTextureMap::const_iterator it = layeredTextures.find( propName );
@ -1792,7 +1794,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextu
} }
} }
void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh ) void FBXConverter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh )
{ {
TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh ); TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh ); TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh );
@ -1807,7 +1809,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& tex
TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh ); TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh );
} }
void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh ) void FBXConverter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh )
{ {
TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh );
@ -1822,7 +1824,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureM
TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh ); TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh );
} }
aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName, aiColor3D FBXConverter::GetColorPropertyFactored( const PropertyTable& props, const std::string& colorName,
const std::string& factorName, bool& result, bool useTemplate ) const std::string& factorName, bool& result, bool useTemplate )
{ {
result = true; result = true;
@ -1847,13 +1849,13 @@ aiColor3D Converter::GetColorPropertyFactored( const PropertyTable& props, const
return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z ); return aiColor3D( BaseColor.x, BaseColor.y, BaseColor.z );
} }
aiColor3D Converter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName, aiColor3D FBXConverter::GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
bool& result ) bool& result )
{ {
return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true ); return GetColorPropertyFactored( props, baseName + "Color", baseName + "Factor", result, true );
} }
aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::string& colorName, aiColor3D FBXConverter::GetColorProperty( const PropertyTable& props, const std::string& colorName,
bool& result, bool useTemplate ) bool& result, bool useTemplate )
{ {
result = true; result = true;
@ -1866,7 +1868,7 @@ aiColor3D Converter::GetColorProperty( const PropertyTable& props, const std::st
return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z ); return aiColor3D( ColorVec.x, ColorVec.y, ColorVec.z );
} }
void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props ) void FBXConverter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props )
{ {
// Set shading properties. // Set shading properties.
// Modern FBX Files have two separate systems for defining these, // Modern FBX Files have two separate systems for defining these,
@ -1965,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 ) { switch ( fp ) {
case FileGlobalSettings::FrameRate_DEFAULT: case FileGlobalSettings::FrameRate_DEFAULT:
return 1.0; return 1.0;
case FileGlobalSettings::FrameRate_120: case FileGlobalSettings::FrameRate_120:
return 120.0; return 120.0;
case FileGlobalSettings::FrameRate_100: case FileGlobalSettings::FrameRate_100:
return 100.0; return 100.0;
case FileGlobalSettings::FrameRate_60: case FileGlobalSettings::FrameRate_60:
return 60.0; return 60.0;
case FileGlobalSettings::FrameRate_50: case FileGlobalSettings::FrameRate_50:
return 50.0; return 50.0;
case FileGlobalSettings::FrameRate_48: case FileGlobalSettings::FrameRate_48:
return 48.0; return 48.0;
case FileGlobalSettings::FrameRate_30: case FileGlobalSettings::FrameRate_30:
case FileGlobalSettings::FrameRate_30_DROP: case FileGlobalSettings::FrameRate_30_DROP:
return 30.0; return 30.0;
case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME: case FileGlobalSettings::FrameRate_NTSC_DROP_FRAME:
case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME: case FileGlobalSettings::FrameRate_NTSC_FULL_FRAME:
return 29.9700262; return 29.9700262;
case FileGlobalSettings::FrameRate_PAL: case FileGlobalSettings::FrameRate_PAL:
return 25.0; return 25.0;
case FileGlobalSettings::FrameRate_CINEMA: case FileGlobalSettings::FrameRate_CINEMA:
return 24.0; return 24.0;
case FileGlobalSettings::FrameRate_1000: case FileGlobalSettings::FrameRate_1000:
return 1000.0; return 1000.0;
case FileGlobalSettings::FrameRate_CINEMA_ND: case FileGlobalSettings::FrameRate_CINEMA_ND:
return 23.976; return 23.976;
case FileGlobalSettings::FrameRate_CUSTOM: case FileGlobalSettings::FrameRate_CUSTOM:
return customFPSVal; return customFPSVal;
case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings case FileGlobalSettings::FrameRate_MAX: // this is to silence compiler warnings
break; break;
} }
ai_assert( false ); ai_assert( false );
return -1.0f; return -1.0f;
} }
void Converter::ConvertAnimations() void FBXConverter::ConvertAnimations()
{ {
// first of all determine framerate // first of all determine framerate
const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode(); const FileGlobalSettings::FrameRate fps = doc.GlobalSettings().TimeMode();
@ -2031,7 +2033,7 @@ void Converter::ConvertAnimations()
} }
} }
std::string Converter::FixNodeName( const std::string& name ) { std::string FBXConverter::FixNodeName( const std::string& name ) {
// strip Model:: prefix, avoiding ambiguities (i.e. don't strip if // strip Model:: prefix, avoiding ambiguities (i.e. don't strip if
// this causes ambiguities, well possible between empty identifiers, // this causes ambiguities, well possible between empty identifiers,
// such as "Model::" and ""). Make sure the behaviour is consistent // such as "Model::" and ""). Make sure the behaviour is consistent
@ -2044,7 +2046,7 @@ std::string Converter::FixNodeName( const std::string& name ) {
return name; return name;
} }
void Converter::ConvertAnimationStack( const AnimationStack& st ) void FBXConverter::ConvertAnimationStack( const AnimationStack& st )
{ {
const AnimationLayerList& layers = st.Layers(); const AnimationLayerList& layers = st.Layers();
if ( layers.empty() ) { if ( layers.empty() ) {
@ -2186,7 +2188,7 @@ static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>
#endif // ASSIMP_BUILD_DEBUG #endif // ASSIMP_BUILD_DEBUG
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims, void FBXConverter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
const std::string& fixed_name, const std::string& fixed_name,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2420,10 +2422,9 @@ void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
node_anim_chain_bits[ fixed_name ] = flags; node_anim_chain_bits[ fixed_name ] = flags;
} }
bool Converter::IsRedundantAnimationData( const Model& target, bool FBXConverter::IsRedundantAnimationData( const Model& target,
TransformationComp comp, TransformationComp comp,
const std::vector<const AnimationCurveNode*>& curves ) const std::vector<const AnimationCurveNode*>& curves ) {
{
ai_assert( curves.size() ); ai_assert( curves.size() );
// look for animation nodes with // look for animation nodes with
@ -2466,7 +2467,7 @@ bool Converter::IsRedundantAnimationData( const Model& target,
} }
aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateRotationNodeAnim( const std::string& name,
const Model& target, const Model& target,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2496,7 +2497,7 @@ aiNodeAnim* Converter::GenerateRotationNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateScalingNodeAnim( const std::string& name,
const Model& /*target*/, const Model& /*target*/,
const std::vector<const AnimationCurveNode*>& curves, const std::vector<const AnimationCurveNode*>& curves,
const LayerMap& layer_map, const LayerMap& layer_map,
@ -2526,16 +2527,14 @@ aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* FBXConverter::GenerateTranslationNodeAnim( const std::string& name,
aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name, const Model& /*target*/,
const Model& /*target*/, const std::vector<const AnimationCurveNode*>& curves,
const std::vector<const AnimationCurveNode*>& curves, const LayerMap& layer_map,
const LayerMap& layer_map, int64_t start, int64_t stop,
int64_t start, int64_t stop, double& max_time,
double& max_time, double& min_time,
double& min_time, bool inverse ) {
bool inverse )
{
std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() ); std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
na->mNodeName.Set( name ); na->mNodeName.Set( name );
@ -2564,7 +2563,7 @@ aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name, aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim( const std::string& name,
const Model& target, const Model& target,
NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ], NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
NodeMap::const_iterator iter_end, NodeMap::const_iterator iter_end,
@ -2700,7 +2699,7 @@ aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
return na.release(); return na.release();
} }
Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop ) FBXConverter::KeyFrameListList FBXConverter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop )
{ {
KeyFrameListList inputs; KeyFrameListList inputs;
inputs.reserve( nodes.size() * 3 ); inputs.reserve( nodes.size() * 3 );
@ -2756,12 +2755,11 @@ Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const
} }
KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs ) KeyTimeList FBXConverter::GetKeyTimeList( const KeyFrameListList& inputs ) {
{ ai_assert( !inputs.empty() );
ai_assert( inputs.size() );
// reserve some space upfront - it is likely that the keyframe lists // reserve some space upfront - it is likely that the key-frame lists
// have matching time values, so max(of all keyframe lists) should // have matching time values, so max(of all key-frame lists) should
// be a good estimate. // be a good estimate.
KeyTimeList keys; KeyTimeList keys;
@ -2805,17 +2803,15 @@ KeyTimeList Converter::GetKeyTimeList( const KeyFrameListList& inputs )
return keys; return keys;
} }
void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, void FBXConverter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
const aiVector3D& def_value, const aiVector3D& def_value,
double& max_time, double& max_time,
double& min_time ) double& min_time ) {
ai_assert( !keys.empty() );
{ ai_assert( nullptr != valOut );
ai_assert( keys.size() );
ai_assert( valOut );
std::vector<unsigned int> next_pos; std::vector<unsigned int> next_pos;
const size_t count = inputs.size(); const size_t count( inputs.size() );
next_pos.resize( inputs.size(), 0 ); next_pos.resize( inputs.size(), 0 );
@ -2826,6 +2822,9 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
const KeyFrameList& kfl = inputs[ i ]; const KeyFrameList& kfl = inputs[ i ];
const size_t ksize = std::get<0>(kfl)->size(); const size_t ksize = std::get<0>(kfl)->size();
if (ksize == 0) {
continue;
}
if ( ksize > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == time ) { if ( ksize > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == time ) {
++next_pos[ i ]; ++next_pos[ i ];
} }
@ -2860,14 +2859,14 @@ void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, c
} }
} }
void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs, void FBXConverter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
const aiVector3D& def_value, const aiVector3D& def_value,
double& maxTime, double& maxTime,
double& minTime, double& minTime,
Model::RotOrder order ) Model::RotOrder order )
{ {
ai_assert( keys.size() ); ai_assert( !keys.empty() );
ai_assert( valOut ); ai_assert( nullptr != valOut );
std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] ); std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] );
InterpolateKeys( temp.get(), keys, inputs, def_value, maxTime, minTime ); InterpolateKeys( temp.get(), keys, inputs, def_value, maxTime, minTime );
@ -2898,7 +2897,7 @@ void Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, con
} }
} }
void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale, void FBXConverter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey* out_scale,
aiVectorKey* out_translation, aiVectorKey* out_translation,
const KeyFrameListList& scaling, const KeyFrameListList& scaling,
const KeyFrameListList& translation, const KeyFrameListList& translation,
@ -2956,7 +2955,7 @@ void Converter::ConvertTransformOrder_TRStoSRT( aiQuatKey* out_quat, aiVectorKey
} }
} }
aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order ) aiQuaternion FBXConverter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
{ {
aiMatrix4x4 m; aiMatrix4x4 m;
GetRotationMatrix( order, rot, m ); GetRotationMatrix( order, rot, m );
@ -2964,7 +2963,7 @@ aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrde
return aiQuaternion( aiMatrix3x3( m ) ); return aiQuaternion( aiMatrix3x3( m ) );
} }
void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/, void FBXConverter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
double& minTime ) double& minTime )
@ -2984,7 +2983,7 @@ void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const Animat
InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime ); InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
} }
void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, void FBXConverter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& /*layers*/, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
@ -3002,7 +3001,7 @@ void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const
InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime ); InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
} }
void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, void FBXConverter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
const LayerMap& /*layers*/, const LayerMap& /*layers*/,
int64_t start, int64_t stop, int64_t start, int64_t stop,
double& maxTime, double& maxTime,
@ -3022,7 +3021,7 @@ void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const Ani
} }
} }
void Converter::ConvertGlobalSettings() { void FBXConverter::ConvertGlobalSettings() {
if (nullptr == out) { if (nullptr == out) {
return; return;
} }
@ -3033,7 +3032,7 @@ void Converter::ConvertGlobalSettings() {
out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor); out->mMetaData->Set(index, "UnitScaleFactor", unitScalFactor);
} }
void Converter::TransferDataToScene() void FBXConverter::TransferDataToScene()
{ {
ai_assert( !out->mMeshes ); ai_assert( !out->mMeshes );
ai_assert( !out->mNumMeshes ); ai_assert( !out->mNumMeshes );
@ -3088,7 +3087,7 @@ void Converter::TransferDataToScene()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc) void ConvertToAssimpScene(aiScene* out, const Document& doc)
{ {
Converter converter(out,doc); FBXConverter converter(out,doc);
} }
} // !FBX } // !FBX

View File

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

View File

@ -210,22 +210,63 @@ void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene
ai_assert(false); ai_assert(false);
} }
// Create nodes for the whole scene if (pModel->m_Objects.size() > 0) {
std::vector<aiMesh*> MeshArray; // Create nodes for the whole scene
for (size_t index = 0; index < pModel->m_Objects.size(); ++index ) { std::vector<aiMesh*> MeshArray;
createNodes(pModel, pModel->m_Objects[ index ], pScene->mRootNode, pScene, 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 ];
} }
}
// Create all materials // Create mesh pointer buffer for this scene
createMaterials( pModel, pScene ); 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 // Copy all vertex colors
if ( !pModel->m_VertexColors.empty()) if ( !pModel->m_VertexColors.empty())
{ {
const aiVector3D color = pModel->m_VertexColors[ vertex ]; const aiVector3D& color = pModel->m_VertexColors[ vertex ];
pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0); pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0);
} }

View File

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

View File

@ -437,6 +437,12 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
} }
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) { for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
if (attr.texcoord[tc]->count != aim->mNumVertices) {
DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name +
"\" does not match the vertex count");
continue;
}
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]); attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents(); aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,45 @@
/// \file glview.hpp /*
/// \brief OpenGL visualisation. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#pragma once #pragma once

View File

@ -1,19 +1,64 @@
/// \file loggerview.cpp /*
/// \brief Stream for Assimp logging subsystem. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "loggerview.hpp" #include "loggerview.hpp"
// Header files, Qt. // Header files, Qt.
#include <QTime> #include <QTime>
#include <QTextBrowser>
CLoggerView::CLoggerView(QTextBrowser* pOutputWidget) CLoggerView::CLoggerView(QTextBrowser* pOutputWidget)
: mOutputWidget(pOutputWidget) : mOutputWidget(pOutputWidget) {
{ // empty
} }
void CLoggerView::write(const char *pMessage) CLoggerView::~CLoggerView() {
{ mOutputWidget = nullptr;
}
void CLoggerView::write(const char *pMessage) {
if (nullptr == mOutputWidget) {
return;
}
mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage)); mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage));
} }

View File

@ -1,33 +1,67 @@
/// \file loggerview.hpp /*
/// \brief Stream for Assimp logging subsystem. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#pragma once #pragma once
// Header files, Qt.
#include <QTextBrowser>
// Header files, Assimp. // Header files, Assimp.
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
/// \class CLoggerView class QTextBrowser;
/// GUI-stream for Assimp logging subsytem. Get data for logging and write it to output widget.
class CLoggerView final : public Assimp::LogStream
{
private:
QTextBrowser* mOutputWidget;///< Widget for displaying messages.
/// @class CLoggerView
/// @brief GUI-stream for Assimp logging sub-sytem. Get data for logging and write it to output widget.
class CLoggerView final : public ::Assimp::LogStream {
public: public:
/// @brief The class constructor.
/// @param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView( QTextBrowser* pOutputWidget );
/// \fn explicit CLoggerView(QTextBrowser* pOutputWidget) /// @brief The class destructor.
/// Constructor. virtual ~CLoggerView();
/// \param [in] pOutputWidget - pointer to output widget.
explicit CLoggerView(QTextBrowser* pOutputWidget);
/// \fn virtual void write(const char *pMessage)
/// Write message to output widget. Used by Assimp. /// Write message to output widget. Used by Assimp.
/// \param [in] pMessage - message for displaying. /// \param [in] pMessage - message for displaying.
virtual void write(const char *pMessage); virtual void write(const char *pMessage);
private:
QTextBrowser * mOutputWidget; ///< Widget for displaying messages.
}; };

View File

@ -1,7 +1,46 @@
/// \file main.cpp /*
/// \brief Start-up file which contain function "main". ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
// Thanks to acorn89 for support. // Thanks to acorn89 for support.
// Header files, project. // Header files, project.
@ -11,9 +50,9 @@
#include <QApplication> #include <QApplication>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
QApplication a(argc, argv); QApplication app(argc, argv);
MainWindow w; MainWindow win;
w.show(); win.show();
return a.exec(); return app.exec();
} }

View File

@ -1,7 +1,45 @@
/// \file mainwindow.hpp /*
/// \brief Main window and algorhytms. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "mainwindow.hpp" #include "mainwindow.hpp"
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
@ -14,22 +52,13 @@
#define __unused __attribute__((unused)) #define __unused __attribute__((unused))
#endif // __unused #endif // __unused
/**********************************/
/************ Functions ***********/
/**********************************/
/********************************************************************/
/********************* Import/Export functions **********************/
/********************************************************************/
void MainWindow::ImportFile(const QString &pFileName)
{
using namespace Assimp; using namespace Assimp;
QTime time_begin = QTime::currentTime();
if(mScene != nullptr) void MainWindow::ImportFile(const QString &pFileName) {
{ QTime time_begin = QTime::currentTime();
if ( mScene != nullptr ) {
mImporter.FreeScene(); mImporter.FreeScene();
mGLView->FreeScene(); mGLView->FreeScene();
} }
@ -37,8 +66,7 @@ QTime time_begin = QTime::currentTime();
// Try to import scene. // Try to import scene.
mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \ mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs); aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
if(mScene != nullptr) if ( mScene != nullptr ) {
{
ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime()))); ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
LogInfo("Import done: " + pFileName); LogInfo("Import done: " + pFileName);
// Prepare widgets for new scene. // Prepare widgets for new scene.
@ -60,8 +88,7 @@ QTime time_begin = QTime::currentTime();
size_t qty_face = 0; size_t qty_face = 0;
size_t qty_vert = 0; size_t qty_vert = 0;
for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) {
{
qty_face += mScene->mMeshes[idx_mesh]->mNumFaces; qty_face += mScene->mMeshes[idx_mesh]->mNumFaces;
qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices; qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices;
} }
@ -241,7 +268,6 @@ MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow), : QMainWindow(parent), ui(new Ui::MainWindow),
mScene(nullptr) mScene(nullptr)
{ {
using namespace Assimp;
// other variables // other variables
mMouse_Transformation.Position_Pressed_Valid = false; mMouse_Transformation.Position_Pressed_Valid = false;

View File

@ -1,7 +1,45 @@
/// \file mainwindow.hpp /*
/// \brief Main window and algorhytms. ---------------------------------------------------------------------------
/// \author smal.root@gmail.com Open Asset Import Library (assimp)
/// \date 2016 ---------------------------------------------------------------------------
Copyright (c) 2006-2018, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#pragma once #pragma once
@ -20,125 +58,64 @@
#include <assimp/Importer.hpp> #include <assimp/Importer.hpp>
#include <assimp/scene.h> #include <assimp/scene.h>
namespace Ui { class MainWindow; } namespace Ui {
class MainWindow;
}
/// \class MainWindow /// \class MainWindow
/// Main window and algorhytms. /// Main window and algorithms.
class MainWindow : public QMainWindow class MainWindow : public QMainWindow {
{ Q_OBJECT
Q_OBJECT
/**********************************/ struct SMouse_Transformation;
/************ Variables ***********/
/**********************************/
private: public:
/// @brief The class constructor.
/// \param [in] pParent - pointer to parent widget.
explicit MainWindow( QWidget* pParent = 0 );
Ui::MainWindow *ui; /// @brief The class destructor.
~MainWindow();
CGLView* mGLView;///< Pointer to OpenGL render.
CLoggerView* mLoggerView;///< Pointer to logging object. /// Import scene from file.
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.
/// \param [in] pFileName - path and name of the file. /// \param [in] pFileName - path and name of the file.
void ImportFile(const QString& pFileName); void ImportFile(const QString& pFileName);
/// \fn void ResetSceneInfos()
/// Reset informations about the scene /// Reset informations about the scene
void ResetSceneInfos(); void ResetSceneInfos();
/********************************************************************/
/************************ Logging functions *************************/
/********************************************************************/
/// \fn void LogInfo(const QString& pMessage)
/// Add message with severity "Warning" to log. /// Add message with severity "Warning" to log.
void LogInfo(const QString& pMessage); void LogInfo(const QString& pMessage);
/// \fn void LogError(const QString& pMessage)
/// Add message with severity "Error" to log. /// Add message with severity "Error" to log.
void LogError(const QString& pMessage); void LogError(const QString& pMessage);
/********************************************************************/
/*********************** Override functions ************************/
/********************************************************************/
protected: protected:
/// \fn void mousePressEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "button pressed". /// Override function which handles mouse event "button pressed".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mousePressEvent(QMouseEvent* pEvent) override; void mousePressEvent(QMouseEvent* pEvent) override;
/// \fn void mouseReleaseEvent(QMouseEvent *pEvent) override
/// Override function which handles mouse event "button released". /// Override function which handles mouse event "button released".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mouseReleaseEvent(QMouseEvent *pEvent) override; void mouseReleaseEvent(QMouseEvent *pEvent) override;
/// \fn void mouseMoveEvent(QMouseEvent* pEvent) override
/// Override function which handles mouse event "move". /// Override function which handles mouse event "move".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void mouseMoveEvent(QMouseEvent* pEvent) override; void mouseMoveEvent(QMouseEvent* pEvent) override;
/// \fn void keyPressEvent(QKeyEvent* pEvent) override
/// Override function which handles key event "key pressed". /// Override function which handles key event "key pressed".
/// \param [in] pEvent - pointer to event data. /// \param [in] pEvent - pointer to event data.
void keyPressEvent(QKeyEvent* pEvent) override; void keyPressEvent(QKeyEvent* pEvent) override;
public:
/********************************************************************/
/********************** Constructor/Destructor **********************/
/********************************************************************/
/// \fn explicit MainWindow(QWidget* pParent = 0)
/// \param [in] pParent - pointer to parent widget.
explicit MainWindow(QWidget* pParent = 0);
/// \fn ~MainWindow()
/// Destructor.
~MainWindow();
/********************************************************************/
/****************************** Slots *******************************/
/********************************************************************/
private slots: private slots:
/// \fn void Paint_Finished(const int pPaintTime)
/// Show paint/render time and distance between camera and center of the scene. /// Show paint/render time and distance between camera and center of the scene.
/// \param [in] pPaintTime_ms - paint time in milliseconds. /// \param [in] pPaintTime_ms - paint time in milliseconds.
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance); void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
/// \fn void SceneObject_Camera(const QString& pName)
/// Add camera name to list. /// Add camera name to list.
/// \param [in] pName - name of the camera. /// \param [in] pName - name of the camera.
void SceneObject_Camera(const QString& pName); void SceneObject_Camera(const QString& pName);
/// \fn void SceneObject_LightSource(const QString& pName)
/// Add lighting source name to list. /// Add lighting source name to list.
/// \param [in] pName - name of the light source, /// \param [in] pName - name of the light source,
void SceneObject_LightSource(const QString& pName); void SceneObject_LightSource(const QString& pName);
@ -151,4 +128,21 @@ private slots:
void on_cbxBBox_clicked(bool checked); void on_cbxBBox_clicked(bool checked);
void on_cbxTextures_clicked(bool checked); void on_cbxTextures_clicked(bool checked);
void on_cbxDrawAxes_clicked(bool checked); void on_cbxDrawAxes_clicked(bool checked);
private:
Ui::MainWindow *ui;
CGLView *mGLView;///< Pointer to OpenGL render.
CLoggerView *mLoggerView;///< Pointer to logging object.
Assimp::Importer mImporter;///< Assimp importer.
const aiScene* mScene;///< Pointer to loaded scene (\ref aiScene).
/// \struct SMouse_Transformation
/// Holds data about transformation of the scene/camera when mouse us used.
struct SMouse_Transformation {
bool Position_Pressed_Valid;///< Mouse button pressed on GLView.
QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button.
QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button.
aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
} mMouse_Transformation;
}; };

File diff suppressed because it is too large Load Diff