Merge branch 'master' into make_tools
commit
a2a7877939
|
@ -12,6 +12,8 @@ build
|
|||
bin/
|
||||
lib/
|
||||
|
||||
# QtCreator
|
||||
CMakeLists.txt.user
|
||||
|
||||
# Generated
|
||||
assimp.pc
|
||||
|
@ -38,6 +40,7 @@ tools/assimp_cmd/Makefile
|
|||
|
||||
# Tests
|
||||
test/results
|
||||
test/readlinetest*
|
||||
|
||||
# Python
|
||||
__pycache__
|
||||
|
|
258
CHANGES
258
CHANGES
|
@ -1,6 +1,264 @@
|
|||
----------------------------------------------------------------------
|
||||
CHANGELOG
|
||||
----------------------------------------------------------------------
|
||||
4.1.0 (2017-12):
|
||||
- FEATURES:
|
||||
- Export 3MF ( experimental )
|
||||
- Import / Export glTF 2
|
||||
- Introduce new zib-lib to eb able to export zip-archives
|
||||
- FIXES/HOUSEKEEPING:
|
||||
- Added missing include to stdlib.h and remove load library call
|
||||
- Fix install for builds with MSVC compiler and NMake.
|
||||
- Update list of supported file formats.
|
||||
- Add TriLib to the official list of supported ports.
|
||||
- Re-enabling PACK_STRUCT for MDL files.
|
||||
- Use std.::unique_ptr
|
||||
- Update D3MFExporter.h
|
||||
- Update MD3Loader.cpp, using index
|
||||
- Fix all warnings on MSVC14
|
||||
- Copy assimp dll to unit folder on windows
|
||||
- Update jvm port supported formats
|
||||
- Add support for building Mac OS X Framework bundles
|
||||
- Check for nullptr dereferencing before copying scene data
|
||||
- Update ValidateDataStructure.h, typo
|
||||
- Enable data structure validation in cases where it doesn't cause failures
|
||||
- Remove some dead assignments
|
||||
- fast_atof: Silence some uninitialized variable warnings
|
||||
- Check for area test if the face is a triangle.
|
||||
- Set mNumUVComponents to 0 when deleting texture coordinate sets
|
||||
- Only scale the root node because this will rescale all children nodes as well.
|
||||
- Issue 1514: Fix frame pointer arithmetic
|
||||
- Prevent failing stringstream to crash the export process
|
||||
- powf -> pow
|
||||
- add Defines.h to include folder for install.
|
||||
- Android:
|
||||
- Fix android build
|
||||
- Fix assimp for cross compile for android
|
||||
- Use define for D_FILE_OFFSET_BITS only for not-android systems.
|
||||
- FBX:
|
||||
- Fix handling with embedded textures
|
||||
- FBX 7500 Binary reading
|
||||
- Remove dead assignment
|
||||
- Fix export of deleted meshes; Add LazyDict::Remove method
|
||||
- Log an error instead of letting the fbx-importer crash. ( issue 213 )
|
||||
- Replace bad pointer casting with memcpy
|
||||
- Remove useless const qualifier from return value
|
||||
- Add explicit instantiation of log_prefix so other FBX source files can see it
|
||||
- add missing inversion of postrotation matrix for fbx.
|
||||
- FIReader: Silence uninitialized variable warning
|
||||
- Update version check in FBX reader to check for version >= 7500
|
||||
- Use actual min/max of anim keys when start/stop time is missing
|
||||
- GLTF1:
|
||||
- Fix output of glTF 1 version string
|
||||
- Fix delete / delete[] mismatch in glTFAsset
|
||||
- Don’t ignore rgba(1,1,1,1) color properties
|
||||
- glTF2 primitives fixes
|
||||
- Don’t ignore rgba(1,1,1,1) color properties
|
||||
- Fix delete / delete[] mismatch in glTFAsset
|
||||
- Remove KHR_binary_glTF code
|
||||
- glTF nodes can only hold one mesh. this simply assigns to and check’s a Node’s Mesh
|
||||
- version in glb header is stored as uint32_t
|
||||
- GLTF2:
|
||||
- node name conflict fix
|
||||
- Fix transform matrices multiplication order
|
||||
- Preserve node names when importing
|
||||
- Add support for tangents in import
|
||||
- Fix typo on gltf2 camera parameters
|
||||
- Moved byteStride from accessor to bufferView
|
||||
- Implemented reading binary glTF2 (glb) files
|
||||
- Fix signed/unsigned warning
|
||||
- Add postprocess step for scaling
|
||||
- Fix shininess to roughness conversion
|
||||
- Prefer “BLEND” over “MASK” as an alphaMode default
|
||||
- Approximate specularity / glossiness in metallicRoughness materials
|
||||
- Diffuse color and diffuse texture import and export improvements
|
||||
- Addressed some mismatched news/deletes caused by the new glTF2 sources.
|
||||
- Fix delete / delete[] mismatches in glTF2 importer
|
||||
- use correct name of exporter to gltf2
|
||||
- Fix possible infinite loop when exporting to gltf2
|
||||
- Fix glTF2::Asset::FindUniqueID() when the input string is >= 256 chars
|
||||
- Fix glTF2 alphaMode storage and reading
|
||||
- Fix glTF 2.0 multi-primitive support
|
||||
- Load gltf .bin files from correct directory
|
||||
- Add support for importing both glTF and glTF2 files
|
||||
- ampler improvements; Add new LazyDict method
|
||||
- Changes to GLTF2 materials
|
||||
- Remove Light, Technique references
|
||||
- Start removing materials common, and adding pbrSpecularGlossiness
|
||||
- Use !ObjectEmpty() vs. MemberCount() > 0
|
||||
- Working read, import, export, and write of gltf2 (pbr) material
|
||||
- Check in gltf2 models to test directory
|
||||
- Remove un-needed test models
|
||||
- Start managing and importing gltf2 pbr materials
|
||||
- Update glTF2 Asset to use indexes
|
||||
- Duplicate gltfImporter as gltf2Importer; Include glTF2 importer in CMake List
|
||||
- glTF2: Fix animation export
|
||||
- use opacity for diffuse alpha + alphaMode
|
||||
- STL:
|
||||
- Restore import of multi mesh binary STLs
|
||||
- Blender:
|
||||
- Silence warning about uninitialized member
|
||||
- MDLImporter:
|
||||
- Don't take address of packed struct member
|
||||
- assimp_cmd:
|
||||
- Fix strict-aliasing warnings
|
||||
- Open3DGC:
|
||||
- Fix strict-aliasing warnings
|
||||
- Add assertions to silence static analyzer warnings
|
||||
- Remove redundant const qualifiers from return types
|
||||
- Fix some uninitialized variable warnings
|
||||
- Remove OPEN3DGC and compression references
|
||||
- unzip:
|
||||
- Remove dead assignment
|
||||
- Bail on bad compression method
|
||||
- Fix possibly uninitialized variables
|
||||
- clipper:
|
||||
- Add assertion to silence a static analyzer warning
|
||||
- OpenDDLExport:
|
||||
- Reduce scope of a variable
|
||||
- Remove dead variable
|
||||
- Remove dead assignment
|
||||
- Fix another potential memory leak
|
||||
- X3DImporter:
|
||||
- Add assertions to silence static analyzer warnings
|
||||
- Add missing unittest
|
||||
- Workaround for buggy Android NDK (issue #1361)
|
||||
- TerragenLoader:
|
||||
- Remove unused variable
|
||||
- SIBImporter:
|
||||
- Add assertions to silence static analyzer warnings
|
||||
- IFC:
|
||||
- Remove dead code
|
||||
- Add explicit instantiation of log_prefix so IFCMaterial.cpp can see it
|
||||
- PLY:
|
||||
- Remove dead assignment and reduce scope of a variable
|
||||
- fix vertex attribute lookup.
|
||||
- OpenGEX:
|
||||
- Add assertion to silence a static analyzer warning
|
||||
- Fix for TextureFile with number in file name
|
||||
- Return early when element is TextureFile
|
||||
- NFF:
|
||||
- Add assertions to silence static analyzer warnings
|
||||
- Split up some complicated assignments
|
||||
- Raw: Fix misleading indentation warning
|
||||
- Reduce scope of a variable
|
||||
- LWO
|
||||
- Reduce scope of a variable
|
||||
- IRRLoader:
|
||||
- Fix confusing boolean casting
|
||||
- AssbinExporter:
|
||||
- Add assertion to silence a static analyzer warning
|
||||
- ASE:
|
||||
- Add assertion to silence a static analyzer warning
|
||||
- AMFImporter:
|
||||
- Add assertion to silence a static analyzer warning
|
||||
- Add a block
|
||||
- OptimizeGraph:
|
||||
- Fix possible null pointer dereference
|
||||
- RemoveRedundantMaterials:
|
||||
- Add assertion to silence a static analyzer warning
|
||||
- ImproveCacheLocality:
|
||||
- Add assertion to silence a static analyzer warning
|
||||
- RemoveRedundantMaterials:
|
||||
- Set pointer to nullptr after deleting it
|
||||
- Travis:
|
||||
- Disable unit tests in scan-build config
|
||||
- Move slower builds earlier to improve parallelization
|
||||
- Add static analysis to build
|
||||
- Remove unused branch rule for travis.
|
||||
- Add Clang UBSan build configuration
|
||||
- Treat warnings as errors, without typos this time
|
||||
- Unittests:
|
||||
- Add VS-based source groups for the unittests.
|
||||
- Collada:
|
||||
- export <library_animations> tag
|
||||
- Update ColladaExporter.cpp
|
||||
- Silence uninitialized variable warning
|
||||
- Add support for line strip primitives
|
||||
- Obj Wavefront:
|
||||
- check in exporting against out-of-bounds-access .
|
||||
- Issue 1351: use correct name for obj-meshname export for groups.
|
||||
- fix mem-lead: face will be not released in case of an error.
|
||||
- Anatoscope obj exporter nomtl
|
||||
- Raise exception when obj file contains invalid face indices
|
||||
- Added alternative displacement texture token in OBJ MTL material.
|
||||
- Obj: rename attribute from exporter.
|
||||
- Fix OBJ discarding all material names if the material library is missing
|
||||
- Step:
|
||||
- use correct lookup for utf32
|
||||
- MD2:
|
||||
- Fix MD2 frames containing garbage
|
||||
- STL
|
||||
- add missing const.
|
||||
- Fix memory-alignment bug.
|
||||
- Fix issue 104: deal with more solids in one STL file.
|
||||
- CMake
|
||||
- Fix issue 213: use correct include folder for assimp
|
||||
- Doxygen
|
||||
- Fix issue 1513: put irrXML onto exclucde list for doxygen run
|
||||
- PyAssimp:
|
||||
- Search for libassimp.so in LD_LIBRARY_PATH if available.
|
||||
- Fix operator precedence issue in header check
|
||||
- Split setup.py into multiple lines
|
||||
- Detect if Anaconda and fixed 3d_viewer for Python 3
|
||||
- created a python3 version of the 3dviewer and fixed the / = float in py3
|
||||
- Blender:
|
||||
- Fix invalid access to mesh array when the array is empty.
|
||||
- Fix short overflow.
|
||||
- Silence warning about inline function which is declared but not defined
|
||||
- JAssimp
|
||||
- Changed license header for IHMC contributions from Apache 2.0 to BSD
|
||||
- Add Node metadata to the Jassmip Java API
|
||||
- Added supported for custom IO Systems in Java. Implemented ClassLoader IO System
|
||||
- Added a link to pure jvm assimp port
|
||||
- Clang sanitizer:
|
||||
- Undefined Behavior sanitizer
|
||||
- Fixed a divide by zero error in IFCBoolean that was latent, but nevertheless a bug
|
||||
- B3DImporter:
|
||||
- Replace bad pointer casting with memcpy
|
||||
- AppVeyor:
|
||||
- Cleanup and Addition of VS 2017 and running Tests
|
||||
- Fixed File Size reported as 0 in tests that use temporary files
|
||||
- x86 isn't a valid VS platform. Win32 it is, then.
|
||||
- Replaced the worker image name, which doesn't work as generator name, with a manually created generator name.
|
||||
- Cleaned up appveyor setup, added VS 2017 to the build matrix and attempted to add running of tests.
|
||||
- Treat warnings as errors on Appveyor
|
||||
- Disable warning 4351 on MSVC 2013
|
||||
- OpenGEXImporter:
|
||||
- Copy materials to scene
|
||||
- Store RefInfo in unique_ptr so they get automatically cleaned up
|
||||
- Fix IOStream leak
|
||||
- Store ChildInfo in unique_ptr so they get automatically cleaned up
|
||||
- improve logging to be able to detect error-prone situations.
|
||||
- AMFImporter:
|
||||
- Fix memory leak
|
||||
- UnrealLoader:
|
||||
- Fix IOStream leak
|
||||
- Upgrade RapidJSON to get rid of a clang warning
|
||||
- zlib:
|
||||
- Update zlib contribution
|
||||
- Removed unnecessary files from zlib contribution
|
||||
- Replaced unsigned long for the crc table to z_crc_t, to match what is returned by get-crc_table
|
||||
- MakeVerboseFormat:
|
||||
- Fix delete / delete[] mismatches in MakeVerboseFormat
|
||||
- MaterialSystem:
|
||||
- Fix out-of-bounds read in MaterialSystem unit test
|
||||
- SIB:
|
||||
- Added support for SIB models from Silo 2.5
|
||||
- AssbinExporter:
|
||||
- Fix strict aliasing violation
|
||||
- Add Write specialization for aiColor3D
|
||||
- DefaultLogger:
|
||||
- Whitespace cleanup to fix GCC misleading indentation warning
|
||||
- MDP:
|
||||
- Fix encoding issues.
|
||||
- PreTransformVertices:
|
||||
- fix name lost in mesh and nodes when load with flag
|
||||
- C4D:
|
||||
- Fixes for C4D importer
|
||||
- Unzip:
|
||||
- Latest greatest.
|
||||
|
||||
4.0.1 (2017-07-28)
|
||||
- FIXES/HOUSEKEEPING:
|
||||
- fix version test.
|
||||
|
|
|
@ -412,32 +412,7 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
|||
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
|
||||
|
||||
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(Qt5Widgets QUIET)
|
||||
FIND_PACKAGE(DevIL QUIET)
|
||||
FIND_PACKAGE(OpenGL QUIET)
|
||||
IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
||||
ELSE()
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
|
||||
IF (NOT Qt5_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
|
||||
ENDIF (NOT Qt5_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 ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||
|
||||
IF ( ASSIMP_BUILD_SAMPLES)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#How to contribute
|
||||
|
||||
If you want to contribute you can follow these setps:
|
||||
- Fist create your own clone of assimp
|
||||
- When you want to fix a bug or add a new feature create a branch on your own fork ( just follow https://help.github.com/articles/creating-a-pull-request-from-a-fork/ )
|
||||
- Push it to the repo and open a pull request
|
||||
- A pull request will start our CI-service, which checks if the build works for linux and windows.
|
||||
It will check for memory leaks, compiler warnings and memory alignment issues. If any of these tests fails: fix it and the tests will be reastarted automatically
|
||||
- At the end we will perform a code review and merge your branch to the master branch.
|
||||
|
||||
|
|
@ -140,8 +140,6 @@ Open Asset Import Library is implemented in C++. The directory structure is:
|
|||
/tools Tools (old assimp viewer, command line `assimp`)
|
||||
/samples A small number of samples to illustrate possible
|
||||
use cases for Assimp
|
||||
/workspaces Build environments for vc,xcode,... (deprecated,
|
||||
CMake has superseeded all legacy build options!)
|
||||
|
||||
|
||||
### Where to get help ###
|
||||
|
|
|
@ -204,8 +204,9 @@ void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type)
|
|||
mat.AddProperty<ai_real>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
||||
|
||||
// Setup the texture mapping mode
|
||||
mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
|
||||
mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
|
||||
int mapMode = static_cast<int>(texture.mMapMode);
|
||||
mat.AddProperty<int>(&mapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
|
||||
mat.AddProperty<int>(&mapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
|
||||
|
||||
// Mirroring - double the scaling values
|
||||
// FIXME: this is not really correct ...
|
||||
|
@ -313,7 +314,8 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
|||
case D3DS::Discreet3DS::Blinn :
|
||||
eShading = aiShadingMode_Blinn; break;
|
||||
}
|
||||
mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
|
||||
int eShading_ = static_cast<int>(eShading);
|
||||
mat.AddProperty<int>(&eShading_, 1, AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
// DIFFUSE texture
|
||||
if( oldMat.sTexDiffuse.mMapName.length() > 0)
|
||||
|
|
|
@ -71,7 +71,7 @@ static const aiImporterDesc desc = {
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
"3ds prj 3DS PRJ"
|
||||
"3ds prj"
|
||||
};
|
||||
|
||||
|
||||
|
@ -127,7 +127,7 @@ Discreet3DSImporter::~Discreet3DSImporter() {
|
|||
// Returns whether the class can handle the format of the given file.
|
||||
bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
||||
std::string extension = GetExtension(pFile);
|
||||
if(extension == "3ds" || extension == "3DS" || extension == "prj"|| extension == "PRJ" ) {
|
||||
if(extension == "3ds" || extension == "prj") {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
}
|
||||
|
||||
/// \def MACRO_ATTRREAD_CHECK_REF
|
||||
/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
|
||||
/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
|
||||
/// "continue" will called.
|
||||
/// \param [in] pAttrName - attribute name.
|
||||
/// \param [out] pVarName - output variable name.
|
||||
|
@ -84,7 +84,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
}
|
||||
|
||||
/// \def MACRO_ATTRREAD_CHECK_RET
|
||||
/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
|
||||
/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
|
||||
/// If result was read then "continue" will called.
|
||||
/// \param [in] pAttrName - attribute name.
|
||||
/// \param [out] pVarName - output variable name.
|
||||
|
@ -130,7 +130,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
} while(false)
|
||||
|
||||
/// \def MACRO_NODECHECK_READCOMP_F
|
||||
/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "float".
|
||||
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float".
|
||||
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
||||
/// \param [in] pNodeName - node name.
|
||||
/// \param [in, out] pReadFlag - read flag.
|
||||
|
@ -147,7 +147,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
}
|
||||
|
||||
/// \def MACRO_NODECHECK_READCOMP_U32
|
||||
/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
|
||||
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
|
||||
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
||||
/// \param [in] pNodeName - node name.
|
||||
/// \param [in, out] pReadFlag - read flag.
|
||||
|
|
|
@ -99,7 +99,7 @@ CAMFImporter_NodeElement* ne;
|
|||
ParseHelper_Node_Exit();
|
||||
// check that all components was defined
|
||||
if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined.");
|
||||
// check if <a> is absent. Then manualy add "a == 1".
|
||||
// check if <a> is absent. Then manually add "a == 1".
|
||||
if(!read_flag[3]) als.Color.a = 1;
|
||||
|
||||
}// if(!mReader->isEmptyElement())
|
||||
|
|
|
@ -770,7 +770,7 @@ std::list<aiNode*> ch_node;
|
|||
// find referenced object
|
||||
if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
|
||||
|
||||
// create node for apllying transformation
|
||||
// create node for applying transformation
|
||||
t_node = new aiNode;
|
||||
t_node->mParent = con_node;
|
||||
// apply transformation
|
||||
|
|
|
@ -427,7 +427,7 @@ public:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
//! Construct a parser from a given input file which is
|
||||
//! guaranted to be terminated with zero.
|
||||
//! guaranteed to be terminated with zero.
|
||||
//! @param szFile Input file
|
||||
//! @param fileFormatDefault Assumed file format version. If the
|
||||
//! file format is specified in the file the new value replaces
|
||||
|
|
|
@ -227,7 +227,7 @@ void DNAParser::Parse ()
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void DNA :: DumpToFile()
|
||||
{
|
||||
// we dont't bother using the VFS here for this is only for debugging.
|
||||
// we don't bother using the VFS here for this is only for debugging.
|
||||
// (and all your bases are belong to us).
|
||||
|
||||
std::ofstream f("dna.txt");
|
||||
|
|
|
@ -663,7 +663,7 @@ public:
|
|||
/** Check whether a specific item is in the cache.
|
||||
* @param s Data type of the item
|
||||
* @param out Output pointer. Unchanged if the
|
||||
* cache doens't know the item yet.
|
||||
* cache doesn't know the item yet.
|
||||
* @param ptr Item address to look for. */
|
||||
template <typename T> void get (
|
||||
const Structure& s,
|
||||
|
|
|
@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define INCLUDED_AI_BLEND_TESSELLATOR_H
|
||||
|
||||
// Use these to toggle between GLU Tessellate or poly2tri
|
||||
// Note (acg) keep GLU Tesselate disabled by default - if it is turned on,
|
||||
// Note (acg) keep GLU Tessellate disabled by default - if it is turned on,
|
||||
// assimp needs to be linked against GLU, which is currently not yet
|
||||
// made configurable in CMake and potentially not wanted by most users
|
||||
// as it requires a Gl environment.
|
||||
|
|
|
@ -208,8 +208,15 @@ OPTION(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT "default value of all ASSIMP_BUILD_
|
|||
# macro to add the CMake Option ADD_ASSIMP_IMPORTER_<name> which enables compile of loader
|
||||
# this way selective loaders can be compiled (reduces filesize + compile time)
|
||||
MACRO(ADD_ASSIMP_IMPORTER name)
|
||||
OPTION(ASSIMP_BUILD_${name}_IMPORTER "build the ${name} importer" ${ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT})
|
||||
IF(ASSIMP_BUILD_${name}_IMPORTER)
|
||||
IF (ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT)
|
||||
set(ASSIMP_IMPORTER_ENABLED TRUE)
|
||||
IF (DEFINED ASSIMP_BUILD_${name}_IMPORTER AND NOT ASSIMP_BUILD_${name}_IMPORTER)
|
||||
set(ASSIMP_IMPORTER_ENABLED FALSE)
|
||||
ENDIF ()
|
||||
ELSE ()
|
||||
set(ASSIMP_IMPORTER_ENABLED ${ASSIMP_BUILD_${name}_IMPORTER})
|
||||
ENDIF ()
|
||||
IF (ASSIMP_IMPORTER_ENABLED)
|
||||
LIST(APPEND ASSIMP_LOADER_SRCS ${ARGN})
|
||||
SET(ASSIMP_IMPORTERS_ENABLED "${ASSIMP_IMPORTERS_ENABLED} ${name}")
|
||||
SET(${name}_SRCS ${ARGN})
|
||||
|
|
|
@ -189,7 +189,7 @@ protected:
|
|||
{}
|
||||
};
|
||||
|
||||
// summarize a material in an convinient way.
|
||||
// summarize a material in an convenient way.
|
||||
struct Material
|
||||
{
|
||||
std::string name;
|
||||
|
|
|
@ -956,7 +956,7 @@ void ColladaLoader::StoreSceneMaterials( aiScene* pScene)
|
|||
// Stores all animations
|
||||
void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
|
||||
{
|
||||
// recursivly collect all animations from the collada scene
|
||||
// recursively collect all animations from the collada scene
|
||||
StoreAnimations( pScene, pParser, &pParser.mAnims, "");
|
||||
|
||||
// catch special case: many animations with the same length, each affecting only a single node.
|
||||
|
@ -1784,7 +1784,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pPars
|
|||
|
||||
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||
// In FBX files textures are now stored internally by Assimp with their filename included
|
||||
// Now Assimp can lookup thru the loaded textures after all data is processed
|
||||
// Now Assimp can lookup through the loaded textures after all data is processed
|
||||
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
||||
// This may occur on this case too, it has to be studied
|
||||
// setup texture reference string
|
||||
|
@ -1819,9 +1819,12 @@ void ColladaLoader::ConvertPath (aiString& ss)
|
|||
|
||||
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
|
||||
// I need to filter it without destroying linux paths starting with "/somewhere"
|
||||
if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' )
|
||||
{
|
||||
ss.length--;
|
||||
#if defined( _MSC_VER )
|
||||
if( ss.data[0] == '/' && isalpha( (unsigned char) ss.data[1]) && ss.data[2] == ':' ) {
|
||||
#else
|
||||
if (ss.data[ 0 ] == '/' && isalpha( ss.data[ 1 ] ) && ss.data[ 2 ] == ':') {
|
||||
#endif
|
||||
--ss.length;
|
||||
::memmove( ss.data, ss.data+1, ss.length);
|
||||
ss.data[ss.length] = 0;
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ void D3MFExporter::writeMetaData() {
|
|||
return;
|
||||
}
|
||||
|
||||
const aiString *key;
|
||||
const aiString *key = nullptr;
|
||||
const aiMetadataEntry *entry(nullptr);
|
||||
for ( size_t i = 0; i < numMetaEntries; ++i ) {
|
||||
mScene->mMetaData->Get( i, key, entry );
|
||||
|
|
|
@ -115,10 +115,10 @@ public:
|
|||
// import the metadata
|
||||
if ( !mMetaData.empty() ) {
|
||||
const size_t numMeta( mMetaData.size() );
|
||||
scene->mMetaData = aiMetadata::Alloc( numMeta );
|
||||
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>( numMeta ) );
|
||||
for ( size_t i = 0; i < numMeta; ++i ) {
|
||||
aiString val( mMetaData[ i ].value );
|
||||
scene->mMetaData->Set( i, mMetaData[ i ].name, val );
|
||||
scene->mMetaData->Set(static_cast<unsigned int>( i ), mMetaData[ i ].name, val );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
|
|||
|
||||
if ( extension.empty() || checkSig ) {
|
||||
static const char *pTokens[] = { "SECTION", "HEADER", "ENDSEC", "BLOCKS" };
|
||||
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 4 );
|
||||
return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 4, 32 );
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -76,11 +76,11 @@ bool DefaultIOSystem::Exists( const char* pFile) const
|
|||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
|
||||
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL);
|
||||
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
|
||||
struct _stat64 filestat;
|
||||
struct __stat64 filestat;
|
||||
if (0 != _wstat64(fileName16, &filestat)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
|
|||
FILE* file;
|
||||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL );
|
||||
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
|
||||
std::string mode8(strMode);
|
||||
|
@ -158,7 +158,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
|
|||
{
|
||||
ai_assert(in && _out);
|
||||
#if defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL);
|
||||
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
|
||||
if (isUnicode) {
|
||||
wchar_t out16[PATHLIMIT];
|
||||
wchar_t in16[PATHLIMIT];
|
||||
|
|
|
@ -154,9 +154,9 @@ Exporter::ExportFormatEntry gExporters[] =
|
|||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
|
||||
Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf", &ExportSceneGLTF2,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb2", &ExportSceneGLB2,
|
||||
Exporter::ExportFormatEntry( "glb2", "GL Transmission Format v. 2 (binary)", "glb", &ExportSceneGLB2,
|
||||
aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
|
||||
#endif
|
||||
|
||||
|
|
|
@ -448,8 +448,8 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
|||
/*Result ignored*/ ReadByte(input, cursor, input + length);
|
||||
const uint32_t version = ReadWord(input, cursor, input + length);
|
||||
const bool is64bits = version >= 7500;
|
||||
while (cursor < input + length)
|
||||
{
|
||||
const char *end = input + length;
|
||||
while (cursor < end ) {
|
||||
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1526,23 +1526,13 @@ unsigned int Converter::ConvertVideo( const Video& video )
|
|||
return static_cast<unsigned int>( textures.size() - 1 );
|
||||
}
|
||||
|
||||
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
|
||||
const std::string& propName,
|
||||
aiTextureType target, const MeshGeometry* const mesh )
|
||||
{
|
||||
TextureMap::const_iterator it = textures.find( propName );
|
||||
if ( it == textures.end() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Texture* const tex = ( *it ).second;
|
||||
if ( tex != 0 )
|
||||
aiString Converter::GetTexturePath(const Texture* tex)
|
||||
{
|
||||
aiString path;
|
||||
path.Set(tex->RelativeFilename());
|
||||
|
||||
const Video* media = tex->Media();
|
||||
if (media != 0) {
|
||||
if (media != nullptr) {
|
||||
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
|
||||
unsigned int index;
|
||||
|
||||
|
@ -1564,7 +1554,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
|
|||
if (textureReady) {
|
||||
// TODO: check the possibility of using the flag "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
|
||||
// In FBX files textures are now stored internally by Assimp with their filename included
|
||||
// Now Assimp can lookup thru the loaded textures after all data is processed
|
||||
// Now Assimp can lookup through the loaded textures after all data is processed
|
||||
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
|
||||
// This may occur on this case too, it has to be studied
|
||||
path.data[0] = '*';
|
||||
|
@ -1573,6 +1563,22 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap&
|
|||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
|
||||
const std::string& propName,
|
||||
aiTextureType target, const MeshGeometry* const mesh )
|
||||
{
|
||||
TextureMap::const_iterator it = textures.find( propName );
|
||||
if ( it == textures.end() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Texture* const tex = ( *it ).second;
|
||||
if ( tex != 0 )
|
||||
{
|
||||
aiString path = GetTexturePath(tex);
|
||||
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, 0 );
|
||||
|
||||
aiUVTransform uvTrafo;
|
||||
|
@ -1696,9 +1702,7 @@ void Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextu
|
|||
|
||||
const Texture* const tex = ( *it ).second->getTexture(texIndex);
|
||||
|
||||
aiString path;
|
||||
path.Set( tex->RelativeFilename() );
|
||||
|
||||
aiString path = GetTexturePath(tex);
|
||||
out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, texIndex );
|
||||
|
||||
aiUVTransform uvTrafo;
|
||||
|
|
|
@ -228,6 +228,10 @@ private:
|
|||
// Video -> aiTexture
|
||||
unsigned int ConvertVideo(const Video& video);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// convert embedded texture if necessary and return actual texture path
|
||||
aiString GetTexturePath(const Texture* tex);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
|
||||
const std::string& propName,
|
||||
|
|
|
@ -575,11 +575,11 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
|||
ai_assert( count != 0 );
|
||||
ai_assert( count <= MAX_CLASSNAMES);
|
||||
|
||||
size_t lenghts[MAX_CLASSNAMES];
|
||||
size_t lengths[MAX_CLASSNAMES];
|
||||
|
||||
const size_t c = count;
|
||||
for (size_t i = 0; i < c; ++i) {
|
||||
lenghts[ i ] = strlen(classnames[i]);
|
||||
lengths[ i ] = strlen(classnames[i]);
|
||||
}
|
||||
|
||||
std::vector<const Connection*> temp;
|
||||
|
@ -597,7 +597,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
|||
|
||||
for (size_t i = 0; i < c; ++i) {
|
||||
ai_assert(classnames[i]);
|
||||
if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) {
|
||||
if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lengths[i] && !strncmp(classnames[i],obtype,lengths[i])) {
|
||||
obtype = NULL;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -450,7 +450,7 @@ void FBXExporter::WriteDocuments ()
|
|||
p.AddP70string("ActiveAnimStackName", ""); // should do this properly?
|
||||
doc.AddChild(p);
|
||||
|
||||
// UID for root node in scene heirarchy.
|
||||
// UID for root node in scene hierarchy.
|
||||
// always set to 0 in the case of a single document.
|
||||
// not sure what happens if more than one document exists,
|
||||
// but that won't matter to us as we're exporting a single scene.
|
||||
|
@ -650,7 +650,7 @@ void FBXExporter::WriteDefinitions ()
|
|||
}
|
||||
|
||||
// Model / FbxNode
|
||||
// <~~ node heirarchy
|
||||
// <~~ node hierarchy
|
||||
count = int32_t(count_nodes(mScene->mRootNode)) - 1; // (not counting root node)
|
||||
if (count) {
|
||||
n = FBX::Node("ObjectType", "Model");
|
||||
|
@ -1223,7 +1223,7 @@ void FBXExporter::WriteObjects ()
|
|||
// it's all about this material
|
||||
aiMaterial* m = mScene->mMaterials[i];
|
||||
|
||||
// these are used to recieve material data
|
||||
// these are used to receive material data
|
||||
float f; aiColor3D c;
|
||||
|
||||
// start the node record
|
||||
|
@ -1311,7 +1311,7 @@ void FBXExporter::WriteObjects ()
|
|||
// Now the legacy system.
|
||||
// For safety let's include it.
|
||||
// thrse values don't exist in the property template,
|
||||
// and usualy are completely ignored when loading.
|
||||
// and usually are completely ignored when loading.
|
||||
// One notable exception is the "Opacity" property,
|
||||
// which Blender uses as (1.0 - alpha).
|
||||
c.r = 0.0f; c.g = 0.0f; c.b = 0.0f;
|
||||
|
@ -1532,7 +1532,7 @@ void FBXExporter::WriteObjects ()
|
|||
// bones.
|
||||
//
|
||||
// output structure:
|
||||
// subset of node heirarchy that are "skeleton",
|
||||
// subset of node hierarchy that are "skeleton",
|
||||
// i.e. do not have meshes but only bones.
|
||||
// but.. i'm not sure how anyone could guarantee that...
|
||||
//
|
||||
|
@ -1544,7 +1544,7 @@ void FBXExporter::WriteObjects ()
|
|||
//
|
||||
// well. we can assume a sane input, i suppose.
|
||||
//
|
||||
// so input is the bone node heirarchy,
|
||||
// so input is the bone node hierarchy,
|
||||
// with an extra thing for the transformation of the MESH in BONE space.
|
||||
//
|
||||
// output is a set of bone nodes,
|
||||
|
@ -1556,7 +1556,7 @@ void FBXExporter::WriteObjects ()
|
|||
// and represents the influence of that bone on the grandparent mesh.
|
||||
// the subdeformer has a list of indices, and weights,
|
||||
// with indices specifying vertex indices,
|
||||
// and weights specifying the correspoding influence of this bone.
|
||||
// and weights specifying the corresponding influence of this bone.
|
||||
// it also has Transform and TransformLink elements,
|
||||
// specifying the transform of the MESH in BONE space,
|
||||
// and the transformation of the BONE in WORLD space,
|
||||
|
@ -1806,7 +1806,7 @@ void FBXExporter::WriteObjects ()
|
|||
// and a correct skeleton would still be output.
|
||||
|
||||
// transformlink should be the position of the bone in world space.
|
||||
// if the bone is in the bind pose (or nonexistant),
|
||||
// if the bone is in the bind pose (or nonexistent),
|
||||
// we can just use the matrix we already calculated
|
||||
if (bone_xform_okay) {
|
||||
sdnode.AddChild("TransformLink", bone_xform);
|
||||
|
@ -1945,7 +1945,7 @@ void FBXExporter::WriteObjects ()
|
|||
|
||||
// TODO: cameras, lights
|
||||
|
||||
// write nodes (i.e. model heirarchy)
|
||||
// write nodes (i.e. model hierarchy)
|
||||
// start at root node
|
||||
WriteModelNodes(
|
||||
outstream, mScene->mRootNode, 0, limbnodes
|
||||
|
@ -2203,8 +2203,8 @@ void FBXExporter::WriteModelNode(
|
|||
} else {
|
||||
// apply the transformation chain.
|
||||
// these transformation elements are created when importing FBX,
|
||||
// which has a complex transformation heirarchy for each node.
|
||||
// as such we can bake the heirarchy back into the node on export.
|
||||
// which has a complex transformation hierarchy for each node.
|
||||
// as such we can bake the hierarchy back into the node on export.
|
||||
for (auto &item : transform_chain) {
|
||||
auto elem = transform_types.find(item.first);
|
||||
if (elem == transform_types.end()) {
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace Assimp
|
|||
const ExportProperties* mProperties; // currently unused
|
||||
std::shared_ptr<IOStream> outfile; // file to write to
|
||||
|
||||
std::vector<FBX::Node> connections; // conection storage
|
||||
std::vector<FBX::Node> connections; // connection storage
|
||||
|
||||
std::vector<int64_t> mesh_uids;
|
||||
std::vector<int64_t> material_uids;
|
||||
|
|
|
@ -302,7 +302,7 @@ Video::Video(uint64_t id, const Element& element, const Document& doc, const std
|
|||
}
|
||||
|
||||
if(Content) {
|
||||
//this field is ommited when the embedded texture is already loaded, let's ignore if it's not found
|
||||
//this field is omitted when the embedded texture is already loaded, let's ignore if it's not found
|
||||
try {
|
||||
const Token& token = GetRequiredToken(*Content, 0);
|
||||
const char* data = token.begin();
|
||||
|
|
|
@ -54,6 +54,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace Assimp;
|
||||
|
||||
//remove mesh at position 'index' from the scene
|
||||
static void removeMesh(aiScene* pScene, unsigned const index);
|
||||
//correct node indices to meshes and remove references to deleted mesh
|
||||
static void updateSceneGraph(aiNode* pNode, unsigned const index);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
FindDegeneratesProcess::FindDegeneratesProcess()
|
||||
|
@ -87,11 +92,50 @@ void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
|
|||
void FindDegeneratesProcess::Execute( aiScene* pScene) {
|
||||
ASSIMP_LOG_DEBUG("FindDegeneratesProcess begin");
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
|
||||
ExecuteOnMesh( pScene->mMeshes[ i ] );
|
||||
if (ExecuteOnMesh(pScene->mMeshes[i])) {
|
||||
removeMesh(pScene, i);
|
||||
--i; //the current i is removed, do not skip the next one
|
||||
}
|
||||
}
|
||||
ASSIMP_LOG_DEBUG("FindDegeneratesProcess finished");
|
||||
}
|
||||
|
||||
static void removeMesh(aiScene* pScene, unsigned const index) {
|
||||
//we start at index and copy the pointers one position forward
|
||||
//save the mesh pointer to delete it later
|
||||
auto delete_me = pScene->mMeshes[index];
|
||||
for (unsigned i = index; i < pScene->mNumMeshes - 1; ++i) {
|
||||
pScene->mMeshes[i] = pScene->mMeshes[i+1];
|
||||
}
|
||||
pScene->mMeshes[pScene->mNumMeshes - 1] = nullptr;
|
||||
--(pScene->mNumMeshes);
|
||||
delete delete_me;
|
||||
|
||||
//removing a mesh also requires updating all references to it in the scene graph
|
||||
updateSceneGraph(pScene->mRootNode, index);
|
||||
}
|
||||
|
||||
static void updateSceneGraph(aiNode* pNode, unsigned const index) {
|
||||
for (unsigned i = 0; i < pNode->mNumMeshes; ++i) {
|
||||
if (pNode->mMeshes[i] > index) {
|
||||
--(pNode->mMeshes[i]);
|
||||
continue;
|
||||
}
|
||||
if (pNode->mMeshes[i] == index) {
|
||||
for (unsigned j = i; j < pNode->mNumMeshes -1; ++j) {
|
||||
pNode->mMeshes[j] = pNode->mMeshes[j+1];
|
||||
}
|
||||
--(pNode->mNumMeshes);
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//recurse to all children
|
||||
for (unsigned i = 0; i < pNode->mNumChildren; ++i) {
|
||||
updateSceneGraph(pNode->mChildren[i], index);
|
||||
}
|
||||
}
|
||||
|
||||
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
|
||||
ai_real s = (a + b + c) / 2;
|
||||
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
|
||||
|
@ -125,7 +169,7 @@ static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Executes the post processing step on the given imported mesh
|
||||
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||
bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
||||
mesh->mPrimitiveTypes = 0;
|
||||
|
||||
std::vector<bool> remove_me;
|
||||
|
@ -161,7 +205,7 @@ void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
|||
|
||||
// NOTE: we set the removed vertex index to an unique value
|
||||
// to make sure the developer gets notified when his
|
||||
// application attemps to access this data.
|
||||
// application attempts to access this data.
|
||||
face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
|
||||
|
||||
if(first) {
|
||||
|
@ -227,30 +271,28 @@ evil_jump_outside:
|
|||
if (&face_src != &face_dest) {
|
||||
// clear source
|
||||
face_src.mNumIndices = 0;
|
||||
face_src.mIndices = NULL;
|
||||
face_src.mIndices = nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Otherwise delete it if we don't need this face
|
||||
delete[] face_src.mIndices;
|
||||
face_src.mIndices = NULL;
|
||||
face_src.mIndices = nullptr;
|
||||
face_src.mNumIndices = 0;
|
||||
}
|
||||
}
|
||||
// Just leave the rest of the array unreferenced, we don't care for now
|
||||
mesh->mNumFaces = n;
|
||||
if (!mesh->mNumFaces) {
|
||||
// WTF!?
|
||||
// OK ... for completeness and because I'm not yet tired,
|
||||
// let's write code that will hopefully never be called
|
||||
// (famous last words)
|
||||
|
||||
// OK ... bad idea.
|
||||
throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
|
||||
//The whole mesh consists of degenerated faces
|
||||
//signal upward, that this mesh should be deleted.
|
||||
ASSIMP_LOG_DEBUG("FindDegeneratesProcess removed a mesh full of degenerated primitives");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (deg && !DefaultLogger::isNullLogger()) {
|
||||
ASSIMP_LOG_WARN_F( "Found ", deg, " degenerated primitives");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,8 @@ public:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
// Execute step on a given mesh
|
||||
void ExecuteOnMesh( aiMesh* mesh);
|
||||
///@returns true if the current mesh should be deleted, false otherwise
|
||||
bool ExecuteOnMesh( aiMesh* mesh);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/// @brief Enable the instant removal of degenerated primitives
|
||||
|
|
|
@ -146,7 +146,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
|
|||
const aiVector3D* pV1 = &pMesh->mVertices[face.mIndices[0]];
|
||||
const aiVector3D* pV2 = &pMesh->mVertices[face.mIndices[1]];
|
||||
const aiVector3D* pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices-1]];
|
||||
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1));
|
||||
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
||||
|
||||
for (unsigned int i = 0;i < face.mNumIndices;++i) {
|
||||
pMesh->mNormals[face.mIndices[i]] = vNor;
|
||||
|
@ -214,17 +214,15 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
|
|||
vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
|
||||
|
||||
aiVector3D vr = pMesh->mNormals[i];
|
||||
ai_real vrlen = vr.Length();
|
||||
|
||||
aiVector3D pcNor;
|
||||
for (unsigned int a = 0; a < verticesFound.size(); ++a) {
|
||||
aiVector3D v = pMesh->mNormals[verticesFound[a]];
|
||||
|
||||
// check whether the angle between the two normals is not too large
|
||||
// HACK: if v.x is qnan the dot product will become qnan, too
|
||||
// therefore the comparison against fLimit should be false
|
||||
// in every case.
|
||||
if (v * vr >= fLimit * vrlen * v.Length())
|
||||
// Check whether the angle between the two normals is not too large.
|
||||
// Skip the angle check on our own normal to avoid false negatives
|
||||
// (v*v is not guaranteed to be 1.0 for all unit vectors v)
|
||||
if (is_not_qnan(v.x) && (verticesFound[a] == i || (v * vr >= fLimit)))
|
||||
pcNor += v;
|
||||
}
|
||||
pcNew[i] = pcNor.NormalizeSafe();
|
||||
|
|
|
@ -91,7 +91,7 @@ protected:
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
/** Read a property of the specified type from the current XML element.
|
||||
* @param out Recives output data
|
||||
* @param out Receives output data
|
||||
*/
|
||||
void ReadHexProperty (HexProperty& out);
|
||||
void ReadStringProperty (StringProperty& out);
|
||||
|
|
|
@ -970,6 +970,8 @@ void Importer::GetExtensionList(aiString& szOut) const
|
|||
(*i)->GetExtensionList(str);
|
||||
}
|
||||
|
||||
// List can be empty
|
||||
if( !str.empty() ) {
|
||||
for (std::set<std::string>::const_iterator it = str.begin();; ) {
|
||||
szOut.Append("*.");
|
||||
szOut.Append((*it).c_str());
|
||||
|
@ -979,6 +981,7 @@ void Importer::GetExtensionList(aiString& szOut) const
|
|||
}
|
||||
szOut.Append(";");
|
||||
}
|
||||
}
|
||||
ASSIMP_END_EXCEPTION_REGION(void);
|
||||
}
|
||||
|
||||
|
@ -997,33 +1000,33 @@ bool Importer::SetPropertyInteger(const char* szName, int iValue)
|
|||
// Set a configuration property
|
||||
bool Importer::SetPropertyFloat(const char* szName, ai_real iValue)
|
||||
{
|
||||
bool exising;
|
||||
bool existing;
|
||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||
exising = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue);
|
||||
existing = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue);
|
||||
ASSIMP_END_EXCEPTION_REGION(bool);
|
||||
return exising;
|
||||
return existing;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Set a configuration property
|
||||
bool Importer::SetPropertyString(const char* szName, const std::string& value)
|
||||
{
|
||||
bool exising;
|
||||
bool existing;
|
||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||
exising = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value);
|
||||
existing = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value);
|
||||
ASSIMP_END_EXCEPTION_REGION(bool);
|
||||
return exising;
|
||||
return existing;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Set a configuration property
|
||||
bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
|
||||
{
|
||||
bool exising;
|
||||
bool existing;
|
||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||
exising = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value);
|
||||
existing = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value);
|
||||
ASSIMP_END_EXCEPTION_REGION(bool);
|
||||
return exising;
|
||||
return existing;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -317,7 +317,7 @@ void TempMesh::FixupFaceOrientation()
|
|||
IfcVector3 farthestCenter = std::accumulate(mVerts.begin() + faceStartIndices[farthestIndex],
|
||||
mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0))
|
||||
/ IfcFloat(mVertcnt[farthestIndex]);
|
||||
// We accapt a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
|
||||
// We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
|
||||
// the file.
|
||||
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 )
|
||||
{
|
||||
|
|
|
@ -108,179 +108,58 @@ void JoinVerticesProcess::Execute( aiScene* pScene)
|
|||
pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Unites identical vertices in the given mesh
|
||||
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
||||
namespace {
|
||||
|
||||
bool areVerticesEqual(const Vertex &lhs, const Vertex &rhs, bool complex)
|
||||
{
|
||||
static_assert( AI_MAX_NUMBER_OF_COLOR_SETS == 8, "AI_MAX_NUMBER_OF_COLOR_SETS == 8");
|
||||
static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8");
|
||||
|
||||
// Return early if we don't have any positions
|
||||
if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We'll never have more vertices afterwards.
|
||||
std::vector<Vertex> uniqueVertices;
|
||||
uniqueVertices.reserve( pMesh->mNumVertices);
|
||||
|
||||
// For each vertex the index of the vertex it was replaced by.
|
||||
// Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
|
||||
// whether a new vertex was created for the index (true) or if it was replaced by an existing
|
||||
// unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
|
||||
// branching performance.
|
||||
static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
|
||||
std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
|
||||
|
||||
// A little helper to find locally close vertices faster.
|
||||
// Try to reuse the lookup table from the last step.
|
||||
const static float epsilon = 1e-5f;
|
||||
// float posEpsilonSqr;
|
||||
SpatialSort* vertexFinder = NULL;
|
||||
SpatialSort _vertexFinder;
|
||||
|
||||
typedef std::pair<SpatialSort,float> SpatPair;
|
||||
if (shared) {
|
||||
std::vector<SpatPair >* avf;
|
||||
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
|
||||
if (avf) {
|
||||
SpatPair& blubb = (*avf)[meshIndex];
|
||||
vertexFinder = &blubb.first;
|
||||
// posEpsilonSqr = blubb.second;
|
||||
}
|
||||
}
|
||||
if (!vertexFinder) {
|
||||
// bad, need to compute it.
|
||||
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
|
||||
vertexFinder = &_vertexFinder;
|
||||
// posEpsilonSqr = ComputePositionEpsilon(pMesh);
|
||||
}
|
||||
|
||||
// Squared because we check against squared length of the vector difference
|
||||
static const float squareEpsilon = epsilon * epsilon;
|
||||
|
||||
// Again, better waste some bytes than a realloc ...
|
||||
std::vector<unsigned int> verticesFound;
|
||||
verticesFound.reserve(10);
|
||||
|
||||
// Run an optimized code path if we don't have multiple UVs or vertex colors.
|
||||
// This should yield false in more than 99% of all imports ...
|
||||
const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);
|
||||
|
||||
// Now check each vertex if it brings something new to the table
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
// collect the vertex data
|
||||
Vertex v(pMesh,a);
|
||||
|
||||
// collect all vertices that are close enough to the given position
|
||||
vertexFinder->FindIdenticalPositions( v.position, verticesFound);
|
||||
unsigned int matchIndex = 0xffffffff;
|
||||
|
||||
// check all unique vertices close to the position if this vertex is already present among them
|
||||
for( unsigned int b = 0; b < verticesFound.size(); b++) {
|
||||
|
||||
const unsigned int vidx = verticesFound[b];
|
||||
const unsigned int uidx = replaceIndex[ vidx];
|
||||
if( uidx & 0x80000000)
|
||||
continue;
|
||||
|
||||
const Vertex& uv = uniqueVertices[ uidx];
|
||||
// Position mismatch is impossible - the vertex finder already discarded all non-matching positions
|
||||
// Square compare is useful for animeshes vertices compare
|
||||
if ((lhs.position - rhs.position).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We just test the other attributes even if they're not present in the mesh.
|
||||
// In this case they're initialized to 0 so the comparison succeeds.
|
||||
// By this method the non-present attributes are effectively ignored in the comparison.
|
||||
if( (uv.normal - v.normal).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( (uv.texcoords[0] - v.texcoords[0]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( (uv.tangent - v.tangent).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( (uv.bitangent - v.bitangent).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if ((lhs.normal - rhs.normal).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((lhs.texcoords[0] - rhs.texcoords[0]).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((lhs.tangent - rhs.tangent).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((lhs.bitangent - rhs.bitangent).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Usually we won't have vertex colors or multiple UVs, so we can skip from here
|
||||
// Actually this increases runtime performance slightly, at least if branch
|
||||
// prediction is on our side.
|
||||
if (complex) {
|
||||
// manually unrolled because continue wouldn't work as desired in an inner loop,
|
||||
// also because some compilers seem to fail the task. Colors and UV coords
|
||||
// are interleaved since the higher entries are most likely to be
|
||||
// zero and thus useless. By interleaving the arrays, vertices are,
|
||||
// on average, rejected earlier.
|
||||
|
||||
if( (uv.texcoords[1] - v.texcoords[1]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[0], v.colors[0]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[2] - v.texcoords[2]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[1], v.colors[1]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[3] - v.texcoords[3]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[2], v.colors[2]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[4] - v.texcoords[4]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[3], v.colors[3]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[5] - v.texcoords[5]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[4], v.colors[4]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[6] - v.texcoords[6]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[5], v.colors[5]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( (uv.texcoords[7] - v.texcoords[7]).SquareLength() > squareEpsilon)
|
||||
continue;
|
||||
if( GetColorDifference( uv.colors[6], v.colors[6]) > squareEpsilon)
|
||||
continue;
|
||||
|
||||
if( GetColorDifference( uv.colors[7], v.colors[7]) > squareEpsilon)
|
||||
continue;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (i > 0 && (lhs.texcoords[i] - rhs.texcoords[i]).SquareLength() > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// we're still here -> this vertex perfectly matches our given vertex
|
||||
matchIndex = uidx;
|
||||
break;
|
||||
}
|
||||
|
||||
// found a replacement vertex among the uniques?
|
||||
if( matchIndex != 0xffffffff)
|
||||
{
|
||||
// store where to found the matching unique vertex
|
||||
replaceIndex[a] = matchIndex | 0x80000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no unique vertex matches it up to now -> so add it
|
||||
replaceIndex[a] = (unsigned int)uniqueVertices.size();
|
||||
uniqueVertices.push_back( v);
|
||||
if (GetColorDifference(lhs.colors[i], rhs.colors[i]) > squareEpsilon) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
|
||||
ASSIMP_LOG_DEBUG_F(
|
||||
"Mesh ",meshIndex,
|
||||
" (",
|
||||
(pMesh->mName.length ? pMesh->mName.data : "unnamed"),
|
||||
") | Verts in: ",pMesh->mNumVertices,
|
||||
" out: ",
|
||||
uniqueVertices.size(),
|
||||
" | ~",
|
||||
((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f,
|
||||
"%"
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class XMesh>
|
||||
void updateXMeshVertices(XMesh *pMesh, std::vector<Vertex> &uniqueVertices) {
|
||||
// replace vertex data with the unique data sets
|
||||
pMesh->mNumVertices = (unsigned int)uniqueVertices.size();
|
||||
|
||||
|
@ -290,11 +169,15 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
// dislikes branches, even if they're easily predictable.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Position
|
||||
// Position, if present (check made for aiAnimMesh)
|
||||
if (pMesh->mVertices)
|
||||
{
|
||||
delete [] pMesh->mVertices;
|
||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
|
||||
for (unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
pMesh->mVertices[a] = uniqueVertices[a].position;
|
||||
}
|
||||
}
|
||||
|
||||
// Normals, if present
|
||||
if (pMesh->mNormals)
|
||||
|
@ -341,6 +224,156 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a];
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Unites identical vertices in the given mesh
|
||||
int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
||||
{
|
||||
static_assert( AI_MAX_NUMBER_OF_COLOR_SETS == 8, "AI_MAX_NUMBER_OF_COLOR_SETS == 8");
|
||||
static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8");
|
||||
|
||||
// Return early if we don't have any positions
|
||||
if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We'll never have more vertices afterwards.
|
||||
std::vector<Vertex> uniqueVertices;
|
||||
uniqueVertices.reserve( pMesh->mNumVertices);
|
||||
|
||||
// For each vertex the index of the vertex it was replaced by.
|
||||
// Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
|
||||
// whether a new vertex was created for the index (true) or if it was replaced by an existing
|
||||
// unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
|
||||
// branching performance.
|
||||
static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
|
||||
std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
|
||||
|
||||
// float posEpsilonSqr;
|
||||
SpatialSort* vertexFinder = NULL;
|
||||
SpatialSort _vertexFinder;
|
||||
|
||||
typedef std::pair<SpatialSort,float> SpatPair;
|
||||
if (shared) {
|
||||
std::vector<SpatPair >* avf;
|
||||
shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
|
||||
if (avf) {
|
||||
SpatPair& blubb = (*avf)[meshIndex];
|
||||
vertexFinder = &blubb.first;
|
||||
// posEpsilonSqr = blubb.second;
|
||||
}
|
||||
}
|
||||
if (!vertexFinder) {
|
||||
// bad, need to compute it.
|
||||
_vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
|
||||
vertexFinder = &_vertexFinder;
|
||||
// posEpsilonSqr = ComputePositionEpsilon(pMesh);
|
||||
}
|
||||
|
||||
// Again, better waste some bytes than a realloc ...
|
||||
std::vector<unsigned int> verticesFound;
|
||||
verticesFound.reserve(10);
|
||||
|
||||
// Run an optimized code path if we don't have multiple UVs or vertex colors.
|
||||
// This should yield false in more than 99% of all imports ...
|
||||
const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);
|
||||
const bool hasAnimMeshes = pMesh->mNumAnimMeshes > 0;
|
||||
|
||||
// We'll never have more vertices afterwards.
|
||||
std::vector<std::vector<Vertex>> uniqueAnimatedVertices;
|
||||
if (hasAnimMeshes) {
|
||||
uniqueAnimatedVertices.resize(pMesh->mNumAnimMeshes);
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
uniqueAnimatedVertices[animMeshIndex].reserve(pMesh->mNumVertices);
|
||||
}
|
||||
}
|
||||
|
||||
// Now check each vertex if it brings something new to the table
|
||||
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
|
||||
// collect the vertex data
|
||||
Vertex v(pMesh,a);
|
||||
|
||||
// collect all vertices that are close enough to the given position
|
||||
vertexFinder->FindIdenticalPositions( v.position, verticesFound);
|
||||
unsigned int matchIndex = 0xffffffff;
|
||||
|
||||
// check all unique vertices close to the position if this vertex is already present among them
|
||||
for( unsigned int b = 0; b < verticesFound.size(); b++) {
|
||||
const unsigned int vidx = verticesFound[b];
|
||||
const unsigned int uidx = replaceIndex[ vidx];
|
||||
if( uidx & 0x80000000)
|
||||
continue;
|
||||
|
||||
const Vertex& uv = uniqueVertices[ uidx];
|
||||
|
||||
if (!areVerticesEqual(v, uv, complex)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hasAnimMeshes) {
|
||||
// If given vertex is animated, then it has to be preserver 1 to 1 (base mesh and animated mesh require same topology)
|
||||
// NOTE: not doing this totaly breaks anim meshes as they don't have their own faces (they use pMesh->mFaces)
|
||||
bool breaksAnimMesh = false;
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
const Vertex& animatedUV = uniqueAnimatedVertices[animMeshIndex][ uidx];
|
||||
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
|
||||
if (!areVerticesEqual(aniMeshVertex, animatedUV, complex)) {
|
||||
breaksAnimMesh = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (breaksAnimMesh) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// we're still here -> this vertex perfectly matches our given vertex
|
||||
matchIndex = uidx;
|
||||
break;
|
||||
}
|
||||
|
||||
// found a replacement vertex among the uniques?
|
||||
if( matchIndex != 0xffffffff)
|
||||
{
|
||||
// store where to found the matching unique vertex
|
||||
replaceIndex[a] = matchIndex | 0x80000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no unique vertex matches it up to now -> so add it
|
||||
replaceIndex[a] = (unsigned int)uniqueVertices.size();
|
||||
uniqueVertices.push_back( v);
|
||||
if (hasAnimMeshes) {
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
Vertex aniMeshVertex(pMesh->mAnimMeshes[animMeshIndex], a);
|
||||
uniqueAnimatedVertices[animMeshIndex].push_back(aniMeshVertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
|
||||
ASSIMP_LOG_DEBUG_F(
|
||||
"Mesh ",meshIndex,
|
||||
" (",
|
||||
(pMesh->mName.length ? pMesh->mName.data : "unnamed"),
|
||||
") | Verts in: ",pMesh->mNumVertices,
|
||||
" out: ",
|
||||
uniqueVertices.size(),
|
||||
" | ~",
|
||||
((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f,
|
||||
"%"
|
||||
);
|
||||
}
|
||||
|
||||
updateXMeshVertices(pMesh, uniqueVertices);
|
||||
if (hasAnimMeshes) {
|
||||
for (unsigned int animMeshIndex = 0; animMeshIndex < pMesh->mNumAnimMeshes; animMeshIndex++) {
|
||||
updateXMeshVertices(pMesh->mAnimMeshes[animMeshIndex], uniqueAnimatedVertices[animMeshIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
// adjust the indices in all faces
|
||||
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
|
||||
|
|
|
@ -253,7 +253,8 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
|
|||
pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));
|
||||
|
||||
// setup the mapping mode
|
||||
pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur));
|
||||
int mapping_ = static_cast<int>(mapping);
|
||||
pcMat->AddProperty<int>(&mapping_, 1, AI_MATKEY_MAPPING(type, cur));
|
||||
|
||||
// add the u-wrapping
|
||||
temp = (unsigned int)GetMapMode(texture.wrapModeWidth);
|
||||
|
@ -365,7 +366,8 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
|
|||
}
|
||||
if (surf.mMaximumSmoothAngle <= 0.0)
|
||||
m = aiShadingMode_Flat;
|
||||
pcMat->AddProperty((int*)&m,1,AI_MATKEY_SHADING_MODEL);
|
||||
int m_ = static_cast<int>(m);
|
||||
pcMat->AddProperty(&m_, 1, AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
// (the diffuse value is just a scaling factor)
|
||||
// If a diffuse texture is set, we set this value to 1.0
|
||||
|
|
|
@ -410,7 +410,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
|
|||
// name to attach light to node -> unique due to LWs indexing system
|
||||
lit->mName = nd->mName;
|
||||
|
||||
// detemine light type and setup additional members
|
||||
// determine light type and setup additional members
|
||||
if (src.lightType == 2) { /* spot light */
|
||||
|
||||
lit->mType = aiLightSource_SPOT;
|
||||
|
|
|
@ -141,7 +141,7 @@ void MDLImporter::SetupProperties(const Importer* pImp)
|
|||
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
|
||||
}
|
||||
|
||||
// AI_CONFIG_IMPORT_MDL_COLORMAP - pallette file
|
||||
// AI_CONFIG_IMPORT_MDL_COLORMAP - palette file
|
||||
configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
|
||||
}
|
||||
|
||||
|
@ -1496,7 +1496,7 @@ void MDLImporter::InternReadFile_3DGS_MDL7( )
|
|||
groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
|
||||
|
||||
// check whether the triangle data structure is large enough
|
||||
// to contain a second UV coodinate set
|
||||
// to contain a second UV coordinate set
|
||||
if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
|
||||
groupData.vTextureCoords2.resize(iNumVertices,aiVector3D());
|
||||
groupData.bNeed2UV = true;
|
||||
|
|
|
@ -217,7 +217,7 @@ aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
|
|||
pMesh->mNumFaces = indexCount / 3;
|
||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||
|
||||
const int numIndices = 3; // trianglular face
|
||||
const int numIndices = 3; // triangular face
|
||||
for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
|
||||
pMesh->mFaces[index].mNumIndices = numIndices;
|
||||
unsigned int *indices = new unsigned int[numIndices];
|
||||
|
|
|
@ -354,8 +354,9 @@ aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
|
|||
return AI_FAILURE;
|
||||
}
|
||||
// Determine mapping type
|
||||
aiTextureMapping mapping = aiTextureMapping_UV;
|
||||
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index),(int*)&mapping);
|
||||
int mapping_ = static_cast<int>(aiTextureMapping_UV);
|
||||
aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index), &mapping_);
|
||||
aiTextureMapping mapping = static_cast<aiTextureMapping>(mapping_);
|
||||
if (_mapping)
|
||||
*_mapping = mapping;
|
||||
|
||||
|
|
|
@ -271,7 +271,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
|||
|
||||
ShadingInfo s; // current material info
|
||||
|
||||
// degree of tesselation
|
||||
// degree of tessellation
|
||||
unsigned int iTesselation = 4;
|
||||
|
||||
// some temporary variables we need to parse the file
|
||||
|
@ -988,7 +988,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
|
|||
::ai_snprintf(currentMesh.name,128,"cone_%i",cone++);
|
||||
else ::ai_snprintf(currentMesh.name,128,"cylinder_%i",cylinder++);
|
||||
}
|
||||
// 'tess' - tesselation
|
||||
// 'tess' - tessellation
|
||||
else if (TokenMatch(sz,"tess",4))
|
||||
{
|
||||
SkipSpaces(&sz);
|
||||
|
|
|
@ -691,7 +691,7 @@ void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene *
|
|||
void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
m_currentMesh = new aiMesh;
|
||||
const size_t meshidx( m_meshCache.size() );
|
||||
// ownership is transfered but a reference remains in m_currentMesh
|
||||
// ownership is transferred but a reference remains in m_currentMesh
|
||||
m_meshCache.emplace_back( m_currentMesh );
|
||||
|
||||
Property *prop = node->getProperties();
|
||||
|
|
|
@ -102,7 +102,7 @@ public:
|
|||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Rmeove a node from the list of locked nodes.
|
||||
/** @brief Remove a node from the list of locked nodes.
|
||||
* @param name Name to be unlocked
|
||||
*/
|
||||
inline void RemoveLockedNode(std::string& name)
|
||||
|
|
|
@ -212,7 +212,7 @@ template <> struct MinMaxChooser<aiVertexWeight> {
|
|||
// -------------------------------------------------------------------------------
|
||||
/** @brief Find the min/max values of an array of Ts
|
||||
* @param in Input array
|
||||
* @param size Numebr of elements to process
|
||||
* @param size Number of elements to process
|
||||
* @param[out] min minimum value
|
||||
* @param[out] max maximum value
|
||||
*/
|
||||
|
|
|
@ -352,7 +352,7 @@ void STLImporter::LoadASCIIFile( aiNode *root ) {
|
|||
|
||||
if (positionBuffer.empty()) {
|
||||
pMesh->mNumFaces = 0;
|
||||
throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded");
|
||||
ASSIMP_LOG_WARN("STL: mesh is empty or invalid; no data loaded");
|
||||
}
|
||||
if (positionBuffer.size() % 3 != 0) {
|
||||
pMesh->mNumFaces = 0;
|
||||
|
@ -365,10 +365,10 @@ void STLImporter::LoadASCIIFile( aiNode *root ) {
|
|||
pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
|
||||
pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
|
||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||
memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
||||
memcpy(pMesh->mVertices, positionBuffer.data(), pMesh->mNumVertices * sizeof(aiVector3D));
|
||||
positionBuffer.clear();
|
||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||
memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
||||
memcpy(pMesh->mNormals, normalBuffer.data(), pMesh->mNumVertices * sizeof(aiVector3D));
|
||||
normalBuffer.clear();
|
||||
|
||||
// now copy faces
|
||||
|
|
|
@ -104,7 +104,7 @@ void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
|
|||
|
||||
aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices;
|
||||
|
||||
// Ensure unsued components are zeroed. This will make 1D texture channels work
|
||||
// Ensure unused components are zeroed. This will make 1D texture channels work
|
||||
// as if they were 2D channels .. just in case an application doesn't handle
|
||||
// this case
|
||||
if (2 == mesh->mNumUVComponents[i]) {
|
||||
|
|
|
@ -377,7 +377,7 @@ void StandardShapes::MakeSphere(unsigned int tess,
|
|||
MakeIcosahedron(positions);
|
||||
|
||||
// ... and subdivide it until the requested output
|
||||
// tesselation is reached
|
||||
// tessellation is reached
|
||||
for (unsigned int i = 0; i<tess;++i)
|
||||
Subdivide(positions);
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ void StepExporter::WriteFile()
|
|||
// see http://shodhganga.inflibnet.ac.in:8080/jspui/bitstream/10603/14116/11/11_chapter%203.pdf
|
||||
// note, that all realnumber values must be comma separated in x files
|
||||
mOutput.setf(std::ios::fixed);
|
||||
// precission for double
|
||||
// precision for double
|
||||
// see http://stackoverflow.com/questions/554063/how-do-i-print-a-double-value-with-full-precision-using-cout
|
||||
mOutput.precision(16);
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
|
|||
{
|
||||
/* This function tries to simplify the input UV transformation.
|
||||
* That's very important as it allows us to reduce the number
|
||||
* of output UV channels. The oder in which the transformations
|
||||
* of output UV channels. The order in which the transformations
|
||||
* are applied is - as always - scaling, rotation, translation.
|
||||
*/
|
||||
|
||||
|
|
|
@ -369,7 +369,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
|||
|
||||
// positions must always be there ...
|
||||
if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) {
|
||||
ReportError("The mesh contains no vertices");
|
||||
ReportError("The mesh %s contains no vertices", pMesh->mName.C_Str());
|
||||
}
|
||||
|
||||
if (pMesh->mNumVertices > AI_MAX_VERTICES) {
|
||||
|
@ -386,7 +386,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
|
|||
|
||||
// faces, too
|
||||
if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) {
|
||||
ReportError("Mesh contains no faces");
|
||||
ReportError("Mesh %s contains no faces", pMesh->mName.C_Str());
|
||||
}
|
||||
|
||||
// now check whether the face indexing layout is correct:
|
||||
|
|
|
@ -50,7 +50,7 @@ static const unsigned int MajorVersion = 4;
|
|||
static const unsigned int MinorVersion = 1;
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// Legal information string - dont't remove this.
|
||||
// Legal information string - don't remove this.
|
||||
static const char* LEGAL_INFORMATION =
|
||||
|
||||
"Open Asset Import Library (Assimp).\n"
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Assimp
|
|||
/// Limitations.
|
||||
///
|
||||
/// Pay attention that X3D is format for interactive graphic and simulations for web browsers. aiScene can not contain all features of the X3D format.
|
||||
/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tesselation:
|
||||
/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tessellation:
|
||||
/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but that's not a good idea at all.
|
||||
///
|
||||
/// Supported nodes:
|
||||
|
|
|
@ -522,7 +522,7 @@ private:
|
|||
/// \param [in] pStartAngle - angle in radians of start of the arc.
|
||||
/// \param [in] pEndAngle - angle in radians of end of the arc.
|
||||
/// \param [in] pRadius - radius of the arc.
|
||||
/// \param [out] pNumSegments - number of segments in arc. In other words - tesselation factor.
|
||||
/// \param [out] pNumSegments - number of segments in arc. In other words - tessellation factor.
|
||||
/// \param [out] pVertices - generated vertices.
|
||||
void GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, std::list<aiVector3D>& pVertices);
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ void X3DImporter::ParseNode_Geometry3D_Cone()
|
|||
}
|
||||
else
|
||||
{
|
||||
const unsigned int tess = 30;///TODO: IME tesselation factor through ai_property
|
||||
const unsigned int tess = 30;///TODO: IME tessellation factor through ai_property
|
||||
|
||||
std::vector<aiVector3D> tvec;// temp array for vertices.
|
||||
|
||||
|
@ -209,7 +209,7 @@ void X3DImporter::ParseNode_Geometry3D_Cylinder()
|
|||
}
|
||||
else
|
||||
{
|
||||
const unsigned int tess = 30;///TODO: IME tesselation factor through ai_property
|
||||
const unsigned int tess = 30;///TODO: IME tessellation factor through ai_property
|
||||
|
||||
std::vector<aiVector3D> tside;// temp array for vertices of side.
|
||||
std::vector<aiVector3D> tcir;// temp array for vertices of circle.
|
||||
|
@ -480,7 +480,7 @@ static aiVector3D GeometryHelper_Extrusion_GetNextY(const size_t pSpine_PointIdx
|
|||
tvec = pSpine[1] - pSpine[0];
|
||||
}
|
||||
else
|
||||
{// The Y-axis used for the last point it is the vector from spine[n-2] to spine[n-1]. In our case(see above about droping tail) spine[n - 1] is
|
||||
{// The Y-axis used for the last point it is the vector from spine[n-2] to spine[n-1]. In our case(see above about dropping tail) spine[n - 1] is
|
||||
// the spine[0].
|
||||
tvec = pSpine[spine_idx_last] - pSpine[spine_idx_last - 1];
|
||||
}
|
||||
|
@ -967,7 +967,7 @@ void X3DImporter::ParseNode_Geometry3D_Sphere()
|
|||
}
|
||||
else
|
||||
{
|
||||
const unsigned int tess = 3;///TODO: IME tesselation factor through ai_property
|
||||
const unsigned int tess = 3;///TODO: IME tessellation factor through ai_property
|
||||
|
||||
std::vector<aiVector3D> tlist;
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
}
|
||||
|
||||
/// \def MACRO_ATTRREAD_CHECK_REF
|
||||
/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
|
||||
/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
|
||||
/// "continue" will called.
|
||||
/// \param [in] pAttrName - attribute name.
|
||||
/// \param [out] pVarName - output variable name.
|
||||
|
@ -89,7 +89,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
}
|
||||
|
||||
/// \def MACRO_ATTRREAD_CHECK_RET
|
||||
/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
|
||||
/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
|
||||
/// If result was read then "continue" will called.
|
||||
/// \param [in] pAttrName - attribute name.
|
||||
/// \param [out] pVarName - output variable name.
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace Assimp
|
|||
if(!mReader->isEmptyElement()) \
|
||||
ParseNode_Metadata(pNE, pMetaName);/* in that case node element will be added to child elements list of current node. */ \
|
||||
else \
|
||||
NodeElement_Cur->Child.push_back(pNE);/* else - add element to child list manualy */ \
|
||||
NodeElement_Cur->Child.push_back(pNE);/* else - add element to child list manually */ \
|
||||
\
|
||||
NodeElement_List.push_back(pNE);/* add new element to elements list. */ \
|
||||
}/* if(!pUSE_Var.empty()) else */ \
|
||||
|
|
|
@ -132,7 +132,7 @@ void XFileExporter::WriteFile()
|
|||
{
|
||||
// note, that all realnumber values must be comma separated in x files
|
||||
mOutput.setf(std::ios::fixed);
|
||||
mOutput.precision(16); // precission for double
|
||||
mOutput.precision(16); // precision for double
|
||||
|
||||
// entry of writing the file
|
||||
WriteHeader();
|
||||
|
|
|
@ -498,7 +498,7 @@ aiMatrix4x4 XGLImporter::ReadTrafo()
|
|||
right = forward ^ up;
|
||||
if (std::fabs(up * forward) > 1e-4) {
|
||||
// this is definitely wrong - a degenerate coordinate space ruins everything
|
||||
// so subtitute identity transform.
|
||||
// so substitute identity transform.
|
||||
LogError("<forward> and <up> vectors in <transform> are skewing, ignoring trafo");
|
||||
return m;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*
|
||||
* glTF Extensions Support:
|
||||
* KHR_materials_pbrSpecularGlossiness full
|
||||
* KHR_materials_unlit full
|
||||
*/
|
||||
#ifndef GLTF2ASSET_H_INC
|
||||
#define GLTF2ASSET_H_INC
|
||||
|
@ -386,7 +387,7 @@ namespace glTF2
|
|||
};
|
||||
|
||||
|
||||
//! Base classe for all glTF top-level objects
|
||||
//! Base class for all glTF top-level objects
|
||||
struct Object
|
||||
{
|
||||
int index; //!< The index of this object within its property container
|
||||
|
@ -741,6 +742,9 @@ namespace glTF2
|
|||
//extension: KHR_materials_pbrSpecularGlossiness
|
||||
Nullable<PbrSpecularGlossiness> pbrSpecularGlossiness;
|
||||
|
||||
//extension: KHR_materials_unlit
|
||||
bool unlit;
|
||||
|
||||
Material() { SetDefaults(); }
|
||||
void Read(Value& obj, Asset& r);
|
||||
void SetDefaults();
|
||||
|
@ -1037,6 +1041,7 @@ namespace glTF2
|
|||
struct Extensions
|
||||
{
|
||||
bool KHR_materials_pbrSpecularGlossiness;
|
||||
bool KHR_materials_unlit;
|
||||
|
||||
} extensionsUsed;
|
||||
|
||||
|
|
|
@ -860,6 +860,8 @@ inline void Material::Read(Value& material, Asset& r)
|
|||
this->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
|
||||
}
|
||||
}
|
||||
|
||||
unlit = nullptr != FindObject(*extensions, "KHR_materials_unlit");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,6 +884,7 @@ inline void Material::SetDefaults()
|
|||
alphaMode = "OPAQUE";
|
||||
alphaCutoff = 0.5;
|
||||
doubleSided = false;
|
||||
unlit = false;
|
||||
}
|
||||
|
||||
inline void PbrSpecularGlossiness::SetDefaults()
|
||||
|
@ -1213,12 +1216,15 @@ inline void Asset::Load(const std::string& pFile, bool isBinary)
|
|||
|
||||
// Read the "scene" property, which specifies which scene to load
|
||||
// and recursively load everything referenced by it
|
||||
unsigned int sceneIndex = 0;
|
||||
if (Value* scene = FindUInt(doc, "scene")) {
|
||||
unsigned int sceneIndex = scene->GetUint();
|
||||
sceneIndex = scene->GetUint();
|
||||
}
|
||||
|
||||
Ref<Scene> s = scenes.Retrieve(sceneIndex);
|
||||
|
||||
this->scene = s;
|
||||
if (Value* scenesArray = FindArray(doc, "scenes")) {
|
||||
if (sceneIndex < scenesArray->Size()) {
|
||||
this->scene = scenes.Retrieve(sceneIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up
|
||||
|
@ -1253,6 +1259,7 @@ inline void Asset::ReadExtensionsUsed(Document& doc)
|
|||
if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
|
||||
|
||||
CHECK_EXT(KHR_materials_pbrSpecularGlossiness);
|
||||
CHECK_EXT(KHR_materials_unlit);
|
||||
|
||||
#undef CHECK_EXT
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*
|
||||
* glTF Extensions Support:
|
||||
* KHR_materials_pbrSpecularGlossiness: full
|
||||
* KHR_materials_unlit: full
|
||||
*/
|
||||
#ifndef GLTF2ASSETWRITER_H_INC
|
||||
#define GLTF2ASSETWRITER_H_INC
|
||||
|
|
|
@ -343,6 +343,12 @@ namespace glTF2 {
|
|||
}
|
||||
}
|
||||
|
||||
if (m.unlit) {
|
||||
Value unlit;
|
||||
unlit.SetObject();
|
||||
exts.AddMember("KHR_materials_unlit", unlit, w.mAl);
|
||||
}
|
||||
|
||||
if (!exts.ObjectEmpty()) {
|
||||
obj.AddMember("extensions", exts, w.mAl);
|
||||
}
|
||||
|
@ -683,6 +689,10 @@ namespace glTF2 {
|
|||
if (this->mAsset.extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
|
||||
exts.PushBack(StringRef("KHR_materials_pbrSpecularGlossiness"), mAl);
|
||||
}
|
||||
|
||||
if (this->mAsset.extensionsUsed.KHR_materials_unlit) {
|
||||
exts.PushBack(StringRef("KHR_materials_unlit"), mAl);
|
||||
}
|
||||
}
|
||||
|
||||
if (!exts.Empty())
|
||||
|
|
|
@ -138,28 +138,29 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
|
|||
}
|
||||
}
|
||||
|
||||
glTF2Exporter::~glTF2Exporter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a 4x4 matrix from struct aiMatrix to typedef mat4.
|
||||
* Also converts from row-major to column-major storage.
|
||||
*/
|
||||
static void CopyValue(const aiMatrix4x4& v, mat4& o)
|
||||
{
|
||||
static void CopyValue(const aiMatrix4x4& v, mat4& o) {
|
||||
o[ 0] = v.a1; o[ 1] = v.b1; o[ 2] = v.c1; o[ 3] = v.d1;
|
||||
o[ 4] = v.a2; o[ 5] = v.b2; o[ 6] = v.c2; o[ 7] = v.d2;
|
||||
o[ 8] = v.a3; o[ 9] = v.b3; o[10] = v.c3; o[11] = v.d3;
|
||||
o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4;
|
||||
}
|
||||
|
||||
static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o)
|
||||
{
|
||||
static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o) {
|
||||
o.a1 = v.a1; o.a2 = v.a2; o.a3 = v.a3; o.a4 = v.a4;
|
||||
o.b1 = v.b1; o.b2 = v.b2; o.b3 = v.b3; o.b4 = v.b4;
|
||||
o.c1 = v.c1; o.c2 = v.c2; o.c3 = v.c3; o.c4 = v.c4;
|
||||
o.d1 = v.d1; o.d2 = v.d2; o.d3 = v.d3; o.d4 = v.d4;
|
||||
}
|
||||
|
||||
static void IdentityMatrix4(mat4& o)
|
||||
{
|
||||
static void IdentityMatrix4(mat4& o) {
|
||||
o[ 0] = 1; o[ 1] = 0; o[ 2] = 0; o[ 3] = 0;
|
||||
o[ 4] = 0; o[ 5] = 1; o[ 6] = 0; o[ 7] = 0;
|
||||
o[ 8] = 0; o[ 9] = 0; o[10] = 1; o[11] = 0;
|
||||
|
@ -169,7 +170,9 @@ static void IdentityMatrix4(mat4& o)
|
|||
inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer,
|
||||
unsigned int count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, bool isIndices = false)
|
||||
{
|
||||
if (!count || !data) return Ref<Accessor>();
|
||||
if (!count || !data) {
|
||||
return Ref<Accessor>();
|
||||
}
|
||||
|
||||
unsigned int numCompsIn = AttribType::GetNumComponents(typeIn);
|
||||
unsigned int numCompsOut = AttribType::GetNumComponents(typeOut);
|
||||
|
@ -513,7 +516,7 @@ void glTF2Exporter::ExportMaterials()
|
|||
if (mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) != AI_SUCCESS) {
|
||||
float shininess;
|
||||
|
||||
if (mat->Get(AI_MATKEY_SHININESS, shininess)) {
|
||||
if (mat->Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
|
||||
pbrSG.glossinessFactor = shininess / 1000;
|
||||
}
|
||||
}
|
||||
|
@ -523,6 +526,12 @@ void glTF2Exporter::ExportMaterials()
|
|||
|
||||
m->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
|
||||
}
|
||||
|
||||
bool unlit;
|
||||
if (mat->Get(AI_MATKEY_GLTF_UNLIT, unlit) == AI_SUCCESS && unlit) {
|
||||
mAsset->extensionsUsed.KHR_materials_unlit = true;
|
||||
m->unlit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -638,11 +647,11 @@ void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buf
|
|||
Mesh::Primitive& p = meshRef->primitives.back();
|
||||
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
if ( vertexJointAccessor ) {
|
||||
unsigned int offset = vertexJointAccessor->bufferView->byteOffset;
|
||||
unsigned int bytesLen = vertexJointAccessor->bufferView->byteLength;
|
||||
size_t offset = vertexJointAccessor->bufferView->byteOffset;
|
||||
size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
|
||||
unsigned int s_bytesPerComp= ComponentTypeSize(ComponentType_UNSIGNED_SHORT);
|
||||
unsigned int bytesPerComp = ComponentTypeSize(vertexJointAccessor->componentType);
|
||||
unsigned int s_bytesLen = bytesLen * s_bytesPerComp / bytesPerComp;
|
||||
size_t s_bytesLen = bytesLen * s_bytesPerComp / bytesPerComp;
|
||||
Ref<Buffer> buf = vertexJointAccessor->bufferView->buffer;
|
||||
uint8_t* arrys = new uint8_t[s_bytesLen];
|
||||
unsigned int i = 0;
|
||||
|
@ -728,8 +737,10 @@ void glTF2Exporter::ExportMeshes()
|
|||
|
||||
/******************** Normals ********************/
|
||||
// Normalize all normals as the validator can emit a warning otherwise
|
||||
if ( nullptr != aim->mNormals) {
|
||||
for ( auto i = 0u; i < aim->mNumVertices; ++i ) {
|
||||
aim->mNormals[ i ].Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
|
||||
|
|
|
@ -87,28 +87,15 @@ namespace Assimp
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
/** Helper class to export a given scene to an glTF file. */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class glTF2Exporter
|
||||
{
|
||||
class glTF2Exporter {
|
||||
public:
|
||||
/// Constructor for a specific scene to export
|
||||
glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
|
||||
const ExportProperties* pProperties, bool binary);
|
||||
~glTF2Exporter();
|
||||
|
||||
private:
|
||||
|
||||
const char* mFilename;
|
||||
IOSystem* mIOSystem;
|
||||
const aiScene* mScene;
|
||||
const ExportProperties* mProperties;
|
||||
|
||||
std::map<std::string, unsigned int> mTexturesByPath;
|
||||
|
||||
std::shared_ptr<glTF2::Asset> mAsset;
|
||||
|
||||
std::vector<unsigned char> mBodyData;
|
||||
|
||||
protected:
|
||||
void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
|
||||
|
||||
void GetTexSampler(const aiMaterial* mat, glTF2::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||
void GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||
|
@ -126,6 +113,15 @@ namespace Assimp
|
|||
unsigned int ExportNode(const aiNode* node, glTF2::Ref<glTF2::Node>& parent);
|
||||
void ExportScene();
|
||||
void ExportAnimations();
|
||||
|
||||
private:
|
||||
const char* mFilename;
|
||||
IOSystem* mIOSystem;
|
||||
const aiScene* mScene;
|
||||
const ExportProperties* mProperties;
|
||||
std::map<std::string, unsigned int> mTexturesByPath;
|
||||
std::shared_ptr<glTF2::Asset> mAsset;
|
||||
std::vector<unsigned char> mBodyData;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -121,6 +121,21 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
|
|||
return false;
|
||||
}
|
||||
|
||||
static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode)
|
||||
{
|
||||
switch (gltfWrapMode) {
|
||||
case SamplerWrap::Mirrored_Repeat:
|
||||
return aiTextureMapMode_Mirror;
|
||||
|
||||
case SamplerWrap::Clamp_To_Edge:
|
||||
return aiTextureMapMode_Clamp;
|
||||
|
||||
case SamplerWrap::UNSET:
|
||||
case SamplerWrap::Repeat:
|
||||
default:
|
||||
return aiTextureMapMode_Wrap;
|
||||
}
|
||||
}
|
||||
|
||||
//static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
|
||||
//{
|
||||
|
@ -198,8 +213,10 @@ inline void SetMaterialTextureProperty(std::vector<int>& embeddedTexIdxs, Asset&
|
|||
mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot));
|
||||
mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot));
|
||||
|
||||
mat->AddProperty(&sampler->wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
|
||||
mat->AddProperty(&sampler->wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
|
||||
aiTextureMapMode wrapS = ConvertWrappingMode(sampler->wrapS);
|
||||
aiTextureMapMode wrapT = ConvertWrappingMode(sampler->wrapT);
|
||||
mat->AddProperty(&wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
|
||||
mat->AddProperty(&wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
|
||||
|
||||
if (sampler->magFilter != SamplerMagFilter::UNSET) {
|
||||
mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot));
|
||||
|
@ -281,6 +298,9 @@ static aiMaterial* ImportMaterial(std::vector<int>& embeddedTexIdxs, Asset& r, M
|
|||
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR);
|
||||
}
|
||||
if (mat.unlit) {
|
||||
aimat->AddProperty(&mat.unlit, 1, AI_MATKEY_GLTF_UNLIT);
|
||||
}
|
||||
|
||||
return aimat;
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@ namespace glTF
|
|||
};
|
||||
|
||||
|
||||
//! Base classe for all glTF top-level objects
|
||||
//! Base class for all glTF top-level objects
|
||||
struct Object
|
||||
{
|
||||
std::string id; //!< The globally unique ID used to reference this object
|
||||
|
|
|
@ -703,7 +703,7 @@ void glTFExporter::ExportMeshes()
|
|||
// Coordinates indices
|
||||
comp_o3dgc_ifs.SetNCoordIndex(aim->mNumFaces);
|
||||
comp_o3dgc_ifs.SetCoordIndex((IndicesType* const)&b->GetPointer()[idx_srcdata_ind]);
|
||||
// Prepare to enconding
|
||||
// Prepare to encoding
|
||||
comp_o3dgc_params.SetNumFloatAttributes(comp_o3dgc_ifs.GetNumFloatAttributes());
|
||||
if(mProperties->GetPropertyBool("extensions.Open3DGC.binary", true))
|
||||
comp_o3dgc_params.SetStreamType(o3dgc::O3DGC_STREAM_TYPE_BINARY);
|
||||
|
|
10
doc/dox.h
10
doc/dox.h
|
@ -164,7 +164,7 @@ If done correctly you should now be able to compile, link, run and use the appli
|
|||
@section install_own Building the library from scratch
|
||||
|
||||
First you need to install cmake. Now just get the code from github or download the latest version from the webside.
|
||||
to buil the library just open a command-prompt / bash, navigate into the repo-folder and run cmake via:
|
||||
to build the library just open a command-prompt / bash, navigate into the repo-folder and run cmake via:
|
||||
|
||||
@code
|
||||
cmake CMakeLists.txt
|
||||
|
@ -653,7 +653,7 @@ To apply such an animation you need to identify the animation tracks that refer
|
|||
in your mesh. Then for every track: <br>
|
||||
a) Find the keys that lay right before the current anim time. <br>
|
||||
b) Optional: interpolate between these and the following keys. <br>
|
||||
c) Combine the calculated position, rotation and scaling to a tranformation matrix <br>
|
||||
c) Combine the calculated position, rotation and scaling to a transformation matrix <br>
|
||||
d) Set the affected node's transformation to the calculated matrix. <br>
|
||||
|
||||
If you need hints on how to convert to or from quaternions, have a look at the
|
||||
|
@ -669,7 +669,7 @@ Such textures are loaded into an aiTexture structure.
|
|||
|
||||
In previous versions, the path from the query for `AI_MATKEY_TEXTURE(textureType, index)` would be
|
||||
`*<index>` where `<index>` is the index of the texture in aiScene::mTextures. Now this call will
|
||||
return a file path for embedded textures in FBX files. To test if it is an embdedded texture use
|
||||
return a file path for embedded textures in FBX files. To test if it is an embedded texture use
|
||||
aiScene::GetEmbeddedTexture. If the returned pointer is not null, it is embedded und can be loaded
|
||||
from the data structure. If it is null, search for a separate file. Other file types still use the
|
||||
old behaviour.<br>
|
||||
|
@ -794,7 +794,7 @@ All material key constants start with 'AI_MATKEY' (it's an ugly macro for histor
|
|||
<td><tt>COLOR_REFLECTIVE</tt></td>
|
||||
<td>aiColor3D</td>
|
||||
<td>black (0,0,0)</td>
|
||||
<td>Defines the reflective color of the material. This is typically scaled by the amount of incoming light from the direction of mirror reflection. Usually combined with an enviroment lightmap of some kind for real-time applications.</td>
|
||||
<td>Defines the reflective color of the material. This is typically scaled by the amount of incoming light from the direction of mirror reflection. Usually combined with an environment lightmap of some kind for real-time applications.</td>
|
||||
<td>---</td>
|
||||
</tr>
|
||||
|
||||
|
@ -819,7 +819,7 @@ All material key constants start with 'AI_MATKEY' (it's an ugly macro for histor
|
|||
<td>int</td>
|
||||
<td>false</td>
|
||||
<td>Specifies whether meshes using this material must be rendered without backface culling. 0 for false, !0 for true. </td>
|
||||
<td>Some importers set this property if they don't know whether the output face oder is right. As long as it is not set, you may safely enable backface culling.</tt></td>
|
||||
<td>Some importers set this property if they don't know whether the output face order is right. As long as it is not set, you may safely enable backface culling.</tt></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
|
|
@ -134,6 +134,30 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Extract a particular vertex from a anim mesh and interleave all components */
|
||||
explicit Vertex(const aiAnimMesh* msh, unsigned int idx) {
|
||||
ai_assert(idx < msh->mNumVertices);
|
||||
position = msh->mVertices[idx];
|
||||
|
||||
if (msh->HasNormals()) {
|
||||
normal = msh->mNormals[idx];
|
||||
}
|
||||
|
||||
if (msh->HasTangentsAndBitangents()) {
|
||||
tangent = msh->mTangents[idx];
|
||||
bitangent = msh->mBitangents[idx];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) {
|
||||
texcoords[i] = msh->mTextureCoords[i][idx];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; msh->HasVertexColors(i); ++i) {
|
||||
colors[i] = msh->mColors[i][idx];
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Vertex& operator += (const Vertex& v) {
|
||||
|
|
|
@ -149,7 +149,8 @@ struct aiMetadata {
|
|||
mValues[ i ].mType = rhs.mValues[ i ].mType;
|
||||
switch ( rhs.mValues[ i ].mType ) {
|
||||
case AI_BOOL:
|
||||
mValues[ i ].mData = new bool( rhs.mValues[i].mData );
|
||||
mValues[ i ].mData = new bool;
|
||||
::memcpy( mValues[ i ].mData, rhs.mValues[ i ].mData, sizeof(bool) );
|
||||
break;
|
||||
case AI_INT32: {
|
||||
int32_t v;
|
||||
|
|
|
@ -56,6 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0
|
||||
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
|
||||
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
|
||||
#define AI_MATKEY_GLTF_UNLIT "$mat.gltf.unlit", 0, 0
|
||||
|
||||
#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
|
||||
#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"
|
||||
|
|
|
@ -98,8 +98,10 @@ AI_FORCE_INLINE bool is_qnan(float in)
|
|||
// compare <register-with-different-width> against <in>
|
||||
|
||||
// FIXME: Use <float> stuff instead? I think fpclassify needs C99
|
||||
return (reinterpret_cast<_IEEESingle*>(&in)->IEEE.Exp == (1u << 8)-1 &&
|
||||
reinterpret_cast<_IEEESingle*>(&in)->IEEE.Frac);
|
||||
_IEEESingle temp;
|
||||
memcpy(&temp, &in, sizeof(float));
|
||||
return (temp.IEEE.Exp == (1u << 8)-1 &&
|
||||
temp.IEEE.Frac);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -114,8 +116,10 @@ AI_FORCE_INLINE bool is_qnan(double in)
|
|||
// compare <register-with-different-width> against <in>
|
||||
|
||||
// FIXME: Use <float> stuff instead? I think fpclassify needs C99
|
||||
return (reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Exp == (1u << 11)-1 &&
|
||||
reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Frac);
|
||||
_IEEEDouble temp;
|
||||
memcpy(&temp, &in, sizeof(in));
|
||||
return (temp.IEEE.Exp == (1u << 11)-1 &&
|
||||
temp.IEEE.Frac);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -125,7 +129,9 @@ AI_FORCE_INLINE bool is_qnan(double in)
|
|||
* @param in Input value */
|
||||
AI_FORCE_INLINE bool is_special_float(float in)
|
||||
{
|
||||
return (reinterpret_cast<_IEEESingle*>(&in)->IEEE.Exp == (1u << 8)-1);
|
||||
_IEEESingle temp;
|
||||
memcpy(&temp, &in, sizeof(float));
|
||||
return (temp.IEEE.Exp == (1u << 8)-1);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -135,7 +141,9 @@ AI_FORCE_INLINE bool is_special_float(float in)
|
|||
* @param in Input value */
|
||||
AI_FORCE_INLINE bool is_special_float(double in)
|
||||
{
|
||||
return (reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Exp == (1u << 11)-1);
|
||||
_IEEESingle temp;
|
||||
memcpy(&temp, &in, sizeof(float));
|
||||
return (temp.IEEE.Exp == (1u << 11)-1);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -1 +1 @@
|
|||
See https://code.google.com/p/assimp-net/ and https://github.com/assimp/assimp-net for a Github mirror.
|
||||
Please check the following github-repo for the source: https://github.com/kebby/assimp-net
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
PyAssimp Readme
|
||||
===============
|
||||
|
||||
A simple Python wrapper for Assimp using `ctypes` to access the library.
|
||||
Requires Python >= 2.6.
|
||||
|
||||
Python 3 support is mostly here, but not well tested.
|
||||
|
||||
Note that pyassimp is not complete. Many ASSIMP features are missing.
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
||||
### Complete example: 3D viewer
|
||||
|
||||
`pyassimp` comes with a simple 3D viewer that shows how to load and display a 3D
|
||||
model using a shader-based OpenGL pipeline.
|
||||
|
||||
![Screenshot](3d_viewer_screenshot.png)
|
||||
|
||||
To use it, from within `/port/PyAssimp`:
|
||||
|
||||
```
|
||||
$ cd scripts
|
||||
$ python ./3D-viewer <path to your model>
|
||||
```
|
||||
|
||||
You can use this code as starting point in your applications.
|
||||
|
||||
### Writing your own code
|
||||
|
||||
To get started with `pyassimp`, examine the simpler `sample.py` script in `scripts/`,
|
||||
which illustrates the basic usage. All Assimp data structures are wrapped using
|
||||
`ctypes`. All the data+length fields in Assimp's data structures (such as
|
||||
`aiMesh::mNumVertices`, `aiMesh::mVertices`) are replaced by simple python
|
||||
lists, so you can call `len()` on them to get their respective size and access
|
||||
members using `[]`.
|
||||
|
||||
For example, to load a file named `hello.3ds` and print the first
|
||||
vertex of the first mesh, you would do (proper error handling
|
||||
substituted by assertions ...):
|
||||
|
||||
```python
|
||||
|
||||
from pyassimp import *
|
||||
scene = load('hello.3ds')
|
||||
|
||||
assert len(scene.meshes)
|
||||
mesh = scene.meshes[0]
|
||||
|
||||
assert len(mesh.vertices)
|
||||
print(mesh.vertices[0])
|
||||
|
||||
# don't forget this one, or you will leak!
|
||||
release(scene)
|
||||
|
||||
```
|
||||
|
||||
Another example to list the 'top nodes' in a
|
||||
scene:
|
||||
|
||||
```python
|
||||
|
||||
from pyassimp import *
|
||||
scene = load('hello.3ds')
|
||||
|
||||
for c in scene.rootnode.children:
|
||||
print(str(c))
|
||||
|
||||
release(scene)
|
||||
|
||||
```
|
||||
|
||||
INSTALL
|
||||
-------
|
||||
|
||||
Install `pyassimp` by running:
|
||||
|
||||
```
|
||||
$ python setup.py install
|
||||
```
|
||||
|
||||
PyAssimp requires a assimp dynamic library (`DLL` on windows,
|
||||
`.so` on linux, `.dynlib` on macOS) in order to work. The default search directories
|
||||
are:
|
||||
|
||||
- the current directory
|
||||
- on linux additionally: `/usr/lib`, `/usr/local/lib`,
|
||||
`/usr/lib/x86_64-linux-gnu`
|
||||
|
||||
To build that library, refer to the Assimp master `INSTALL`
|
||||
instructions. To look in more places, edit `./pyassimp/helper.py`.
|
||||
There's an `additional_dirs` list waiting for your entries.
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
PyAssimp: Python bindings for libassimp
|
||||
=======================================
|
||||
|
||||
A simple Python wrapper for Assimp using ``ctypes`` to access the
|
||||
library. Requires Python >= 2.6.
|
||||
|
||||
Python 3 support is mostly here, but not well tested.
|
||||
|
||||
Note that pyassimp is not complete. Many ASSIMP features are missing.
|
||||
|
||||
USAGE
|
||||
-----
|
||||
|
||||
Complete example: 3D viewer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
``pyassimp`` comes with a simple 3D viewer that shows how to load and
|
||||
display a 3D model using a shader-based OpenGL pipeline.
|
||||
|
||||
.. figure:: 3d_viewer_screenshot.png
|
||||
:alt: Screenshot
|
||||
|
||||
Screenshot
|
||||
|
||||
To use it, from within ``/port/PyAssimp``:
|
||||
|
||||
::
|
||||
|
||||
$ cd scripts
|
||||
$ python ./3D-viewer <path to your model>
|
||||
|
||||
You can use this code as starting point in your applications.
|
||||
|
||||
Writing your own code
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To get started with ``pyassimp``, examine the simpler ``sample.py``
|
||||
script in ``scripts/``, which illustrates the basic usage. All Assimp
|
||||
data structures are wrapped using ``ctypes``. All the data+length fields
|
||||
in Assimp's data structures (such as ``aiMesh::mNumVertices``,
|
||||
``aiMesh::mVertices``) are replaced by simple python lists, so you can
|
||||
call ``len()`` on them to get their respective size and access members
|
||||
using ``[]``.
|
||||
|
||||
For example, to load a file named ``hello.3ds`` and print the first
|
||||
vertex of the first mesh, you would do (proper error handling
|
||||
substituted by assertions ...):
|
||||
|
||||
.. code:: python
|
||||
|
||||
|
||||
from pyassimp import *
|
||||
scene = load('hello.3ds')
|
||||
|
||||
assert len(scene.meshes)
|
||||
mesh = scene.meshes[0]
|
||||
|
||||
assert len(mesh.vertices)
|
||||
print(mesh.vertices[0])
|
||||
|
||||
# don't forget this one, or you will leak!
|
||||
release(scene)
|
||||
|
||||
Another example to list the 'top nodes' in a scene:
|
||||
|
||||
.. code:: python
|
||||
|
||||
|
||||
from pyassimp import *
|
||||
scene = load('hello.3ds')
|
||||
|
||||
for c in scene.rootnode.children:
|
||||
print(str(c))
|
||||
|
||||
release(scene)
|
||||
|
||||
INSTALL
|
||||
-------
|
||||
|
||||
Install ``pyassimp`` by running:
|
||||
|
||||
::
|
||||
|
||||
$ python setup.py install
|
||||
|
||||
PyAssimp requires a assimp dynamic library (``DLL`` on windows, ``.so``
|
||||
on linux, ``.dynlib`` on macOS) in order to work. The default search
|
||||
directories are:
|
||||
|
||||
- the current directory
|
||||
- on linux additionally: ``/usr/lib``, ``/usr/local/lib``,
|
||||
``/usr/lib/x86_64-linux-gnu``
|
||||
|
||||
To build that library, refer to the Assimp master ``INSTALL``
|
||||
instructions. To look in more places, edit ``./pyassimp/helper.py``.
|
||||
There's an ``additional_dirs`` list waiting for your entries.
|
|
@ -312,7 +312,7 @@ def load(filename,
|
|||
file_type)
|
||||
else:
|
||||
# a filename string has been passed
|
||||
model = _assimp_lib.load(filename.encode("ascii"), processing)
|
||||
model = _assimp_lib.load(filename.encode(sys.getfilesystemencoding()), processing)
|
||||
|
||||
if not model:
|
||||
raise AssimpError('Could not import file!')
|
||||
|
@ -342,7 +342,7 @@ def export(scene,
|
|||
'''
|
||||
|
||||
from ctypes import pointer
|
||||
exportStatus = _assimp_lib.export(pointer(scene), file_type.encode("ascii"), filename.encode("ascii"), processing)
|
||||
exportStatus = _assimp_lib.export(pointer(scene), file_type.encode("ascii"), filename.encode(sys.getfilesystemencoding()), processing)
|
||||
|
||||
if exportStatus != 0:
|
||||
raise AssimpError('Could not export scene!')
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
from distutils.core import setup
|
||||
|
||||
def readme():
|
||||
with open('README.rst') as f:
|
||||
return f.read()
|
||||
|
||||
setup(name='pyassimp',
|
||||
version='4.1.0',
|
||||
version='4.1.3',
|
||||
license='ISC',
|
||||
description='Python bindings for the Open Asset Import Library (ASSIMP)',
|
||||
long_description=readme(),
|
||||
url='https://github.com/assimp/assimp',
|
||||
author='ASSIMP developers',
|
||||
author_email='assimp-discussions@lists.sourceforge.net',
|
||||
maintainer='SĂ©verin Lemaignan',
|
||||
maintainer_email='severin@guakamole.org',
|
||||
packages=['pyassimp'],
|
||||
data_files=[
|
||||
('share/pyassimp', ['README.md']),
|
||||
('share/pyassimp', ['README.rst']),
|
||||
('share/examples/pyassimp', ['scripts/' + f for f in os.listdir('scripts/')])
|
||||
],
|
||||
requires=['numpy']
|
||||
|
|
|
@ -59,9 +59,9 @@ build_arch()
|
|||
$XCODE_ROOT_DIR/Developer/usr/bin/make clean
|
||||
$XCODE_ROOT_DIR/Developer/usr/bin/make assimp -j 8 -l
|
||||
|
||||
echo "[!] Moving built library into: $BUILD_DIR/$1/"
|
||||
echo "[!] Moving built libraries into: $BUILD_DIR/$1/"
|
||||
|
||||
mv ./lib/libassimp.a $BUILD_DIR/$1/
|
||||
mv ./lib/*.a $BUILD_DIR/$1/
|
||||
}
|
||||
|
||||
echo "[!] $0 - assimp iOS build script"
|
||||
|
@ -110,14 +110,27 @@ for ARCH_TARGET in $DEPLOY_ARCHS; do
|
|||
#rm ./lib/libassimp.a
|
||||
done
|
||||
|
||||
if [[ "$DEPLOY_FAT" -eq 1 ]]; then
|
||||
echo '[+] Creating fat binary ...'
|
||||
|
||||
make_fat_binary()
|
||||
{
|
||||
LIB_NAME=$1
|
||||
LIPO_ARGS=''
|
||||
for ARCH_TARGET in $DEPLOY_ARCHS; do
|
||||
LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/libassimp.a "
|
||||
LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.a "
|
||||
done
|
||||
LIPO_ARGS="$LIPO_ARGS-create -output $BUILD_DIR/libassimp-fat.a"
|
||||
LIPO_ARGS="$LIPO_ARGS-create -output $BUILD_DIR/$LIB_NAME-fat.a"
|
||||
lipo $LIPO_ARGS
|
||||
echo "[!] Done! The fat binary can be found at $BUILD_DIR"
|
||||
}
|
||||
|
||||
if [[ "$DEPLOY_FAT" -eq 1 ]]; then
|
||||
echo '[+] Creating fat binaries ...'
|
||||
|
||||
make_fat_binary 'libassimp'
|
||||
make_fat_binary 'libIrrXML'
|
||||
make_fat_binary 'libzlibstatic'
|
||||
|
||||
echo "[!] Done! The fat binaries can be found at $BUILD_DIR"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
solid testTriangle
|
||||
facet normal 0.0 0.0 1.0
|
||||
outer loop
|
||||
vertex 1.0 1.0 0.0
|
||||
vertex -1.0 1.0 0.0
|
||||
vertex 0.0 -1.0 0.0
|
||||
endloop
|
||||
endfacet
|
||||
endsolid
|
||||
solid emptySolid
|
||||
endsolid
|
|
@ -146,8 +146,8 @@
|
|||
{
|
||||
"magFilter": 9729,
|
||||
"minFilter": 9986,
|
||||
"wrapS": 10497,
|
||||
"wrapT": 10497
|
||||
"wrapS": 33648,
|
||||
"wrapT": 33071
|
||||
}
|
||||
],
|
||||
"bufferViews": [
|
||||
|
|
|
@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
#include "UnitTestPCH.h"
|
||||
#include "AbstractImportExportBase.h"
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#include <assimp/Importer.hpp>
|
||||
|
||||
|
@ -52,13 +53,90 @@ class utLWSImportExport : public AbstractImportExportBase {
|
|||
public:
|
||||
virtual bool importerTest() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/LWS/move_x.lws", 0 );
|
||||
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/LWS/move_x.lws", aiProcess_ValidateDataStructure);
|
||||
return nullptr != scene;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F( utLWSImportExport, importLWSFromFileTest ) {
|
||||
EXPECT_TRUE( importerTest() );
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_x_post_linear) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_x_post_linear.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_xz_bezier) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_xz_bezier.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_xz_stepped) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_xz_stepped.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_x_oldformat_56) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_x_oldformat_56.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_x_post_offset_repeat) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_x_post_offset_repeat.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_xz_hermite) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_xz_hermite.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_y_pre_ofrep_post_osc) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_y_pre_ofrep_post_osc.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_x_oldformat_6) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_x_oldformat_6.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_x_post_repeat) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_x_post_repeat.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_xz_linear) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_xz_linear.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_x_post_constant) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_x_post_constant.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_x_post_reset) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_x_post_reset.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
TEST_F(utLWSImportExport, importLWSmove_xz_spline) {
|
||||
::Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/LWS/move_xz_spline.lws", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
|
|
|
@ -210,7 +210,7 @@ TEST_F( utMetadata, copy_test ) {
|
|||
|
||||
// int32_t test
|
||||
{
|
||||
int32_t v;
|
||||
int32_t v = 0;
|
||||
bool ok = copy.Get( "int32", v );
|
||||
EXPECT_TRUE( ok );
|
||||
EXPECT_EQ( i32v, v );
|
||||
|
|
|
@ -73,6 +73,16 @@ TEST_F( utSTLImporterExporter, test_with_two_solids ) {
|
|||
EXPECT_NE( nullptr, scene );
|
||||
}
|
||||
|
||||
TEST_F(utSTLImporterExporter, test_with_empty_solid) {
|
||||
Assimp::Importer importer;
|
||||
//STL File with empty mesh. We should still be able to import other meshes in this file. ValidateDataStructure should fail.
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_empty_solid.stl", 0);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
|
||||
const aiScene *scene2 = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_empty_solid.stl", aiProcess_ValidateDataStructure);
|
||||
EXPECT_EQ(nullptr, scene2);
|
||||
}
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
|
||||
TEST_F(utSTLImporterExporter, exporterTest) {
|
||||
|
|
|
@ -78,7 +78,7 @@ TEST_F(SharedPPDataTest, testPODProperty)
|
|||
{
|
||||
int i = 5;
|
||||
shared->AddProperty("test",i);
|
||||
int o;
|
||||
int o = 0;
|
||||
EXPECT_TRUE(shared->GetProperty("test",o));
|
||||
EXPECT_EQ(5, o);
|
||||
EXPECT_FALSE(shared->GetProperty("test2",o));
|
||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <assimp/scene.h>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
@ -54,7 +55,21 @@ public:
|
|||
virtual bool importerTest() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", aiProcess_ValidateDataStructure);
|
||||
return nullptr != scene;
|
||||
EXPECT_NE( scene, nullptr );
|
||||
if ( !scene ) return false;
|
||||
|
||||
EXPECT_TRUE( scene->HasMaterials() );
|
||||
if ( !scene->HasMaterials() ) return false;
|
||||
const aiMaterial *material = scene->mMaterials[0];
|
||||
|
||||
aiString path;
|
||||
aiTextureMapMode modes[2];
|
||||
EXPECT_EQ( aiReturn_SUCCESS, material->GetTexture(aiTextureType_DIFFUSE, 0, &path, nullptr, nullptr, nullptr, nullptr, modes) );
|
||||
EXPECT_STREQ( path.C_Str(), "CesiumLogoFlat.png" );
|
||||
EXPECT_EQ( modes[0], aiTextureMapMode_Mirror );
|
||||
EXPECT_EQ( modes[1], aiTextureMapMode_Clamp );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool binaryImporterTest() {
|
||||
|
@ -89,4 +104,5 @@ TEST_F( utglTF2ImportExport, importBinaryglTF2FromFileTest ) {
|
|||
TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
|
||||
EXPECT_TRUE( exporterTest() );
|
||||
}
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
|
|
|
@ -106,6 +106,7 @@ int Assimp_Export(const char* const* params, unsigned int num)
|
|||
continue;
|
||||
}
|
||||
if (!strncmp( params[i], "-f",2)) {
|
||||
if ( strncmp( params[ i ], "-fi",3 ))
|
||||
outf = std::string(params[i]+2);
|
||||
}
|
||||
else if ( !strncmp( params[i], "--format=",9)) {
|
||||
|
|
|
@ -261,7 +261,6 @@ void PrintHorBar()
|
|||
printf("-----------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Import a specific file
|
||||
const aiScene* ImportModel(
|
||||
|
@ -390,105 +389,101 @@ int ProcessStandardArguments(
|
|||
|
||||
for (unsigned int i = 0; i < num;++i)
|
||||
{
|
||||
if (! strcmp(params[i], "-ptv") || ! strcmp(params[i], "--pretransform-vertices")) {
|
||||
const char *param = params[ i ];
|
||||
printf( "param = %s\n", param );
|
||||
if (! strcmp( param, "-ptv") || ! strcmp( param, "--pretransform-vertices")) {
|
||||
fill.ppFlags |= aiProcess_PreTransformVertices;
|
||||
}
|
||||
else if (! strcmp(params[i], "-gsn") || ! strcmp(params[i], "--gen-smooth-normals")) {
|
||||
else if (! strcmp( param, "-gsn") || ! strcmp( param, "--gen-smooth-normals")) {
|
||||
fill.ppFlags |= aiProcess_GenSmoothNormals;
|
||||
}
|
||||
else if (! strcmp(params[i], "-gn") || ! strcmp(params[i], "--gen-normals")) {
|
||||
else if (! strcmp( param, "-gn") || ! strcmp( param, "--gen-normals")) {
|
||||
fill.ppFlags |= aiProcess_GenNormals;
|
||||
}
|
||||
else if (! strcmp(params[i], "-jiv") || ! strcmp(params[i], "--join-identical-vertices")) {
|
||||
else if (! strcmp( param, "-jiv") || ! strcmp( param, "--join-identical-vertices")) {
|
||||
fill.ppFlags |= aiProcess_JoinIdenticalVertices;
|
||||
}
|
||||
else if (! strcmp(params[i], "-rrm") || ! strcmp(params[i], "--remove-redundant-materials")) {
|
||||
else if (! strcmp( param, "-rrm") || ! strcmp( param, "--remove-redundant-materials")) {
|
||||
fill.ppFlags |= aiProcess_RemoveRedundantMaterials;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fd") || ! strcmp(params[i], "--find-degenerates")) {
|
||||
else if (! strcmp( param, "-fd") || ! strcmp( param, "--find-degenerates")) {
|
||||
fill.ppFlags |= aiProcess_FindDegenerates;
|
||||
}
|
||||
else if (! strcmp(params[i], "-slm") || ! strcmp(params[i], "--split-large-meshes")) {
|
||||
else if (! strcmp( param, "-slm") || ! strcmp( param, "--split-large-meshes")) {
|
||||
fill.ppFlags |= aiProcess_SplitLargeMeshes;
|
||||
}
|
||||
else if (! strcmp(params[i], "-lbw") || ! strcmp(params[i], "--limit-bone-weights")) {
|
||||
else if (! strcmp( param, "-lbw") || ! strcmp( param, "--limit-bone-weights")) {
|
||||
fill.ppFlags |= aiProcess_LimitBoneWeights;
|
||||
}
|
||||
else if (! strcmp(params[i], "-vds") || ! strcmp(params[i], "--validate-data-structure")) {
|
||||
else if (! strcmp( param, "-vds") || ! strcmp( param, "--validate-data-structure")) {
|
||||
fill.ppFlags |= aiProcess_ValidateDataStructure;
|
||||
}
|
||||
else if (! strcmp(params[i], "-icl") || ! strcmp(params[i], "--improve-cache-locality")) {
|
||||
else if (! strcmp( param, "-icl") || ! strcmp( param, "--improve-cache-locality")) {
|
||||
fill.ppFlags |= aiProcess_ImproveCacheLocality;
|
||||
}
|
||||
else if (! strcmp(params[i], "-sbpt") || ! strcmp(params[i], "--sort-by-ptype")) {
|
||||
else if (! strcmp( param, "-sbpt") || ! strcmp( param, "--sort-by-ptype")) {
|
||||
fill.ppFlags |= aiProcess_SortByPType;
|
||||
}
|
||||
else if (! strcmp(params[i], "-lh") || ! strcmp(params[i], "--left-handed")) {
|
||||
else if (! strcmp( param, "-lh") || ! strcmp( param, "--left-handed")) {
|
||||
fill.ppFlags |= aiProcess_ConvertToLeftHanded;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fuv") || ! strcmp(params[i], "--flip-uv")) {
|
||||
else if (! strcmp( param, "-fuv") || ! strcmp( param, "--flip-uv")) {
|
||||
fill.ppFlags |= aiProcess_FlipUVs;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fwo") || ! strcmp(params[i], "--flip-winding-order")) {
|
||||
else if (! strcmp( param, "-fwo") || ! strcmp( param, "--flip-winding-order")) {
|
||||
fill.ppFlags |= aiProcess_FlipWindingOrder;
|
||||
}
|
||||
else if (! strcmp(params[i], "-tuv") || ! strcmp(params[i], "--transform-uv-coords")) {
|
||||
else if (! strcmp( param, "-tuv") || ! strcmp( param, "--transform-uv-coords")) {
|
||||
fill.ppFlags |= aiProcess_TransformUVCoords;
|
||||
}
|
||||
else if (! strcmp(params[i], "-guv") || ! strcmp(params[i], "--gen-uvcoords")) {
|
||||
else if (! strcmp( param, "-guv") || ! strcmp( param, "--gen-uvcoords")) {
|
||||
fill.ppFlags |= aiProcess_GenUVCoords;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fid") || ! strcmp(params[i], "--find-invalid-data")) {
|
||||
else if (! strcmp( param, "-fid") || ! strcmp( param, "--find-invalid-data")) {
|
||||
fill.ppFlags |= aiProcess_FindInvalidData;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fixn") || ! strcmp(params[i], "--fix-normals")) {
|
||||
else if (! strcmp( param, "-fixn") || ! strcmp( param, "--fix-normals")) {
|
||||
fill.ppFlags |= aiProcess_FixInfacingNormals;
|
||||
}
|
||||
else if (! strcmp(params[i], "-tri") || ! strcmp(params[i], "--triangulate")) {
|
||||
else if (! strcmp( param, "-tri") || ! strcmp( param, "--triangulate")) {
|
||||
fill.ppFlags |= aiProcess_Triangulate;
|
||||
}
|
||||
else if (! strcmp(params[i], "-cts") || ! strcmp(params[i], "--calc-tangent-space")) {
|
||||
else if (! strcmp( param, "-cts") || ! strcmp( param, "--calc-tangent-space")) {
|
||||
fill.ppFlags |= aiProcess_CalcTangentSpace;
|
||||
}
|
||||
else if (! strcmp(params[i], "-fi") || ! strcmp(params[i], "--find-instances")) {
|
||||
else if (! strcmp( param, "-fi") || ! strcmp( param, "--find-instances")) {
|
||||
fill.ppFlags |= aiProcess_FindInstances;
|
||||
}
|
||||
else if (! strcmp(params[i], "-og") || ! strcmp(params[i], "--optimize-graph")) {
|
||||
else if (! strcmp( param, "-og") || ! strcmp( param, "--optimize-graph")) {
|
||||
fill.ppFlags |= aiProcess_OptimizeGraph;
|
||||
}
|
||||
else if (! strcmp(params[i], "-om") || ! strcmp(params[i], "--optimize-meshes")) {
|
||||
else if (! strcmp( param, "-om") || ! strcmp( param, "--optimize-meshes")) {
|
||||
fill.ppFlags |= aiProcess_OptimizeMeshes;
|
||||
}
|
||||
else if (! strcmp(params[i], "-db") || ! strcmp(params[i], "--debone")) {
|
||||
else if (! strcmp( param, "-db") || ! strcmp( param, "--debone")) {
|
||||
fill.ppFlags |= aiProcess_Debone;
|
||||
}
|
||||
else if (! strcmp(params[i], "-sbc") || ! strcmp(params[i], "--split-by-bone-count")) {
|
||||
else if (! strcmp( param, "-sbc") || ! strcmp( param, "--split-by-bone-count")) {
|
||||
fill.ppFlags |= aiProcess_SplitByBoneCount;
|
||||
}
|
||||
|
||||
|
||||
else if (! strncmp(params[i], "-c",2) || ! strncmp(params[i], "--config=",9)) {
|
||||
|
||||
else if (! strncmp( param, "-c",2) || ! strncmp( param, "--config=",9)) {
|
||||
const unsigned int ofs = (params[i][1] == '-' ? 9 : 2);
|
||||
|
||||
// use default configurations
|
||||
if (! strncmp(params[i]+ofs,"full",4)) {
|
||||
if (!strncmp( param + ofs, "full", 4 )) {
|
||||
fill.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality;
|
||||
}
|
||||
else if (! strncmp(params[i]+ofs,"default",7)) {
|
||||
} else if (!strncmp( param + ofs, "default", 7 )) {
|
||||
fill.ppFlags |= aiProcessPreset_TargetRealtime_Quality;
|
||||
}
|
||||
else if (! strncmp(params[i]+ofs,"fast",4)) {
|
||||
} else if (! strncmp( param +ofs,"fast",4)) {
|
||||
fill.ppFlags |= aiProcessPreset_TargetRealtime_Fast;
|
||||
}
|
||||
}
|
||||
else if (! strcmp(params[i], "-l") || ! strcmp(params[i], "--show-log")) {
|
||||
} else if (! strcmp( param, "-l") || ! strcmp( param, "--show-log")) {
|
||||
fill.showLog = true;
|
||||
}
|
||||
else if (! strcmp(params[i], "-v") || ! strcmp(params[i], "--verbose")) {
|
||||
else if (! strcmp( param, "-v") || ! strcmp( param, "--verbose")) {
|
||||
fill.verbose = true;
|
||||
}
|
||||
else if (! strncmp(params[i], "--log-out=",10) || ! strncmp(params[i], "-lo",3)) {
|
||||
else if (! strncmp( param, "--log-out=",10) || ! strncmp( param, "-lo",3)) {
|
||||
fill.logFile = std::string(params[i]+(params[i][1] == '-' ? 10 : 3));
|
||||
if (!fill.logFile.length()) {
|
||||
fill.logFile = "assimp-log.txt";
|
||||
|
|
|
@ -3,12 +3,55 @@ project(assimp_qt_viewer)
|
|||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(DevIL REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
OPTION( ASSIMP_QT4_VIEWER
|
||||
"Set to ON to enable Qt4 against Qt5 for assimp_qt_viewer"
|
||||
OFF
|
||||
)
|
||||
|
||||
include_directories(
|
||||
${Qt5Widgets_INCLUDES}
|
||||
FIND_PACKAGE(DevIL QUIET)
|
||||
FIND_PACKAGE(OpenGL QUIET)
|
||||
|
||||
IF(ASSIMP_QT4_VIEWER)
|
||||
# Qt4 version
|
||||
FIND_PACKAGE(Qt4 QUIET)
|
||||
ELSE(ASSIMP_QT4_VIEWER)
|
||||
# Qt5 version
|
||||
FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
|
||||
ENDIF(ASSIMP_QT4_VIEWER)
|
||||
|
||||
SET(VIEWER_BUILD:BOOL FALSE)
|
||||
|
||||
IF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND)
|
||||
SET(VIEWER_BUILD TRUE)
|
||||
|
||||
ELSE((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
|
||||
|
||||
IF(ASSIMP_QT4_VIEWER)
|
||||
IF (NOT Qt4_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt4")
|
||||
ENDIF (NOT Qt4_FOUND)
|
||||
|
||||
ELSE(ASSIMP_QT4_VIEWER)
|
||||
IF (NOT Qt5_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
|
||||
ENDIF (NOT Qt5_FOUND)
|
||||
|
||||
ENDIF(ASSIMP_QT4_VIEWER)
|
||||
|
||||
IF (NOT IL_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL")
|
||||
ENDIF (NOT IL_FOUND)
|
||||
|
||||
IF (NOT OPENGL_FOUND)
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
|
||||
ENDIF (NOT OPENGL_FOUND)
|
||||
|
||||
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
|
||||
ENDIF((Qt4_FOUND OR Qt5Widgets_FOUND) AND IL_FOUND AND OPENGL_FOUND)
|
||||
|
||||
IF(VIEWER_BUILD)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${Assimp_SOURCE_DIR}/include
|
||||
${Assimp_SOURCE_DIR}/code
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
@ -17,29 +60,46 @@ include_directories(
|
|||
${IL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
link_directories(${Assimp_BINARY_DIR})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
|
||||
LINK_DIRECTORIES(${Assimp_BINARY_DIR})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
|
||||
|
||||
set(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp)
|
||||
SET(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp)
|
||||
|
||||
IF(ASSIMP_QT4_VIEWER)
|
||||
MESSAGE("assimp_qt_viewer use Qt4")
|
||||
ADD_DEFINITIONS( -DASSIMP_QT4_VIEWER )
|
||||
INCLUDE_DIRECTORIES(${QT_INCLUDES})
|
||||
qt4_wrap_ui(UISrcs mainwindow.ui)
|
||||
qt4_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
|
||||
ELSE()
|
||||
MESSAGE("assimp_qt_viewer use Qt5")
|
||||
INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
|
||||
qt5_wrap_ui(UISrcs mainwindow.ui)
|
||||
qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
|
||||
ENDIF()
|
||||
|
||||
add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
|
||||
|
||||
IF(ASSIMP_QT4_VIEWER)
|
||||
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
|
||||
ELSE()
|
||||
target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
|
||||
ENDIF()
|
||||
|
||||
qt5_use_modules(${PROJECT_NAME} Widgets OpenGL)
|
||||
if(WIN32) # Check if we are on Windows
|
||||
if(MSVC) # Check if we are using the Visual Studio compiler
|
||||
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)
|
||||
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)
|
||||
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()
|
||||
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})
|
||||
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
INSTALL(TARGETS assimp_qt_viewer DESTINATION "${ASSIMP_BIN_INSTALL_DIR}")
|
||||
ENDIF(VIEWER_BUILD)
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
|
||||
#include "glview.hpp"
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QTime>
|
||||
|
||||
// Header files, OpenGL.
|
||||
#if defined(__APPLE__)
|
||||
# include <OpenGL/glu.h>
|
||||
|
@ -58,6 +61,33 @@ void CGLView::SHelper_Camera::SetDefault()
|
|||
/************ CGLView *************/
|
||||
/**********************************/
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
# define ConditionalContextControl_Begin \
|
||||
bool ContextEnabledHere; \
|
||||
\
|
||||
if(mGLContext_Current) \
|
||||
{ \
|
||||
ContextEnabledHere = false; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
makeCurrent(); \
|
||||
mGLContext_Current = true; \
|
||||
ContextEnabledHere = true; \
|
||||
} \
|
||||
\
|
||||
do {} while(false)
|
||||
|
||||
# define ConditionalContextControl_End \
|
||||
if(ContextEnabledHere) \
|
||||
{ \
|
||||
doneCurrent(); \
|
||||
mGLContext_Current = false; \
|
||||
} \
|
||||
\
|
||||
do {} while(false)
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
void CGLView::Material_Apply(const aiMaterial* pMaterial)
|
||||
{
|
||||
GLfloat tcol[4];
|
||||
|
@ -105,7 +135,7 @@ void CGLView::Material_Apply(const aiMaterial* pMaterial)
|
|||
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, tcol);
|
||||
// Shininess
|
||||
float shininess, strength;
|
||||
ai_real shininess, strength;
|
||||
|
||||
max = 1;
|
||||
ret1 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS, &shininess, &max);
|
||||
|
@ -406,9 +436,9 @@ void CGLView::BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVe
|
|||
|
||||
for(size_t idx_vert = 1; idx_vert < pVerticesQuantity; idx_vert++)
|
||||
{
|
||||
const GLfloat x = pVertices[idx_vert].x;
|
||||
const GLfloat y = pVertices[idx_vert].y;
|
||||
const GLfloat z = pVertices[idx_vert].z;
|
||||
const ai_real x = pVertices[idx_vert].x;
|
||||
const ai_real y = pVertices[idx_vert].y;
|
||||
const ai_real z = pVertices[idx_vert].z;
|
||||
|
||||
// search minimal...
|
||||
AssignIfLesser(&pBBox.Minimum.x, x);
|
||||
|
@ -446,7 +476,12 @@ void CGLView::Draw_Node(const aiNode* pNode)
|
|||
// Apply node transformation matrix.
|
||||
mat_node.Transpose();
|
||||
glPushMatrix();
|
||||
#if ASSIMP_DOUBLE_PRECISION
|
||||
glMultMatrixd((GLdouble*)mat_node[0]);
|
||||
#else
|
||||
glMultMatrixf((GLfloat*)&mat_node);
|
||||
#endif // ASSIMP_DOUBLE_PRECISION
|
||||
|
||||
// Draw all meshes assigned to this node
|
||||
for(size_t idx_mesh_arr = 0; idx_mesh_arr < pNode->mNumMeshes; idx_mesh_arr++) Draw_Mesh(pNode->mMeshes[idx_mesh_arr]);
|
||||
|
||||
|
@ -473,13 +508,21 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
|
|||
// Vertices array
|
||||
//
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
#if ASSIMP_DOUBLE_PRECISION
|
||||
glVertexPointer(3, GL_DOUBLE, 0, mesh_cur.mVertices);
|
||||
#else
|
||||
glVertexPointer(3, GL_FLOAT, 0, mesh_cur.mVertices);
|
||||
#endif // ASSIMP_DOUBLE_PRECISION
|
||||
|
||||
if(mesh_cur.HasVertexColors(0))
|
||||
{
|
||||
glEnable(GL_COLOR_MATERIAL);///TODO: cache
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
#if ASSIMP_DOUBLE_PRECISION
|
||||
glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]);
|
||||
#else
|
||||
glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]);
|
||||
#endif // ASSIMP_DOUBLE_PRECISION
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -488,7 +531,11 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
|
|||
if(mesh_cur.HasTextureCoords(0))
|
||||
{
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
#if ASSIMP_DOUBLE_PRECISION
|
||||
glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
|
||||
#else
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
|
||||
#endif // ASSIMP_DOUBLE_PRECISION
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -497,7 +544,11 @@ void CGLView::Draw_Mesh(const size_t pMesh_Index)
|
|||
if(mesh_cur.HasNormals())
|
||||
{
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
#if ASSIMP_DOUBLE_PRECISION
|
||||
glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals);
|
||||
#else
|
||||
glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals);
|
||||
#endif // ASSIMP_DOUBLE_PRECISION
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -530,22 +581,46 @@ void CGLView::Draw_BBox(const SBBox& pBBox)
|
|||
glBindTexture(GL_TEXTURE_1D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_3D, 0);
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
qglColor(QColor(Qt::white));
|
||||
#else
|
||||
const QColor c_w(Qt::white);
|
||||
|
||||
glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF());
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
# if ASSIMP_DOUBLE_PRECISION
|
||||
glVertex3dv(&vertex[0][0]), glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[0][0]);// "Minimum" side.
|
||||
glVertex3dv(&vertex[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side.
|
||||
# else
|
||||
glVertex3fv(&vertex[0][0]), glVertex3fv(&vertex[1][0]), glVertex3fv(&vertex[2][0]), glVertex3fv(&vertex[3][0]), glVertex3fv(&vertex[0][0]);// "Minimum" side.
|
||||
glVertex3fv(&vertex[4][0]), glVertex3fv(&vertex[5][0]), glVertex3fv(&vertex[6][0]), glVertex3fv(&vertex[7][0]), glVertex3fv(&vertex[4][0]);// Edge and "maximum" side.
|
||||
# endif // ASSIMP_DOUBLE_PRECISION
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINES);
|
||||
# if ASSIMP_DOUBLE_PRECISION
|
||||
glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]);
|
||||
glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]);
|
||||
glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]);
|
||||
# else
|
||||
glVertex3fv(&vertex[1][0]), glVertex3fv(&vertex[5][0]);
|
||||
glVertex3fv(&vertex[2][0]), glVertex3fv(&vertex[6][0]);
|
||||
glVertex3fv(&vertex[3][0]), glVertex3fv(&vertex[7][0]);
|
||||
# endif // ASSIMP_DOUBLE_PRECISION
|
||||
glEnd();
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
if(mLightingEnabled) glEnable(GL_LIGHTING);
|
||||
|
||||
}
|
||||
|
||||
void CGLView::Enable_Textures(const bool pEnable)
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_Begin;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
if(pEnable)
|
||||
{
|
||||
glEnable(GL_TEXTURE_1D);
|
||||
|
@ -558,30 +633,10 @@ void CGLView::Enable_Textures(const bool pEnable)
|
|||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_TEXTURE_3D);
|
||||
}
|
||||
}
|
||||
|
||||
void CGLView::Enable_Axes(const bool pEnable){
|
||||
if(pEnable)
|
||||
{
|
||||
this->mAxesEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->mAxesEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CGLView::Enable_Reload_Textures(const bool pEnable)
|
||||
{
|
||||
if(pEnable)
|
||||
{
|
||||
this->mReloadTexturesEnabled = true;
|
||||
// this->mScene->ImportTextures(this->mScene->pScenePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->mReloadTexturesEnabled = false;
|
||||
}
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_End;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -590,7 +645,13 @@ void CGLView::Enable_Reload_Textures(const bool pEnable)
|
|||
|
||||
void CGLView::initializeGL()
|
||||
{
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
qglClearColor(Qt::gray);
|
||||
#else
|
||||
mGLContext_Current = true;
|
||||
initializeOpenGLFunctions();
|
||||
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -607,23 +668,38 @@ void CGLView::initializeGL()
|
|||
glCullFace(GL_BACK);
|
||||
|
||||
glFrontFace(GL_CCW);
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
mGLContext_Current = false;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void CGLView::resizeGL(int pWidth, int pHeight)
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
mGLContext_Current = true;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
mCamera_Viewport_AspectRatio = (GLdouble)pWidth / pHeight;
|
||||
glViewport(0, 0, pWidth, pHeight);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(mCamera_FOVY, mCamera_Viewport_AspectRatio, 1.0, 100000.0);///TODO: znear/zfar depend on scene size.
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
mGLContext_Current = false;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void CGLView::drawCoordSystem() {
|
||||
// Disable lighting. Colors must be bright and colorful)
|
||||
if ( mLightingEnabled ) glDisable( GL_LIGHTING );///TODO: display list
|
||||
|
||||
// For same reason - disable textures.
|
||||
glBindTexture(GL_TEXTURE_1D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_3D, 0);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glBegin(GL_LINES);
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
// X, -X
|
||||
qglColor(QColor(Qt::red)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0);
|
||||
qglColor(QColor(Qt::cyan)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
|
||||
|
@ -634,11 +710,30 @@ void CGLView::drawCoordSystem() {
|
|||
qglColor(QColor(Qt::blue)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0);
|
||||
qglColor(QColor(Qt::yellow)), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0);
|
||||
qglColor(QColor(Qt::white));
|
||||
#else
|
||||
// X, -X
|
||||
glColor3f(1.0f, 0.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0);
|
||||
glColor3f(0.5f, 0.5f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
|
||||
// Y, -Y
|
||||
glColor3f(0.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 100000.0, 0.0);
|
||||
glColor3f(1.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, -100000.0, 0.0);
|
||||
// Z, -Z
|
||||
glColor3f(0.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0);
|
||||
glColor3f(1.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0);
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
glEnd();
|
||||
// Restore previous state of lighting.
|
||||
if(mLightingEnabled) glEnable(GL_LIGHTING);
|
||||
|
||||
}
|
||||
|
||||
void CGLView::paintGL()
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
mGLContext_Current = true;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
QTime time_paintbegin;
|
||||
|
||||
time_paintbegin = QTime::currentTime();
|
||||
|
@ -647,30 +742,36 @@ void CGLView::paintGL()
|
|||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
// Apply current camera transformations.
|
||||
#if ASSIMP_DOUBLE_PRECISION
|
||||
glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera);
|
||||
glTranslated(-mHelper_Camera.Translation_ToScene.x, -mHelper_Camera.Translation_ToScene.y, -mHelper_Camera.Translation_ToScene.z);
|
||||
glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_Scene);
|
||||
#else
|
||||
glMultMatrixf((GLfloat*)&mHelper_Camera.Rotation_AroundCamera);
|
||||
glTranslatef(-mHelper_Camera.Translation_ToScene.x, -mHelper_Camera.Translation_ToScene.y, -mHelper_Camera.Translation_ToScene.z);
|
||||
glMultMatrixf((GLfloat*)&mHelper_Camera.Rotation_Scene);
|
||||
#endif // ASSIMP_DOUBLE_PRECISION
|
||||
|
||||
// Coordinate system
|
||||
if ( mLightingEnabled ) {
|
||||
glDisable( GL_LIGHTING );///TODO: display list
|
||||
}
|
||||
if (this->mAxesEnabled == true)
|
||||
if (mScene_AxesEnabled == true)
|
||||
{
|
||||
drawCoordSystem();
|
||||
}
|
||||
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
if(mLightingEnabled) glEnable(GL_LIGHTING);
|
||||
|
||||
// Scene
|
||||
if(mScene != nullptr)
|
||||
{
|
||||
Draw_Node(mScene->mRootNode);
|
||||
// Scene BBox
|
||||
if(mScene_DrawBBox) Draw_BBox(mScene_BBox);
|
||||
|
||||
}
|
||||
|
||||
emit Paint_Finished((size_t)time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length());
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
mGLContext_Current = false;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -678,10 +779,12 @@ void CGLView::paintGL()
|
|||
/********************************************************************/
|
||||
|
||||
CGLView::CGLView(QWidget *pParent)
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
: QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer), pParent)
|
||||
#else
|
||||
: QOpenGLWidget(pParent), mGLContext_Current(false)
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
{
|
||||
static_assert(sizeof(GLfloat) == sizeof(ai_real), "ai_real in Assimp must be equal to GLfloat/float.");///TODO: may be templates can be used.
|
||||
|
||||
// set initial view
|
||||
mHelper_CameraDefault.SetDefault();
|
||||
Camera_Set(0);
|
||||
|
@ -698,6 +801,10 @@ CGLView::~CGLView()
|
|||
|
||||
void CGLView::FreeScene()
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_Begin;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
// Set scene to null and after that \ref paintGL will not try to render it.
|
||||
mScene = nullptr;
|
||||
// Clean helper objects.
|
||||
|
@ -727,10 +834,18 @@ void CGLView::FreeScene()
|
|||
mTexture_IDMap.clear();
|
||||
delete [] id_tex;
|
||||
}
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_End;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_Begin;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
FreeScene();// Clear old data
|
||||
// Why checking here, not at begin of function. Because old scene may not exist at know. So, need cleanup.
|
||||
if(pScene == nullptr) return;
|
||||
|
@ -957,6 +1072,10 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
|
|||
emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str());
|
||||
}
|
||||
}// if(!mScene->HasCameras()) else
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_End;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -965,39 +1084,65 @@ void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath)
|
|||
|
||||
void CGLView::Lighting_Enable()
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_Begin;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
mLightingEnabled = true;
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_End;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void CGLView::Lighting_Disable()
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_Begin;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
glDisable(GL_LIGHTING);
|
||||
mLightingEnabled = false;
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_End;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_Begin;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
const size_t light_num = GL_LIGHT0 + pLightNumber;
|
||||
|
||||
GLfloat farr[4];
|
||||
|
||||
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
|
||||
|
||||
glLightfv(light_num, GL_AMBIENT, &pLightParameters.Ambient.r);// Ambient color
|
||||
glLightfv(light_num, GL_DIFFUSE, &pLightParameters.Diffuse.r);// Diffuse color
|
||||
glLightfv(light_num, GL_SPECULAR, &pLightParameters.Specular.r);// Specular color
|
||||
// Ambient color
|
||||
farr[0] = pLightParameters.Ambient.r, farr[1] = pLightParameters.Ambient.g; farr[2] = pLightParameters.Ambient.b; farr[3] = pLightParameters.Ambient.a;
|
||||
glLightfv(light_num, GL_AMBIENT, farr);
|
||||
// Diffuse color
|
||||
farr[0] = pLightParameters.Diffuse.r, farr[1] = pLightParameters.Diffuse.g; farr[2] = pLightParameters.Diffuse.b; farr[3] = pLightParameters.Diffuse.a;
|
||||
glLightfv(light_num, GL_DIFFUSE, farr);
|
||||
// Specular color
|
||||
farr[0] = pLightParameters.Specular.r, farr[1] = pLightParameters.Specular.g; farr[2] = pLightParameters.Specular.b; farr[3] = pLightParameters.Specular.a;
|
||||
glLightfv(light_num, GL_SPECULAR, farr);
|
||||
// Other parameters
|
||||
switch(pLightParameters.Type)
|
||||
{
|
||||
case aiLightSource_DIRECTIONAL:
|
||||
// Direction
|
||||
farr[0] = pLightParameters.For.Directional.Direction.x, farr[2] = pLightParameters.For.Directional.Direction.y;
|
||||
farr[0] = pLightParameters.For.Directional.Direction.x, farr[1] = pLightParameters.For.Directional.Direction.y;
|
||||
farr[2] = pLightParameters.For.Directional.Direction.z; farr[3] = 0;
|
||||
glLightfv(light_num, GL_POSITION, farr);
|
||||
break;
|
||||
case aiLightSource_POINT:
|
||||
// Position
|
||||
farr[0] = pLightParameters.For.Point.Position.x, farr[2] = pLightParameters.For.Point.Position.y;
|
||||
farr[0] = pLightParameters.For.Point.Position.x, farr[1] = pLightParameters.For.Point.Position.y;
|
||||
farr[2] = pLightParameters.For.Point.Position.z; farr[3] = 1;
|
||||
glLightfv(light_num, GL_POSITION, farr);
|
||||
// Attenuation
|
||||
|
@ -1008,20 +1153,20 @@ GLfloat farr[4];
|
|||
break;
|
||||
case aiLightSource_SPOT:
|
||||
// Position
|
||||
farr[0] = pLightParameters.For.Spot.Position.x, farr[2] = pLightParameters.For.Spot.Position.y, farr[2] = pLightParameters.For.Spot.Position.z; farr[3] = 1;
|
||||
farr[0] = pLightParameters.For.Spot.Position.x, farr[1] = pLightParameters.For.Spot.Position.y, farr[2] = pLightParameters.For.Spot.Position.z; farr[3] = 1;
|
||||
glLightfv(light_num, GL_POSITION, farr);
|
||||
// Attenuation
|
||||
glLightf(light_num, GL_CONSTANT_ATTENUATION, pLightParameters.For.Spot.Attenuation_Constant);
|
||||
glLightf(light_num, GL_LINEAR_ATTENUATION, pLightParameters.For.Spot.Attenuation_Linear);
|
||||
glLightf(light_num, GL_QUADRATIC_ATTENUATION, pLightParameters.For.Spot.Attenuation_Quadratic);
|
||||
// Spot specific
|
||||
farr[0] = pLightParameters.For.Spot.Direction.x, farr[2] = pLightParameters.For.Spot.Direction.y, farr[2] = pLightParameters.For.Spot.Direction.z; farr[3] = 0;
|
||||
farr[0] = pLightParameters.For.Spot.Direction.x, farr[1] = pLightParameters.For.Spot.Direction.y, farr[2] = pLightParameters.For.Spot.Direction.z; farr[3] = 0;
|
||||
glLightfv(light_num, GL_SPOT_DIRECTION, farr);
|
||||
glLightf(light_num, GL_SPOT_CUTOFF, pLightParameters.For.Spot.CutOff);
|
||||
break;
|
||||
default:// For unknown light source types use point source.
|
||||
// Position
|
||||
farr[0] = pLightParameters.For.Point.Position.x, farr[2] = pLightParameters.For.Point.Position.y;
|
||||
farr[0] = pLightParameters.For.Point.Position.x, farr[1] = pLightParameters.For.Point.Position.y;
|
||||
farr[2] = pLightParameters.For.Point.Position.z; farr[3] = 1;
|
||||
glLightfv(light_num, GL_POSITION, farr);
|
||||
// Attenuation
|
||||
|
@ -1031,20 +1176,40 @@ GLfloat farr[4];
|
|||
glLightf(light_num, GL_SPOT_CUTOFF, 180.0);
|
||||
break;
|
||||
}// switch(pLightParameters.Type)
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_End;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void CGLView::Lighting_EnableSource(const size_t pLightNumber)
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_Begin;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
|
||||
|
||||
glEnable(GL_LIGHT0 + pLightNumber);
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_End;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void CGLView::Lighting_DisableSource(const size_t pLightNumber)
|
||||
{
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_Begin;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
|
||||
|
||||
glDisable(GL_LIGHT0 + pLightNumber);
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
ConditionalContextControl_End;
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -1096,23 +1261,29 @@ void CGLView::Camera_Set(const size_t pCameraNumber)
|
|||
gluLookAt(hcam.Position.x, hcam.Position.y, hcam.Position.z, hcam.Target.x, hcam.Target.y, hcam.Target.z, up.x, up.y, up.z);
|
||||
}
|
||||
|
||||
void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z)
|
||||
void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
|
||||
{
|
||||
auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 180.0; };
|
||||
|
||||
aiMatrix4x4 mat_rot;
|
||||
|
||||
mat_rot.FromEulerAnglesXYZ(deg2rad(pAngle_X), deg2rad(pAngle_Y), deg2rad(pAngle_Z));
|
||||
if(pMatrix_Rotation_Initial != nullptr)
|
||||
mHelper_Camera.Rotation_Scene = *pMatrix_Rotation_Initial * mat_rot;
|
||||
else
|
||||
mHelper_Camera.Rotation_Scene *= mat_rot;
|
||||
}
|
||||
|
||||
void CGLView::Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z)
|
||||
void CGLView::Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
|
||||
{
|
||||
auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 180.0; };
|
||||
|
||||
aiMatrix4x4 mat_rot;
|
||||
|
||||
mat_rot.FromEulerAnglesXYZ(deg2rad(pAngle_X), deg2rad(pAngle_Y), deg2rad(pAngle_Z));
|
||||
if(pMatrix_Rotation_Initial != nullptr)
|
||||
mHelper_Camera.Rotation_AroundCamera = *pMatrix_Rotation_Initial * mat_rot;
|
||||
else
|
||||
mHelper_Camera.Rotation_AroundCamera *= mat_rot;
|
||||
}
|
||||
|
||||
|
@ -1123,3 +1294,10 @@ aiVector3D vect_tr(pTranslate_X, pTranslate_Y, pTranslate_Z);
|
|||
vect_tr *= mHelper_Camera.Rotation_AroundCamera;
|
||||
mHelper_Camera.Translation_ToScene += vect_tr;
|
||||
}
|
||||
|
||||
void CGLView::Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera)
|
||||
{
|
||||
pRotation_Camera = mHelper_Camera.Rotation_AroundCamera;
|
||||
pRotation_Scene = mHelper_Camera.Rotation_Scene;
|
||||
pTranslation_Camera = mHelper_Camera.Translation_ToScene;
|
||||
}
|
||||
|
|
|
@ -6,14 +6,24 @@
|
|||
#pragma once
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QMap>
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
# include <QtOpenGL>
|
||||
#else
|
||||
# include <QOpenGLWidget>
|
||||
# include <QOpenGLFunctions>
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
|
||||
// Header files Assimp
|
||||
#include <assimp/scene.h>
|
||||
|
||||
/// \class CGLView
|
||||
/// Class which hold and render scene.
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
class CGLView : public QGLWidget
|
||||
#else
|
||||
class CGLView : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -75,9 +85,7 @@ private:
|
|||
};
|
||||
|
||||
public:
|
||||
bool mAxesEnabled = true;
|
||||
// Textures
|
||||
bool mReloadTexturesEnabled = false; // If true then textures will reload when the window is activated.
|
||||
|
||||
/// \enum ELightType
|
||||
/// Type of light source.
|
||||
enum class ELightType { Directional, Point, Spot };
|
||||
|
@ -141,11 +149,16 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
#if !ASSIMP_QT4_VIEWER
|
||||
// Qt5 widget has another behavior, so you must to know that you already made context are current. Yes, its a dirty hack. Better decision are welcome.
|
||||
bool mGLContext_Current;///< Widget's GL-context made current.
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
// 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.
|
||||
bool mScene_AxesEnabled = true;///< Flag which control drawing axes of the coordinate system.
|
||||
// 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.
|
||||
|
@ -254,7 +267,11 @@ private:
|
|||
/********************************************************************/
|
||||
|
||||
protected:
|
||||
|
||||
/// \fn void drawCoordSystem()
|
||||
/// Draw axes of the coordinate system.
|
||||
void drawCoordSystem();
|
||||
|
||||
/// \fn void initializeGL() override
|
||||
/// Override function to initialise OpenGL.
|
||||
void initializeGL() override;
|
||||
|
@ -307,11 +324,10 @@ public:
|
|||
/// \param [in] pEnable - if true then enable textures, false - disable textures.
|
||||
void Enable_Textures(const bool pEnable);
|
||||
|
||||
void Enable_Axes(const bool pEnable);
|
||||
/// \fn void Enable_Textures(const bool pEnable)
|
||||
/// Control textures drawing.
|
||||
/// \param [in] pEnable - if true then enable textures, false - disable textures.
|
||||
void Enable_Reload_Textures(const bool pEnable);
|
||||
/// \fn void Enable_Axes(const bool pEnable)
|
||||
/// Control axes drawing.
|
||||
/// \param [in] pEnable - if true then enable axes, false - disable axes.
|
||||
void Enable_Axes(const bool pEnable) { this->mScene_AxesEnabled = pEnable; }
|
||||
|
||||
/********************************************************************/
|
||||
/******************** Lighting control functions ********************/
|
||||
|
@ -350,19 +366,23 @@ public:
|
|||
/// \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)
|
||||
/// \fn void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
|
||||
/// 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);
|
||||
/// \param [in] pMatrix_Rotation_Initial - matrix from which calculates new transformation matrix. If not set (equal to nullptr) then current transformation matrix
|
||||
/// will be used.
|
||||
void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr);
|
||||
|
||||
/// \fn void Camera_Rotate(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, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr)
|
||||
/// 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);
|
||||
/// \param [in] pMatrix_Rotation_Initial - matrix from which calculates new transformation matrix. If not set (equal to nullptr) then current transformation matrix
|
||||
/// will be used.
|
||||
void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr);
|
||||
|
||||
/// \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.
|
||||
|
@ -371,6 +391,13 @@ public:
|
|||
/// \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);
|
||||
|
||||
/// \fn void Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera)
|
||||
/// Return data about camera position in world.
|
||||
/// \param [out] pRotation_Camera - rotation matrix which set rotation angles of the scene around camera.
|
||||
/// \param [out] pRotation_Scene - rotation matrix which set rotation angles of the scene around own center.
|
||||
/// \param [out] pTranslation_Camera - translation vector from camera to the scene.
|
||||
void Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera);
|
||||
|
||||
signals:
|
||||
|
||||
/// \fn void Paint_Finished(const size_t pPaintTime, const GLfloat pDistance)
|
||||
|
|
|
@ -48,7 +48,7 @@ QTime time_begin = QTime::currentTime();
|
|||
ui->cbxLighting->setChecked(true); mGLView->Lighting_Enable();
|
||||
ui->cbxBBox->setChecked(false); mGLView->Enable_SceneBBox(false);
|
||||
ui->cbxTextures->setChecked(true); mGLView->Enable_Textures(true);
|
||||
ui->cbxReloadTextures->setChecked(true); mGLView->Enable_Reload_Textures(false);
|
||||
|
||||
//
|
||||
// Fill info labels
|
||||
//
|
||||
|
@ -84,7 +84,11 @@ QTime time_begin = QTime::currentTime();
|
|||
mGLView->Camera_Set(0);
|
||||
// Scene is loaded, do first rendering.
|
||||
LogInfo("Scene is ready for rendering.");
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -128,40 +132,74 @@ void MainWindow::LogError(const QString& pMessage)
|
|||
|
||||
void MainWindow::mousePressEvent(QMouseEvent* pEvent)
|
||||
{
|
||||
const QPoint ms_pt = pEvent->pos();
|
||||
|
||||
__unused aiVector3D temp_v3;
|
||||
|
||||
// Check if GLView is pointed.
|
||||
if(childAt(ms_pt) == mGLView)
|
||||
{
|
||||
if(!mMouse_Transformation.Position_Pressed_Valid)
|
||||
{
|
||||
mMouse_Transformation.Position_Pressed_Valid = true;// set flag
|
||||
// Store current transformation matrices.
|
||||
mGLView->Camera_Matrix(mMouse_Transformation.Rotation_AroundCamera, mMouse_Transformation.Rotation_Scene, temp_v3);
|
||||
}
|
||||
|
||||
if(pEvent->button() & Qt::LeftButton)
|
||||
mPosition_Pressed_LMB = pEvent->pos();
|
||||
mMouse_Transformation.Position_Pressed_LMB = ms_pt;
|
||||
else if(pEvent->button() & Qt::RightButton)
|
||||
mPosition_Pressed_RMB = pEvent->pos();
|
||||
mMouse_Transformation.Position_Pressed_RMB = ms_pt;
|
||||
}
|
||||
else
|
||||
{
|
||||
mMouse_Transformation.Position_Pressed_Valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::mouseReleaseEvent(QMouseEvent *pEvent)
|
||||
{
|
||||
if(pEvent->buttons() == 0) mMouse_Transformation.Position_Pressed_Valid = false;
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::mouseMoveEvent(QMouseEvent* pEvent)
|
||||
{
|
||||
if(mMouse_Transformation.Position_Pressed_Valid)
|
||||
{
|
||||
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();
|
||||
GLfloat dx = 180 * GLfloat(pEvent->x() - mMouse_Transformation.Position_Pressed_LMB.x()) / mGLView->width();
|
||||
GLfloat dy = 180 * GLfloat(pEvent->y() - mMouse_Transformation.Position_Pressed_LMB.y()) / mGLView->height();
|
||||
|
||||
if(pEvent->modifiers() & Qt::ShiftModifier)
|
||||
mGLView->Camera_RotateScene(dy, 0, dx);// Rotate around oX and oZ axises.
|
||||
mGLView->Camera_RotateScene(dy, 0, dx, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oZ axises.
|
||||
else
|
||||
mGLView->Camera_RotateScene(dy, dx, 0);// Rotate around oX and oY axises.
|
||||
mGLView->Camera_RotateScene(dy, dx, 0, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oY axises.
|
||||
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
mPosition_Pressed_LMB = pEvent->pos();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
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();
|
||||
GLfloat dx = 180 * GLfloat(pEvent->x() - mMouse_Transformation.Position_Pressed_RMB.x()) / mGLView->width();
|
||||
GLfloat dy = 180 * GLfloat(pEvent->y() - mMouse_Transformation.Position_Pressed_RMB.y()) / mGLView->height();
|
||||
|
||||
if(pEvent->modifiers() & Qt::ShiftModifier)
|
||||
mGLView->Camera_Rotate(dy, 0, dx);// Rotate around oX and oZ axises.
|
||||
mGLView->Camera_Rotate(dy, 0, dx, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oZ axises.
|
||||
else
|
||||
mGLView->Camera_Rotate(dy, dx, 0);// Rotate around oX and oY axises.
|
||||
mGLView->Camera_Rotate(dy, dx, 0, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oY axises.
|
||||
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
mPosition_Pressed_RMB = pEvent->pos();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,19 +227,16 @@ GLfloat step;
|
|||
else if(pEvent->key() == Qt::Key_Down)
|
||||
mGLView->Camera_Translate(0, 0, step);
|
||||
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/********************** Constructor/Destructor **********************/
|
||||
/********************************************************************/
|
||||
bool MainWindow::event(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::WindowActivate && this->mGLView->mReloadTexturesEnabled == true) {
|
||||
qInfo() << "Window Activated";
|
||||
}
|
||||
return QWidget::event(e);
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), ui(new Ui::MainWindow),
|
||||
|
@ -209,6 +244,9 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
{
|
||||
using namespace Assimp;
|
||||
|
||||
// other variables
|
||||
mMouse_Transformation.Position_Pressed_Valid = false;
|
||||
|
||||
ui->setupUi(this);
|
||||
// Create OpenGL widget
|
||||
mGLView = new CGLView(this);
|
||||
|
@ -281,7 +319,6 @@ QString filename, filter;
|
|||
if(!filename.isEmpty()) ImportFile(filename);
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_butExport_clicked()
|
||||
{
|
||||
using namespace Assimp;
|
||||
|
@ -301,7 +338,7 @@ QMap<QString, const aiExportFormatDesc*> exportersMap;
|
|||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < exporter.GetExportFormatCount(); ++i)
|
||||
for (size_t i = 0; i < exporter.GetExportFormatCount(); ++i)
|
||||
{
|
||||
const aiExportFormatDesc* desc = exporter.GetExportFormatDescription(i);
|
||||
exportersList.push_back(desc->id + QString(": ") + desc->description);
|
||||
|
@ -345,7 +382,11 @@ void MainWindow::on_cbxLighting_clicked(bool pChecked)
|
|||
else
|
||||
mGLView->Lighting_Disable();
|
||||
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void MainWindow::on_lstLight_itemSelectionChanged()
|
||||
|
@ -357,35 +398,49 @@ bool selected = ui->lstLight->isItemSelected(ui->lstLight->currentItem());
|
|||
else
|
||||
mGLView->Lighting_DisableSource(ui->lstLight->currentRow());
|
||||
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void MainWindow::on_lstCamera_clicked( const QModelIndex &)
|
||||
{
|
||||
mGLView->Camera_Set(ui->lstLight->currentRow());
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxBBox_clicked(bool checked)
|
||||
{
|
||||
mGLView->Enable_SceneBBox(checked);
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxDrawAxes_clicked(bool checked)
|
||||
{
|
||||
mGLView->Enable_Axes(checked);
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxReloadTextures_clicked(bool checked)
|
||||
{
|
||||
mGLView->Enable_Reload_Textures(checked);
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxTextures_clicked(bool checked)
|
||||
{
|
||||
mGLView->Enable_Textures(checked);
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
#pragma once
|
||||
|
||||
// Header files, Qt.
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
# include <QMainWindow>
|
||||
#else
|
||||
# include <QtWidgets>
|
||||
#endif
|
||||
|
||||
// Header files, project.
|
||||
#include "glview.hpp"
|
||||
|
@ -36,8 +40,17 @@ private:
|
|||
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.
|
||||
|
||||
/// \struct SMouse_Transformation
|
||||
/// Holds data about transformation of the scene/camera when mouse us used.
|
||||
struct SMouse_Transformation
|
||||
{
|
||||
bool Position_Pressed_Valid;///< Mouse button pressed on GLView.
|
||||
QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button.
|
||||
QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button.
|
||||
aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
|
||||
aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
|
||||
} mMouse_Transformation;
|
||||
|
||||
/**********************************/
|
||||
/************ Functions ***********/
|
||||
|
@ -80,6 +93,11 @@ protected:
|
|||
/// \param [in] pEvent - pointer to event data.
|
||||
void mousePressEvent(QMouseEvent* pEvent) override;
|
||||
|
||||
/// \fn void mouseReleaseEvent(QMouseEvent *pEvent) override
|
||||
/// Override function which handles mouse event "button released".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
void mouseReleaseEvent(QMouseEvent *pEvent) override;
|
||||
|
||||
/// \fn void mouseMoveEvent(QMouseEvent* pEvent) override
|
||||
/// Override function which handles mouse event "move".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
|
@ -90,7 +108,6 @@ protected:
|
|||
/// \param [in] pEvent - pointer to event data.
|
||||
void keyPressEvent(QKeyEvent* pEvent) override;
|
||||
|
||||
bool event(QEvent*);
|
||||
public:
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -134,5 +151,4 @@ private slots:
|
|||
void on_cbxBBox_clicked(bool checked);
|
||||
void on_cbxTextures_clicked(bool checked);
|
||||
void on_cbxDrawAxes_clicked(bool checked);
|
||||
void on_cbxReloadTextures_clicked(bool checked);
|
||||
};
|
||||
|
|
|
@ -302,6 +302,9 @@
|
|||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
|
@ -312,6 +315,9 @@
|
|||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
|
@ -325,6 +331,9 @@
|
|||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
|
@ -335,6 +344,9 @@
|
|||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
|
@ -349,6 +361,9 @@
|
|||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -511,13 +526,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="cbxReloadTextures">
|
||||
<property name="text">
|
||||
<string>Live Reload Textures</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2015, assimp team
|
||||
Copyright (c) 2006-2018, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
#include "assimp_view.h"
|
||||
|
||||
#include <tuple>
|
||||
|
||||
using namespace AssimpView;
|
||||
|
|
|
@ -96,9 +96,10 @@ D3DXVECTOR4 g_aclNormalColors[14] =
|
|||
void GetNodeCount(aiNode* pcNode, unsigned int* piCnt)
|
||||
{
|
||||
*piCnt = *piCnt+1;
|
||||
for (unsigned int i = 0; i < pcNode->mNumChildren;++i)
|
||||
for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) {
|
||||
GetNodeCount(pcNode->mChildren[i], piCnt);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
int CDisplay::EnableAnimTools(BOOL hm)
|
||||
|
@ -1042,16 +1043,23 @@ int CDisplay::OnSetupTextureView(TextureInfo* pcNew)
|
|||
switch (pcNew->eOp)
|
||||
{
|
||||
case aiTextureOp_Add:
|
||||
szOp = "add";break;
|
||||
szOp = "add";
|
||||
break;
|
||||
case aiTextureOp_Subtract:
|
||||
szOp = "sub";break;
|
||||
szOp = "sub";
|
||||
break;
|
||||
case aiTextureOp_Divide:
|
||||
szOp = "div";break;
|
||||
szOp = "div";
|
||||
break;
|
||||
case aiTextureOp_SignedAdd:
|
||||
szOp = "addsign";break;
|
||||
szOp = "addsign";
|
||||
break;
|
||||
case aiTextureOp_SmoothAdd:
|
||||
szOp = "addsmooth";break;
|
||||
default: szOp = "mul";
|
||||
szOp = "addsmooth";
|
||||
break;
|
||||
default:
|
||||
szOp = "mul";
|
||||
break;
|
||||
};
|
||||
SetWindowText(GetDlgItem(g_hDlg,IDC_ELOAD),szOp);
|
||||
|
||||
|
@ -2251,7 +2259,7 @@ int CDisplay::RenderTextureView()
|
|||
const float ny = (float)sRect.bottom;
|
||||
const float x = (float)sDesc.Width;
|
||||
const float y = (float)sDesc.Height;
|
||||
float f = min((nx-30) / x,(ny-30) / y) * (m_fTextureZoom/1000.0f);
|
||||
float f = std::min((nx-30) / x,(ny-30) / y) * (m_fTextureZoom/1000.0f);
|
||||
|
||||
float fHalfX = (nx - (f * x)) / 2.0f;
|
||||
float fHalfY = (ny - (f * y)) / 2.0f;
|
||||
|
|
|
@ -275,7 +275,7 @@ bool CMaterialManager::TryLongerPath(char* szTemp,aiString* p_szString)
|
|||
for (unsigned int i = 0; i < iSizeFound;++i)
|
||||
info.cFileName[i] = (CHAR)tolower(info.cFileName[i]);
|
||||
|
||||
if (0 == memcmp(info.cFileName,szFile2, min(iSizeFound,iSize)))
|
||||
if (0 == memcmp(info.cFileName,szFile2, std::min(iSizeFound,iSize)))
|
||||
{
|
||||
// we have it. Build the full path ...
|
||||
char* sz = strrchr(szTempB,'*');
|
||||
|
|
|
@ -45,7 +45,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <windowsx.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <mmsystem.h>
|
||||
#else
|
||||
#include <timeapi.h>
|
||||
#endif
|
||||
|
||||
namespace AssimpView {
|
||||
|
||||
|
@ -80,8 +85,7 @@ void SaveHistory();
|
|||
// File associations are registered in HKCU\Software\Classes. They might
|
||||
// be overwritten by global file associations.
|
||||
//-------------------------------------------------------------------------------
|
||||
void MakeFileAssociations()
|
||||
{
|
||||
void MakeFileAssociations() {
|
||||
char szTemp2[MAX_PATH];
|
||||
char szTemp[MAX_PATH + 10];
|
||||
|
||||
|
@ -1050,9 +1054,9 @@ void DoExport(size_t formatId)
|
|||
ai_assert(strlen(szFileName) <= MAX_PATH);
|
||||
|
||||
// invent a nice default file name
|
||||
char* sz = max(strrchr(szFileName,'\\'),strrchr(szFileName,'/'));
|
||||
char* sz = std::max(strrchr(szFileName,'\\'),strrchr(szFileName,'/'));
|
||||
if (sz) {
|
||||
strncpy(sz,max(strrchr(g_szFileName,'\\'),strrchr(g_szFileName,'/')),MAX_PATH);
|
||||
strncpy(sz,std::max(strrchr(g_szFileName,'\\'),strrchr(g_szFileName,'/')),MAX_PATH);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1399,7 +1403,7 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
|
|||
|
||||
g_hDlg = hwndDlg;
|
||||
|
||||
// load the state of the usr interface
|
||||
// load the state of the user interface
|
||||
InitUI();
|
||||
|
||||
// load the file history
|
||||
|
@ -1643,11 +1647,6 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
|
|||
xPos = xPos2 = sPoint.x;
|
||||
yPos = yPos2 = sPoint.y;
|
||||
|
||||
/* xPos -= 10;
|
||||
yPos -= 10;
|
||||
xPos2 = xPos-3;
|
||||
yPos2 = yPos-5;*/
|
||||
|
||||
RECT sRect;
|
||||
GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
|
||||
sRect.right -= sRect.left;
|
||||
|
@ -1830,7 +1829,6 @@ INT_PTR CALLBACK MessageProc(HWND hwndDlg,UINT uMsg,
|
|||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
|
||||
HMENU hMenu = GetMenu(g_hDlg);
|
||||
if (ID_VIEWER_QUIT == LOWORD(wParam))
|
||||
{
|
||||
|
@ -2371,10 +2369,9 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
|
|||
// load windows common controls library to get XP style
|
||||
InitCommonControls();
|
||||
|
||||
// intiailize the IDirect3D9 interface
|
||||
// initialize the IDirect3D9 interface
|
||||
g_hInstance = hInstance;
|
||||
if (0 == InitD3D())
|
||||
{
|
||||
if (0 == InitD3D()) {
|
||||
MessageBox(NULL,"Failed to initialize Direct3D 9",
|
||||
"ASSIMP ModelViewer",MB_OK);
|
||||
return -6;
|
||||
|
@ -2395,8 +2392,7 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
|
|||
Assimp::DefaultLogger::Debugging | Assimp::DefaultLogger::Info |
|
||||
Assimp::DefaultLogger::Err | Assimp::DefaultLogger::Warn);
|
||||
|
||||
if (NULL == hDlg)
|
||||
{
|
||||
if (NULL == hDlg) {
|
||||
MessageBox(NULL,"Failed to create dialog from resource",
|
||||
"ASSIMP ModelViewer",MB_OK);
|
||||
return -5;
|
||||
|
@ -2410,12 +2406,12 @@ int APIENTRY _tWinMain(HINSTANCE hInstance,
|
|||
UpdateWindow( hDlg );
|
||||
|
||||
// create the D3D device object
|
||||
if (0 == CreateDevice(g_sOptions.bMultiSample,false,true))
|
||||
{
|
||||
if (0 == CreateDevice(g_sOptions.bMultiSample,false,true)) {
|
||||
MessageBox(NULL,"Failed to initialize Direct3D 9 (2)",
|
||||
"ASSIMP ModelViewer",MB_OK);
|
||||
return -4;
|
||||
}
|
||||
|
||||
CLogDisplay::Instance().AddEntry("[OK] Here we go!");
|
||||
|
||||
// create the log window
|
||||
|
|
|
@ -43,10 +43,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
|
||||
#include "assimp_view.h"
|
||||
#include <timeapi.h>
|
||||
#include <assimp/StringUtils.h>
|
||||
#include <map>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <mmsystem.h>
|
||||
#else
|
||||
#include <timeapi.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace AssimpView {
|
||||
|
@ -143,7 +148,7 @@ float g_fLoadTime = 0.0f;
|
|||
|
||||
//-------------------------------------------------------------------------------
|
||||
// Entry point for the loader thread
|
||||
// The laoder thread loads the asset while the progress dialog displays the
|
||||
// The loader thread loads the asset while the progress dialog displays the
|
||||
// smart progress bar
|
||||
//-------------------------------------------------------------------------------
|
||||
DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
|
||||
|
@ -200,9 +205,9 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
|
|||
// load the current asset
|
||||
// THe path to the asset is specified in the global path variable
|
||||
//-------------------------------------------------------------------------------
|
||||
int LoadAsset(void)
|
||||
int LoadAsset()
|
||||
{
|
||||
// set the world and world rotation matrices to the identuty
|
||||
// set the world and world rotation matrices to the identity
|
||||
g_mWorldRotate = aiMatrix4x4();
|
||||
g_mWorld = aiMatrix4x4();
|
||||
|
||||
|
@ -1130,8 +1135,6 @@ int GetProjectionMatrix (aiMatrix4x4& p_mOut)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------
|
||||
aiVector3D GetCameraMatrix (aiMatrix4x4& p_mOut)
|
||||
{
|
||||
|
|
|
@ -46,6 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#define AI_SHADER_COMPILE_FLAGS D3DXSHADER_USE_LEGACY_D3DX9_31_DLL
|
||||
|
||||
// Because Dx headers include windef.h with min/max redefinition
|
||||
#define NOMINMAX
|
||||
|
||||
// include resource definitions
|
||||
#include "resource.h"
|
||||
|
||||
|
@ -177,7 +180,7 @@ type clamp(intype in)
|
|||
{
|
||||
// for unsigned types only ...
|
||||
intype mask = (0x1u << (sizeof(type)*8))-1;
|
||||
return (type)max((intype)0,min(in,mask));
|
||||
return (type)std::max((intype)0,std::min(in,mask));
|
||||
}
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue