Merge branch 'master' into coverity_scan
commit
91f24db739
120
CMakeLists.txt
120
CMakeLists.txt
|
@ -39,7 +39,50 @@ SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
|
|||
cmake_minimum_required( VERSION 2.8 )
|
||||
PROJECT( Assimp )
|
||||
|
||||
OPTION(BUILD_SHARED_LIBS "Build package with shared libraries." ON)
|
||||
# All supported options ###############################################
|
||||
OPTION( BUILD_SHARED_LIBS
|
||||
"Build package with shared libraries."
|
||||
ON
|
||||
)
|
||||
OPTION( ASSIMP_DOUBLE_PRECISION
|
||||
"Set to ON to enable double precision processing"
|
||||
OFF
|
||||
)
|
||||
OPTION( ASSIMP_OPT_BUILD_PACKAGES
|
||||
"Set to ON to generate CPack configuration files and packaging targets"
|
||||
OFF
|
||||
)
|
||||
OPTION( ASSIMP_ANDROID_JNIIOSYSTEM
|
||||
"Android JNI IOSystem support is active"
|
||||
OFF
|
||||
)
|
||||
OPTION( ASSIMP_NO_EXPORT
|
||||
"Disable Assimp's export functionality."
|
||||
OFF
|
||||
)
|
||||
OPTION( ASSIMP_BUILD_ZLIB
|
||||
"Build your own zlib"
|
||||
OFF
|
||||
)
|
||||
option( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||
"If the supplementary tools for Assimp are built in addition to the library."
|
||||
ON
|
||||
)
|
||||
option ( ASSIMP_BUILD_SAMPLES
|
||||
"If the official samples are built as well (needs Glut)."
|
||||
OFF
|
||||
)
|
||||
OPTION ( ASSIMP_BUILD_TESTS
|
||||
"If the test suite for Assimp is built in addition to the library."
|
||||
ON
|
||||
)
|
||||
IF(MSVC)
|
||||
OPTION( ASSIMP_INSTALL_PDB
|
||||
"Install MSVC debug files."
|
||||
ON
|
||||
)
|
||||
ENDIF(MSVC)
|
||||
|
||||
IF(NOT BUILD_SHARED_LIBS)
|
||||
SET(LINK_SEARCH_START_STATIC TRUE)
|
||||
ENDIF(NOT BUILD_SHARED_LIBS)
|
||||
|
@ -80,18 +123,12 @@ IF(NOT GIT_COMMIT_HASH)
|
|||
SET(GIT_COMMIT_HASH 0)
|
||||
ENDIF(NOT GIT_COMMIT_HASH)
|
||||
|
||||
OPTION(ASSIMP_DOUBLE_PRECISION
|
||||
"Set to ON to enable double precision processing"
|
||||
OFF
|
||||
)
|
||||
|
||||
IF(ASSIMP_DOUBLE_PRECISION)
|
||||
ADD_DEFINITIONS(-DAI_DOUBLE_PRECISION)
|
||||
ENDIF(ASSIMP_DOUBLE_PRECISION)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/revision.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
||||
)
|
||||
|
||||
|
@ -106,23 +143,28 @@ include_directories(
|
|||
${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
)
|
||||
|
||||
OPTION(ASSIMP_OPT_BUILD_PACKAGES "Set to ON to generate CPack configuration files and packaging targets" OFF)
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" )
|
||||
SET(LIBASSIMP_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}" )
|
||||
SET(LIBASSIMP-DEV_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}-dev" )
|
||||
SET(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
|
||||
SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
||||
|
||||
OPTION(ASSIMP_ANDROID_JNIIOSYSTEM "Android JNI IOSystem support is active" OFF)
|
||||
|
||||
# Workaround to be able to deal with compiler bug "Too many sections" with mingw.
|
||||
IF( CMAKE_COMPILER_IS_MINGW )
|
||||
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_IFC_IMPORTER )
|
||||
ENDIF()
|
||||
|
||||
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
|
||||
IF( UNIX )
|
||||
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW)
|
||||
IF (BUILD_SHARED_LIBS AND CMAKE_SIZEOF_VOID_P EQUAL 8) # -fPIC is only required for shared libs on 64 bit
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||
ENDIF()
|
||||
# hide all not-exported symbols
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -std=c++0x" )
|
||||
|
@ -171,8 +213,6 @@ IF (NOT TARGET uninstall)
|
|||
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
ENDIF()
|
||||
|
||||
|
||||
|
||||
# cmake configuration files
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
||||
|
@ -180,22 +220,12 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${C
|
|||
|
||||
FIND_PACKAGE( DirectX )
|
||||
|
||||
OPTION ( ASSIMP_NO_EXPORT
|
||||
"Disable Assimp's export functionality."
|
||||
OFF
|
||||
)
|
||||
|
||||
IF( CMAKE_COMPILER_IS_GNUCXX )
|
||||
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
||||
ENDIF( CMAKE_COMPILER_IS_GNUCXX )
|
||||
|
||||
# Search for external dependencies, and build them from source if not found
|
||||
# Search for zlib
|
||||
OPTION(ASSIMP_BUILD_ZLIB
|
||||
"Build your own zlib"
|
||||
OFF
|
||||
)
|
||||
|
||||
IF ( NOT ASSIMP_BUILD_ZLIB )
|
||||
find_package(ZLIB)
|
||||
ENDIF( NOT ASSIMP_BUILD_ZLIB )
|
||||
|
@ -293,10 +323,6 @@ ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
|||
|
||||
|
||||
ADD_SUBDIRECTORY( code/ )
|
||||
option ( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||
"If the supplementary tools for Assimp are built in addition to the library."
|
||||
ON
|
||||
)
|
||||
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||
IF ( WIN32 )
|
||||
option ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} )
|
||||
|
@ -306,12 +332,34 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
|||
ENDIF ( WIN32 )
|
||||
|
||||
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
||||
|
||||
# Check dependencies for assimp_qt_viewer.
|
||||
# Why here? Maybe user do not want Qt viewer and have no Qt.
|
||||
# Why assimp_qt_viewer/CMakeLists.txt still contain similar check?
|
||||
# Because viewer can be build independently of Assimp.
|
||||
FIND_PACKAGE(Qt4 QUIET)
|
||||
FIND_PACKAGE(DevIL QUIET)
|
||||
FIND_PACKAGE(OpenGL QUIET)
|
||||
IF ( Qt4_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
||||
ELSE()
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
|
||||
IF (NOT Qt4_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt4")
|
||||
ENDIF (NOT Qt4_FOUND)
|
||||
|
||||
IF (NOT IL_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL")
|
||||
ENDIF (NOT IL_FOUND)
|
||||
|
||||
IF (NOT OPENGL_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
|
||||
ENDIF (NOT OPENGL_FOUND)
|
||||
|
||||
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
|
||||
ENDIF ( Qt4_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||
|
||||
option ( ASSIMP_BUILD_SAMPLES
|
||||
"If the official samples are built as well (needs Glut)."
|
||||
OFF
|
||||
)
|
||||
|
||||
IF ( ASSIMP_BUILD_SAMPLES)
|
||||
IF ( WIN32 )
|
||||
|
@ -320,22 +368,10 @@ IF ( ASSIMP_BUILD_SAMPLES)
|
|||
ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
|
||||
ENDIF ( ASSIMP_BUILD_SAMPLES )
|
||||
|
||||
OPTION ( ASSIMP_BUILD_TESTS
|
||||
"If the test suite for Assimp is built in addition to the library."
|
||||
ON
|
||||
)
|
||||
|
||||
IF ( ASSIMP_BUILD_TESTS )
|
||||
ADD_SUBDIRECTORY( test/ )
|
||||
ENDIF ( ASSIMP_BUILD_TESTS )
|
||||
|
||||
IF(MSVC)
|
||||
OPTION ( ASSIMP_INSTALL_PDB
|
||||
"Install MSVC debug files."
|
||||
ON
|
||||
)
|
||||
ENDIF(MSVC)
|
||||
|
||||
# Generate a pkg-config .pc for the Assimp library.
|
||||
CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/assimp.pc.in" "${PROJECT_BINARY_DIR}/assimp.pc" @ONLY )
|
||||
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
||||
|
|
4
CREDITS
4
CREDITS
|
@ -7,13 +7,13 @@ The following is a non-exhaustive list of all constributors over the years.
|
|||
If you think your name should be listed here, drop us a line and we'll add you.
|
||||
|
||||
- Alexander Gessler,
|
||||
3DS-, BLEND-, ASE-, DXF-, HMP-, MDL-, MD2-, MD3-, MD5-, MDC-, NFF-, PLY-, STL-, RAW-, OFF-, MS3D-, Q3D- and LWO-Loader, Assimp-Viewer, assimp-cmd, -noboost, Website (Admin and Design).
|
||||
3DS-, BLEND-, ASE-, DXF-, HMP-, MDL-, MD2-, MD3-, MD5-, MDC-, NFF-, PLY-, STL-, RAW-, OFF-, MS3D-, Q3D- and LWO-Loader, Assimp-Viewer, assimp-cmd, -noboost, Website (Design).
|
||||
|
||||
- Thomas Schulze,
|
||||
X-, Collada-, BVH-Loader, Postprocessing framework. Data structure & Interface design, documentation.
|
||||
|
||||
- Kim Kulling,
|
||||
Obj-Loader, Logging system, Scons-build environment, CMake build environment, Linux build.
|
||||
Obj-, Q3BSD-, OpenGEX-Loader, Logging system, CMake-build-environment, Linux-build, Website ( Admin ), Coverity ( Admin ), Glitter ( Admin ).
|
||||
|
||||
- R.Schmidt,
|
||||
Linux build, eclipse support.
|
||||
|
|
|
@ -14,7 +14,6 @@ Coverity<a href="https://scan.coverity.com/projects/5607">
|
|||
<img alt="Coverity Scan Build Status"
|
||||
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
||||
</a>
|
||||
Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
<br>
|
||||
__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
|
||||
|
||||
|
@ -117,8 +116,7 @@ For development discussions, there is also a (very low-volume) mailing list, _as
|
|||
|
||||
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
||||
|
||||
And we also have an IRC-channel at freenode: #assetimporterlib . You can easily join us via: [KiwiIRC/freenote](https://kiwiirc.com/client/irc.freenode.net), choose your nickname and type
|
||||
> /join #assetimporterlib
|
||||
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
||||
|
||||
### Contributing ###
|
||||
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
||||
|
|
|
@ -25,8 +25,8 @@ conditions are met:
|
|||
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
|
||||
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,
|
||||
|
@ -1463,30 +1463,29 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
|||
continue;
|
||||
}
|
||||
// another mesh UV channel ...
|
||||
if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19))
|
||||
{
|
||||
|
||||
unsigned int iIndex = 0;
|
||||
if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19)) {
|
||||
unsigned int iIndex( 0 );
|
||||
ParseLV4MeshLong(iIndex);
|
||||
|
||||
if (iIndex < 2)
|
||||
{
|
||||
LogWarning("Mapping channel has an invalid index. Skipping UV channel");
|
||||
if ( 0 == iIndex ) {
|
||||
LogWarning( "Mapping channel has an invalid index. Skipping UV channel" );
|
||||
// skip it ...
|
||||
SkipSection();
|
||||
} else {
|
||||
if ( iIndex < 2 ) {
|
||||
LogWarning( "Mapping channel has an invalid index. Skipping UV channel" );
|
||||
// skip it ...
|
||||
SkipSection();
|
||||
}
|
||||
if ( iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS ) {
|
||||
LogWarning( "Too many UV channels specified. Skipping channel .." );
|
||||
// skip it ...
|
||||
SkipSection();
|
||||
} else {
|
||||
// parse the mapping channel
|
||||
ParseLV3MappingChannel( iIndex - 1, mesh );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS)
|
||||
{
|
||||
LogWarning("Too many UV channels specified. Skipping channel ..");
|
||||
// skip it ...
|
||||
SkipSection();
|
||||
}
|
||||
else
|
||||
{
|
||||
// parse the mapping channel
|
||||
ParseLV3MappingChannel(iIndex-1,mesh);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// mesh animation keyframe. Not supported
|
||||
if (TokenMatch(filePtr,"MESH_ANIMATION" ,14))
|
||||
|
|
|
@ -61,15 +61,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
// #define ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
|
||||
namespace Assimp {
|
||||
template <bool,bool> class StreamReader;
|
||||
typedef StreamReader<true,true> StreamReaderAny;
|
||||
|
||||
namespace Blender {
|
||||
class FileDatabase;
|
||||
struct FileBlockHead;
|
||||
template <bool,bool> class StreamReader;
|
||||
typedef StreamReader<true,true> StreamReaderAny;
|
||||
|
||||
template <template <typename> class TOUT>
|
||||
class ObjectCache;
|
||||
namespace Blender {
|
||||
|
||||
class FileDatabase;
|
||||
struct FileBlockHead;
|
||||
|
||||
template <template <typename> class TOUT>
|
||||
class ObjectCache;
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Exception class used by the blender loader to selectively catch exceptions
|
||||
|
@ -78,20 +80,21 @@ namespace Assimp {
|
|||
* the loader itself, it will still be caught by Assimp due to its
|
||||
* ancestry. */
|
||||
// -------------------------------------------------------------------------------
|
||||
struct Error : DeadlyImportError
|
||||
{
|
||||
struct Error : DeadlyImportError {
|
||||
Error (const std::string& s)
|
||||
: DeadlyImportError(s)
|
||||
{}
|
||||
: DeadlyImportError(s) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** The only purpose of this structure is to feed a virtual dtor into its
|
||||
* descendents. It serves as base class for all data structure fields. */
|
||||
// -------------------------------------------------------------------------------
|
||||
struct ElemBase
|
||||
{
|
||||
virtual ~ElemBase() {}
|
||||
struct ElemBase {
|
||||
virtual ~ElemBase() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/** Type name of the element. The type
|
||||
* string points is the `c_str` of the `name` attribute of the
|
||||
|
@ -103,25 +106,28 @@ struct ElemBase
|
|||
const char* dna_type;
|
||||
};
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Represents a generic pointer to a memory location, which can be either 32
|
||||
* or 64 bits. These pointers are loaded from the BLEND file and finally
|
||||
* fixed to point to the real, converted representation of the objects
|
||||
* they used to point to.*/
|
||||
// -------------------------------------------------------------------------------
|
||||
struct Pointer
|
||||
{
|
||||
Pointer() : val() {}
|
||||
struct Pointer {
|
||||
Pointer()
|
||||
: val() {
|
||||
// empty
|
||||
}
|
||||
uint64_t val;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Represents a generic offset within a BLEND file */
|
||||
// -------------------------------------------------------------------------------
|
||||
struct FileOffset
|
||||
{
|
||||
FileOffset() : val() {}
|
||||
struct FileOffset {
|
||||
FileOffset()
|
||||
: val() {
|
||||
// empty
|
||||
}
|
||||
uint64_t val;
|
||||
};
|
||||
|
||||
|
@ -132,8 +138,7 @@ struct FileOffset
|
|||
* functions of shared_ptr */
|
||||
// -------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
class vector : public std::vector<T>
|
||||
{
|
||||
class vector : public std::vector<T> {
|
||||
public:
|
||||
using std::vector<T>::resize;
|
||||
using std::vector<T>::empty;
|
||||
|
@ -150,8 +155,7 @@ public:
|
|||
// -------------------------------------------------------------------------------
|
||||
/** Mixed flags for use in #Field */
|
||||
// -------------------------------------------------------------------------------
|
||||
enum FieldFlags
|
||||
{
|
||||
enum FieldFlags {
|
||||
FieldFlag_Pointer = 0x1,
|
||||
FieldFlag_Array = 0x2
|
||||
};
|
||||
|
@ -159,8 +163,7 @@ enum FieldFlags
|
|||
// -------------------------------------------------------------------------------
|
||||
/** Represents a single member of a data structure in a BLEND file */
|
||||
// -------------------------------------------------------------------------------
|
||||
struct Field
|
||||
{
|
||||
struct Field {
|
||||
std::string name;
|
||||
std::string type;
|
||||
|
||||
|
@ -180,8 +183,7 @@ struct Field
|
|||
* mission critical so we need them, while others can silently be default
|
||||
* initialized and no animations are harmed. */
|
||||
// -------------------------------------------------------------------------------
|
||||
enum ErrorPolicy
|
||||
{
|
||||
enum ErrorPolicy {
|
||||
/** Substitute default value and ignore */
|
||||
ErrorPolicy_Igno,
|
||||
/** Substitute default value and write to log */
|
||||
|
@ -202,15 +204,14 @@ enum ErrorPolicy
|
|||
* binary `blob` read from the file to such a structure instance with
|
||||
* meaningful contents. */
|
||||
// -------------------------------------------------------------------------------
|
||||
class Structure
|
||||
{
|
||||
class Structure {
|
||||
template <template <typename> class> friend class ObjectCache;
|
||||
|
||||
public:
|
||||
|
||||
Structure()
|
||||
: cache_idx(static_cast<size_t>(-1) )
|
||||
{}
|
||||
: cache_idx(static_cast<size_t>(-1) ){
|
||||
// empty
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
@ -709,8 +710,6 @@ class FileDatabase
|
|||
template <template <typename> class TOUT> friend class ObjectCache;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
FileDatabase()
|
||||
: _cacheArrays(*this)
|
||||
, _cache(*this)
|
||||
|
@ -718,7 +717,6 @@ public:
|
|||
{}
|
||||
|
||||
public:
|
||||
|
||||
// publicly accessible fields
|
||||
bool i64bit;
|
||||
bool little;
|
||||
|
|
|
@ -532,7 +532,7 @@ template <typename T> struct signless;
|
|||
template <> struct signless<char> {typedef unsigned char type;};
|
||||
template <> struct signless<short> {typedef unsigned short type;};
|
||||
template <> struct signless<int> {typedef unsigned int type;};
|
||||
|
||||
template <> struct signless<unsigned char> { typedef unsigned char type; };
|
||||
template <typename T>
|
||||
struct static_cast_silent {
|
||||
template <typename V>
|
||||
|
@ -614,6 +614,22 @@ template <> inline void Structure :: Convert<char> (char& dest,const FileDatab
|
|||
ConvertDispatcher(dest,*this,db);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> inline void Structure::Convert<unsigned char>(unsigned char& dest, const FileDatabase& db) const
|
||||
{
|
||||
// automatic rescaling from char to float and vice versa (seems useful for RGB colors)
|
||||
if (name == "float") {
|
||||
dest = static_cast<unsigned char>(db.reader->GetF4() * 255.f);
|
||||
return;
|
||||
}
|
||||
else if (name == "double") {
|
||||
dest = static_cast<unsigned char>(db.reader->GetF8() * 255.f);
|
||||
return;
|
||||
}
|
||||
ConvertDispatcher(dest, *this, db);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const
|
||||
{
|
||||
|
|
|
@ -123,7 +123,8 @@ namespace Blender {
|
|||
|
||||
struct ObjectCompare {
|
||||
bool operator() (const Object* left, const Object* right) const {
|
||||
return strcmp(left->id.name, right->id.name) == -1;
|
||||
printf( "left: %s, right: %s\n", left->id.name, right->id.name );
|
||||
return ::strncmp(left->id.name, right->id.name, strlen( left->id.name ) ) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -144,7 +145,8 @@ namespace Blender {
|
|||
|
||||
struct ObjectCompare {
|
||||
bool operator() (const Object* left, const Object* right) const {
|
||||
return strcmp(left->id.name, right->id.name) == -1;
|
||||
printf( "left: %s, right: %s\n", left->id.name, right->id.name );
|
||||
return ::strncmp( left->id.name, right->id.name, strlen( left->id.name ) ) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1118,12 +1118,13 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
|||
const aiFace& f = out->mFaces[out->mNumFaces++];
|
||||
|
||||
aiColor4D* vo = &out->mColors[0][out->mNumVertices];
|
||||
const ai_real scaleZeroToOne = 1.f/255.f;
|
||||
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
|
||||
const MLoopCol& col = mesh->mloopcol[v.loopstart + j];
|
||||
vo->r = col.r;
|
||||
vo->g = col.g;
|
||||
vo->b = col.b;
|
||||
vo->a = col.a;
|
||||
vo->r = ai_real(col.r) * scaleZeroToOne;
|
||||
vo->g = ai_real(col.g) * scaleZeroToOne;
|
||||
vo->b = ai_real(col.b) * scaleZeroToOne;
|
||||
vo->a = ai_real(col.a) * scaleZeroToOne;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ struct MLoopUV : ElemBase {
|
|||
// -------------------------------------------------------------------------------
|
||||
// Note that red and blue are not swapped, as with MCol
|
||||
struct MLoopCol : ElemBase {
|
||||
char r, g, b, a;
|
||||
unsigned char r, g, b, a;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
|
|
@ -722,6 +722,7 @@ if (UNZIP_FOUND)
|
|||
SET (unzip_compile_SRCS "")
|
||||
else (UNZIP_FOUND)
|
||||
SET (unzip_compile_SRCS ${unzip_SRCS})
|
||||
INCLUDE_DIRECTORIES( "../contrib/unzip/" )
|
||||
endif (UNZIP_FOUND)
|
||||
|
||||
MESSAGE(STATUS "Enabled formats:${ASSIMP_IMPORTERS_ENABLED}")
|
||||
|
|
|
@ -55,6 +55,7 @@ DefaultIOStream::~DefaultIOStream()
|
|||
{
|
||||
if (mFile) {
|
||||
::fclose(mFile);
|
||||
mFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,9 +110,9 @@ size_t DefaultIOStream::FileSize() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (SIZE_MAX == cachedSize) {
|
||||
if (SIZE_MAX == mCachedSize ) {
|
||||
|
||||
// Although fseek/ftell would allow us to reuse the exising file handle here,
|
||||
// Although fseek/ftell would allow us to reuse the existing file handle here,
|
||||
// it is generally unsafe because:
|
||||
// - For binary streams, it is not technically well-defined
|
||||
// - For text files the results are meaningless
|
||||
|
@ -124,16 +125,19 @@ size_t DefaultIOStream::FileSize() const
|
|||
int err = _stat64( mFilename.c_str(), &fileStat );
|
||||
if (0 != err)
|
||||
return 0;
|
||||
cachedSize = (size_t) (fileStat.st_size);
|
||||
#else
|
||||
mCachedSize = (size_t) (fileStat.st_size);
|
||||
#elif defined __gnu_linux__ || defined __APPLE__ || defined __MACH__
|
||||
struct stat fileStat;
|
||||
int err = stat(mFilename.c_str(), &fileStat );
|
||||
if (0 != err)
|
||||
return 0;
|
||||
cachedSize = (size_t) (fileStat.st_size);
|
||||
const unsigned long long cachedSize = fileStat.st_size;
|
||||
mCachedSize = static_cast< size_t >( cachedSize );
|
||||
#else
|
||||
# error "Unknown platform"
|
||||
#endif
|
||||
}
|
||||
return cachedSize;
|
||||
return mCachedSize;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------
|
||||
|
|
|
@ -59,11 +59,11 @@ class ASSIMP_API DefaultIOStream : public IOStream
|
|||
{
|
||||
friend class DefaultIOSystem;
|
||||
#if __ANDROID__
|
||||
#if __ANDROID_API__ > 9
|
||||
#if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
# if __ANDROID_API__ > 9
|
||||
# if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
friend class AndroidJNIIOSystem;
|
||||
#endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
#endif // __ANDROID_API__ > 9
|
||||
# endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
# endif // __ANDROID_API__ > 9
|
||||
#endif // __ANDROID__
|
||||
|
||||
protected:
|
||||
|
@ -111,7 +111,7 @@ private:
|
|||
std::string mFilename;
|
||||
|
||||
// Cached file size
|
||||
mutable size_t cachedSize;
|
||||
mutable size_t mCachedSize;
|
||||
};
|
||||
|
||||
|
||||
|
@ -119,7 +119,7 @@ private:
|
|||
inline DefaultIOStream::DefaultIOStream () :
|
||||
mFile (NULL),
|
||||
mFilename (""),
|
||||
cachedSize (SIZE_MAX)
|
||||
mCachedSize(SIZE_MAX)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ inline DefaultIOStream::DefaultIOStream (FILE* pFile,
|
|||
const std::string &strFilename) :
|
||||
mFile(pFile),
|
||||
mFilename(strFilename),
|
||||
cachedSize (SIZE_MAX)
|
||||
mCachedSize(SIZE_MAX)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
|
|
@ -1916,57 +1916,92 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextu
|
|||
return;
|
||||
}
|
||||
|
||||
const Texture* const tex = ( *it ).second->getTexture();
|
||||
int texCount = (*it).second->textureCount();
|
||||
|
||||
aiString path;
|
||||
path.Set( tex->RelativeFilename() );
|
||||
// Set the blend mode for layered textures
|
||||
int blendmode= (*it).second->GetBlendMode();
|
||||
out_mat->AddProperty(&blendmode,1,_AI_MATKEY_TEXOP_BASE,target,0);
|
||||
|
||||
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );
|
||||
for(int texIndex = 0; texIndex < texCount; texIndex++){
|
||||
|
||||
aiUVTransform uvTrafo;
|
||||
// XXX handle all kinds of UV transformations
|
||||
uvTrafo.mScaling = tex->UVScaling();
|
||||
uvTrafo.mTranslation = tex->UVTranslation();
|
||||
out_mat->AddProperty( &uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, 0 );
|
||||
const Texture* const tex = ( *it ).second->getTexture(texIndex);
|
||||
|
||||
const PropertyTable& props = tex->Props();
|
||||
aiString path;
|
||||
path.Set( tex->RelativeFilename() );
|
||||
|
||||
int uvIndex = 0;
|
||||
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, texIndex );
|
||||
|
||||
bool ok;
|
||||
const std::string& uvSet = PropertyGet<std::string>( props, "UVSet", ok );
|
||||
if ( ok ) {
|
||||
// "default" is the name which usually appears in the FbxFileTexture template
|
||||
if ( uvSet != "default" && uvSet.length() ) {
|
||||
// this is a bit awkward - we need to find a mesh that uses this
|
||||
// material and scan its UV channels for the given UV name because
|
||||
// assimp references UV channels by index, not by name.
|
||||
aiUVTransform uvTrafo;
|
||||
// XXX handle all kinds of UV transformations
|
||||
uvTrafo.mScaling = tex->UVScaling();
|
||||
uvTrafo.mTranslation = tex->UVTranslation();
|
||||
out_mat->AddProperty( &uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, texIndex );
|
||||
|
||||
// XXX: the case that UV channels may appear in different orders
|
||||
// in meshes is unhandled. A possible solution would be to sort
|
||||
// the UV channels alphabetically, but this would have the side
|
||||
// effect that the primary (first) UV channel would sometimes
|
||||
// be moved, causing trouble when users read only the first
|
||||
// UV channel and ignore UV channel assignments altogether.
|
||||
const PropertyTable& props = tex->Props();
|
||||
|
||||
const unsigned int matIndex = static_cast<unsigned int>( std::distance( materials.begin(),
|
||||
std::find( materials.begin(), materials.end(), out_mat )
|
||||
) );
|
||||
int uvIndex = 0;
|
||||
|
||||
uvIndex = -1;
|
||||
if ( !mesh )
|
||||
{
|
||||
for( const MeshMap::value_type& v : meshes_converted ) {
|
||||
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*> ( v.first );
|
||||
if ( !mesh ) {
|
||||
continue;
|
||||
bool ok;
|
||||
const std::string& uvSet = PropertyGet<std::string>( props, "UVSet", ok );
|
||||
if ( ok ) {
|
||||
// "default" is the name which usually appears in the FbxFileTexture template
|
||||
if ( uvSet != "default" && uvSet.length() ) {
|
||||
// this is a bit awkward - we need to find a mesh that uses this
|
||||
// material and scan its UV channels for the given UV name because
|
||||
// assimp references UV channels by index, not by name.
|
||||
|
||||
// XXX: the case that UV channels may appear in different orders
|
||||
// in meshes is unhandled. A possible solution would be to sort
|
||||
// the UV channels alphabetically, but this would have the side
|
||||
// effect that the primary (first) UV channel would sometimes
|
||||
// be moved, causing trouble when users read only the first
|
||||
// UV channel and ignore UV channel assignments altogether.
|
||||
|
||||
const unsigned int matIndex = static_cast<unsigned int>( std::distance( materials.begin(),
|
||||
std::find( materials.begin(), materials.end(), out_mat )
|
||||
) );
|
||||
|
||||
uvIndex = -1;
|
||||
if ( !mesh )
|
||||
{
|
||||
for( const MeshMap::value_type& v : meshes_converted ) {
|
||||
const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*> ( v.first );
|
||||
if ( !mesh ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const MatIndexArray& mats = mesh->GetMaterialIndices();
|
||||
if ( std::find( mats.begin(), mats.end(), matIndex ) == mats.end() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
for ( unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i ) {
|
||||
if ( mesh->GetTextureCoords( i ).empty() ) {
|
||||
break;
|
||||
}
|
||||
const std::string& name = mesh->GetTextureCoordChannelName( i );
|
||||
if ( name == uvSet ) {
|
||||
index = static_cast<int>( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( index == -1 ) {
|
||||
FBXImporter::LogWarn( "did not find UV channel named " + uvSet + " in a mesh using this material" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( uvIndex == -1 ) {
|
||||
uvIndex = index;
|
||||
}
|
||||
else {
|
||||
FBXImporter::LogWarn( "the UV channel named " + uvSet +
|
||||
" appears at different positions in meshes, results will be wrong" );
|
||||
}
|
||||
}
|
||||
|
||||
const MatIndexArray& mats = mesh->GetMaterialIndices();
|
||||
if ( std::find( mats.begin(), mats.end(), matIndex ) == mats.end() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = -1;
|
||||
for ( unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i ) {
|
||||
if ( mesh->GetTextureCoords( i ).empty() ) {
|
||||
|
@ -1980,48 +2015,22 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextu
|
|||
}
|
||||
if ( index == -1 ) {
|
||||
FBXImporter::LogWarn( "did not find UV channel named " + uvSet + " in a mesh using this material" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( uvIndex == -1 ) {
|
||||
uvIndex = index;
|
||||
}
|
||||
else {
|
||||
FBXImporter::LogWarn( "the UV channel named " + uvSet +
|
||||
" appears at different positions in meshes, results will be wrong" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = -1;
|
||||
for ( unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i ) {
|
||||
if ( mesh->GetTextureCoords( i ).empty() ) {
|
||||
break;
|
||||
}
|
||||
const std::string& name = mesh->GetTextureCoordChannelName( i );
|
||||
if ( name == uvSet ) {
|
||||
index = static_cast<int>( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( index == -1 ) {
|
||||
FBXImporter::LogWarn( "did not find UV channel named " + uvSet + " in a mesh using this material" );
|
||||
}
|
||||
|
||||
if ( uvIndex == -1 ) {
|
||||
uvIndex = index;
|
||||
FBXImporter::LogWarn( "failed to resolve UV channel " + uvSet + ", using first UV channel" );
|
||||
uvIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( uvIndex == -1 ) {
|
||||
FBXImporter::LogWarn( "failed to resolve UV channel " + uvSet + ", using first UV channel" );
|
||||
uvIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out_mat->AddProperty( &uvIndex, 1, _AI_MATKEY_UVWSRC_BASE, target, 0 );
|
||||
out_mat->AddProperty( &uvIndex, 1, _AI_MATKEY_UVWSRC_BASE, target, texIndex );
|
||||
}
|
||||
}
|
||||
|
||||
void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh )
|
||||
|
@ -2030,6 +2039,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& tex
|
|||
TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh );
|
||||
TrySetTextureProperties( out_mat, textures, "EmissiveColor", aiTextureType_EMISSIVE, mesh );
|
||||
TrySetTextureProperties( out_mat, textures, "SpecularColor", aiTextureType_SPECULAR, mesh );
|
||||
TrySetTextureProperties( out_mat, textures, "SpecularFactor", aiTextureType_SPECULAR, mesh);
|
||||
TrySetTextureProperties( out_mat, textures, "TransparentColor", aiTextureType_OPACITY, mesh );
|
||||
TrySetTextureProperties( out_mat, textures, "ReflectionColor", aiTextureType_REFLECTION, mesh );
|
||||
TrySetTextureProperties( out_mat, textures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh );
|
||||
|
@ -2044,6 +2054,7 @@ void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureM
|
|||
TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh );
|
||||
TrySetTextureProperties( out_mat, layeredTextures, "EmissiveColor", aiTextureType_EMISSIVE, mesh );
|
||||
TrySetTextureProperties( out_mat, layeredTextures, "SpecularColor", aiTextureType_SPECULAR, mesh );
|
||||
TrySetTextureProperties( out_mat, layeredTextures, "SpecularFactor", aiTextureType_SPECULAR, mesh);
|
||||
TrySetTextureProperties( out_mat, layeredTextures, "TransparentColor", aiTextureType_OPACITY, mesh );
|
||||
TrySetTextureProperties( out_mat, layeredTextures, "ReflectionColor", aiTextureType_REFLECTION, mesh );
|
||||
TrySetTextureProperties( out_mat, layeredTextures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh );
|
||||
|
|
|
@ -594,23 +594,24 @@ public:
|
|||
BlendMode_BlendModeCount
|
||||
};
|
||||
|
||||
const Texture* getTexture() const
|
||||
const Texture* getTexture(int index=0) const
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
return textures[index];
|
||||
|
||||
BlendMode GetBlendMode()
|
||||
}
|
||||
const int textureCount() const {
|
||||
return textures.size();
|
||||
}
|
||||
const BlendMode GetBlendMode() const
|
||||
{
|
||||
return blendMode;
|
||||
}
|
||||
|
||||
float Alpha()
|
||||
{
|
||||
return alpha;
|
||||
}
|
||||
|
||||
private:
|
||||
const Texture* texture;
|
||||
std::vector<const Texture*> textures;
|
||||
BlendMode blendMode;
|
||||
float alpha;
|
||||
};
|
||||
|
|
|
@ -227,7 +227,6 @@ Texture::~Texture()
|
|||
|
||||
LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name)
|
||||
: Object(id,element,name)
|
||||
,texture(0)
|
||||
,blendMode(BlendMode_Modulate)
|
||||
,alpha(1)
|
||||
{
|
||||
|
@ -267,7 +266,7 @@ void LayeredTexture::fillTexture(const Document& doc)
|
|||
|
||||
const Texture* const tex = dynamic_cast<const Texture*>(ob);
|
||||
|
||||
texture = tex;
|
||||
textures.push_back(tex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul
|
|||
const size_t next = (i+1)%size;
|
||||
|
||||
result.vertcnt.push_back(4);
|
||||
const IfcVector3& base_0 = out[base+i*4+3],base_1 = out[base+next*4+3];
|
||||
const IfcVector3 base_0 = out[base+i*4+3],base_1 = out[base+next*4+3];
|
||||
|
||||
out.push_back(base_0);
|
||||
out.push_back(base_1);
|
||||
|
|
|
@ -731,6 +731,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
|||
}
|
||||
VALIDATE_FILE_SIZE(szCurrent);
|
||||
*szCurrentOut = szCurrent;
|
||||
if ( nullptr != pcNew ) {
|
||||
delete pcNew;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -171,7 +171,7 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
|
|||
// build output vertex weights
|
||||
for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
|
||||
{
|
||||
delete pcMesh->mBones[i]->mWeights;
|
||||
delete [] pcMesh->mBones[i]->mWeights;
|
||||
if (!newWeights[i].empty()) {
|
||||
pcMesh->mBones[i]->mWeights = new aiVertexWeight[newWeights[i].size()];
|
||||
aiVertexWeight *weightToCopy = &( newWeights[i][0] );
|
||||
|
|
|
@ -39,7 +39,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
|
||||
|
||||
#include "DefaultIOSystem.h"
|
||||
|
@ -52,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
"Wavefront Object Importer",
|
||||
"",
|
||||
|
|
|
@ -696,6 +696,8 @@ void ObjFileParser::getGroupName()
|
|||
{
|
||||
std::string strGroupName;
|
||||
|
||||
// here we skip 'g ' from line
|
||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, strGroupName);
|
||||
if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) {
|
||||
return;
|
||||
|
@ -832,7 +834,11 @@ bool ObjFileParser::needsNewMesh( const std::string &materialName )
|
|||
bool newMat = false;
|
||||
int matIdx = getMaterialIndex( materialName );
|
||||
int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
|
||||
if ( curMatIdx != int(ObjFile::Mesh::NoMaterial) && curMatIdx != matIdx )
|
||||
if ( curMatIdx != int(ObjFile::Mesh::NoMaterial)
|
||||
&& curMatIdx != matIdx
|
||||
// no need create a new mesh if no faces in current
|
||||
// lets say 'usemtl' goes straight after 'g'
|
||||
&& m_pModel->m_pCurrentMesh->m_Faces.size() > 0 )
|
||||
{
|
||||
// New material -> only one material per mesh, so we need to create a new
|
||||
// material
|
||||
|
|
|
@ -56,11 +56,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
//using namespace Assimp;
|
||||
namespace Assimp {
|
||||
|
||||
// make sure typeof returns consistent output across different platforms
|
||||
// make sure type_of returns consistent output across different platforms
|
||||
// also consider using: typeid(VAR).name()
|
||||
template <typename T> const char* typeof(T&) { return "unknown"; }
|
||||
template<> const char* typeof(float&) { return "float"; }
|
||||
template<> const char* typeof(double&) { return "double"; }
|
||||
template <typename T> const char* type_of(T&) { return "unknown"; }
|
||||
template<> const char* type_of(float&) { return "float"; }
|
||||
template<> const char* type_of(double&) { return "double"; }
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
|
||||
|
@ -146,7 +146,7 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina
|
|||
// definitely not good to always write float even if we might have double precision
|
||||
|
||||
ai_real tmp = 0.0;
|
||||
const char * typeName = typeof(tmp);
|
||||
const char * typeName = type_of(tmp);
|
||||
|
||||
mOutput << "element vertex " << vertices << endl;
|
||||
mOutput << "property " << typeName << " x" << endl;
|
||||
|
|
|
@ -102,12 +102,16 @@ static const aiImporterDesc desc = {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
XGLImporter::XGLImporter()
|
||||
{}
|
||||
: m_reader( nullptr )
|
||||
, m_scene( nullptr ) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
XGLImporter::~XGLImporter()
|
||||
{}
|
||||
XGLImporter::~XGLImporter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
|
@ -149,7 +153,7 @@ void XGLImporter::InternReadFile( const std::string& pFile,
|
|||
free_it free_it_really(dest);
|
||||
#endif
|
||||
|
||||
scene = pScene;
|
||||
m_scene = pScene;
|
||||
std::shared_ptr<IOStream> stream( pIOHandler->Open( pFile, "rb"));
|
||||
|
||||
// check whether we can read from the file
|
||||
|
@ -211,14 +215,13 @@ void XGLImporter::InternReadFile( const std::string& pFile,
|
|||
|
||||
// construct the irrXML parser
|
||||
CIrrXML_IOStreamReader st(stream.get());
|
||||
std::unique_ptr<IrrXMLReader> read( createIrrXMLReader((IFileReadCallBack*) &st) );
|
||||
reader = read.get();
|
||||
m_reader.reset( createIrrXMLReader( ( IFileReadCallBack* ) &st ) );
|
||||
|
||||
// parse the XML file
|
||||
TempScope scope;
|
||||
|
||||
while (ReadElement()) {
|
||||
if (!ASSIMP_stricmp(reader->getNodeName(),"world")) {
|
||||
if (!ASSIMP_stricmp(m_reader->getNodeName(),"world")) {
|
||||
ReadWorld(scope);
|
||||
}
|
||||
}
|
||||
|
@ -231,21 +234,21 @@ void XGLImporter::InternReadFile( const std::string& pFile,
|
|||
}
|
||||
|
||||
// copy meshes
|
||||
scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
||||
scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
|
||||
std::copy(meshes.begin(),meshes.end(),scene->mMeshes);
|
||||
m_scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
||||
m_scene->mMeshes = new aiMesh*[m_scene->mNumMeshes]();
|
||||
std::copy(meshes.begin(),meshes.end(),m_scene->mMeshes);
|
||||
|
||||
// copy materials
|
||||
scene->mNumMaterials = static_cast<unsigned int>(materials.size());
|
||||
scene->mMaterials = new aiMaterial*[scene->mNumMaterials]();
|
||||
std::copy(materials.begin(),materials.end(),scene->mMaterials);
|
||||
m_scene->mNumMaterials = static_cast<unsigned int>(materials.size());
|
||||
m_scene->mMaterials = new aiMaterial*[m_scene->mNumMaterials]();
|
||||
std::copy(materials.begin(),materials.end(),m_scene->mMaterials);
|
||||
|
||||
if (scope.light) {
|
||||
scene->mNumLights = 1;
|
||||
scene->mLights = new aiLight*[1];
|
||||
scene->mLights[0] = scope.light;
|
||||
m_scene->mNumLights = 1;
|
||||
m_scene->mLights = new aiLight*[1];
|
||||
m_scene->mLights[0] = scope.light;
|
||||
|
||||
scope.light->mName = scene->mRootNode->mName;
|
||||
scope.light->mName = m_scene->mRootNode->mName;
|
||||
}
|
||||
|
||||
scope.dismiss();
|
||||
|
@ -254,8 +257,8 @@ void XGLImporter::InternReadFile( const std::string& pFile,
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
bool XGLImporter::ReadElement()
|
||||
{
|
||||
while(reader->read()) {
|
||||
if (reader->getNodeType() == EXN_ELEMENT) {
|
||||
while(m_reader->read()) {
|
||||
if (m_reader->getNodeType() == EXN_ELEMENT) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -265,11 +268,11 @@ bool XGLImporter::ReadElement()
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
bool XGLImporter::ReadElementUpToClosing(const char* closetag)
|
||||
{
|
||||
while(reader->read()) {
|
||||
if (reader->getNodeType() == EXN_ELEMENT) {
|
||||
while(m_reader->read()) {
|
||||
if (m_reader->getNodeType() == EXN_ELEMENT) {
|
||||
return true;
|
||||
}
|
||||
else if (reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(reader->getNodeName(),closetag)) {
|
||||
else if (m_reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(m_reader->getNodeName(),closetag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -280,11 +283,11 @@ bool XGLImporter::ReadElementUpToClosing(const char* closetag)
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
bool XGLImporter::SkipToText()
|
||||
{
|
||||
while(reader->read()) {
|
||||
if (reader->getNodeType() == EXN_TEXT) {
|
||||
while(m_reader->read()) {
|
||||
if (m_reader->getNodeType() == EXN_TEXT) {
|
||||
return true;
|
||||
}
|
||||
else if (reader->getNodeType() == EXN_ELEMENT || reader->getNodeType() == EXN_ELEMENT_END) {
|
||||
else if (m_reader->getNodeType() == EXN_ELEMENT || m_reader->getNodeType() == EXN_ELEMENT_END) {
|
||||
ThrowException("expected text contents but found another element (or element end)");
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +297,7 @@ bool XGLImporter::SkipToText()
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
std::string XGLImporter::GetElementName()
|
||||
{
|
||||
const char* s = reader->getNodeName();
|
||||
const char* s = m_reader->getNodeName();
|
||||
size_t len = strlen(s);
|
||||
|
||||
std::string ret;
|
||||
|
@ -328,7 +331,7 @@ void XGLImporter::ReadWorld(TempScope& scope)
|
|||
nd->mName.Set("WORLD");
|
||||
}
|
||||
|
||||
scene->mRootNode = nd;
|
||||
m_scene->mRootNode = nd;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -586,29 +589,29 @@ bool XGLImporter::ReadMesh(TempScope& scope)
|
|||
ReadMaterial(scope);
|
||||
}
|
||||
else if (s == "p") {
|
||||
if (!reader->getAttributeValue("ID")) {
|
||||
if (!m_reader->getAttributeValue("ID")) {
|
||||
LogWarn("no ID attribute on <p>, ignoring");
|
||||
}
|
||||
else {
|
||||
int id = reader->getAttributeValueAsInt("ID");
|
||||
int id = m_reader->getAttributeValueAsInt("ID");
|
||||
t.points[id] = ReadVec3();
|
||||
}
|
||||
}
|
||||
else if (s == "n") {
|
||||
if (!reader->getAttributeValue("ID")) {
|
||||
if (!m_reader->getAttributeValue("ID")) {
|
||||
LogWarn("no ID attribute on <n>, ignoring");
|
||||
}
|
||||
else {
|
||||
int id = reader->getAttributeValueAsInt("ID");
|
||||
int id = m_reader->getAttributeValueAsInt("ID");
|
||||
t.normals[id] = ReadVec3();
|
||||
}
|
||||
}
|
||||
else if (s == "tc") {
|
||||
if (!reader->getAttributeValue("ID")) {
|
||||
if (!m_reader->getAttributeValue("ID")) {
|
||||
LogWarn("no ID attribute on <tc>, ignoring");
|
||||
}
|
||||
else {
|
||||
int id = reader->getAttributeValueAsInt("ID");
|
||||
int id = m_reader->getAttributeValueAsInt("ID");
|
||||
t.uvs[id] = ReadVec2();
|
||||
}
|
||||
}
|
||||
|
@ -828,10 +831,10 @@ void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out)
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int XGLImporter::ReadIDAttr()
|
||||
{
|
||||
for(int i = 0, e = reader->getAttributeCount(); i < e; ++i) {
|
||||
for(int i = 0, e = m_reader->getAttributeCount(); i < e; ++i) {
|
||||
|
||||
if(!ASSIMP_stricmp(reader->getAttributeName(i),"id")) {
|
||||
return reader->getAttributeValueAsInt(i);
|
||||
if(!ASSIMP_stricmp(m_reader->getAttributeName(i),"id")) {
|
||||
return m_reader->getAttributeValueAsInt(i);
|
||||
}
|
||||
}
|
||||
return ~0u;
|
||||
|
@ -844,7 +847,7 @@ float XGLImporter::ReadFloat()
|
|||
LogError("unexpected EOF reading float element contents");
|
||||
return 0.f;
|
||||
}
|
||||
const char* s = reader->getNodeData(), *se;
|
||||
const char* s = m_reader->getNodeData(), *se;
|
||||
|
||||
if(!SkipSpaces(&s)) {
|
||||
LogError("unexpected EOL, failed to parse float");
|
||||
|
@ -869,7 +872,7 @@ unsigned int XGLImporter::ReadIndexFromText()
|
|||
LogError("unexpected EOF reading index element contents");
|
||||
return ~0u;
|
||||
}
|
||||
const char* s = reader->getNodeData(), *se;
|
||||
const char* s = m_reader->getNodeData(), *se;
|
||||
if(!SkipSpaces(&s)) {
|
||||
LogError("unexpected EOL, failed to parse index element");
|
||||
return ~0u;
|
||||
|
@ -894,7 +897,7 @@ aiVector2D XGLImporter::ReadVec2()
|
|||
LogError("unexpected EOF reading vec2 contents");
|
||||
return vec;
|
||||
}
|
||||
const char* s = reader->getNodeData();
|
||||
const char* s = m_reader->getNodeData();
|
||||
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
if(!SkipSpaces(&s)) {
|
||||
|
@ -923,7 +926,7 @@ aiVector3D XGLImporter::ReadVec3()
|
|||
LogError("unexpected EOF reading vec3 contents");
|
||||
return vec;
|
||||
}
|
||||
const char* s = reader->getNodeData();
|
||||
const char* s = m_reader->getNodeData();
|
||||
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
if(!SkipSpaces(&s)) {
|
||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/light.h>
|
||||
#include <memory>
|
||||
|
||||
struct aiNode;
|
||||
|
||||
|
@ -203,12 +204,8 @@ private:
|
|||
unsigned int ResolveMaterialRef(TempScope& scope);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
private:
|
||||
|
||||
irr::io::IrrXMLReader* reader;
|
||||
aiScene* scene;
|
||||
std::shared_ptr<irr::io::IrrXMLReader> m_reader;
|
||||
aiScene* m_scene;
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
|
|
@ -40,6 +40,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
namespace glTF {
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace glTF {
|
|||
type = "arraybuffer";
|
||||
}
|
||||
|
||||
obj.AddMember("byteLength", b.byteLength, w.mAl);
|
||||
obj.AddMember("byteLength", static_cast<uint64_t>(b.byteLength), w.mAl);
|
||||
obj.AddMember("type", StringRef(type), w.mAl);
|
||||
obj.AddMember("uri", Value(dataURI, w.mAl).Move(), w.mAl);
|
||||
}
|
||||
|
@ -113,8 +113,8 @@ namespace glTF {
|
|||
inline void Write(Value& obj, BufferView& bv, AssetWriter& w)
|
||||
{
|
||||
obj.AddMember("buffer", Value(bv.buffer->id, w.mAl).Move(), w.mAl);
|
||||
obj.AddMember("byteOffset", bv.byteOffset, w.mAl);
|
||||
obj.AddMember("byteLength", bv.byteLength, w.mAl);
|
||||
obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
|
||||
obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
|
||||
obj.AddMember("target", int(bv.target), w.mAl);
|
||||
}
|
||||
|
||||
|
|
|
@ -93,11 +93,11 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
|
|||
, mScene(pScene)
|
||||
, mProperties(pProperties)
|
||||
{
|
||||
std::unique_ptr<Asset> asset(new glTF::Asset(pIOSystem));
|
||||
mAsset = asset.get();
|
||||
std::unique_ptr<Asset> asset();
|
||||
mAsset.reset( new glTF::Asset( pIOSystem ) );
|
||||
|
||||
if (isBinary) {
|
||||
asset->SetAsBinary();
|
||||
mAsset->SetAsBinary();
|
||||
}
|
||||
|
||||
ExportMetadata();
|
||||
|
|
|
@ -46,13 +46,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <assimp/types.h>
|
||||
#include <assimp/material.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
struct aiScene;
|
||||
struct aiNode;
|
||||
struct aiMaterial;
|
||||
|
@ -89,7 +88,7 @@ namespace Assimp
|
|||
|
||||
std::map<std::string, unsigned int> mTexturesByPath;
|
||||
|
||||
glTF::Asset* mAsset;
|
||||
std::shared_ptr<glTF::Asset> mAsset;
|
||||
|
||||
std::vector<unsigned char> mBodyData;
|
||||
|
||||
|
|
|
@ -303,7 +303,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
|||
attr.normal[0]->ExtractData(aim->mNormals);
|
||||
}
|
||||
|
||||
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) {
|
||||
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
|
||||
aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std:
|
|||
statement += "[";
|
||||
char buffer[ 256 ];
|
||||
::memset( buffer, '\0', 256 * sizeof( char ) );
|
||||
sprintf( buffer, "%d", numItems );
|
||||
sprintf( buffer, "%d", int(numItems) );
|
||||
statement += buffer;
|
||||
statement += "]";
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ public:
|
|||
if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
|
||||
AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size);
|
||||
|
||||
void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
|
||||
void *buffer = reinterpret_cast<char *>(chunkHead_ + 1) + chunkHead_->size;
|
||||
chunkHead_->size += size;
|
||||
return buffer;
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ public:
|
|||
return originalPtr;
|
||||
|
||||
// Simply expand it if it is the last allocation and there is sufficient space
|
||||
if (originalPtr == (char *)(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
|
||||
if (originalPtr == (char *)(chunkHead_ + 1) + chunkHead_->size - originalSize) {
|
||||
size_t increment = static_cast<size_t>(newSize - originalSize);
|
||||
increment = RAPIDJSON_ALIGN(increment);
|
||||
if (chunkHead_->size + increment <= chunkHead_->capacity) {
|
||||
|
@ -231,7 +231,7 @@ private:
|
|||
void AddChunk(size_t capacity) {
|
||||
if (!baseAllocator_)
|
||||
ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
|
||||
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity));
|
||||
ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(sizeof(ChunkHeader) + capacity));
|
||||
chunk->capacity = capacity;
|
||||
chunk->size = 0;
|
||||
chunk->next = chunkHead_;
|
||||
|
|
|
@ -69,9 +69,6 @@ RAPIDJSON_NAMESPACE_BEGIN
|
|||
template <typename Encoding, typename Allocator>
|
||||
class GenericValue;
|
||||
|
||||
template <typename Encoding, typename Allocator, typename StackAllocator>
|
||||
class GenericDocument;
|
||||
|
||||
//! Name-value pair in a JSON object value.
|
||||
/*!
|
||||
This class was internal to GenericValue. It used to be a inner struct.
|
||||
|
@ -449,16 +446,6 @@ private:
|
|||
//! Copy constructor is not permitted.
|
||||
GenericValue(const GenericValue& rhs);
|
||||
|
||||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
//! Moving from a GenericDocument is not permitted.
|
||||
template <typename StackAllocator>
|
||||
GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
|
||||
|
||||
//! Move assignment from a GenericDocument is not permitted.
|
||||
template <typename StackAllocator>
|
||||
GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
//! Constructor with JSON value type.
|
||||
|
@ -545,28 +532,6 @@ public:
|
|||
flags_ |= kIntFlag;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
//! Constructor for unsigned long value.
|
||||
explicit GenericValue(unsigned long u64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUint64Flag) {
|
||||
data_.n.u64 = u64;
|
||||
if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
|
||||
flags_ |= kInt64Flag;
|
||||
if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
|
||||
flags_ |= kUintFlag;
|
||||
if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
|
||||
flags_ |= kIntFlag;
|
||||
}
|
||||
|
||||
#if !defined(__x86_64__) && !defined(__arm64__)
|
||||
//! Constructor for size_t value.
|
||||
explicit GenericValue( size_t u ) RAPIDJSON_NOEXCEPT : data_(), flags_( kNumberUintFlag ) {
|
||||
data_.n.u64 = u;
|
||||
if ( !( u&0x80000000 ) )
|
||||
flags_ |= kIntFlag|kInt64Flag;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//! Constructor for double value.
|
||||
explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberDoubleFlag) { data_.n.d = d; }
|
||||
|
||||
|
@ -695,20 +660,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
//! free-standing swap function helper
|
||||
/*!
|
||||
Helper function to enable support for common swap implementation pattern based on \c std::swap:
|
||||
\code
|
||||
void swap(MyClass& a, MyClass& b) {
|
||||
using std::swap;
|
||||
swap(a.value, b.value);
|
||||
// ...
|
||||
}
|
||||
\endcode
|
||||
\see Swap()
|
||||
*/
|
||||
friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
|
||||
|
||||
//! Prepare Value for move semantics
|
||||
/*! \return *this */
|
||||
GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
|
||||
|
@ -1262,31 +1213,6 @@ public:
|
|||
return pos;
|
||||
}
|
||||
|
||||
//! Erase a member in object by its name.
|
||||
/*! \param name Name of member to be removed.
|
||||
\return Whether the member existed.
|
||||
\note Linear time complexity.
|
||||
*/
|
||||
bool EraseMember(const Ch* name) {
|
||||
GenericValue n(StringRef(name));
|
||||
return EraseMember(n);
|
||||
}
|
||||
|
||||
#if RAPIDJSON_HAS_STDSTRING
|
||||
bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
|
||||
#endif
|
||||
|
||||
template <typename SourceAllocator>
|
||||
bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
|
||||
MemberIterator m = FindMember(name);
|
||||
if (m != MemberEnd()) {
|
||||
EraseMember(m);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
//!@name Array
|
||||
|
@ -1798,22 +1724,7 @@ public:
|
|||
typedef Allocator AllocatorType; //!< Allocator type from template parameter.
|
||||
|
||||
//! Constructor
|
||||
/*! Creates an empty document of specified type.
|
||||
\param type Mandatory type of object to create.
|
||||
\param allocator Optional allocator for allocating memory.
|
||||
\param stackCapacity Optional initial capacity of stack in bytes.
|
||||
\param stackAllocator Optional allocator for allocating memory for stack.
|
||||
*/
|
||||
explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
|
||||
GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
|
||||
{
|
||||
if (!allocator_)
|
||||
ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
|
||||
}
|
||||
|
||||
//! Constructor
|
||||
/*! Creates an empty document which type is Null.
|
||||
\param allocator Optional allocator for allocating memory.
|
||||
/*! \param allocator Optional allocator for allocating memory.
|
||||
\param stackCapacity Optional initial capacity of stack in bytes.
|
||||
\param stackAllocator Optional allocator for allocating memory for stack.
|
||||
*/
|
||||
|
@ -1827,7 +1738,7 @@ public:
|
|||
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
|
||||
//! Move constructor in C++11
|
||||
GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
|
||||
: ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
|
||||
: ValueType(std::move(rhs)),
|
||||
allocator_(rhs.allocator_),
|
||||
ownAllocator_(rhs.ownAllocator_),
|
||||
stack_(std::move(rhs.stack_)),
|
||||
|
@ -1867,35 +1778,6 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
//! Exchange the contents of this document with those of another.
|
||||
/*!
|
||||
\param other Another document.
|
||||
\note Constant complexity.
|
||||
\see GenericValue::Swap
|
||||
*/
|
||||
GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
|
||||
ValueType::Swap(rhs);
|
||||
stack_.Swap(rhs.stack_);
|
||||
internal::Swap(allocator_, rhs.allocator_);
|
||||
internal::Swap(ownAllocator_, rhs.ownAllocator_);
|
||||
internal::Swap(parseResult_, rhs.parseResult_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! free-standing swap function helper
|
||||
/*!
|
||||
Helper function to enable support for common swap implementation pattern based on \c std::swap:
|
||||
\code
|
||||
void swap(MyClass& a, MyClass& b) {
|
||||
using std::swap;
|
||||
swap(a.doc, b.doc);
|
||||
// ...
|
||||
}
|
||||
\endcode
|
||||
\see Swap()
|
||||
*/
|
||||
friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
|
||||
|
||||
//!@name Parse from stream
|
||||
//!@{
|
||||
|
||||
|
@ -1908,13 +1790,13 @@ public:
|
|||
*/
|
||||
template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
|
||||
GenericDocument& ParseStream(InputStream& is) {
|
||||
GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
|
||||
stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
|
||||
ValueType::SetNull(); // Remove existing root if exist
|
||||
GenericReader<SourceEncoding, Encoding, StackAllocator> reader(&stack_.GetAllocator());
|
||||
ClearStackOnExit scope(*this);
|
||||
parseResult_ = reader.template Parse<parseFlags>(is, *this);
|
||||
if (parseResult_) {
|
||||
RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
|
||||
ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
|
||||
this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13.
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -2011,10 +1893,7 @@ public:
|
|||
//!@}
|
||||
|
||||
//! Get the allocator of this document.
|
||||
Allocator& GetAllocator() {
|
||||
RAPIDJSON_ASSERT(allocator_);
|
||||
return *allocator_;
|
||||
}
|
||||
Allocator& GetAllocator() { return *allocator_; }
|
||||
|
||||
//! Get the capacity of stack in bytes.
|
||||
size_t GetStackCapacity() const { return stack_.GetCapacity(); }
|
||||
|
@ -2123,7 +2002,6 @@ GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,Sourc
|
|||
default: // kNumberType, kTrueType, kFalseType, kNullType
|
||||
flags_ = rhs.flags_;
|
||||
data_ = *reinterpret_cast<const Data*>(&rhs.data_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,8 +77,8 @@ public:
|
|||
void Flush() { os_.Flush(); }
|
||||
|
||||
// Not implemented
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); }
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); }
|
||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
@ -146,7 +146,7 @@ private:
|
|||
if (!c)
|
||||
return;
|
||||
|
||||
unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
|
||||
unsigned bom = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
|
||||
hasBOM_ = false;
|
||||
if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
||||
else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
|
||||
|
@ -227,8 +227,8 @@ public:
|
|||
void Flush() { os_->Flush(); }
|
||||
|
||||
// Not implemented
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
|
||||
Ch Peek() const { RAPIDJSON_ASSERT(false); }
|
||||
Ch Take() { RAPIDJSON_ASSERT(false); }
|
||||
size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
|
||||
Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
|
||||
size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
|
||||
|
|
|
@ -57,11 +57,7 @@ public:
|
|||
|
||||
void Flush() {
|
||||
if (current_ != buffer_) {
|
||||
size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
||||
if (result < static_cast<size_t>(current_ - buffer_)) {
|
||||
// failure deliberately ignored at this time
|
||||
// added to avoid warn_unused_result build errors
|
||||
}
|
||||
fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
|
||||
current_ = buffer_;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||
#include <intrin.h> // for _umul128
|
||||
#pragma intrinsic(_umul128)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
@ -52,15 +51,6 @@ public:
|
|||
AppendDecimal64(decimals + i, decimals + i + length);
|
||||
}
|
||||
|
||||
BigInteger& operator=(const BigInteger &rhs)
|
||||
{
|
||||
if (this != &rhs) {
|
||||
count_ = rhs.count_;
|
||||
std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BigInteger& operator=(uint64_t u) {
|
||||
digits_[0] = u;
|
||||
count_ = 1;
|
||||
|
@ -240,7 +230,7 @@ private:
|
|||
uint64_t r = 0;
|
||||
for (const char* p = begin; p != end; ++p) {
|
||||
RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
|
||||
r = r * 10u + (unsigned)(*p - '0');
|
||||
r = r * 10 + (*p - '0');
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_BitScanReverse64)
|
||||
#pragma intrinsic(_umul128)
|
||||
#endif
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
|
@ -233,8 +232,8 @@ inline DiyFp GetCachedPower(int e, int* K) {
|
|||
}
|
||||
|
||||
inline DiyFp GetCachedPower10(int exp, int *outExp) {
|
||||
unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u;
|
||||
*outExp = -348 + static_cast<int>(index) * 8;
|
||||
unsigned index = (exp + 348) / 8;
|
||||
*outExp = -348 + index * 8;
|
||||
return GetCachedPowerByIndex(index);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
|
|||
const DiyFp wp_w = Mp - W;
|
||||
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
||||
uint64_t p2 = Mp.f & (one.f - 1);
|
||||
unsigned kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
|
||||
int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
|
||||
*len = 0;
|
||||
|
||||
while (kappa > 0) {
|
||||
|
@ -101,7 +101,7 @@ inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buff
|
|||
kappa--;
|
||||
if (p2 < delta) {
|
||||
*K += kappa;
|
||||
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-static_cast<int>(kappa)]);
|
||||
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -158,14 +158,14 @@ inline char* Prettify(char* buffer, int length, int k) {
|
|||
}
|
||||
else if (0 < kk && kk <= 21) {
|
||||
// 1234e-2 -> 12.34
|
||||
std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
|
||||
std::memmove(&buffer[kk + 1], &buffer[kk], length - kk);
|
||||
buffer[kk] = '.';
|
||||
return &buffer[length + 1];
|
||||
}
|
||||
else if (-6 < kk && kk <= 0) {
|
||||
// 1234e-6 -> 0.001234
|
||||
const int offset = 2 - kk;
|
||||
std::memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length));
|
||||
std::memmove(&buffer[offset], &buffer[0], length);
|
||||
buffer[0] = '0';
|
||||
buffer[1] = '.';
|
||||
for (int i = 2; i < offset; i++)
|
||||
|
@ -179,7 +179,7 @@ inline char* Prettify(char* buffer, int length, int k) {
|
|||
}
|
||||
else {
|
||||
// 1234e30 -> 1.234e33
|
||||
std::memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1));
|
||||
std::memmove(&buffer[2], &buffer[1], length - 1);
|
||||
buffer[1] = '.';
|
||||
buffer[length + 1] = 'e';
|
||||
return WriteExponent(kk - 1, &buffer[0 + length + 2]);
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
else if (order <= -1074)
|
||||
return 0;
|
||||
else
|
||||
return (unsigned)order + 1074;
|
||||
return order + 1074;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#define RAPIDJSON_INTERNAL_STACK_H_
|
||||
|
||||
#include "../rapidjson.h"
|
||||
#include "swap.h"
|
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN
|
||||
namespace internal {
|
||||
|
@ -82,15 +81,6 @@ public:
|
|||
}
|
||||
#endif
|
||||
|
||||
void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
|
||||
internal::Swap(allocator_, rhs.allocator_);
|
||||
internal::Swap(ownAllocator_, rhs.ownAllocator_);
|
||||
internal::Swap(stack_, rhs.stack_);
|
||||
internal::Swap(stackTop_, rhs.stackTop_);
|
||||
internal::Swap(stackEnd_, rhs.stackEnd_);
|
||||
internal::Swap(initialCapacity_, rhs.initialCapacity_);
|
||||
}
|
||||
|
||||
void Clear() { stackTop_ = stack_; }
|
||||
|
||||
void ShrinkToFit() {
|
||||
|
@ -134,14 +124,7 @@ public:
|
|||
template<typename T>
|
||||
T* Bottom() { return (T*)stack_; }
|
||||
|
||||
bool HasAllocator() const {
|
||||
return allocator_ != 0;
|
||||
}
|
||||
|
||||
Allocator& GetAllocator() {
|
||||
RAPIDJSON_ASSERT(allocator_);
|
||||
return *allocator_;
|
||||
}
|
||||
Allocator& GetAllocator() { return *allocator_; }
|
||||
bool Empty() const { return stackTop_ == stack_; }
|
||||
size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
|
||||
size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
|
||||
|
|
|
@ -95,13 +95,13 @@ inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {
|
|||
hS_Exp2 -= common_Exp2;
|
||||
|
||||
BigInteger dS = d;
|
||||
dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<unsigned>(dS_Exp2);
|
||||
dS.MultiplyPow5(dS_Exp5) <<= dS_Exp2;
|
||||
|
||||
BigInteger bS(bInt);
|
||||
bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<unsigned>(bS_Exp2);
|
||||
bS.MultiplyPow5(bS_Exp5) <<= bS_Exp2;
|
||||
|
||||
BigInteger hS(1);
|
||||
hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<unsigned>(hS_Exp2);
|
||||
hS.MultiplyPow5(hS_Exp5) <<= hS_Exp2;
|
||||
|
||||
BigInteger delta(0);
|
||||
dS.Difference(bS, &delta);
|
||||
|
@ -134,7 +134,7 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
|||
if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
|
||||
(significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
|
||||
break;
|
||||
significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
|
||||
significand = significand * 10 + (decimals[i] - '0');
|
||||
}
|
||||
|
||||
if (i < length && decimals[i] >= '5') // Rounding
|
||||
|
@ -163,10 +163,10 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
|||
DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6
|
||||
DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7
|
||||
};
|
||||
int adjustment = dExp - actualExp - 1;
|
||||
int adjustment = dExp - actualExp - 1;
|
||||
RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);
|
||||
v = v * kPow10[adjustment];
|
||||
if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit
|
||||
if (length + adjustment > 19) // has more digits than decimal digits in 64-bit
|
||||
error += kUlp / 2;
|
||||
}
|
||||
|
||||
|
@ -184,14 +184,14 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
|||
unsigned scaleExp = (precisionSize + kUlpShift) - 63;
|
||||
v.f >>= scaleExp;
|
||||
v.e += scaleExp;
|
||||
error = (error >> scaleExp) + 1 + static_cast<int>(kUlp);
|
||||
error = (error >> scaleExp) + 1 + kUlp;
|
||||
precisionSize -= scaleExp;
|
||||
}
|
||||
|
||||
DiyFp rounded(v.f >> precisionSize, v.e + static_cast<int>(precisionSize));
|
||||
DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
|
||||
const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
|
||||
const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
|
||||
if (precisionBits >= halfWay + static_cast<unsigned>(error)) {
|
||||
if (precisionBits >= halfWay + error) {
|
||||
rounded.f++;
|
||||
if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340)
|
||||
rounded.f >>= 1;
|
||||
|
@ -201,7 +201,7 @@ inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosit
|
|||
|
||||
*result = rounded.ToDouble();
|
||||
|
||||
return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
|
||||
return halfWay - error >= precisionBits || precisionBits >= halfWay + error;
|
||||
}
|
||||
|
||||
inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
|
||||
|
@ -249,7 +249,7 @@ inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t
|
|||
if ((int)length > kMaxDecimalDigit) {
|
||||
int delta = (int(length) - kMaxDecimalDigit);
|
||||
exp += delta;
|
||||
decimalPosition -= static_cast<unsigned>(delta);
|
||||
decimalPosition -= delta;
|
||||
length = kMaxDecimalDigit;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@
|
|||
|
||||
//! Whether using 64-bit architecture
|
||||
#ifndef RAPIDJSON_64BIT
|
||||
#if defined(__LP64__) || defined(_WIN64) || defined(__EMSCRIPTEN__)
|
||||
#if defined(__LP64__) || defined(_WIN64)
|
||||
#define RAPIDJSON_64BIT 1
|
||||
#else
|
||||
#define RAPIDJSON_64BIT 0
|
||||
|
@ -238,13 +238,13 @@
|
|||
\param x pointer to align
|
||||
|
||||
Some machines require strict data alignment. Currently the default uses 4 bytes
|
||||
alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.
|
||||
alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.,
|
||||
*/
|
||||
#ifndef RAPIDJSON_ALIGN
|
||||
#if RAPIDJSON_64BIT == 1
|
||||
#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))
|
||||
#define RAPIDJSON_ALIGN(x) ((x + 7u) & ~7u)
|
||||
#else
|
||||
#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)
|
||||
#define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -140,7 +140,6 @@ enum ParseFlag {
|
|||
kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing.
|
||||
kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.
|
||||
kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower).
|
||||
kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments.
|
||||
kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
|
||||
};
|
||||
|
||||
|
@ -272,7 +271,7 @@ inline const char *SkipWhitespace_SIMD(const char* p) {
|
|||
|
||||
// The rest of string using SIMD
|
||||
static const char whitespace[16] = " \n\r\t";
|
||||
const __m128i w = _mm_loadu_si128((const __m128i *)&whitespace[0]);
|
||||
const __m128i w = _mm_load_si128((const __m128i *)&whitespace[0]);
|
||||
|
||||
for (;; p += 16) {
|
||||
const __m128i s = _mm_load_si128((const __m128i *)p);
|
||||
|
@ -399,8 +398,7 @@ public:
|
|||
|
||||
ClearStackOnExit scope(*this);
|
||||
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
SkipWhitespace(is);
|
||||
|
||||
if (is.Peek() == '\0') {
|
||||
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
|
||||
|
@ -411,8 +409,7 @@ public:
|
|||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
|
||||
if (!(parseFlags & kParseStopWhenDoneFlag)) {
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
SkipWhitespace(is);
|
||||
|
||||
if (is.Peek() != '\0') {
|
||||
RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
|
||||
|
@ -465,40 +462,6 @@ private:
|
|||
ClearStackOnExit& operator=(const ClearStackOnExit&);
|
||||
};
|
||||
|
||||
template<unsigned parseFlags, typename InputStream>
|
||||
void SkipWhitespaceAndComments(InputStream& is) {
|
||||
SkipWhitespace(is);
|
||||
|
||||
if (parseFlags & kParseCommentsFlag) {
|
||||
while (is.Peek() == '/') {
|
||||
is.Take();
|
||||
|
||||
if (is.Peek() == '*') {
|
||||
is.Take();
|
||||
while (true) {
|
||||
if (is.Peek() == '\0')
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||
|
||||
if (is.Take() == '*') {
|
||||
if (is.Peek() == '\0')
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||
|
||||
if (is.Take() == '/')
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (is.Peek() == '/') {
|
||||
is.Take();
|
||||
while (is.Peek() != '\0' && is.Take() != '\n') { }
|
||||
} else {
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||
}
|
||||
|
||||
SkipWhitespace(is);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse object: { string : value, ... }
|
||||
template<unsigned parseFlags, typename InputStream, typename Handler>
|
||||
void ParseObject(InputStream& is, Handler& handler) {
|
||||
|
@ -508,8 +471,7 @@ private:
|
|||
if (!handler.StartObject())
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
SkipWhitespace(is);
|
||||
|
||||
if (is.Peek() == '}') {
|
||||
is.Take();
|
||||
|
@ -525,35 +487,27 @@ private:
|
|||
ParseString<parseFlags>(is, handler, true);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
SkipWhitespace(is);
|
||||
|
||||
if (is.Take() != ':')
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
|
||||
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
SkipWhitespace(is);
|
||||
|
||||
ParseValue<parseFlags>(is, handler);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
SkipWhitespace(is);
|
||||
|
||||
++memberCount;
|
||||
|
||||
switch (is.Take()) {
|
||||
case ',':
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
break;
|
||||
case ',': SkipWhitespace(is); break;
|
||||
case '}':
|
||||
if (!handler.EndObject(memberCount))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
return;
|
||||
default:
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
|
||||
break;
|
||||
default: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -567,8 +521,7 @@ private:
|
|||
if (!handler.StartArray())
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
SkipWhitespace(is);
|
||||
|
||||
if (is.Peek() == ']') {
|
||||
is.Take();
|
||||
|
@ -582,21 +535,15 @@ private:
|
|||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
|
||||
++elementCount;
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
SkipWhitespace(is);
|
||||
|
||||
switch (is.Take()) {
|
||||
case ',':
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
|
||||
break;
|
||||
case ',': SkipWhitespace(is); break;
|
||||
case ']':
|
||||
if (!handler.EndArray(elementCount))
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
|
||||
return;
|
||||
default:
|
||||
RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
|
||||
break;
|
||||
default: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1020,13 +967,13 @@ private:
|
|||
else {
|
||||
if (use64bit) {
|
||||
if (minus)
|
||||
cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
|
||||
cont = handler.Int64(-(int64_t)i64);
|
||||
else
|
||||
cont = handler.Uint64(i64);
|
||||
}
|
||||
else {
|
||||
if (minus)
|
||||
cont = handler.Int(static_cast<int32_t>(~i + 1));
|
||||
cont = handler.Int(-(int)i);
|
||||
else
|
||||
cont = handler.Uint(i);
|
||||
}
|
||||
|
@ -1045,10 +992,7 @@ private:
|
|||
case '"': ParseString<parseFlags>(is, handler); break;
|
||||
case '{': ParseObject<parseFlags>(is, handler); break;
|
||||
case '[': ParseArray <parseFlags>(is, handler); break;
|
||||
default :
|
||||
ParseNumber<parseFlags>(is, handler);
|
||||
break;
|
||||
|
||||
default : ParseNumber<parseFlags>(is, handler);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1443,14 +1387,14 @@ private:
|
|||
}
|
||||
|
||||
switch (src) {
|
||||
case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
|
||||
case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
|
||||
case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell());
|
||||
case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell());
|
||||
case IterativeParsingObjectInitialState:
|
||||
case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
|
||||
case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
|
||||
case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
|
||||
case IterativeParsingElementState: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
|
||||
default: RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell()); return;
|
||||
case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
|
||||
case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
|
||||
case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell());
|
||||
case IterativeParsingElementState: RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
|
||||
default: RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1460,8 +1404,7 @@ private:
|
|||
ClearStackOnExit scope(*this);
|
||||
IterativeParsingState state = IterativeParsingStartState;
|
||||
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
SkipWhitespace(is);
|
||||
while (is.Peek() != '\0') {
|
||||
Token t = Tokenize(is.Peek());
|
||||
IterativeParsingState n = Predict(state, t);
|
||||
|
@ -1478,8 +1421,7 @@ private:
|
|||
if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
|
||||
break;
|
||||
|
||||
SkipWhitespaceAndComments<parseFlags>(is);
|
||||
RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
|
||||
SkipWhitespace(is);
|
||||
}
|
||||
|
||||
// Handle the end of file.
|
||||
|
|
|
@ -350,7 +350,7 @@ template<>
|
|||
inline bool Writer<StringBuffer>::WriteInt(int i) {
|
||||
char *buffer = os_->Push(11);
|
||||
const char* end = internal::i32toa(i, buffer);
|
||||
os_->Pop(static_cast<size_t>(11 - (end - buffer)));
|
||||
os_->Pop(11 - (end - buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -358,7 +358,7 @@ template<>
|
|||
inline bool Writer<StringBuffer>::WriteUint(unsigned u) {
|
||||
char *buffer = os_->Push(10);
|
||||
const char* end = internal::u32toa(u, buffer);
|
||||
os_->Pop(static_cast<size_t>(10 - (end - buffer)));
|
||||
os_->Pop(10 - (end - buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,7 @@ template<>
|
|||
inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
|
||||
char *buffer = os_->Push(21);
|
||||
const char* end = internal::i64toa(i64, buffer);
|
||||
os_->Pop(static_cast<size_t>(21 - (end - buffer)));
|
||||
os_->Pop(21 - (end - buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -374,7 +374,7 @@ template<>
|
|||
inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
|
||||
char *buffer = os_->Push(20);
|
||||
const char* end = internal::u64toa(u, buffer);
|
||||
os_->Pop(static_cast<size_t>(20 - (end - buffer)));
|
||||
os_->Pop(20 - (end - buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -382,7 +382,7 @@ template<>
|
|||
inline bool Writer<StringBuffer>::WriteDouble(double d) {
|
||||
char *buffer = os_->Push(25);
|
||||
char* end = internal::dtoa(d, buffer);
|
||||
os_->Pop(static_cast<size_t>(25 - (end - buffer)));
|
||||
os_->Pop(25 - (end - buffer));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ Tencent is pleased to support the open source community by making RapidJSON avai
|
|||
Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
|
||||
|
||||
If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License.
|
||||
If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license.
|
||||
If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON.
|
||||
A copy of the MIT License is included in this file.
|
||||
|
||||
Other dependencies and licenses:
|
||||
|
|
|
@ -10,8 +10,8 @@ Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights
|
|||
|
||||
* [RapidJSON GitHub](https://github.com/miloyip/rapidjson/)
|
||||
* RapidJSON Documentation
|
||||
* [English](http://rapidjson.org/)
|
||||
* [简体ä¸ć–‡](http://rapidjson.org/zh-cn/)
|
||||
* [English](http://miloyip.github.io/rapidjson/)
|
||||
* [简体ä¸ć–‡](http://miloyip.github.io/rapidjson/zh-cn/)
|
||||
* [GitBook](https://www.gitbook.com/book/miloyip/rapidjson/) with downloadable PDF/EPUB/MOBI, without API reference.
|
||||
|
||||
## Build status
|
||||
|
@ -31,15 +31,15 @@ Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights
|
|||
|
||||
RapidJSON is a JSON parser and generator for C++. It was inspired by [RapidXml](http://rapidxml.sourceforge.net/).
|
||||
|
||||
* RapidJSON is **small** but **complete**. It supports both SAX and DOM style API. The SAX parser is only a half thousand lines of code.
|
||||
* RapidJSON is small but complete. It supports both SAX and DOM style API. The SAX parser is only a half thousand lines of code.
|
||||
|
||||
* RapidJSON is **fast**. Its performance can be comparable to `strlen()`. It also optionally supports SSE2/SSE4.2 for acceleration.
|
||||
* RapidJSON is fast. Its performance can be comparable to `strlen()`. It also optionally supports SSE2/SSE4.2 for acceleration.
|
||||
|
||||
* RapidJSON is **self-contained** and **header-only**. It does not depend on external libraries such as BOOST. It even does not depend on STL.
|
||||
* RapidJSON is self-contained. It does not depend on external libraries such as BOOST. It even does not depend on STL.
|
||||
|
||||
* RapidJSON is **memory-friendly**. Each JSON value occupies exactly 16/20 bytes for most 32/64-bit machines (excluding text string). By default it uses a fast memory allocator, and the parser allocates memory compactly during parsing.
|
||||
* RapidJSON is memory friendly. Each JSON value occupies exactly 16/20 bytes for most 32/64-bit machines (excluding text string). By default it uses a fast memory allocator, and the parser allocates memory compactly during parsing.
|
||||
|
||||
* RapidJSON is **Unicode-friendly**. It supports UTF-8, UTF-16, UTF-32 (LE & BE), and their detection, validation and transcoding internally. For example, you can read a UTF-8 file and let RapidJSON transcode the JSON strings into UTF-16 in the DOM. It also supports surrogates and "\u0000" (null character).
|
||||
* RapidJSON is Unicode friendly. It supports UTF-8, UTF-16, UTF-32 (LE & BE), and their detection, validation and transcoding internally. For example, you can read a UTF-8 file and let RapidJSON transcode the JSON strings into UTF-16 in the DOM. It also supports surrogates and "\u0000" (null character).
|
||||
|
||||
More features can be read [here](doc/features.md).
|
||||
|
||||
|
|
|
@ -211,14 +211,14 @@ the dump is written to <tt><model>-dump.txt</tt>
|
|||
<p>
|
||||
<tt>-b<br>
|
||||
</tt><br>
|
||||
Optional. If this switch is specified, the dumb is written in binary format.
|
||||
Optional. If this switch is specified, the dump is written in binary format.
|
||||
The long form of this parameter is <tt>--binary</tt>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<tt>-s<n><br>
|
||||
</tt><br>
|
||||
Optional. If this switch is specified, the dumb is shortened to include only
|
||||
Optional. If this switch is specified, the dump is shortened to include only
|
||||
min/max values for all vertex components and animation channels. The resulting
|
||||
file is much smaller, but the original model can't be reconstructed from it. This is
|
||||
used by Assimp's regression test suite, comparing those minidumps provides
|
||||
|
@ -368,7 +368,6 @@ of all supported steps along with short descriptions of what they're doing. <br>
|
|||
more information can be found in the <tt>aiPostProcess.h</tt> header.
|
||||
|
||||
<table border="1">
|
||||
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
<th>Long parameter</th>
|
||||
|
@ -432,13 +431,13 @@ more information can be found in the <tt>aiPostProcess.h</tt> header.
|
|||
<td>Improve the cache locality of the vertex buffer by reordering the index buffer
|
||||
to achieve a lower ACMR (average post-transform vertex cache miss ratio)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><tt>-sbpt</tt></td>
|
||||
<td><tt>--sort-by-ptype</tt></td>
|
||||
<td>Splits meshes which consist of more than one kind of primitives (e.g. lines and triangles mixed up)
|
||||
in 'clean' submeshes. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><tt>-lh</tt></td>
|
||||
<td><tt>--convert-to-lh</tt></td>
|
||||
<td>Converts the imported data to left-handed coordinate space</td>
|
||||
|
@ -479,19 +478,47 @@ more information can be found in the <tt>aiPostProcess.h</tt> header.
|
|||
<td>Search the data structure for instanced meshes and replace them by references. This can
|
||||
reduce vertex/face counts but the postprocessing-step takes some time.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<tr>
|
||||
<td><tt>-og</tt></td>
|
||||
<td><tt>--optimize-graph</tt></td>
|
||||
<td>Simplify and optimize the scenegraph. Use it with care, all hierarchy information could be lost.
|
||||
Animations remain untouched. </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<tr>
|
||||
<td><tt>-om</tt></td>
|
||||
<td><tt>--optimize-mesh</tt></td>
|
||||
<td><tt>--optimize-meshes</tt></td>
|
||||
<td>Optimize mesh usage. Meshes are merged, if possible. Very effective in combination with <tt>--optimize-graph</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>-tuv</tt></td>
|
||||
<td><tt>--transform-uv-coords</tt></td>
|
||||
<td>Will transform uv-coordinates if possible.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>-guv</tt></td>
|
||||
<td><tt>--gen-uvcoords</tt></td>
|
||||
<td>Will generate uv-coordinates for textures if possible.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>-fid</tt></td>
|
||||
<td><tt>--find-invalid-data</tt></td>
|
||||
<td>Will look for invalid data in the imported model structure.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>-fixn</tt></td>
|
||||
<td><tt>--fix normals</tt></td>
|
||||
<td>Imported normal vector will be fixed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>-db</tt></td>
|
||||
<td><tt>--debone</tt></td>
|
||||
<td>Removes nearly losslessly or according to a configured threshold bones from the model.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>-sbc</tt></td>
|
||||
<td><tt>--split-by-bone-count</tt></td>
|
||||
<td>Split meshes with too many bones. Necessary for our (limited) hardware skinning shader.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
For convenience some default postprocessing configurations are provided.
|
||||
|
|
|
@ -714,30 +714,33 @@ public:
|
|||
// -------------------------------------------------------------------
|
||||
/** Helper function to get all parameters pertaining to a
|
||||
* particular texture slot from a material.
|
||||
*
|
||||
* This function is provided just for convenience, you could also
|
||||
* read the single material properties manually.
|
||||
* @param type Specifies the type of the texture to be retrieved (
|
||||
* e.g. diffuse, specular, height map ...)
|
||||
* @param index Index of the texture to be retrieved. The function fails
|
||||
* if there is no texture of that type with this index.
|
||||
* #GetTextureCount() can be used to determine the number of textures
|
||||
* per texture type.
|
||||
* @param path Receives the path to the texture.
|
||||
* NULL is a valid value.
|
||||
* @param mapping The texture mapping.
|
||||
* NULL is allowed as value.
|
||||
* @param uvindex Receives the UV index of the texture.
|
||||
* NULL is a valid value.
|
||||
* @param blend Receives the blend factor for the texture
|
||||
* NULL is a valid value.
|
||||
* @param op Receives the texture operation to be performed between
|
||||
* this texture and the previous texture. NULL is allowed as value.
|
||||
* @param mapmode Receives the mapping modes to be used for the texture.
|
||||
* The parameter may be NULL but if it is a valid pointer it MUST
|
||||
* point to an array of 3 aiTextureMapMode's (one for each
|
||||
* axis: UVW order (=XYZ)).
|
||||
*/
|
||||
*
|
||||
* This function is provided just for convenience, you could also
|
||||
* read the single material properties manually.
|
||||
* @param type Specifies the type of the texture to be retrieved (
|
||||
* e.g. diffuse, specular, height map ...)
|
||||
* @param index Index of the texture to be retrieved. The function fails
|
||||
* if there is no texture of that type with this index.
|
||||
* #GetTextureCount() can be used to determine the number of textures
|
||||
* per texture type.
|
||||
* @param path Receives the path to the texture.
|
||||
* If the texture is embedded, receives a '*' followed by the id of
|
||||
* the texture (for the textures stored in the corresponding scene) which
|
||||
* can be converted to an int using a function like atoi.
|
||||
* NULL is a valid value.
|
||||
* @param mapping The texture mapping.
|
||||
* NULL is allowed as value.
|
||||
* @param uvindex Receives the UV index of the texture.
|
||||
* NULL is a valid value.
|
||||
* @param blend Receives the blend factor for the texture
|
||||
* NULL is a valid value.
|
||||
* @param op Receives the texture operation to be performed between
|
||||
* this texture and the previous texture. NULL is allowed as value.
|
||||
* @param mapmode Receives the mapping modes to be used for the texture.
|
||||
* The parameter may be NULL but if it is a valid pointer it MUST
|
||||
* point to an array of 3 aiTextureMapMode's (one for each
|
||||
* axis: UVW order (=XYZ)).
|
||||
*/
|
||||
// -------------------------------------------------------------------
|
||||
aiReturn GetTexture(aiTextureType type,
|
||||
unsigned int index,
|
||||
|
@ -1506,7 +1509,10 @@ ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMa
|
|||
* #aiGetMaterialTextureCount() can be used to determine the number of
|
||||
* textures in a particular texture stack.
|
||||
* @param[out] path Receives the output path
|
||||
* This parameter must be non-null.
|
||||
* If the texture is embedded, receives a '*' followed by the id of
|
||||
* the texture (for the textures stored in the corresponding scene) which
|
||||
* can be converted to an int using a function like atoi.
|
||||
* This parameter must be non-null.
|
||||
* @param mapping The texture mapping mode to be used.
|
||||
* Pass NULL if you're not interested in this information.
|
||||
* @param[out] uvindex For UV-mapped textures: receives the index of the UV
|
||||
|
|
|
@ -216,7 +216,7 @@ struct aiColor3D
|
|||
|
||||
/** Check whether a color is black */
|
||||
bool IsBlack() const {
|
||||
static const ai_real epsilon = 10e-3;
|
||||
static const ai_real epsilon = ai_real(10e-3);
|
||||
return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ SOURCE_GROUP( unit FILES
|
|||
|
||||
SET( TEST_SRCS
|
||||
unit/AssimpAPITest.cpp
|
||||
unit/utBlenderIntermediate.cpp
|
||||
unit/utBlendImportAreaLight.cpp
|
||||
unit/utBlendImportMaterials.cpp
|
||||
unit/utColladaExportCamera.cpp
|
||||
|
|
|
@ -63,7 +63,7 @@ def log( sev, msg ):
|
|||
logEntry = logEntry + "[WARN]: "
|
||||
elif sev == 2:
|
||||
logEntry = logEntry + "[ERR] : "
|
||||
logEntry = logEntry + msg
|
||||
logEntry = logEntry + str( msg )
|
||||
print( logEntry )
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
#include "UnitTestPCH.h"
|
||||
#include "BlenderIntermediate.h"
|
||||
|
||||
using namespace ::Assimp;
|
||||
using namespace ::Assimp::Blender;
|
||||
|
||||
class BlenderIntermediateTest : public ::testing::Test {
|
||||
// empty
|
||||
};
|
||||
|
||||
TEST_F( BlenderIntermediateTest,ConversionData_ObjectCompareTest ) {
|
||||
Object obj1, obj2;
|
||||
strncpy( obj1.id.name, "name1", 5 );
|
||||
strncpy( obj2.id.name, "name2", 5 );
|
||||
Blender::ObjectCompare cmp_false;
|
||||
bool res( cmp_false( &obj1, &obj2 ) );
|
||||
EXPECT_FALSE( res );
|
||||
|
||||
Blender::ObjectCompare cmp_true;
|
||||
res = cmp_true( &obj1, &obj1 );
|
||||
EXPECT_TRUE( res );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -48,7 +48,12 @@ class utDefaultIOStream : public ::testing::Test {
|
|||
class TestDefaultIOStream : public DefaultIOStream {
|
||||
public:
|
||||
TestDefaultIOStream()
|
||||
: DefaultIOStream() {
|
||||
: DefaultIOStream() {
|
||||
// empty
|
||||
}
|
||||
|
||||
TestDefaultIOStream( FILE* pFile, const std::string &strFilename )
|
||||
: DefaultIOStream( pFile, strFilename ) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -58,7 +63,14 @@ public:
|
|||
};
|
||||
|
||||
TEST_F( utDefaultIOStream, FileSizeTest ) {
|
||||
TestDefaultIOStream myStream;
|
||||
char buffer[ L_tmpnam ];
|
||||
tmpnam( buffer );
|
||||
std::FILE *fs( std::fopen( buffer, "w+" ) );
|
||||
size_t written( std::fwrite( buffer, 1, sizeof( char ) * L_tmpnam, fs ) );
|
||||
std::fflush( fs );
|
||||
|
||||
TestDefaultIOStream myStream( fs, buffer );
|
||||
size_t size = myStream.FileSize();
|
||||
EXPECT_EQ( size, 0 );
|
||||
EXPECT_EQ( size, sizeof( char ) * L_tmpnam );
|
||||
remove( buffer );
|
||||
}
|
||||
|
|
|
@ -378,7 +378,6 @@ int ProcessStandardArguments(
|
|||
// -fixn --fix normals
|
||||
// -tri --triangulate
|
||||
// -fi --find-instances
|
||||
// -fi --find-instances
|
||||
// -og --optimize-graph
|
||||
// -om --optimize-meshes
|
||||
// -db --debone
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
project(assimp_qt_viewer)
|
||||
set(PROJECT_VERSION "")
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
find_package(Qt4 REQUIRED)
|
||||
find_package(DevIL REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
include_directories(
|
||||
${QT_INCLUDES}
|
||||
${Assimp_SOURCE_DIR}/include
|
||||
${Assimp_SOURCE_DIR}/code
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
${IL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
link_directories(${Assimp_BINARY_DIR})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
|
||||
|
||||
set(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp)
|
||||
qt4_wrap_ui(UISrcs mainwindow.ui)
|
||||
qt4_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
|
||||
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
|
||||
|
||||
if(WIN32) # Check if we are on Windows
|
||||
if(MSVC) # Check if we are using the Visual Studio compiler
|
||||
set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested
|
||||
else()
|
||||
message(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)")
|
||||
endif()
|
||||
elseif(UNIX)
|
||||
# Nothing special required
|
||||
else()
|
||||
message(SEND_ERROR "You are on an unsupported platform! (Not Win32 or Unix)")
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,382 @@
|
|||
/// \file glview.hpp
|
||||
/// \brief OpenGL visualisation.
|
||||
/// \author smal.root@gmail.com
|
||||
/// \date 2016
|
||||
|
||||
#pragma once
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QtOpenGL>
|
||||
|
||||
// Header files Assimp
|
||||
#include <assimp/scene.h>
|
||||
|
||||
/// \class CGLView
|
||||
/// Class which hold and render scene.
|
||||
class CGLView : public QGLWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**********************************/
|
||||
/************* Types **************/
|
||||
/**********************************/
|
||||
|
||||
private:
|
||||
|
||||
/// \struct SBBox
|
||||
/// Bounding box for object.
|
||||
struct SBBox
|
||||
{
|
||||
aiVector3D Minimum;///< Minimum values of coordinates.
|
||||
aiVector3D Maximum;///< Maximum values of coordinates.
|
||||
};
|
||||
|
||||
/// \struct SHelper_Mesh
|
||||
/// Helper object for fast rendering of mesh (\ref aiMesh).
|
||||
struct SHelper_Mesh
|
||||
{
|
||||
const size_t Quantity_Point;///< Quantity of points.
|
||||
const size_t Quantity_Line;///< Quantity of lines.
|
||||
const size_t Quantity_Triangle;///< Quantity of triangles.
|
||||
GLuint* Index_Point;///< Array of indices for drawing points.
|
||||
GLuint* Index_Line;///< Array of indices for drawing lines.
|
||||
GLuint* Index_Triangle;///< Array of indices for drawing triangles.
|
||||
|
||||
const SBBox BBox;///< BBox of mesh.
|
||||
|
||||
/// \fn explicit SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox = {{0, 0, 0}, {0, 0, 0}})
|
||||
/// Constructor.
|
||||
/// \param [in] pQuantity_Point - quantity of points.
|
||||
/// \param [in] pQuantity_Line - quantity of lines.
|
||||
/// \param [in] pQuantity_Triangle - quantity of triangles.
|
||||
/// \param [in] pBBox - BBox of mesh.
|
||||
explicit SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox = {{0, 0, 0}, {0, 0, 0}});
|
||||
|
||||
/// \fn ~SHelper_Mesh()
|
||||
/// Destructor.
|
||||
~SHelper_Mesh();
|
||||
};
|
||||
|
||||
/// \struct SHelper_Camera
|
||||
/// Information about position of the camera in space.
|
||||
struct SHelper_Camera
|
||||
{
|
||||
aiVector3D Position;///< Coordinates of the camera.
|
||||
aiVector3D Target;///< Target point of the camera.
|
||||
// Transformation path:
|
||||
// set Camera -> Rotation_AroundCamera -> Translation_ToScene -> Rotation_Scene -> draw Scene
|
||||
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.
|
||||
aiVector3D Translation_ToScene;///< Translation vector from camera to the scene.
|
||||
|
||||
/// \fn void SetDefault()
|
||||
/// Set default parameters of camera.
|
||||
void SetDefault();
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// \enum ELightType
|
||||
/// Type of light source.
|
||||
enum class ELightType { Directional, Point, Spot };
|
||||
|
||||
/// \struct SLightParameters
|
||||
/// Parameters of light source.
|
||||
struct SLightParameters
|
||||
{
|
||||
aiLightSourceType Type;///< Type of light source.
|
||||
|
||||
aiColor4D Ambient;///< Ambient RGBA intensity of the light.
|
||||
aiColor4D Diffuse;///< Diffuse RGBA intensity of the light.
|
||||
aiColor4D Specular;///< Specular RGBA intensity of the light.
|
||||
|
||||
union UFor
|
||||
{
|
||||
/// \struct SDirectional
|
||||
/// Parameters of directional light source.
|
||||
struct SDirectional
|
||||
{
|
||||
aiVector3D Direction;
|
||||
|
||||
SDirectional() {}
|
||||
} Directional;
|
||||
|
||||
/// \struct SPoint
|
||||
/// Parameters of point light source.
|
||||
struct SPoint
|
||||
{
|
||||
aiVector3D Position;
|
||||
GLfloat Attenuation_Constant;
|
||||
GLfloat Attenuation_Linear;
|
||||
GLfloat Attenuation_Quadratic;
|
||||
|
||||
SPoint() {}
|
||||
} Point;
|
||||
|
||||
/// \struct SSpot
|
||||
/// Parameters of spot light source.
|
||||
struct SSpot
|
||||
{
|
||||
aiVector3D Position;
|
||||
GLfloat Attenuation_Constant;
|
||||
GLfloat Attenuation_Linear;
|
||||
GLfloat Attenuation_Quadratic;
|
||||
aiVector3D Direction;
|
||||
GLfloat CutOff;
|
||||
|
||||
SSpot() {}
|
||||
} Spot;
|
||||
|
||||
UFor() {}
|
||||
} For;
|
||||
|
||||
SLightParameters() {}
|
||||
};
|
||||
|
||||
/**********************************/
|
||||
/************ Variables ***********/
|
||||
/**********************************/
|
||||
|
||||
private:
|
||||
|
||||
// Scene
|
||||
const aiScene* mScene = nullptr;///< Copy of pointer to scene (\ref aiScene).
|
||||
SBBox mScene_BBox;///< Bounding box of scene.
|
||||
aiVector3D mScene_Center;///< Coordinates of center of the scene.
|
||||
bool mScene_DrawBBox = false;///< Flag which control drawing scene BBox.
|
||||
// Meshes
|
||||
size_t mHelper_Mesh_Quantity = 0;///< Quantity of meshes in scene.
|
||||
SHelper_Mesh** mHelper_Mesh = nullptr;///< Array of pointers to helper objects for drawing mesh. Sequence of meshes are equivalent to \ref aiScene::mMeshes.
|
||||
// Cameras
|
||||
SHelper_Camera mHelper_Camera;///< Information about current camera placing in space.
|
||||
SHelper_Camera mHelper_CameraDefault;///< Information about default camera initial placing in space.
|
||||
bool mCamera_DefaultAdded = true;///< If true then scene has no defined cameras and default was added, if false - scene has defined cameras.
|
||||
GLdouble mCamera_FOVY = 45.0;///< Specifies the field of view angle, in degrees, in the y direction.
|
||||
GLdouble mCamera_Viewport_AspectRatio;///< Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
|
||||
// Lighting
|
||||
bool mLightingEnabled = false;///< If true then OpenGL lighting is enabled (glEnable(GL_LIGHTING)), if false - disabled.
|
||||
// Textures
|
||||
QMap<QString, GLuint> mTexture_IDMap;///< Map image filenames to textures ID's.
|
||||
|
||||
/**********************************/
|
||||
/************ Functions ***********/
|
||||
/**********************************/
|
||||
|
||||
private:
|
||||
|
||||
// Why in some cases pointers are used? Because: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
|
||||
template<typename TArg> void AssignIfLesser(TArg* pBaseValue, const TArg pTestValue) { if(pTestValue < *pBaseValue) *pBaseValue = pTestValue; }
|
||||
template<typename TArg> void AssignIfGreater(TArg* pBaseValue, const TArg pTestValue) { if(pTestValue > *pBaseValue) *pBaseValue = pTestValue; }
|
||||
|
||||
template<typename TArg> void AssignIfLesser(TArg& pBaseValue, const TArg pTestValue) { if(pTestValue < pBaseValue) pBaseValue = pTestValue; }
|
||||
template<typename TArg> void AssignIfGreater(TArg& pBaseValue, const TArg pTestValue) { if(pTestValue > pBaseValue) pBaseValue = pTestValue; }
|
||||
|
||||
/// \fn void Material_Apply(const aiMaterial* pMaterial)
|
||||
/// Enable pointed material.
|
||||
/// \param [in] pMaterial - pointer to material which must be used.
|
||||
void Material_Apply(const aiMaterial* pMaterial);
|
||||
|
||||
/// \fn void Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix)
|
||||
/// Calculate matrix for transforming coordinates from pointed node to root node (read as "global coordinate system").
|
||||
/// \param [in] pNode - pointer initial node from which relative coordintaes will be taken,
|
||||
/// \param [out] pOutMatrix - matrix for transform relative coordinates in \ref pNode to coordinates in root node (\ref aiScene::mRootNode).
|
||||
void Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix);
|
||||
|
||||
/// \fn void ImportTextures()
|
||||
/// Import textures.
|
||||
/// \param [in] pScenePath - path to the file of the scene.
|
||||
void ImportTextures(const QString& pScenePath);
|
||||
|
||||
/// \fn void BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParentNode_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign)
|
||||
/// Calculate BBox for pointed node. Function walk thru child nodes and apply all transformations.
|
||||
/// \param [in] pNode - reference to node for which needed BBox.
|
||||
/// \param [in] pParent_TransformationMatrix - reference to parent (parent for pNode) transformation matrix.
|
||||
/// \param [in,out] pNodeBBox - reference to where pNode BBox will be placed. It will expanded by child nodes BBoxes.
|
||||
/// \param [in] pFirstAssign - means that pNodeBBox not contain valid BBox at now and assign ('=') will used for setting new value, If
|
||||
/// false then \ref BBox_Extend will be used for setting new BBox.
|
||||
void BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParent_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign);
|
||||
|
||||
/// \fn void BBox_Extend(const SBBox& pChild, SBBox& pParent)
|
||||
/// Check and if need - extend current node BBox with BBox of child node.
|
||||
/// \param [in] pChild - reference to BBox which used for extend parent BBox.
|
||||
/// \param [in.out] pParent - BBox which will be extended using child BBox.
|
||||
void BBox_Extend(const SBBox& pChild, SBBox& pParent);
|
||||
|
||||
/// \fn void BBox_GetVertices(const SBBox& pBBox, aiVector3D pVertices[8])
|
||||
/// Get vertices of a parallelepiped which is described by BBox.
|
||||
/// \param [in] pBBox - input BBox.
|
||||
/// \param [out] pVertices - array of vertices.
|
||||
void BBox_GetVertices(const SBBox& pBBox, aiVector3D pVertices[8]);
|
||||
|
||||
/// \fn void BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVerticesQuantity, SBBox& pBBox)
|
||||
/// Calculate BBox for vertices array.
|
||||
/// \param [in] pVertices - vertices array.
|
||||
/// \param [in] pVerticesQuantity - quantity of vertices in array. If 0 then pBBox will be assigned with {{0, 0, 0}, {0, 0, 0}}.
|
||||
/// \param [out] pBBox - calculated BBox.
|
||||
void BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVerticesQuantity, SBBox& pBBox);
|
||||
|
||||
/********************************************************************/
|
||||
/************************ Logging functions *************************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void LogInfo(const QString& pMessage)
|
||||
/// Add message with severity "Warning" to log.
|
||||
void LogInfo(const QString& pMessage);
|
||||
|
||||
/// \fn void LogError(const QString& pMessage)
|
||||
/// Add message with severity "Error" to log.
|
||||
void LogError(const QString& pMessage);
|
||||
|
||||
/********************************************************************/
|
||||
/************************** Draw functions **************************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void Draw_Node(const aiNode* pNode)
|
||||
/// Apply node transformation and draw meshes assigned to this node.
|
||||
/// \param [in] pNode - pointer to node for drawing (\ref aiNode).
|
||||
void Draw_Node(const aiNode* pNode);
|
||||
|
||||
/// \fn void Draw_Mesh(const size_t pMesh_Index)
|
||||
/// Draw mesh.
|
||||
/// \param [in] pMesh_Index - index of mesh which must be drawn. Index point to mesh in \ref mHelper_Mesh.
|
||||
void Draw_Mesh(const size_t pMesh_Index);
|
||||
|
||||
/// \fn void Draw_BBox(const SBBox& pBBox)
|
||||
/// Draw bounding box using lines.
|
||||
/// \param [in] pBBox - bounding box for drawing.
|
||||
void Draw_BBox(const SBBox& pBBox);
|
||||
|
||||
/********************************************************************/
|
||||
/*********************** Overrided functions ************************/
|
||||
/********************************************************************/
|
||||
|
||||
protected:
|
||||
|
||||
/// \fn void initializeGL() override
|
||||
/// Overrided function for initialise OpenGL.
|
||||
void initializeGL() override;
|
||||
|
||||
/// \fn void resizeGL(int pWidth, int pHeight) override
|
||||
/// \param [in] pWidth - new width of viewport.
|
||||
/// \param [in] pHeight - new height of viewport.
|
||||
void resizeGL(int pWidth, int pHeight) override;
|
||||
|
||||
/// \fn void paintGL() override
|
||||
/// Overrided function for rendering.
|
||||
void paintGL() override;
|
||||
|
||||
public:
|
||||
|
||||
/********************************************************************/
|
||||
/********************** Constructor/Destructor **********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn explicit CGLView(QWidget* pParent)
|
||||
/// Constructor.
|
||||
/// \param [in] pParent - parent widget.
|
||||
explicit CGLView(QWidget* pParent);
|
||||
|
||||
/// \fn virtual ~CGLView()
|
||||
/// Destructor.
|
||||
virtual ~CGLView();
|
||||
|
||||
/********************************************************************/
|
||||
/********************* Scene control functions **********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void FreeScene()
|
||||
/// Free all helper objects data.
|
||||
void FreeScene();
|
||||
|
||||
/// \fn void SetScene(const aiScene* pScene)
|
||||
/// Set scene for rendering.
|
||||
/// \param [in] pScene - pointer to scene.
|
||||
/// \param [in] pScenePath - path to the file of the scene.
|
||||
void SetScene(const aiScene* pScene, const QString& pScenePath);
|
||||
|
||||
/// \fn void Enable_SceneBBox(const bool pEnable)
|
||||
/// Enable drawing scene bounding box.
|
||||
/// \param [in] pEnable - if true then bbox will be drawing, if false - will not be drawing.
|
||||
void Enable_SceneBBox(const bool pEnable) { mScene_DrawBBox = pEnable; }
|
||||
|
||||
/// \fn void Enable_Textures(const bool pEnable)
|
||||
/// Control textures drawing.
|
||||
/// \param [in] pEnable - if true then enable textures, false - disable textures.
|
||||
void Enable_Textures(const bool pEnable);
|
||||
|
||||
/********************************************************************/
|
||||
/******************** Lighting control functions ********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void Lighting_Enable()
|
||||
/// Enable OpenGL lighting.
|
||||
void Lighting_Enable();
|
||||
|
||||
/// \fn void Lighting_Disable()
|
||||
/// Disable OpenGL lighting.
|
||||
void Lighting_Disable();
|
||||
|
||||
/// \fn void Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
|
||||
/// Edit light source properties.
|
||||
/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
|
||||
/// \param [in] pLightParameters - light source parameters.
|
||||
void Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters);///TODO: function set
|
||||
|
||||
/// \fn void Lighting_EnableSource(const size_t pLightNumber)
|
||||
/// Enable light source.
|
||||
/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
|
||||
void Lighting_EnableSource(const size_t pLightNumber);
|
||||
|
||||
///void Lighting_DisableSource(const size_t pLightNumber)
|
||||
/// Disable light source,
|
||||
/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
|
||||
void Lighting_DisableSource(const size_t pLightNumber);
|
||||
|
||||
/********************************************************************/
|
||||
/******************** Cameras control functions *********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void Camera_Set(const size_t pCameraNumber)
|
||||
/// Set view from pointed camera.
|
||||
/// \param [in] pCamera_Index - index of the camera (\ref aiScene::mCameras).
|
||||
void Camera_Set(const size_t pCameraNumber);
|
||||
|
||||
/// \fn void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z)
|
||||
/// Rotate scene around axisees.
|
||||
/// \param [in] pAngle_X - specifies the angle of rotation around axis oX, in degrees.
|
||||
/// \param [in] pAngle_Y - specifies the angle of rotation around axis oY, in degrees.
|
||||
/// \param [in] pAngle_Z - specifies the angle of rotation around axis oZ, in degrees.
|
||||
void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z);
|
||||
|
||||
/// \fn void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z)
|
||||
/// Rotate camera around axisees.
|
||||
/// \param [in] pAngle_X - specifies the angle of rotation around axis oX, in degrees.
|
||||
/// \param [in] pAngle_Y - specifies the angle of rotation around axis oY, in degrees.
|
||||
/// \param [in] pAngle_Z - specifies the angle of rotation around axis oZ, in degrees.
|
||||
void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z);
|
||||
|
||||
/// \fn void Camera_Translate(const size_t pTranslate_X, const size_t pTranslate_Y, const size_t pTranslate_Z)
|
||||
/// Translate camera along axises. In local coordinates.
|
||||
/// \param [in] pTranslate_X - specifies the X coordinate of translation vector.
|
||||
/// \param [in] pTranslate_Y - specifies the Y coordinate of translation vector.
|
||||
/// \param [in] pTranslate_Z - specifies the Z coordinate of translation vector.
|
||||
void Camera_Translate(const GLfloat pTranslate_X, const GLfloat pTranslate_Y, const GLfloat pTranslate_Z);
|
||||
|
||||
signals:
|
||||
|
||||
/// \fn void Paint_Finished(const size_t pPaintTime, const GLfloat pDistance)
|
||||
///< Signal. Emits when execution of \ref paintGL is end.
|
||||
/// \param [out] pPaintTime_ms - time spent for rendering, in milliseconds.
|
||||
/// \param [out] pDistance - distance between current camera and center of the scene. \sa SHelper_Camera::Translation_ToScene.
|
||||
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
|
||||
|
||||
/// \fn void SceneObject_Camera(const QString& pName)
|
||||
/// Signal. Emit for every camera found in scene. Also for default camera.
|
||||
/// \param [out] pName - name of the camera.
|
||||
void SceneObject_Camera(const QString& pName);
|
||||
|
||||
/// \fn void SceneObject_LightSource(const QString& pName)
|
||||
/// Signal. Emit for every light source found in scene. Also for default light source.
|
||||
/// \param [out] pName - name of the light source.
|
||||
void SceneObject_LightSource(const QString& pName);
|
||||
};// class CGLView
|
|
@ -0,0 +1,19 @@
|
|||
/// \file loggerview.cpp
|
||||
/// \brief Stream for Assimp logging subsystem.
|
||||
/// \author smal.root@gmail.com
|
||||
/// \date 2016
|
||||
|
||||
#include "loggerview.hpp"
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QTime>
|
||||
|
||||
CLoggerView::CLoggerView(QTextBrowser* pOutputWidget)
|
||||
: mOutputWidget(pOutputWidget)
|
||||
{
|
||||
}
|
||||
|
||||
void CLoggerView::write(const char *pMessage)
|
||||
{
|
||||
mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage));
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/// \file loggerview.hpp
|
||||
/// \brief Stream for Assimp logging subsystem.
|
||||
/// \author smal.root@gmail.com
|
||||
/// \date 2016
|
||||
|
||||
#pragma once
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QTextBrowser>
|
||||
|
||||
// Header files, Assimp.
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
/// \class CLoggerView
|
||||
/// GUI-stream for Assimp logging subsytem. Get data for logging and write it to output widget.
|
||||
class CLoggerView final : public Assimp::LogStream
|
||||
{
|
||||
private:
|
||||
|
||||
QTextBrowser* mOutputWidget;///< Widget for displaying messages.
|
||||
|
||||
public:
|
||||
|
||||
/// \fn explicit CLoggerView(QTextBrowser* pOutputWidget)
|
||||
/// Constructor.
|
||||
/// \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.
|
||||
/// \param [in] pMessage - message for displaying.
|
||||
virtual void write(const char *pMessage);
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
/// \file main.cpp
|
||||
/// \brief Start-up file which contain function "main".
|
||||
/// \author smal.root@gmail.com
|
||||
/// \date 2016
|
||||
// Thanks to acorn89 for support.
|
||||
|
||||
// Header files, project.
|
||||
#include "mainwindow.hpp"
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w;
|
||||
|
||||
w.show();
|
||||
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,344 @@
|
|||
/// \file mainwindow.hpp
|
||||
/// \brief Main window and algorhytms.
|
||||
/// \author smal.root@gmail.com
|
||||
/// \date 2016
|
||||
|
||||
#include "mainwindow.hpp"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
// Header files, Assimp.
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#ifndef __unused
|
||||
#define __unused __attribute__((unused))
|
||||
#endif // __unused
|
||||
|
||||
/**********************************/
|
||||
/************ Functions ***********/
|
||||
/**********************************/
|
||||
|
||||
/********************************************************************/
|
||||
/********************* Import/Export functions **********************/
|
||||
/********************************************************************/
|
||||
|
||||
void MainWindow::ImportFile(const QString &pFileName)
|
||||
{
|
||||
using namespace Assimp;
|
||||
|
||||
QTime time_begin = QTime::currentTime();
|
||||
|
||||
if(mScene != nullptr)
|
||||
{
|
||||
mImporter.FreeScene();
|
||||
mGLView->FreeScene();
|
||||
}
|
||||
|
||||
// Try to import scene.
|
||||
mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
|
||||
aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
|
||||
if(mScene != nullptr)
|
||||
{
|
||||
ui->lblLoadTime->setText(QString("%1").arg(time_begin.secsTo(QTime::currentTime())));
|
||||
LogInfo("Import done: " + pFileName);
|
||||
// Prepare widgets for new scene.
|
||||
ui->leFileName->setText(pFileName.right(pFileName.length() - pFileName.lastIndexOf('/') - 1));
|
||||
ui->lstLight->clear();
|
||||
ui->lstCamera->clear();
|
||||
ui->cbxLighting->setChecked(true), mGLView->Lighting_Enable();
|
||||
ui->cbxBBox->setChecked(false); mGLView->Enable_SceneBBox(false);
|
||||
ui->cbxTextures->setChecked(true), mGLView->Enable_Textures(true);
|
||||
//
|
||||
// Fill info labels
|
||||
//
|
||||
// Cameras
|
||||
ui->lblCameraCount->setText(QString("%1").arg(mScene->mNumCameras));
|
||||
// Lights
|
||||
ui->lblLightCount->setText(QString("%1").arg(mScene->mNumLights));
|
||||
// Meshes, faces, vertices.
|
||||
size_t qty_face = 0;
|
||||
size_t qty_vert = 0;
|
||||
|
||||
for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++)
|
||||
{
|
||||
qty_face += mScene->mMeshes[idx_mesh]->mNumFaces;
|
||||
qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices;
|
||||
}
|
||||
|
||||
ui->lblMeshCount->setText(QString("%1").arg(mScene->mNumMeshes));
|
||||
ui->lblFaceCount->setText(QString("%1").arg(qty_face));
|
||||
ui->lblVertexCount->setText(QString("%1").arg(qty_vert));
|
||||
// Animation
|
||||
if(mScene->mNumAnimations)
|
||||
ui->lblHasAnimation->setText("yes");
|
||||
else
|
||||
ui->lblHasAnimation->setText("no");
|
||||
|
||||
//
|
||||
// Set scene for GL viewer.
|
||||
//
|
||||
mGLView->SetScene(mScene, pFileName);
|
||||
// Select first camera
|
||||
ui->lstCamera->setCurrentRow(0);
|
||||
mGLView->Camera_Set(0);
|
||||
// Scene is loaded, do first rendering.
|
||||
LogInfo("Scene is ready for rendering.");
|
||||
mGLView->updateGL();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->lblLoadTime->clear();
|
||||
LogError(QString("Error parsing \'%1\' : \'%2\'").arg(pFileName).arg(mImporter.GetErrorString()));
|
||||
}// if(mScene != nullptr)
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/************************ Logging functions *************************/
|
||||
/********************************************************************/
|
||||
|
||||
void MainWindow::LogInfo(const QString& pMessage)
|
||||
{
|
||||
Assimp::DefaultLogger::get()->info(pMessage.toStdString());
|
||||
}
|
||||
|
||||
void MainWindow::LogError(const QString& pMessage)
|
||||
{
|
||||
Assimp::DefaultLogger::get()->error(pMessage.toStdString());
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/*********************** Overrided functions ************************/
|
||||
/********************************************************************/
|
||||
|
||||
void MainWindow::mousePressEvent(QMouseEvent* pEvent)
|
||||
{
|
||||
if(pEvent->button() & Qt::LeftButton)
|
||||
mPosition_Pressed_LMB = pEvent->pos();
|
||||
else if(pEvent->button() & Qt::RightButton)
|
||||
mPosition_Pressed_RMB = pEvent->pos();
|
||||
}
|
||||
|
||||
void MainWindow::mouseMoveEvent(QMouseEvent* pEvent)
|
||||
{
|
||||
if(pEvent->buttons() & Qt::LeftButton)
|
||||
{
|
||||
GLfloat dx = 180 * GLfloat(pEvent->x() - mPosition_Pressed_LMB.x()) / mGLView->width();
|
||||
GLfloat dy = 180 * GLfloat(pEvent->y() - mPosition_Pressed_LMB.y()) / mGLView->height();
|
||||
|
||||
if(pEvent->modifiers() & Qt::ShiftModifier)
|
||||
mGLView->Camera_RotateScene(dy, 0, dx);// Rotate around oX and oZ axises.
|
||||
else
|
||||
mGLView->Camera_RotateScene(dy, dx, 0);// Rotate around oX and oY axises.
|
||||
|
||||
mGLView->updateGL();
|
||||
mPosition_Pressed_LMB = pEvent->pos();
|
||||
}
|
||||
|
||||
if(pEvent->buttons() & Qt::RightButton)
|
||||
{
|
||||
GLfloat dx = 180 * GLfloat(pEvent->x() - mPosition_Pressed_RMB.x()) / mGLView->width();
|
||||
GLfloat dy = 180 * GLfloat(pEvent->y() - mPosition_Pressed_RMB.y()) / mGLView->height();
|
||||
|
||||
if(pEvent->modifiers() & Qt::ShiftModifier)
|
||||
mGLView->Camera_Rotate(dy, 0, dx);// Rotate around oX and oZ axises.
|
||||
else
|
||||
mGLView->Camera_Rotate(dy, dx, 0);// Rotate around oX and oY axises.
|
||||
|
||||
mGLView->updateGL();
|
||||
mPosition_Pressed_RMB = pEvent->pos();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::keyPressEvent(QKeyEvent* pEvent)
|
||||
{
|
||||
GLfloat step;
|
||||
|
||||
if(pEvent->modifiers() & Qt::ControlModifier)
|
||||
step = 10;
|
||||
else if(pEvent->modifiers() & Qt::AltModifier)
|
||||
step = 100;
|
||||
else
|
||||
step = 1;
|
||||
|
||||
if(pEvent->key() == Qt::Key_A)
|
||||
mGLView->Camera_Translate(-step, 0, 0);
|
||||
else if(pEvent->key() == Qt::Key_D)
|
||||
mGLView->Camera_Translate(step, 0, 0);
|
||||
else if(pEvent->key() == Qt::Key_W)
|
||||
mGLView->Camera_Translate(0, step, 0);
|
||||
else if(pEvent->key() == Qt::Key_S)
|
||||
mGLView->Camera_Translate(0, -step, 0);
|
||||
else if(pEvent->key() == Qt::Key_Up)
|
||||
mGLView->Camera_Translate(0, 0, -step);
|
||||
else if(pEvent->key() == Qt::Key_Down)
|
||||
mGLView->Camera_Translate(0, 0, step);
|
||||
|
||||
mGLView->updateGL();
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/********************** Constructor/Destructor **********************/
|
||||
/********************************************************************/
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), ui(new Ui::MainWindow),
|
||||
mScene(nullptr)
|
||||
{
|
||||
using namespace Assimp;
|
||||
|
||||
ui->setupUi(this);
|
||||
// Create OpenGL widget
|
||||
mGLView = new CGLView(this);
|
||||
mGLView->setMinimumSize(800, 600);
|
||||
mGLView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
|
||||
mGLView->setFocusPolicy(Qt::StrongFocus);
|
||||
// Connect to GLView signals.
|
||||
connect(mGLView, SIGNAL(Paint_Finished(size_t, GLfloat)), SLOT(Paint_Finished(size_t, GLfloat)));
|
||||
connect(mGLView, SIGNAL(SceneObject_Camera(QString)), SLOT(SceneObject_Camera(QString)));
|
||||
connect(mGLView, SIGNAL(SceneObject_LightSource(QString)), SLOT(SceneObject_LightSource(QString)));
|
||||
// and add it to layout
|
||||
ui->hlMainView->insertWidget(0, mGLView, 4);
|
||||
// Create logger
|
||||
mLoggerView = new CLoggerView(ui->tbLog);
|
||||
DefaultLogger::create("", Logger::VERBOSE);
|
||||
DefaultLogger::get()->attachStream(mLoggerView, DefaultLogger::Debugging | DefaultLogger::Info | DefaultLogger::Err | DefaultLogger::Warn);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
using namespace Assimp;
|
||||
|
||||
DefaultLogger::get()->detatchStream(mLoggerView, DefaultLogger::Debugging | DefaultLogger::Info | DefaultLogger::Err | DefaultLogger::Warn);
|
||||
DefaultLogger::kill();
|
||||
|
||||
if(mScene != nullptr) mImporter.FreeScene();
|
||||
if(mLoggerView != nullptr) delete mLoggerView;
|
||||
if(mGLView != nullptr) delete mGLView;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/****************************** Slots *******************************/
|
||||
/********************************************************************/
|
||||
|
||||
void MainWindow::Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance)
|
||||
{
|
||||
ui->lblRenderTime->setText(QString("%1").arg(pPaintTime_ms));
|
||||
ui->lblDistance->setText(QString("%1").arg(pDistance));
|
||||
}
|
||||
|
||||
void MainWindow::SceneObject_Camera(const QString& pName)
|
||||
{
|
||||
ui->lstCamera->addItem(pName);
|
||||
}
|
||||
|
||||
void MainWindow::SceneObject_LightSource(const QString& pName)
|
||||
{
|
||||
ui->lstLight->addItem(pName);
|
||||
// After item added "currentRow" is still contain old value (even '-1' if first item added). Because "currentRow"/"currentItem" is changed by user interaction,
|
||||
// not by "addItem". So, "currentRow" must be set manually.
|
||||
ui->lstLight->setCurrentRow(ui->lstLight->count() - 1);
|
||||
// And after "selectAll" handler of "signal itemSelectionChanged" will get right "currentItem" and "currentRow" values.
|
||||
ui->lstLight->selectAll();
|
||||
}
|
||||
|
||||
void MainWindow::on_butOpenFile_clicked()
|
||||
{
|
||||
aiString filter_temp;
|
||||
QString filename, filter;
|
||||
|
||||
mImporter.GetExtensionList(filter_temp);
|
||||
filter = filter_temp.C_Str();
|
||||
filter.replace(';', ' ');
|
||||
filter.append(" ;; All (*.*)");
|
||||
filename = QFileDialog::getOpenFileName(this, "Choose the file", "", filter);
|
||||
|
||||
if(!filename.isEmpty()) ImportFile(filename);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_butExport_clicked()
|
||||
{
|
||||
using namespace Assimp;
|
||||
|
||||
QString filename, filter, format_id;
|
||||
Exporter exporter;
|
||||
QTime time_begin;
|
||||
aiReturn rv;
|
||||
|
||||
if(mScene == nullptr)
|
||||
{
|
||||
QMessageBox::critical(this, "Export error", "Scene is empty");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// build filter
|
||||
{
|
||||
aiString filter_temp;
|
||||
|
||||
mImporter.GetExtensionList(filter_temp);
|
||||
filter = filter_temp.C_Str();
|
||||
filter.replace(';', ' ');
|
||||
}
|
||||
|
||||
// get file path
|
||||
filename = QFileDialog::getSaveFileName(this, "Set file name", "", filter);
|
||||
// extract format ID
|
||||
format_id = filename.right(filename.length() - filename.lastIndexOf('.') - 1);
|
||||
if(format_id.isEmpty())
|
||||
{
|
||||
QMessageBox::critical(this, "Export error", "File name must has extension.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// begin export
|
||||
time_begin = QTime::currentTime();
|
||||
rv = exporter.Export(mScene, format_id.toLocal8Bit(), filename.toLocal8Bit());
|
||||
ui->lblExportTime->setText(QString("%1").arg(time_begin.secsTo(QTime::currentTime())));
|
||||
if(rv == aiReturn_SUCCESS)
|
||||
LogInfo("Export done: " + filename);
|
||||
else
|
||||
LogError("Export failed: " + filename);
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxLighting_clicked(bool pChecked)
|
||||
{
|
||||
if(pChecked)
|
||||
mGLView->Lighting_Enable();
|
||||
else
|
||||
mGLView->Lighting_Disable();
|
||||
|
||||
mGLView->updateGL();
|
||||
}
|
||||
|
||||
void MainWindow::on_lstLight_itemSelectionChanged()
|
||||
{
|
||||
bool selected = ui->lstLight->isItemSelected(ui->lstLight->currentItem());
|
||||
|
||||
if(selected)
|
||||
mGLView->Lighting_EnableSource(ui->lstLight->currentRow());
|
||||
else
|
||||
mGLView->Lighting_DisableSource(ui->lstLight->currentRow());
|
||||
|
||||
mGLView->updateGL();
|
||||
}
|
||||
|
||||
void MainWindow::on_lstCamera_clicked(__unused const QModelIndex &index)
|
||||
{
|
||||
mGLView->Camera_Set(ui->lstLight->currentRow());
|
||||
mGLView->updateGL();
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxBBox_clicked(bool checked)
|
||||
{
|
||||
mGLView->Enable_SceneBBox(checked);
|
||||
mGLView->updateGL();
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxTextures_clicked(bool checked)
|
||||
{
|
||||
mGLView->Enable_Textures(checked);
|
||||
mGLView->updateGL();
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/// \file mainwindow.hpp
|
||||
/// \brief Main window and algorhytms.
|
||||
/// \author smal.root@gmail.com
|
||||
/// \date 2016
|
||||
|
||||
#pragma once
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QMainWindow>
|
||||
|
||||
// Header files, project.
|
||||
#include "glview.hpp"
|
||||
#include "loggerview.hpp"
|
||||
|
||||
// Header files, Assimp.
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
|
||||
namespace Ui { class MainWindow; }
|
||||
|
||||
/// \class MainWindow
|
||||
/// Main window and algorhytms.
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/**********************************/
|
||||
/************ Variables ***********/
|
||||
/**********************************/
|
||||
|
||||
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).
|
||||
QPoint mPosition_Pressed_LMB;///< Position where was pressed left mouse button.
|
||||
QPoint mPosition_Pressed_RMB;///< Position where was pressed right mouse button.
|
||||
|
||||
/**********************************/
|
||||
/************ Functions ***********/
|
||||
/**********************************/
|
||||
|
||||
/********************************************************************/
|
||||
/********************* Import/Export functions **********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void ImportFile(const QString& pFileName)
|
||||
/// Import scene from file.
|
||||
/// \param [in] pFileName - path and name of the file.
|
||||
void ImportFile(const QString& pFileName);
|
||||
|
||||
/********************************************************************/
|
||||
/************************ Logging functions *************************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void LogInfo(const QString& pMessage)
|
||||
/// Add message with severity "Warning" to log.
|
||||
void LogInfo(const QString& pMessage);
|
||||
|
||||
/// \fn void LogError(const QString& pMessage)
|
||||
/// Add message with severity "Error" to log.
|
||||
void LogError(const QString& pMessage);
|
||||
|
||||
/********************************************************************/
|
||||
/*********************** Overrided functions ************************/
|
||||
/********************************************************************/
|
||||
|
||||
protected:
|
||||
|
||||
/// \fn void mousePressEvent(QMouseEvent* pEvent) override
|
||||
/// Overrided function which handle mouse event "button pressed".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
void mousePressEvent(QMouseEvent* pEvent) override;
|
||||
|
||||
/// \fn void mouseMoveEvent(QMouseEvent* pEvent) override
|
||||
/// Overrided function which handle mouse event "move".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
void mouseMoveEvent(QMouseEvent* pEvent) override;
|
||||
|
||||
/// \fn void keyPressEvent(QKeyEvent* pEvent) override
|
||||
/// Overrided function which handle key event "key pressed".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
void keyPressEvent(QKeyEvent* pEvent) override;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/********************************************************************/
|
||||
/********************** Constructor/Destructor **********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn explicit MainWindow(QWidget* pParent = 0)
|
||||
/// \param [in] pParent - pointer to parent widget.
|
||||
explicit MainWindow(QWidget* pParent = 0);
|
||||
|
||||
/// \fn ~MainWindow()
|
||||
/// Destructor.
|
||||
~MainWindow();
|
||||
|
||||
/********************************************************************/
|
||||
/****************************** Slots *******************************/
|
||||
/********************************************************************/
|
||||
|
||||
private slots:
|
||||
|
||||
/// \fn void Paint_Finished(const int pPaintTime)
|
||||
/// Show paint/render time and distance between camera and center of the scene.
|
||||
/// \param [in] pPaintTime_ms - paint time in milliseconds.
|
||||
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
|
||||
|
||||
/// \fn void SceneObject_Camera(const QString& pName)
|
||||
/// Add camera name to list.
|
||||
/// \param [in] pName - name of the camera.
|
||||
void SceneObject_Camera(const QString& pName);
|
||||
|
||||
/// \fn void SceneObject_LightSource(const QString& pName)
|
||||
/// Add lighting source name to list.
|
||||
/// \param [in] pName - name of the light source,
|
||||
void SceneObject_LightSource(const QString& pName);
|
||||
|
||||
void on_butOpenFile_clicked();
|
||||
void on_butExport_clicked();
|
||||
void on_cbxLighting_clicked(bool pChecked);
|
||||
void on_lstLight_itemSelectionChanged();
|
||||
void on_lstCamera_clicked(const QModelIndex &index);
|
||||
void on_cbxBBox_clicked(bool checked);
|
||||
void on_cbxTextures_clicked(bool checked);
|
||||
};
|
|
@ -0,0 +1,516 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>641</width>
|
||||
<height>734</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="5,1">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="hlMainView" stretch="0">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="grpFile">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="butOpenFile">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblFileName_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="leFileName">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>160</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblLoadTime_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load time, s</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblLoadTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="butExport">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Export</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="lblExportTime_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Export time, s</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="lblExportTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="grpInfo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblRenderTime_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Render time, ms</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblRenderTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblMeshCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Meshes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblFaceCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Faces</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblMeshCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblFaceCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblVertexCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Vertices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="lblVertexCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lblLightCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lights</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lblCameraCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cameras</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="lblHasAnimation_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Animation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="lblShaderCount_Label">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shaders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="lblLightCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="lblCameraCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="lblShaderCount">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="lblHasAnimation">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="lblDistance_Label">
|
||||
<property name="text">
|
||||
<string>Distance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="lblDistance">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="grpDynamics">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Dynamics</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="butAnimationStart">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Animation start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="butAnimationStop">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Animation stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabInfoAndControl">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Log</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextBrowser" name="tbLog">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Lights and cameras</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QListWidget" name="lstLight">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Light sources of the scene</string>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::SelectedClicked</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="lstCamera">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Cameras of the scene</string>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Control</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="cbxLighting">
|
||||
<property name="toolTip">
|
||||
<string>Enable/Disable OpenGL lighting</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lighting</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="cbxBBox">
|
||||
<property name="text">
|
||||
<string>Scene BBox</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="cbxTextures">
|
||||
<property name="text">
|
||||
<string>Textures</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -62,6 +62,7 @@ ADD_EXECUTABLE( assimp_viewer WIN32
|
|||
Normals.cpp
|
||||
SceneAnimator.cpp
|
||||
Shaders.cpp
|
||||
assimp_view.h
|
||||
assimp_view.cpp
|
||||
stdafx.cpp
|
||||
assimp_view.rc
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2015, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -160,7 +160,6 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
|
|||
|
||||
// Call ASSIMPs C-API to load the file
|
||||
g_pcAsset->pcScene = (aiScene*)aiImportFileExWithProperties(g_szFileName,
|
||||
|
||||
ppsteps | /* configurable pp steps */
|
||||
aiProcess_GenSmoothNormals | // generate smooth normal vectors if not existing
|
||||
aiProcess_SplitLargeMeshes | // split large, unrenderable meshes into submeshes
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2012, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -71,14 +71,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "../../code/MaterialSystem.h" // aiMaterial class
|
||||
#include "../../code/StringComparison.h" // ASSIMP_stricmp and ASSIMP_strincmp
|
||||
|
||||
// in order for std::min and std::max to behave properly
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif // max
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif // min
|
||||
|
||||
#include <time.h>
|
||||
|
||||
// default movement speed
|
||||
|
|
Loading…
Reference in New Issue