Merge branch 'master' into add_VS2013_VS2019
commit
19fddb0861
|
@ -7,7 +7,8 @@
|
|||
#
|
||||
function generate() {
|
||||
OPTIONS="-DASSIMP_WERROR=ON"
|
||||
|
||||
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
|
||||
|
||||
if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
|
||||
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"
|
||||
else
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
:: This is an example file to generate binaries using Windows Operating System
|
||||
:: This script is configured to be executed from the source directory
|
||||
|
||||
:: Compiled binaries will be placed in BINARIES_DIR\code\CONFIG
|
||||
|
||||
:: NOTE
|
||||
:: The build process will generate a config.h file that is placed in BINARIES_DIR\include
|
||||
:: This file must be merged with SOURCE_DIR\include
|
||||
:: You should write yourself a script that copies the files where you want them.
|
||||
:: Also see: https://github.com/assimp/assimp/pull/2646
|
||||
|
||||
SET SOURCE_DIR=.
|
||||
|
||||
:: For generators see "cmake --help"
|
||||
SET GENERATOR=Visual Studio 15 2017
|
||||
|
||||
SET BINARIES_DIR="./BINARIES/Win32"
|
||||
cmake CMakeLists.txt -G "%GENERATOR%" -S %SOURCE_DIR% -B %BINARIES_DIR%
|
||||
cmake --build %BINARIES_DIR% --config release
|
||||
|
||||
SET BINARIES_DIR="./BINARIES/x64"
|
||||
cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR%
|
||||
cmake --build %BINARIES_DIR% --config debug
|
||||
cmake --build %BINARIES_DIR% --config release
|
||||
|
||||
PAUSE
|
28
Build.md
28
Build.md
|
@ -1,17 +1,31 @@
|
|||
# Build Instructions
|
||||
## Install CMake
|
||||
|
||||
## Build on all platforms using vcpkg
|
||||
You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
|
||||
```bash
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
vcpkg install assimp
|
||||
```
|
||||
The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
## Manual build instructions
|
||||
|
||||
### Install CMake
|
||||
Asset-Importer-Lib can be build for a lot of different platforms. We are using cmake to generate the build environment for these via cmake. So you have to make sure that you have a working cmake-installation on your system. You can download it at https://cmake.org/ or for linux install it via
|
||||
```bash
|
||||
sudo apt-get install cmake
|
||||
```
|
||||
|
||||
## Get the source
|
||||
### Get the source
|
||||
Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
|
||||
```bash
|
||||
git clone https://github.com/assimp/assimp.git
|
||||
```
|
||||
|
||||
## Build instructions for Windows with Visual-Studio
|
||||
### Build instructions for Windows with Visual-Studio
|
||||
|
||||
First you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
|
||||
To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
|
||||
|
@ -20,10 +34,10 @@ cmake CMakeLists.txt
|
|||
```
|
||||
This will generate the project files for the visual studio. All dependencies used to build Asset-IMporter-Lib shall be part of the repo. If you want to use you own zlib.installation this is possible as well. Check the options for it.
|
||||
|
||||
## Build instructions for Windows with UWP
|
||||
### Build instructions for Windows with UWP
|
||||
See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app>
|
||||
|
||||
## Build instructions for Linux / Unix
|
||||
### Build instructions for Linux / Unix
|
||||
Open a terminal and got to your repository. You can generate the makefiles and build the library via:
|
||||
|
||||
```bash
|
||||
|
@ -34,7 +48,7 @@ The option -j descripes the number of parallel processes for the build. In this
|
|||
|
||||
If you want to use a IDE for linux you can try QTCreator for instance.
|
||||
|
||||
## Build instructions for MinGW
|
||||
### Build instructions for MinGW
|
||||
Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag
|
||||
required to compile some of assimp's files, especially for debug builds.
|
||||
Version 7.3.0 of g++-mingw-w64 & gcc-mingw-w64 appears to work.
|
||||
|
@ -50,7 +64,7 @@ The following toolchain may or may not be helpful for building assimp using MinG
|
|||
|
||||
Besides the toolchain, compilation should be the same as for Linux / Unix.
|
||||
|
||||
## CMake build options
|
||||
### CMake build options
|
||||
The cmake-build-environment provides options to configure the build. The following options can be used:
|
||||
- **BUILD_SHARED_LIBS ( default ON )**: Generation of shared libs ( dll for windows, so for Linux ). Set this to OFF to get a static lib.
|
||||
- **BUILD_FRAMEWORK ( default OFF, MacOnly)**: Build package as Mac OS X Framework bundle
|
||||
|
|
|
@ -277,16 +277,14 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
|||
ENDIF()
|
||||
|
||||
IF ( IOS AND NOT HUNTER_ENABLED)
|
||||
|
||||
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
|
||||
ELSE()
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
|
||||
# Experimental for pdb generation
|
||||
ENDIF()
|
||||
|
||||
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
|
||||
ELSE()
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
|
||||
# Experimental for pdb generation
|
||||
ENDIF()
|
||||
ENDIF( IOS AND NOT HUNTER_ENABLED)
|
||||
|
||||
IF (ASSIMP_COVERALLS)
|
||||
|
@ -559,17 +557,15 @@ ENDIF(NOT HUNTER_ENABLED)
|
|||
|
||||
ADD_SUBDIRECTORY( code/ )
|
||||
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||
# The viewer for windows only
|
||||
IF ( WIN32 AND DirectX_D3DX9_LIBRARY )
|
||||
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} )
|
||||
IF ( ASSIMP_BUILD_ASSIMP_VIEW )
|
||||
ADD_SUBDIRECTORY( tools/assimp_view/ )
|
||||
ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW )
|
||||
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
|
||||
|
||||
# Te command line tool
|
||||
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
||||
IF (NOT IOS)
|
||||
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
||||
ENDIF (NOT IOS)
|
||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||
|
||||
IF ( ASSIMP_BUILD_SAMPLES)
|
||||
|
|
|
@ -120,7 +120,7 @@ __Exporters__:
|
|||
- FBX ( experimental )
|
||||
|
||||
### Building ###
|
||||
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
|
||||
Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
|
||||
|
||||
### Ports ###
|
||||
* [Android](port/AndroidJNI/README.md)
|
||||
|
|
|
@ -18,6 +18,7 @@ image:
|
|||
- Visual Studio 2015
|
||||
- Visual Studio 2017
|
||||
- Visual Studio 2019
|
||||
- MinGW
|
||||
|
||||
platform:
|
||||
- Win32
|
||||
|
@ -28,10 +29,13 @@ configuration: Release
|
|||
install:
|
||||
- set PATH=C:\Ruby24-x64\bin;%PATH%
|
||||
- set CMAKE_DEFINES -DASSIMP_WERROR=ON
|
||||
- if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH%
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
|
||||
- if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
|
||||
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" .
|
||||
# Rename sh.exe as sh.exe in PATH interferes with MinGW
|
||||
- rename "C:\Program Files\Git\usr\bin\sh.exe" "sh2.exe"
|
||||
- set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"
|
||||
- ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe
|
||||
- ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe
|
||||
|
|
|
@ -766,6 +766,8 @@ ADD_ASSIMP_EXPORTER( X3D
|
|||
)
|
||||
|
||||
ADD_ASSIMP_IMPORTER( GLTF
|
||||
glTF/glTFCommon.h
|
||||
glTF/glTFCommon.cpp
|
||||
glTF/glTFAsset.h
|
||||
glTF/glTFAsset.inl
|
||||
glTF/glTFAssetWriter.h
|
||||
|
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "ColladaExporter.h"
|
||||
#include <assimp/Bitmap.h>
|
||||
#include <assimp/MathFunctions.h>
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <assimp/SceneCombiner.h>
|
||||
#include <assimp/StringUtils.h>
|
||||
|
@ -155,7 +156,7 @@ void ColladaExporter::WriteFile() {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes the asset header
|
||||
void ColladaExporter::WriteHeader() {
|
||||
static const ai_real epsilon = ai_real( 0.00001 );
|
||||
static const ai_real epsilon = Math::getEpsilon<ai_real>();
|
||||
static const aiQuaternion x_rot(aiMatrix3x3(
|
||||
0, -1, 0,
|
||||
1, 0, 0,
|
||||
|
@ -317,7 +318,7 @@ void ColladaExporter::WriteTextures() {
|
|||
|
||||
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint);
|
||||
|
||||
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + name, "wb"));
|
||||
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
|
||||
if(outfile == NULL) {
|
||||
throw DeadlyExportError("could not open output texture file: " + mPath + name);
|
||||
}
|
||||
|
@ -1671,4 +1672,4 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
|
|||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -85,7 +85,7 @@ void BaseImporter::UpdateImporterScale( Importer* pImp )
|
|||
double activeScale = importerScale * fileScale;
|
||||
|
||||
// Set active scaling
|
||||
pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, activeScale);
|
||||
pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
|
||||
|
||||
ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "FBXImporter.h"
|
||||
|
||||
#include <assimp/StringComparison.h>
|
||||
#include <assimp/MathFunctions.h>
|
||||
|
||||
#include <assimp/scene.h>
|
||||
|
||||
|
@ -553,7 +554,7 @@ namespace Assimp {
|
|||
return;
|
||||
}
|
||||
|
||||
const float angle_epsilon = 1e-6f;
|
||||
const float angle_epsilon = Math::getEpsilon<float>();
|
||||
|
||||
out = aiMatrix4x4();
|
||||
|
||||
|
@ -694,7 +695,7 @@ namespace Assimp {
|
|||
std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
|
||||
|
||||
// generate transformation matrices for all the different transformation components
|
||||
const float zero_epsilon = 1e-6f;
|
||||
const float zero_epsilon = Math::getEpsilon<float>();
|
||||
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
||||
|
||||
const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
||||
|
@ -2001,6 +2002,21 @@ namespace Assimp {
|
|||
TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
|
||||
|
||||
// Maya PBR
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
||||
|
||||
// Maya stingray
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
|
||||
TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
|
||||
}
|
||||
|
||||
void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
|
||||
|
@ -2952,7 +2968,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
|
|||
TransformationCompDefaultValue(comp)
|
||||
);
|
||||
|
||||
const float epsilon = 1e-6f;
|
||||
const float epsilon = Math::getEpsilon<float>();
|
||||
return (dyn_val - static_val).SquareLength() < epsilon;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,11 +59,7 @@ namespace FBX {
|
|||
|
||||
FBXExportProperty::FBXExportProperty(bool v)
|
||||
: type('C')
|
||||
, data(1) {
|
||||
data = {
|
||||
uint8_t(v)
|
||||
};
|
||||
}
|
||||
, data(1, uint8_t(v)) {}
|
||||
|
||||
FBXExportProperty::FBXExportProperty(int16_t v)
|
||||
: type('Y')
|
||||
|
|
|
@ -1289,7 +1289,7 @@ void FBXExporter::WriteObjects ()
|
|||
|
||||
for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
|
||||
{
|
||||
FBX::Node layerExtra("Layer", int32_t(1));
|
||||
FBX::Node layerExtra("Layer", int32_t(lr));
|
||||
layerExtra.AddChild("Version", int32_t(100));
|
||||
FBX::Node leExtra("LayerElement");
|
||||
leExtra.AddChild("Type", "LayerElementUV");
|
||||
|
|
|
@ -311,10 +311,9 @@ class TrimmedCurve : public BoundedCurve {
|
|||
public:
|
||||
// --------------------------------------------------
|
||||
TrimmedCurve(const Schema_2x3::IfcTrimmedCurve& entity, ConversionData& conv)
|
||||
: BoundedCurve(entity,conv)
|
||||
: BoundedCurve(entity,conv),
|
||||
base(std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv)))
|
||||
{
|
||||
base = std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv));
|
||||
|
||||
typedef std::shared_ptr<const STEP::EXPRESS::DataType> Entry;
|
||||
|
||||
// for some reason, trimmed curves can either specify a parametric value
|
||||
|
@ -500,7 +499,7 @@ bool Curve::InRange(IfcFloat u) const {
|
|||
if (IsClosed()) {
|
||||
return true;
|
||||
}
|
||||
const IfcFloat epsilon = 1e-5;
|
||||
const IfcFloat epsilon = Math::getEpsilon<float>();
|
||||
return u - range.first > -epsilon && range.second - u > -epsilon;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -593,7 +593,7 @@ typedef std::vector<std::pair<
|
|||
bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
|
||||
{
|
||||
// TODO: I'm pretty sure there is a much more compact way to check this
|
||||
const IfcFloat epsilon = 1e-5f;
|
||||
const IfcFloat epsilon = Math::getEpsilon<float>();
|
||||
return (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
|
||||
(std::fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) ||
|
||||
(std::fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) ||
|
||||
|
@ -681,7 +681,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours)
|
||||
{
|
||||
const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(1e-8);
|
||||
const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
|
||||
const BoundingBox& bb = (*current).bb;
|
||||
|
||||
// What is to be done here is to populate the skip lists for the contour
|
||||
|
@ -758,7 +758,7 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta)
|
||||
{
|
||||
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(1e-5);
|
||||
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
|
||||
return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
|
||||
}
|
||||
|
||||
|
|
|
@ -344,7 +344,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
|
|||
if (pcSkins->name[0])
|
||||
{
|
||||
aiString szString;
|
||||
const size_t iLen = ::strlen(pcSkins->name);
|
||||
const ai_uint32 iLen = (ai_uint32) ::strlen(pcSkins->name);
|
||||
::memcpy(szString.data,pcSkins->name,iLen);
|
||||
szString.data[iLen] = '\0';
|
||||
szString.length = iLen;
|
||||
|
|
|
@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "MD5Loader.h"
|
||||
#include <assimp/StringComparison.h>
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <assimp/MathFunctions.h>
|
||||
#include <assimp/SkeletonMeshBuilder.h>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
|
@ -64,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
using namespace Assimp;
|
||||
|
||||
// Minimum weight value. Weights inside [-n ... n] are ignored
|
||||
#define AI_MD5_WEIGHT_EPSILON 1e-5f
|
||||
#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
|
||||
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
|
|
|
@ -235,7 +235,7 @@ bool MD5Parser::ParseSection(Section& out)
|
|||
const char* szStart = ++sz; \
|
||||
while('\"'!=*sz)++sz; \
|
||||
const char* szEnd = (sz++); \
|
||||
out.length = (size_t)(szEnd - szStart); \
|
||||
out.length = (ai_uint32) (szEnd - szStart); \
|
||||
::memcpy(out.data,szStart,out.length); \
|
||||
out.data[out.length] = '\0';
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -94,23 +92,24 @@ static const aiImporterDesc desc = {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
MDLImporter::MDLImporter()
|
||||
: configFrameID(),
|
||||
mBuffer(),
|
||||
iGSFileVersion(),
|
||||
pIOHandler(),
|
||||
pScene(),
|
||||
iFileSize()
|
||||
{}
|
||||
: configFrameID()
|
||||
, mBuffer()
|
||||
, iGSFileVersion()
|
||||
, pIOHandler()
|
||||
, pScene()
|
||||
, iFileSize() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
MDLImporter::~MDLImporter()
|
||||
{}
|
||||
MDLImporter::~MDLImporter() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
||||
{
|
||||
bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
||||
const std::string extension = GetExtension(pFile);
|
||||
|
||||
// if check for extension is not enough, check for the magic tokens
|
||||
|
@ -404,23 +403,15 @@ void MDLImporter::InternReadFile_Quake1() {
|
|||
|
||||
// now get a pointer to the first frame in the file
|
||||
BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
|
||||
BE_NCONST MDL::SimpleFrame* pcFirstFrame;
|
||||
MDL::SimpleFrame* pcFirstFrame;
|
||||
|
||||
if (0 == pcFrames->type) {
|
||||
// get address of single frame
|
||||
pcFirstFrame = &pcFrames->frame;
|
||||
pcFirstFrame =( MDL::SimpleFrame*) &pcFrames->frame;
|
||||
} else {
|
||||
// get the first frame in the group
|
||||
|
||||
#if 1
|
||||
// FIXME: the cast is wrong and cause a warning on clang 5.0
|
||||
// disable this code for now, fix it later
|
||||
ai_assert(false && "Bad pointer cast");
|
||||
pcFirstFrame = nullptr; // Workaround: msvc++ C4703 error
|
||||
#else
|
||||
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
|
||||
pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
|
||||
#endif
|
||||
BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*) pcFrames;
|
||||
pcFirstFrame = &(pcFrames2->frames[0]);
|
||||
}
|
||||
BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
|
||||
VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));
|
||||
|
|
|
@ -89,16 +89,12 @@ public:
|
|||
MDLImporter();
|
||||
~MDLImporter();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns whether the class can handle the format of the given file.
|
||||
* See BaseImporter::CanRead() for details. */
|
||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||
bool checkSig) const;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Called prior to ReadFile().
|
||||
* The function is a request to the importer to update its configuration
|
||||
|
@ -107,8 +103,6 @@ public:
|
|||
void SetupProperties(const Importer* pImp);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Return importer meta information.
|
||||
* See #BaseImporter::GetInfo for the details
|
||||
|
@ -122,8 +116,6 @@ protected:
|
|||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||
IOSystem* pIOHandler);
|
||||
|
||||
protected:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Import a quake 1 MDL file (IDPO)
|
||||
*/
|
||||
|
@ -154,7 +146,6 @@ protected:
|
|||
void SizeCheck(const void* szPos);
|
||||
void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Validate the header data structure of a game studio MDL7 file
|
||||
* \param pcHeader Input header to be validated
|
||||
|
@ -167,7 +158,6 @@ protected:
|
|||
*/
|
||||
void ValidateHeader_Quake1(const MDL::Header* pcHeader);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Try to load a palette from the current directory (colormap.lmp)
|
||||
* If it is not found the default palette of Quake1 is returned
|
||||
|
@ -179,9 +169,8 @@ protected:
|
|||
*/
|
||||
void FreePalette(const unsigned char* pszColorMap);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Load a paletized texture from the file and convert it to 32bpp
|
||||
/** Load a palletized texture from the file and convert it to 32bpp
|
||||
*/
|
||||
void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
|
||||
|
||||
|
@ -195,7 +184,6 @@ protected:
|
|||
unsigned int iType,
|
||||
unsigned int* piSkip);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Used to load textures from MDL5
|
||||
* \param szData Input data
|
||||
|
@ -206,7 +194,6 @@ protected:
|
|||
unsigned int iType,
|
||||
unsigned int* piSkip);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Checks whether a texture can be replaced with a single color
|
||||
* This is useful for all file formats before MDL7 (all those
|
||||
|
@ -218,14 +205,12 @@ protected:
|
|||
*/
|
||||
aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Converts the absolute texture coordinates in MDL5 files to
|
||||
* relative in a range between 0 and 1
|
||||
*/
|
||||
void CalculateUVCoordinates_MDL5();
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Read an UV coordinate from the file. If the file format is not
|
||||
* MDL5, the function calculates relative texture coordinates
|
||||
|
@ -245,7 +230,6 @@ protected:
|
|||
*/
|
||||
void SetupMaterialProperties_3DGS_MDL5_Quake1( );
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Parse a skin lump in a MDL7/HMP7 file with all of its features
|
||||
* variant 1: Current cursor position is the beginning of the skin header
|
||||
|
|
|
@ -545,23 +545,7 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput,
|
|||
unsigned int type,
|
||||
unsigned int index)
|
||||
{
|
||||
// We don't want to add the whole buffer .. write a 32 bit length
|
||||
// prefix followed by the zero-terminated UTF8 string.
|
||||
// (HACK) I don't want to break the ABI now, but we definitely
|
||||
// ought to change aiString::mLength to uint32_t one day.
|
||||
if (sizeof(size_t) == 8) {
|
||||
aiString copy = *pInput;
|
||||
uint32_t* s = reinterpret_cast<uint32_t*>(©.length);
|
||||
s[1] = static_cast<uint32_t>(pInput->length);
|
||||
|
||||
return AddBinaryProperty(s+1,
|
||||
static_cast<unsigned int>(pInput->length+1+4),
|
||||
pKey,
|
||||
type,
|
||||
index,
|
||||
aiPTI_String);
|
||||
}
|
||||
ai_assert(sizeof(size_t)==4);
|
||||
ai_assert(sizeof(ai_uint32)==4);
|
||||
return AddBinaryProperty(pInput,
|
||||
static_cast<unsigned int>(pInput->length+1+4),
|
||||
pKey,
|
||||
|
|
|
@ -79,10 +79,7 @@ using namespace std;
|
|||
ObjFileImporter::ObjFileImporter()
|
||||
: m_Buffer()
|
||||
, m_pRootObject( nullptr )
|
||||
, m_strAbsPath( "" ) {
|
||||
DefaultIOSystem io;
|
||||
m_strAbsPath = io.getOsSeparator();
|
||||
}
|
||||
, m_strAbsPath( std::string(1, DefaultIOSystem().getOsSeparator()) ) {}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor.
|
||||
|
|
|
@ -354,12 +354,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
|
|||
}
|
||||
else if (axis * base_axis_z >= angle_epsilon) {
|
||||
FindMeshCenter(mesh, center, min, max);
|
||||
diffu = max.y - min.y;
|
||||
diffv = max.z - min.z;
|
||||
diffu = max.x - min.x;
|
||||
diffv = max.y - min.y;
|
||||
|
||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||
const aiVector3D& pos = mesh->mVertices[pnt];
|
||||
out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.0);
|
||||
out[pnt].Set((pos.x - min.x) / diffu,(pos.y - min.y) / diffv,0.0);
|
||||
}
|
||||
}
|
||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||
|
|
|
@ -958,7 +958,7 @@ void ValidateDSProcess::Validate( const aiString* pString)
|
|||
{
|
||||
if (pString->length > MAXLEN)
|
||||
{
|
||||
ReportError("aiString::length is too large (%lu, maximum is %lu)",
|
||||
ReportError("aiString::length is too large (%u, maximum is %lu)",
|
||||
pString->length,MAXLEN);
|
||||
}
|
||||
const char* sz = pString->data;
|
||||
|
|
|
@ -596,11 +596,11 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
|
|||
// do not crah when no face definitions are there
|
||||
if (numFaces > 0) {
|
||||
// normal face creation
|
||||
pMesh->mNormFaces.resize( pMesh->mNormFaces.size() + numFaces );
|
||||
pMesh->mNormFaces.resize( numFaces );
|
||||
for( unsigned int a = 0; a < numFaces; ++a ) {
|
||||
unsigned int numIndices = ReadInt();
|
||||
pMesh->mNormFaces.push_back( Face() );
|
||||
Face& face = pMesh->mNormFaces.back();
|
||||
pMesh->mNormFaces[a] = Face();
|
||||
Face& face = pMesh->mNormFaces[a];
|
||||
for( unsigned int b = 0; b < numIndices; ++b ) {
|
||||
face.mIndices.push_back( ReadInt());
|
||||
}
|
||||
|
|
|
@ -614,7 +614,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::ve
|
|||
|
||||
XML_ReadNode_GetAttrVal_AsListCol3f(pAttrIdx, tlist);// read as list
|
||||
// and copy to array
|
||||
if(tlist.size() > 0)
|
||||
if(!tlist.empty())
|
||||
{
|
||||
pValue.reserve(tlist.size());
|
||||
for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); ++it) pValue.push_back(*it);
|
||||
|
|
|
@ -289,7 +289,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
// at first create mesh from existing vertices.
|
||||
*pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIdx, tnemesh.Vertices);
|
||||
// copy additional information from children
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
||||
|
@ -301,7 +301,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid)
|
||||
|
@ -313,7 +313,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
|
||||
|
||||
// at first search for <Coordinate> node and create mesh.
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{
|
||||
|
@ -322,7 +322,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
}
|
||||
|
||||
// copy additional information from children
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
|
||||
|
@ -338,7 +338,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet)
|
||||
|
@ -348,7 +348,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
|
||||
|
||||
// at first search for <Coordinate> node and create mesh.
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{
|
||||
|
@ -357,7 +357,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
}
|
||||
|
||||
// copy additional information from children
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
ai_assert(*pMesh);
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||
|
@ -369,7 +369,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
{} // skip because already read when mesh created.
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet)
|
||||
|
@ -381,7 +381,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
|
||||
|
||||
// at first search for <Coordinate> node and create mesh.
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{
|
||||
|
@ -390,7 +390,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
}
|
||||
|
||||
// copy additional information from children
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
ai_assert(*pMesh);
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||
|
@ -408,7 +408,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \
|
||||
IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet))
|
||||
|
@ -430,7 +430,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
|
||||
|
||||
// at first search for <Coordinate> node and create mesh.
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{
|
||||
|
@ -448,7 +448,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
}
|
||||
|
||||
// copy additional information from children
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
ai_assert(*pMesh);
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||
|
@ -459,7 +459,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
{} // skip because already read when mesh created.
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet)
|
||||
|
@ -469,7 +469,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
|
||||
|
||||
// at first search for <Coordinate> node and create mesh.
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{
|
||||
|
@ -478,7 +478,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
}
|
||||
|
||||
// copy additional information from children
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
ai_assert(*pMesh);
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
|
||||
|
@ -489,7 +489,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
{} // skip because already read when mesh created.
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet)
|
||||
|
@ -499,7 +499,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
|
||||
|
||||
// at first search for <Coordinate> node and create mesh.
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{
|
||||
|
@ -508,7 +508,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
}
|
||||
|
||||
// copy additional information from children
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if ( nullptr == *pMesh ) {
|
||||
break;
|
||||
|
@ -526,7 +526,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet)
|
||||
|
@ -536,7 +536,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
|
||||
|
||||
// at first search for <Coordinate> node and create mesh.
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
{
|
||||
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{
|
||||
|
@ -570,7 +570,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet)
|
||||
|
@ -605,7 +605,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet)
|
||||
|
|
|
@ -92,38 +92,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#include "glTF/glTFCommon.h"
|
||||
|
||||
namespace glTF
|
||||
{
|
||||
#ifdef ASSIMP_API
|
||||
using Assimp::IOStream;
|
||||
using Assimp::IOSystem;
|
||||
using std::shared_ptr;
|
||||
#else
|
||||
using std::shared_ptr;
|
||||
|
||||
typedef std::runtime_error DeadlyImportError;
|
||||
typedef std::runtime_error DeadlyExportError;
|
||||
|
||||
enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
|
||||
class IOSystem;
|
||||
class IOStream
|
||||
{
|
||||
FILE* f;
|
||||
public:
|
||||
IOStream(FILE* file) : f(file) {}
|
||||
~IOStream() { fclose(f); f = 0; }
|
||||
|
||||
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
|
||||
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
|
||||
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
|
||||
size_t Tell() const { return ftell(f); }
|
||||
|
||||
size_t FileSize() {
|
||||
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
|
||||
return size_t((Seek(p, aiOrigin_SET), len));
|
||||
}
|
||||
};
|
||||
#endif
|
||||
using glTFCommon::shared_ptr;
|
||||
using glTFCommon::IOSystem;
|
||||
using glTFCommon::IOStream;
|
||||
|
||||
using rapidjson::Value;
|
||||
using rapidjson::Document;
|
||||
|
@ -136,37 +111,9 @@ namespace glTF
|
|||
struct Light;
|
||||
struct Skin;
|
||||
|
||||
|
||||
// Vec/matrix types, as raw float arrays
|
||||
typedef float (vec3)[3];
|
||||
typedef float (vec4)[4];
|
||||
typedef float (mat4)[16];
|
||||
|
||||
|
||||
namespace Util
|
||||
{
|
||||
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
|
||||
|
||||
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
|
||||
|
||||
inline size_t DecodeBase64(const char* in, uint8_t*& out)
|
||||
{
|
||||
return DecodeBase64(in, strlen(in), out);
|
||||
}
|
||||
|
||||
struct DataURI
|
||||
{
|
||||
const char* mediaType;
|
||||
const char* charset;
|
||||
bool base64;
|
||||
const char* data;
|
||||
size_t dataLength;
|
||||
};
|
||||
|
||||
//! Check if a uri is a data URI
|
||||
inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
|
||||
}
|
||||
|
||||
using glTFCommon::vec3;
|
||||
using glTFCommon::vec4;
|
||||
using glTFCommon::mat4;
|
||||
|
||||
//! Magic number for GLB files
|
||||
#define AI_GLB_MAGIC_NUMBER "glTF"
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -52,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#endif
|
||||
|
||||
using namespace Assimp;
|
||||
using namespace glTFCommon;
|
||||
|
||||
namespace glTF {
|
||||
|
||||
|
@ -301,7 +301,7 @@ inline void Buffer::Read(Value& obj, Asset& r)
|
|||
|
||||
const char* uri = it->GetString();
|
||||
|
||||
Util::DataURI dataURI;
|
||||
glTFCommon::Util::DataURI dataURI;
|
||||
if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
|
||||
if (dataURI.base64) {
|
||||
uint8_t* data = 0;
|
||||
|
@ -654,12 +654,12 @@ inline void Image::Read(Value& obj, Asset& r)
|
|||
if (Value* uri = FindString(obj, "uri")) {
|
||||
const char* uristr = uri->GetString();
|
||||
|
||||
Util::DataURI dataURI;
|
||||
glTFCommon::Util::DataURI dataURI;
|
||||
if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
|
||||
mimeType = dataURI.mediaType;
|
||||
if (dataURI.base64) {
|
||||
uint8_t *ptr = nullptr;
|
||||
mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
|
||||
mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
|
||||
mData.reset(ptr);
|
||||
}
|
||||
}
|
||||
|
@ -1180,8 +1180,12 @@ inline void Light::SetDefaults()
|
|||
falloffExponent = 0.f;
|
||||
}
|
||||
|
||||
inline void Node::Read(Value& obj, Asset& r)
|
||||
{
|
||||
inline
|
||||
void Node::Read(Value& obj, Asset& r) {
|
||||
if (name.empty()) {
|
||||
name = id;
|
||||
}
|
||||
|
||||
if (Value* children = FindArray(obj, "children")) {
|
||||
this->children.reserve(children->Size());
|
||||
for (unsigned int i = 0; i < children->Size(); ++i) {
|
||||
|
@ -1474,190 +1478,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
|
|||
return id;
|
||||
}
|
||||
|
||||
namespace Util {
|
||||
|
||||
inline
|
||||
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
|
||||
if ( NULL == const_uri ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const_uri[0] != 0x10) { // we already parsed this uri?
|
||||
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
|
||||
return false;
|
||||
}
|
||||
|
||||
// set defaults
|
||||
out.mediaType = "text/plain";
|
||||
out.charset = "US-ASCII";
|
||||
out.base64 = false;
|
||||
|
||||
char* uri = const_cast<char*>(const_uri);
|
||||
if (uri[0] != 0x10) {
|
||||
uri[0] = 0x10;
|
||||
uri[1] = uri[2] = uri[3] = uri[4] = 0;
|
||||
|
||||
size_t i = 5, j;
|
||||
if (uri[i] != ';' && uri[i] != ',') { // has media type?
|
||||
uri[1] = char(i);
|
||||
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
||||
// nothing to do!
|
||||
}
|
||||
}
|
||||
while (uri[i] == ';' && i < uriLen) {
|
||||
uri[i++] = '\0';
|
||||
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
||||
// nothing to do!
|
||||
}
|
||||
|
||||
if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
|
||||
uri[2] = char(j + 8);
|
||||
} else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
|
||||
uri[3] = char(j);
|
||||
}
|
||||
}
|
||||
if (i < uriLen) {
|
||||
uri[i++] = '\0';
|
||||
uri[4] = char(i);
|
||||
} else {
|
||||
uri[1] = uri[2] = uri[3] = 0;
|
||||
uri[4] = 5;
|
||||
}
|
||||
}
|
||||
|
||||
if ( uri[ 1 ] != 0 ) {
|
||||
out.mediaType = uri + uri[ 1 ];
|
||||
}
|
||||
if ( uri[ 2 ] != 0 ) {
|
||||
out.charset = uri + uri[ 2 ];
|
||||
}
|
||||
if ( uri[ 3 ] != 0 ) {
|
||||
out.base64 = true;
|
||||
}
|
||||
out.data = uri + uri[4];
|
||||
out.dataLength = (uri + uriLen) - out.data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool B>
|
||||
struct DATA
|
||||
{
|
||||
static const uint8_t tableDecodeBase64[128];
|
||||
};
|
||||
|
||||
template<bool B>
|
||||
const uint8_t DATA<B>::tableDecodeBase64[128] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
|
||||
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
|
||||
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
inline char EncodeCharBase64(uint8_t b)
|
||||
{
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
|
||||
}
|
||||
|
||||
inline uint8_t DecodeCharBase64(char c)
|
||||
{
|
||||
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
|
||||
/*if (c >= 'A' && c <= 'Z') return c - 'A';
|
||||
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
|
||||
if (c >= '0' && c <= '9') return c - '0' + 52;
|
||||
if (c == '+') return 62;
|
||||
if (c == '/') return 63;
|
||||
return 64; // '-' */
|
||||
}
|
||||
|
||||
inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
|
||||
{
|
||||
ai_assert(inLength % 4 == 0);
|
||||
|
||||
if (inLength < 4) {
|
||||
out = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nEquals = int(in[inLength - 1] == '=') +
|
||||
int(in[inLength - 2] == '=');
|
||||
|
||||
size_t outLength = (inLength * 3) / 4 - nEquals;
|
||||
out = new uint8_t[outLength];
|
||||
memset(out, 0, outLength);
|
||||
|
||||
size_t i, j = 0;
|
||||
|
||||
for (i = 0; i + 4 < inLength; i += 4) {
|
||||
uint8_t b0 = DecodeCharBase64(in[i]);
|
||||
uint8_t b1 = DecodeCharBase64(in[i + 1]);
|
||||
uint8_t b2 = DecodeCharBase64(in[i + 2]);
|
||||
uint8_t b3 = DecodeCharBase64(in[i + 3]);
|
||||
|
||||
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
|
||||
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
|
||||
out[j++] = (uint8_t)((b2 << 6) | b3);
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t b0 = DecodeCharBase64(in[i]);
|
||||
uint8_t b1 = DecodeCharBase64(in[i + 1]);
|
||||
uint8_t b2 = DecodeCharBase64(in[i + 2]);
|
||||
uint8_t b3 = DecodeCharBase64(in[i + 3]);
|
||||
|
||||
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
|
||||
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
|
||||
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
|
||||
}
|
||||
|
||||
return outLength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void EncodeBase64(
|
||||
const uint8_t* in, size_t inLength,
|
||||
std::string& out)
|
||||
{
|
||||
size_t outLength = ((inLength + 2) / 3) * 4;
|
||||
|
||||
size_t j = out.size();
|
||||
out.resize(j + outLength);
|
||||
|
||||
for (size_t i = 0; i < inLength; i += 3) {
|
||||
uint8_t b = (in[i] & 0xFC) >> 2;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = (in[i] & 0x03) << 4;
|
||||
if (i + 1 < inLength) {
|
||||
b |= (in[i + 1] & 0xF0) >> 4;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = (in[i + 1] & 0x0F) << 2;
|
||||
if (i + 2 < inLength) {
|
||||
b |= (in[i + 2] & 0xC0) >> 6;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = in[i + 2] & 0x3F;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
}
|
||||
else {
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
out[j++] = '=';
|
||||
}
|
||||
}
|
||||
else {
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
out[j++] = '=';
|
||||
out[j++] = '=';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // ns glTF
|
||||
|
|
|
@ -55,7 +55,8 @@ namespace glTF {
|
|||
namespace {
|
||||
|
||||
template<size_t N>
|
||||
inline Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
|
||||
inline
|
||||
Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
|
||||
val.SetArray();
|
||||
val.Reserve(N, al);
|
||||
for (decltype(N) i = 0; i < N; ++i) {
|
||||
|
@ -64,7 +65,8 @@ namespace glTF {
|
|||
return val;
|
||||
}
|
||||
|
||||
inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
|
||||
inline
|
||||
Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
|
||||
val.SetArray();
|
||||
val.Reserve(static_cast<rapidjson::SizeType>(r.size()), al);
|
||||
for (unsigned int i = 0; i < r.size(); ++i) {
|
||||
|
@ -213,7 +215,7 @@ namespace glTF {
|
|||
else if (img.HasData()) {
|
||||
uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
|
||||
uri += ";base64,";
|
||||
Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
|
||||
glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
|
||||
}
|
||||
else {
|
||||
uri = img.uri;
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#include "glTF/glTFCommon.h"
|
||||
|
||||
namespace glTFCommon {
|
||||
|
||||
using namespace glTFCommon::Util;
|
||||
|
||||
namespace Util {
|
||||
|
||||
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out) {
|
||||
ai_assert(inLength % 4 == 0);
|
||||
|
||||
if (inLength < 4) {
|
||||
out = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nEquals = int(in[inLength - 1] == '=') +
|
||||
int(in[inLength - 2] == '=');
|
||||
|
||||
size_t outLength = (inLength * 3) / 4 - nEquals;
|
||||
out = new uint8_t[outLength];
|
||||
memset(out, 0, outLength);
|
||||
|
||||
size_t i, j = 0;
|
||||
|
||||
for (i = 0; i + 4 < inLength; i += 4) {
|
||||
uint8_t b0 = DecodeCharBase64(in[i]);
|
||||
uint8_t b1 = DecodeCharBase64(in[i + 1]);
|
||||
uint8_t b2 = DecodeCharBase64(in[i + 2]);
|
||||
uint8_t b3 = DecodeCharBase64(in[i + 3]);
|
||||
|
||||
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
|
||||
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
|
||||
out[j++] = (uint8_t)((b2 << 6) | b3);
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t b0 = DecodeCharBase64(in[i]);
|
||||
uint8_t b1 = DecodeCharBase64(in[i + 1]);
|
||||
uint8_t b2 = DecodeCharBase64(in[i + 2]);
|
||||
uint8_t b3 = DecodeCharBase64(in[i + 3]);
|
||||
|
||||
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
|
||||
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
|
||||
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
|
||||
}
|
||||
|
||||
return outLength;
|
||||
}
|
||||
|
||||
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out) {
|
||||
size_t outLength = ((inLength + 2) / 3) * 4;
|
||||
|
||||
size_t j = out.size();
|
||||
out.resize(j + outLength);
|
||||
|
||||
for (size_t i = 0; i < inLength; i += 3) {
|
||||
uint8_t b = (in[i] & 0xFC) >> 2;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = (in[i] & 0x03) << 4;
|
||||
if (i + 1 < inLength) {
|
||||
b |= (in[i + 1] & 0xF0) >> 4;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = (in[i + 1] & 0x0F) << 2;
|
||||
if (i + 2 < inLength) {
|
||||
b |= (in[i + 2] & 0xC0) >> 6;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = in[i + 2] & 0x3F;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
}
|
||||
else {
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
out[j++] = '=';
|
||||
}
|
||||
}
|
||||
else {
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
out[j++] = '=';
|
||||
out[j++] = '=';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
|
||||
if (nullptr == const_uri) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const_uri[0] != 0x10) { // we already parsed this uri?
|
||||
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
|
||||
return false;
|
||||
}
|
||||
|
||||
// set defaults
|
||||
out.mediaType = "text/plain";
|
||||
out.charset = "US-ASCII";
|
||||
out.base64 = false;
|
||||
|
||||
char* uri = const_cast<char*>(const_uri);
|
||||
if (uri[0] != 0x10) {
|
||||
uri[0] = 0x10;
|
||||
uri[1] = uri[2] = uri[3] = uri[4] = 0;
|
||||
|
||||
size_t i = 5, j;
|
||||
if (uri[i] != ';' && uri[i] != ',') { // has media type?
|
||||
uri[1] = char(i);
|
||||
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
||||
// nothing to do!
|
||||
}
|
||||
}
|
||||
while (uri[i] == ';' && i < uriLen) {
|
||||
uri[i++] = '\0';
|
||||
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
||||
// nothing to do!
|
||||
}
|
||||
|
||||
if (strncmp(uri + j, "charset=", 8) == 0) {
|
||||
uri[2] = char(j + 8);
|
||||
}
|
||||
else if (strncmp(uri + j, "base64", 6) == 0) {
|
||||
uri[3] = char(j);
|
||||
}
|
||||
}
|
||||
if (i < uriLen) {
|
||||
uri[i++] = '\0';
|
||||
uri[4] = char(i);
|
||||
}
|
||||
else {
|
||||
uri[1] = uri[2] = uri[3] = 0;
|
||||
uri[4] = 5;
|
||||
}
|
||||
}
|
||||
|
||||
if (uri[1] != 0) {
|
||||
out.mediaType = uri + uri[1];
|
||||
}
|
||||
if (uri[2] != 0) {
|
||||
out.charset = uri + uri[2];
|
||||
}
|
||||
if (uri[3] != 0) {
|
||||
out.base64 = true;
|
||||
}
|
||||
out.data = uri + uri[4];
|
||||
out.dataLength = (uri + uriLen) - out.data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef AI_GLFTCOMMON_H_INC
|
||||
#define AI_GLFTCOMMON_H_INC
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||
|
||||
#include <assimp/Exceptional.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#define RAPIDJSON_HAS_STDSTRING 1
|
||||
#include <rapidjson/rapidjson.h>
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/error/en.h>
|
||||
|
||||
#ifdef ASSIMP_API
|
||||
# include <memory>
|
||||
# include <assimp/DefaultIOSystem.h>
|
||||
# include <assimp/ByteSwapper.h>
|
||||
#else
|
||||
# include <memory>
|
||||
# define AI_SWAP4(p)
|
||||
# define ai_assert
|
||||
#endif
|
||||
|
||||
|
||||
#if _MSC_VER > 1500 || (defined __GNUC___)
|
||||
# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||
# else
|
||||
# define gltf_unordered_map map
|
||||
#endif
|
||||
|
||||
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||
# include <unordered_map>
|
||||
# if _MSC_VER > 1600
|
||||
# define gltf_unordered_map unordered_map
|
||||
# else
|
||||
# define gltf_unordered_map tr1::unordered_map
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace glTFCommon {
|
||||
|
||||
#ifdef ASSIMP_API
|
||||
using Assimp::IOStream;
|
||||
using Assimp::IOSystem;
|
||||
using std::shared_ptr;
|
||||
#else
|
||||
using std::shared_ptr;
|
||||
|
||||
typedef std::runtime_error DeadlyImportError;
|
||||
typedef std::runtime_error DeadlyExportError;
|
||||
|
||||
enum aiOrigin {
|
||||
aiOrigin_SET = 0,
|
||||
aiOrigin_CUR = 1,
|
||||
aiOrigin_END = 2
|
||||
};
|
||||
|
||||
class IOSystem;
|
||||
|
||||
class IOStream {
|
||||
public:
|
||||
IOStream(FILE* file) : f(file) {}
|
||||
~IOStream() { fclose(f); f = 0; }
|
||||
|
||||
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
|
||||
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
|
||||
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
|
||||
size_t Tell() const { return ftell(f); }
|
||||
|
||||
size_t FileSize() {
|
||||
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
|
||||
return size_t((Seek(p, aiOrigin_SET), len));
|
||||
}
|
||||
|
||||
private:
|
||||
FILE* f;
|
||||
};
|
||||
#endif
|
||||
|
||||
// Vec/matrix types, as raw float arrays
|
||||
typedef float(vec3)[3];
|
||||
typedef float(vec4)[4];
|
||||
typedef float(mat4)[16];
|
||||
|
||||
inline
|
||||
void CopyValue(const glTFCommon::vec3& v, aiColor4D& out) {
|
||||
out.r = v[0];
|
||||
out.g = v[1];
|
||||
out.b = v[2];
|
||||
out.a = 1.0;
|
||||
}
|
||||
|
||||
inline
|
||||
void CopyValue(const glTFCommon::vec4& v, aiColor4D& out) {
|
||||
out.r = v[0];
|
||||
out.g = v[1];
|
||||
out.b = v[2];
|
||||
out.a = v[3];
|
||||
}
|
||||
|
||||
inline
|
||||
void CopyValue(const glTFCommon::vec4& v, aiColor3D& out) {
|
||||
out.r = v[0];
|
||||
out.g = v[1];
|
||||
out.b = v[2];
|
||||
}
|
||||
|
||||
inline
|
||||
void CopyValue(const glTFCommon::vec3& v, aiColor3D& out) {
|
||||
out.r = v[0];
|
||||
out.g = v[1];
|
||||
out.b = v[2];
|
||||
}
|
||||
|
||||
inline
|
||||
void CopyValue(const glTFCommon::vec3& v, aiVector3D& out) {
|
||||
out.x = v[0];
|
||||
out.y = v[1];
|
||||
out.z = v[2];
|
||||
}
|
||||
|
||||
inline
|
||||
void CopyValue(const glTFCommon::vec4& v, aiQuaternion& out) {
|
||||
out.x = v[0];
|
||||
out.y = v[1];
|
||||
out.z = v[2];
|
||||
out.w = v[3];
|
||||
}
|
||||
|
||||
inline
|
||||
void CopyValue(const glTFCommon::mat4& v, aiMatrix4x4& o) {
|
||||
o.a1 = v[0]; o.b1 = v[1]; o.c1 = v[2]; o.d1 = v[3];
|
||||
o.a2 = v[4]; o.b2 = v[5]; o.c2 = v[6]; o.d2 = v[7];
|
||||
o.a3 = v[8]; o.b3 = v[9]; o.c3 = v[10]; o.d3 = v[11];
|
||||
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
|
||||
}
|
||||
|
||||
namespace Util {
|
||||
|
||||
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
|
||||
|
||||
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
|
||||
|
||||
inline
|
||||
size_t DecodeBase64(const char* in, uint8_t*& out) {
|
||||
return DecodeBase64(in, strlen(in), out);
|
||||
}
|
||||
|
||||
struct DataURI {
|
||||
const char* mediaType;
|
||||
const char* charset;
|
||||
bool base64;
|
||||
const char* data;
|
||||
size_t dataLength;
|
||||
};
|
||||
|
||||
//! Check if a uri is a data URI
|
||||
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out);
|
||||
|
||||
template<bool B>
|
||||
struct DATA {
|
||||
static const uint8_t tableDecodeBase64[128];
|
||||
};
|
||||
|
||||
template<bool B>
|
||||
const uint8_t DATA<B>::tableDecodeBase64[128] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
|
||||
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
|
||||
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
inline
|
||||
char EncodeCharBase64(uint8_t b) {
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
|
||||
}
|
||||
|
||||
inline
|
||||
uint8_t DecodeCharBase64(char c) {
|
||||
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
|
||||
/*if (c >= 'A' && c <= 'Z') return c - 'A';
|
||||
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
|
||||
if (c >= '0' && c <= '9') return c - '0' + 52;
|
||||
if (c == '+') return 62;
|
||||
if (c == '/') return 63;
|
||||
return 64; // '-' */
|
||||
}
|
||||
|
||||
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
|
||||
|
||||
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||
|
||||
#endif // AI_GLFTCOMMON_H_INC
|
|
@ -242,7 +242,10 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
|
|||
|
||||
namespace {
|
||||
void GetMatScalar(const aiMaterial* mat, float& val, const char* propName, int type, int idx) {
|
||||
ai_assert(mat->Get(propName, type, idx, val) == AI_SUCCESS);
|
||||
ai_assert( nullptr != mat );
|
||||
if ( nullptr != mat ) {
|
||||
mat->Get(propName, type, idx, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ glTFImporter::glTFImporter()
|
|||
: BaseImporter()
|
||||
, meshOffsets()
|
||||
, embeddedTexIdxs()
|
||||
, mScene( NULL ) {
|
||||
, mScene( nullptr ) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
@ -90,17 +90,16 @@ glTFImporter::~glTFImporter() {
|
|||
// empty
|
||||
}
|
||||
|
||||
const aiImporterDesc* glTFImporter::GetInfo() const
|
||||
{
|
||||
const aiImporterDesc* glTFImporter::GetInfo() const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const
|
||||
{
|
||||
bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const {
|
||||
const std::string &extension = GetExtension(pFile);
|
||||
|
||||
if (extension != "gltf" && extension != "glb")
|
||||
if (extension != "gltf" && extension != "glb") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pIOHandler) {
|
||||
glTF::Asset asset(pIOHandler);
|
||||
|
@ -116,44 +115,9 @@ bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//static void CopyValue(const glTF::vec3& v, aiColor3D& out)
|
||||
//{
|
||||
// out.r = v[0]; out.g = v[1]; out.b = v[2];
|
||||
//}
|
||||
|
||||
static void CopyValue(const glTF::vec4& v, aiColor4D& out)
|
||||
{
|
||||
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
|
||||
}
|
||||
|
||||
static void CopyValue(const glTF::vec4& v, aiColor3D& out)
|
||||
{
|
||||
out.r = v[0]; out.g = v[1]; out.b = v[2];
|
||||
}
|
||||
|
||||
static void CopyValue(const glTF::vec3& v, aiVector3D& out)
|
||||
{
|
||||
out.x = v[0]; out.y = v[1]; out.z = v[2];
|
||||
}
|
||||
|
||||
static void CopyValue(const glTF::vec4& v, aiQuaternion& out)
|
||||
{
|
||||
out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
|
||||
}
|
||||
|
||||
static void CopyValue(const glTF::mat4& v, aiMatrix4x4& o)
|
||||
{
|
||||
o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
|
||||
o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
|
||||
o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
|
||||
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
|
||||
}
|
||||
|
||||
inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
|
||||
aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx)
|
||||
{
|
||||
inline
|
||||
void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
|
||||
aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx) {
|
||||
if (prop.texture) {
|
||||
if (prop.texture->source) {
|
||||
aiString uri(prop.texture->source->uri);
|
||||
|
@ -167,16 +131,14 @@ inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /
|
|||
|
||||
mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
aiColor4D col;
|
||||
CopyValue(prop.color, col);
|
||||
mat->AddProperty(&col, 1, pKey, type, idx);
|
||||
}
|
||||
}
|
||||
|
||||
void glTFImporter::ImportMaterials(glTF::Asset& r)
|
||||
{
|
||||
void glTFImporter::ImportMaterials(glTF::Asset& r) {
|
||||
mScene->mNumMaterials = unsigned(r.materials.Size());
|
||||
mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
|
||||
|
||||
|
@ -304,7 +266,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
|||
|
||||
aim->mName = mesh.id;
|
||||
if (mesh.primitives.size() > 1) {
|
||||
size_t& len = aim->mName.length;
|
||||
ai_uint32& len = aim->mName.length;
|
||||
aim->mName.data[len] = '-';
|
||||
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
|
||||
}
|
||||
|
@ -499,27 +461,31 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
|||
CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
|
||||
}
|
||||
|
||||
void glTFImporter::ImportCameras(glTF::Asset& r)
|
||||
{
|
||||
if (!r.cameras.Size()) return;
|
||||
void glTFImporter::ImportCameras(glTF::Asset& r) {
|
||||
if (!r.cameras.Size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mScene->mNumCameras = r.cameras.Size();
|
||||
mScene->mCameras = new aiCamera*[r.cameras.Size()];
|
||||
|
||||
for (size_t i = 0; i < r.cameras.Size(); ++i) {
|
||||
Camera& cam = r.cameras[i];
|
||||
|
||||
aiCamera* aicam = mScene->mCameras[i] = new aiCamera();
|
||||
|
||||
if (cam.type == Camera::Perspective) {
|
||||
|
||||
aicam->mAspect = cam.perspective.aspectRatio;
|
||||
aicam->mHorizontalFOV = cam.perspective.yfov * aicam->mAspect;
|
||||
aicam->mHorizontalFOV = cam.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
|
||||
aicam->mClipPlaneFar = cam.perspective.zfar;
|
||||
aicam->mClipPlaneNear = cam.perspective.znear;
|
||||
}
|
||||
else {
|
||||
// assimp does not support orthographic cameras
|
||||
} else {
|
||||
aicam->mClipPlaneFar = cam.ortographic.zfar;
|
||||
aicam->mClipPlaneNear = cam.ortographic.znear;
|
||||
aicam->mHorizontalFOV = 0.0;
|
||||
aicam->mAspect = 1.0f;
|
||||
if (0.f != cam.ortographic.ymag) {
|
||||
aicam->mAspect = cam.ortographic.xmag / cam.ortographic.ymag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,38 +95,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <assimp/StringUtils.h>
|
||||
|
||||
#include "glTF/glTFCommon.h"
|
||||
|
||||
namespace glTF2
|
||||
{
|
||||
#ifdef ASSIMP_API
|
||||
using Assimp::IOStream;
|
||||
using Assimp::IOSystem;
|
||||
using std::shared_ptr;
|
||||
#else
|
||||
using std::shared_ptr;
|
||||
|
||||
typedef std::runtime_error DeadlyImportError;
|
||||
typedef std::runtime_error DeadlyExportError;
|
||||
|
||||
enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
|
||||
class IOSystem;
|
||||
class IOStream
|
||||
{
|
||||
FILE* f;
|
||||
public:
|
||||
IOStream(FILE* file) : f(file) {}
|
||||
~IOStream() { fclose(f); f = 0; }
|
||||
|
||||
size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
|
||||
size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
|
||||
int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
|
||||
size_t Tell() const { return ftell(f); }
|
||||
|
||||
size_t FileSize() {
|
||||
long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
|
||||
return size_t((Seek(p, aiOrigin_SET), len));
|
||||
}
|
||||
};
|
||||
#endif
|
||||
using glTFCommon::shared_ptr;
|
||||
using glTFCommon::IOSystem;
|
||||
using glTFCommon::IOStream;
|
||||
|
||||
using rapidjson::Value;
|
||||
using rapidjson::Document;
|
||||
|
@ -138,35 +113,9 @@ namespace glTF2
|
|||
struct Texture;
|
||||
struct Skin;
|
||||
|
||||
// Vec/matrix types, as raw float arrays
|
||||
typedef float (vec3)[3];
|
||||
typedef float (vec4)[4];
|
||||
typedef float (mat4)[16];
|
||||
|
||||
namespace Util
|
||||
{
|
||||
void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
|
||||
|
||||
size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
|
||||
|
||||
inline size_t DecodeBase64(const char* in, uint8_t*& out)
|
||||
{
|
||||
return DecodeBase64(in, strlen(in), out);
|
||||
}
|
||||
|
||||
struct DataURI
|
||||
{
|
||||
const char* mediaType;
|
||||
const char* charset;
|
||||
bool base64;
|
||||
const char* data;
|
||||
size_t dataLength;
|
||||
};
|
||||
|
||||
//! Check if a uri is a data URI
|
||||
inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
|
||||
}
|
||||
|
||||
using glTFCommon::vec3;
|
||||
using glTFCommon::vec4;
|
||||
using glTFCommon::mat4;
|
||||
|
||||
//! Magic number for GLB files
|
||||
#define AI_GLB_MAGIC_NUMBER "glTF"
|
||||
|
@ -552,7 +501,7 @@ namespace glTF2
|
|||
/// but in real life you'll get:
|
||||
/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
|
||||
/// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
|
||||
/// And when before you start to read data of current mesh (with encoded data ofcourse) you must decode region of "bufferView", after read finished
|
||||
/// And when before you start to read data of current mesh (with encoded data of course) you must decode region of "bufferView", after read finished
|
||||
/// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
|
||||
///
|
||||
/// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in
|
||||
|
|
|
@ -282,9 +282,7 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
|
|||
template<class T>
|
||||
Ref<T> LazyDict<T>::Get(unsigned int i)
|
||||
{
|
||||
|
||||
return Ref<T>(mObjs, i);
|
||||
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
@ -361,11 +359,11 @@ inline void Buffer::Read(Value& obj, Asset& r)
|
|||
|
||||
const char* uri = it->GetString();
|
||||
|
||||
Util::DataURI dataURI;
|
||||
glTFCommon::Util::DataURI dataURI;
|
||||
if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
|
||||
if (dataURI.base64) {
|
||||
uint8_t* data = 0;
|
||||
this->byteLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
|
||||
this->byteLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
|
||||
this->mData.reset(data, std::default_delete<uint8_t[]>());
|
||||
|
||||
if (statedLength > 0 && this->byteLength != statedLength) {
|
||||
|
@ -717,12 +715,12 @@ inline void Image::Read(Value& obj, Asset& r)
|
|||
if (Value* uri = FindString(obj, "uri")) {
|
||||
const char* uristr = uri->GetString();
|
||||
|
||||
Util::DataURI dataURI;
|
||||
glTFCommon::Util::DataURI dataURI;
|
||||
if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
|
||||
mimeType = dataURI.mediaType;
|
||||
if (dataURI.base64) {
|
||||
uint8_t *ptr = nullptr;
|
||||
mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
|
||||
mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
|
||||
mData.reset(ptr);
|
||||
}
|
||||
}
|
||||
|
@ -1100,8 +1098,11 @@ inline void Light::Read(Value& obj, Asset& /*r*/)
|
|||
}
|
||||
}
|
||||
|
||||
inline void Node::Read(Value& obj, Asset& r)
|
||||
{
|
||||
inline
|
||||
void Node::Read(Value& obj, Asset& r) {
|
||||
if (name.empty()) {
|
||||
name = id;
|
||||
}
|
||||
|
||||
if (Value* children = FindArray(obj, "children")) {
|
||||
this->children.reserve(children->Size());
|
||||
|
@ -1515,190 +1516,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
|
|||
return id;
|
||||
}
|
||||
|
||||
namespace Util {
|
||||
|
||||
inline
|
||||
bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
|
||||
if ( NULL == const_uri ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (const_uri[0] != 0x10) { // we already parsed this uri?
|
||||
if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
|
||||
return false;
|
||||
}
|
||||
|
||||
// set defaults
|
||||
out.mediaType = "text/plain";
|
||||
out.charset = "US-ASCII";
|
||||
out.base64 = false;
|
||||
|
||||
char* uri = const_cast<char*>(const_uri);
|
||||
if (uri[0] != 0x10) {
|
||||
uri[0] = 0x10;
|
||||
uri[1] = uri[2] = uri[3] = uri[4] = 0;
|
||||
|
||||
size_t i = 5, j;
|
||||
if (uri[i] != ';' && uri[i] != ',') { // has media type?
|
||||
uri[1] = char(i);
|
||||
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
||||
// nothing to do!
|
||||
}
|
||||
}
|
||||
while (uri[i] == ';' && i < uriLen) {
|
||||
uri[i++] = '\0';
|
||||
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
||||
// nothing to do!
|
||||
}
|
||||
|
||||
if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
|
||||
uri[2] = char(j + 8);
|
||||
} else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
|
||||
uri[3] = char(j);
|
||||
}
|
||||
}
|
||||
if (i < uriLen) {
|
||||
uri[i++] = '\0';
|
||||
uri[4] = char(i);
|
||||
} else {
|
||||
uri[1] = uri[2] = uri[3] = 0;
|
||||
uri[4] = 5;
|
||||
}
|
||||
}
|
||||
|
||||
if ( uri[ 1 ] != 0 ) {
|
||||
out.mediaType = uri + uri[ 1 ];
|
||||
}
|
||||
if ( uri[ 2 ] != 0 ) {
|
||||
out.charset = uri + uri[ 2 ];
|
||||
}
|
||||
if ( uri[ 3 ] != 0 ) {
|
||||
out.base64 = true;
|
||||
}
|
||||
out.data = uri + uri[4];
|
||||
out.dataLength = (uri + uriLen) - out.data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool B>
|
||||
struct DATA
|
||||
{
|
||||
static const uint8_t tableDecodeBase64[128];
|
||||
};
|
||||
|
||||
template<bool B>
|
||||
const uint8_t DATA<B>::tableDecodeBase64[128] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
|
||||
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
|
||||
0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
inline char EncodeCharBase64(uint8_t b)
|
||||
{
|
||||
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
|
||||
}
|
||||
|
||||
inline uint8_t DecodeCharBase64(char c)
|
||||
{
|
||||
return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
|
||||
/*if (c >= 'A' && c <= 'Z') return c - 'A';
|
||||
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
|
||||
if (c >= '0' && c <= '9') return c - '0' + 52;
|
||||
if (c == '+') return 62;
|
||||
if (c == '/') return 63;
|
||||
return 64; // '-' */
|
||||
}
|
||||
|
||||
inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
|
||||
{
|
||||
ai_assert(inLength % 4 == 0);
|
||||
|
||||
if (inLength < 4) {
|
||||
out = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nEquals = int(in[inLength - 1] == '=') +
|
||||
int(in[inLength - 2] == '=');
|
||||
|
||||
size_t outLength = (inLength * 3) / 4 - nEquals;
|
||||
out = new uint8_t[outLength];
|
||||
memset(out, 0, outLength);
|
||||
|
||||
size_t i, j = 0;
|
||||
|
||||
for (i = 0; i + 4 < inLength; i += 4) {
|
||||
uint8_t b0 = DecodeCharBase64(in[i]);
|
||||
uint8_t b1 = DecodeCharBase64(in[i + 1]);
|
||||
uint8_t b2 = DecodeCharBase64(in[i + 2]);
|
||||
uint8_t b3 = DecodeCharBase64(in[i + 3]);
|
||||
|
||||
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
|
||||
out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
|
||||
out[j++] = (uint8_t)((b2 << 6) | b3);
|
||||
}
|
||||
|
||||
{
|
||||
uint8_t b0 = DecodeCharBase64(in[i]);
|
||||
uint8_t b1 = DecodeCharBase64(in[i + 1]);
|
||||
uint8_t b2 = DecodeCharBase64(in[i + 2]);
|
||||
uint8_t b3 = DecodeCharBase64(in[i + 3]);
|
||||
|
||||
out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
|
||||
if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
|
||||
if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
|
||||
}
|
||||
|
||||
return outLength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline void EncodeBase64(
|
||||
const uint8_t* in, size_t inLength,
|
||||
std::string& out)
|
||||
{
|
||||
size_t outLength = ((inLength + 2) / 3) * 4;
|
||||
|
||||
size_t j = out.size();
|
||||
out.resize(j + outLength);
|
||||
|
||||
for (size_t i = 0; i < inLength; i += 3) {
|
||||
uint8_t b = (in[i] & 0xFC) >> 2;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = (in[i] & 0x03) << 4;
|
||||
if (i + 1 < inLength) {
|
||||
b |= (in[i + 1] & 0xF0) >> 4;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = (in[i + 1] & 0x0F) << 2;
|
||||
if (i + 2 < inLength) {
|
||||
b |= (in[i + 2] & 0xC0) >> 6;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
|
||||
b = in[i + 2] & 0x3F;
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
}
|
||||
else {
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
out[j++] = '=';
|
||||
}
|
||||
}
|
||||
else {
|
||||
out[j++] = EncodeCharBase64(b);
|
||||
out[j++] = '=';
|
||||
out[j++] = '=';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // ns glTF
|
||||
|
|
|
@ -218,7 +218,7 @@ namespace glTF2 {
|
|||
if (img.HasData()) {
|
||||
uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
|
||||
uri += ";base64,";
|
||||
Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
|
||||
glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
|
||||
}
|
||||
else {
|
||||
uri = img.uri;
|
||||
|
|
|
@ -64,6 +64,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace Assimp;
|
||||
using namespace glTF2;
|
||||
using namespace glTFCommon;
|
||||
|
||||
namespace {
|
||||
// generate bi-tangents from normals and tangents according to spec
|
||||
|
@ -140,22 +141,23 @@ static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode)
|
|||
}
|
||||
}
|
||||
|
||||
static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
|
||||
/*static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
|
||||
{
|
||||
out.r = v[0]; out.g = v[1]; out.b = v[2];
|
||||
}
|
||||
|
||||
|
||||
static void CopyValue(const glTF2::vec4& v, aiColor4D& out)
|
||||
{
|
||||
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
|
||||
}
|
||||
}*/
|
||||
|
||||
/*static void CopyValue(const glTF2::vec4& v, aiColor3D& out)
|
||||
{
|
||||
out.r = v[0]; out.g = v[1]; out.b = v[2];
|
||||
}*/
|
||||
|
||||
static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
|
||||
/*static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
|
||||
{
|
||||
out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0;
|
||||
}
|
||||
|
@ -168,15 +170,15 @@ static void CopyValue(const glTF2::vec3& v, aiVector3D& out)
|
|||
static void CopyValue(const glTF2::vec4& v, aiQuaternion& out)
|
||||
{
|
||||
out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
|
||||
}
|
||||
}*/
|
||||
|
||||
static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
|
||||
/*static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
|
||||
{
|
||||
o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
|
||||
o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
|
||||
o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
|
||||
o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
|
||||
}
|
||||
}*/
|
||||
|
||||
inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
|
||||
{
|
||||
|
@ -188,7 +190,7 @@ inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat,
|
|||
inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
|
||||
{
|
||||
aiColor4D col;
|
||||
CopyValue(prop, col);
|
||||
glTFCommon::CopyValue(prop, col);
|
||||
mat->AddProperty(&col, 1, pKey, type, idx);
|
||||
}
|
||||
|
||||
|
@ -383,7 +385,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
|||
aim->mName = mesh.name.empty() ? mesh.id : mesh.name;
|
||||
|
||||
if (mesh.primitives.size() > 1) {
|
||||
size_t& len = aim->mName.length;
|
||||
ai_uint32& len = aim->mName.length;
|
||||
aim->mName.data[len] = '-';
|
||||
len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
|
||||
}
|
||||
|
@ -442,7 +444,6 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
|
|||
"\" does not match the vertex count");
|
||||
continue;
|
||||
}
|
||||
aim->mColors[c] = new aiColor4D[attr.color[c]->count];
|
||||
attr.color[c]->ExtractData(aim->mColors[c]);
|
||||
}
|
||||
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
||||
|
@ -700,12 +701,17 @@ void glTF2Importer::ImportCameras(glTF2::Asset& r)
|
|||
if (cam.type == Camera::Perspective) {
|
||||
|
||||
aicam->mAspect = cam.cameraProperties.perspective.aspectRatio;
|
||||
aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * aicam->mAspect;
|
||||
aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
|
||||
aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar;
|
||||
aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear;
|
||||
}
|
||||
else {
|
||||
// assimp does not support orthographic cameras
|
||||
} else {
|
||||
aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar;
|
||||
aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear;
|
||||
aicam->mHorizontalFOV = 0.0;
|
||||
aicam->mAspect = 1.0f;
|
||||
if (0.f != cam.cameraProperties.ortographic.ymag ) {
|
||||
aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -901,6 +907,9 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
|
|||
std::vector<std::vector<aiVertexWeight>> weighting(mesh->mNumBones);
|
||||
BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting);
|
||||
|
||||
mat4* pbindMatrices = nullptr;
|
||||
node.skin->inverseBindMatrices->ExtractData(pbindMatrices);
|
||||
|
||||
for (uint32_t i = 0; i < mesh->mNumBones; ++i) {
|
||||
aiBone* bone = new aiBone();
|
||||
|
||||
|
@ -916,6 +925,8 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
|
|||
}
|
||||
GetNodeTransform(bone->mOffsetMatrix, *joint);
|
||||
|
||||
CopyValue(pbindMatrices[i], bone->mOffsetMatrix);
|
||||
|
||||
std::vector<aiVertexWeight>& weights = weighting[i];
|
||||
|
||||
bone->mNumWeights = static_cast<uint32_t>(weights.size());
|
||||
|
@ -931,6 +942,10 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
|
|||
}
|
||||
mesh->mBones[i] = bone;
|
||||
}
|
||||
|
||||
if (pbindMatrices) {
|
||||
delete[] pbindMatrices;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -987,7 +1002,12 @@ void glTF2Importer::ImportNodes(glTF2::Asset& r)
|
|||
}
|
||||
|
||||
struct AnimationSamplers {
|
||||
AnimationSamplers() : translation(nullptr), rotation(nullptr), scale(nullptr) {}
|
||||
AnimationSamplers()
|
||||
: translation(nullptr)
|
||||
, rotation(nullptr)
|
||||
, scale(nullptr) {
|
||||
// empty
|
||||
}
|
||||
|
||||
Animation::Sampler* translation;
|
||||
Animation::Sampler* rotation;
|
||||
|
@ -1016,7 +1036,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
|
|||
delete[] values;
|
||||
} else if (node.translation.isPresent) {
|
||||
anim->mNumPositionKeys = 1;
|
||||
anim->mPositionKeys = new aiVectorKey();
|
||||
anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
|
||||
anim->mPositionKeys->mTime = 0.f;
|
||||
anim->mPositionKeys->mValue.x = node.translation.value[0];
|
||||
anim->mPositionKeys->mValue.y = node.translation.value[1];
|
||||
|
@ -1156,7 +1176,7 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
|
|||
}
|
||||
}
|
||||
ai_anim->mDuration = maxDuration;
|
||||
ai_anim->mTicksPerSecond = (maxNumberOfKeys > 0 && maxDuration > 0) ? (maxNumberOfKeys / (maxDuration/1000)) : 30;
|
||||
ai_anim->mTicksPerSecond = 1000.0;
|
||||
|
||||
mScene->mAnimations[i] = ai_anim;
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
|
|||
<< ", expected_values[i] is " << PrintValue(expected_values[i])
|
||||
<< ", *it is " << PrintValue(*it)
|
||||
<< ", and 'it' is an iterator created with the copy constructor.\n";
|
||||
it++;
|
||||
++it;
|
||||
}
|
||||
EXPECT_TRUE(it == generator.end())
|
||||
<< "At the presumed end of sequence when accessing via an iterator "
|
||||
|
@ -161,7 +161,7 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
|
|||
<< ", expected_values[i] is " << PrintValue(expected_values[i])
|
||||
<< ", *it is " << PrintValue(*it)
|
||||
<< ", and 'it' is an iterator created with the copy constructor.\n";
|
||||
it++;
|
||||
++it;
|
||||
}
|
||||
EXPECT_TRUE(it == generator.end())
|
||||
<< "At the presumed end of sequence when accessing via an iterator "
|
||||
|
|
|
@ -215,7 +215,7 @@ namespace io
|
|||
two methods to read your data and give a pointer to an instance of
|
||||
your implementation when calling createIrrXMLReader(),
|
||||
createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
|
||||
class IFileReadCallBack
|
||||
class IRRXML_API IFileReadCallBack
|
||||
{
|
||||
public:
|
||||
|
||||
|
|
|
@ -39,22 +39,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/** @file MathFunctions.h
|
||||
* @brief Implementation of the math functions (gcd and lcm)
|
||||
* @brief Implementation of math utility functions.
|
||||
*
|
||||
* Copied from BoostWorkaround/math
|
||||
*/
|
||||
*/
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace Assimp {
|
||||
namespace Math {
|
||||
|
||||
// TODO: use binary GCD for unsigned integers ....
|
||||
template < typename IntegerType >
|
||||
IntegerType gcd( IntegerType a, IntegerType b )
|
||||
{
|
||||
inline
|
||||
IntegerType gcd( IntegerType a, IntegerType b ) {
|
||||
const IntegerType zero = (IntegerType)0;
|
||||
while ( true )
|
||||
{
|
||||
while ( true ) {
|
||||
if ( a == zero )
|
||||
return b;
|
||||
b %= a;
|
||||
|
@ -66,12 +68,19 @@ IntegerType gcd( IntegerType a, IntegerType b )
|
|||
}
|
||||
|
||||
template < typename IntegerType >
|
||||
IntegerType lcm( IntegerType a, IntegerType b )
|
||||
{
|
||||
inline
|
||||
IntegerType lcm( IntegerType a, IntegerType b ) {
|
||||
const IntegerType t = gcd (a,b);
|
||||
if (!t)return t;
|
||||
if (!t)
|
||||
return t;
|
||||
return a / t * b;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline
|
||||
T getEpsilon() {
|
||||
return std::numeric_limits<T>::epsilon();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,6 @@ struct aiCamera
|
|||
*/
|
||||
C_STRUCT aiVector3D mPosition;
|
||||
|
||||
|
||||
/** 'Up' - vector of the camera coordinate system relative to
|
||||
* the coordinate space defined by the corresponding node.
|
||||
*
|
||||
|
@ -134,7 +133,6 @@ struct aiCamera
|
|||
*/
|
||||
C_STRUCT aiVector3D mLookAt;
|
||||
|
||||
|
||||
/** Half horizontal field of view angle, in radians.
|
||||
*
|
||||
* The field of view angle is the angle between the center
|
||||
|
|
|
@ -196,34 +196,40 @@ enum aiTextureType
|
|||
* (#aiMaterialProperty::mSemantic) for all material properties
|
||||
* *not* related to textures.
|
||||
*/
|
||||
aiTextureType_NONE = 0x0,
|
||||
aiTextureType_NONE = 0,
|
||||
|
||||
/** LEGACY API MATERIALS
|
||||
* Legacy refers to materials which
|
||||
* Were originally implemented in the specifications around 2000.
|
||||
* These must never be removed, as most engines support them.
|
||||
*/
|
||||
|
||||
/** The texture is combined with the result of the diffuse
|
||||
* lighting equation.
|
||||
*/
|
||||
aiTextureType_DIFFUSE = 0x1,
|
||||
aiTextureType_DIFFUSE = 1,
|
||||
|
||||
/** The texture is combined with the result of the specular
|
||||
* lighting equation.
|
||||
*/
|
||||
aiTextureType_SPECULAR = 0x2,
|
||||
aiTextureType_SPECULAR = 2,
|
||||
|
||||
/** The texture is combined with the result of the ambient
|
||||
* lighting equation.
|
||||
*/
|
||||
aiTextureType_AMBIENT = 0x3,
|
||||
aiTextureType_AMBIENT = 3,
|
||||
|
||||
/** The texture is added to the result of the lighting
|
||||
* calculation. It isn't influenced by incoming light.
|
||||
*/
|
||||
aiTextureType_EMISSIVE = 0x4,
|
||||
aiTextureType_EMISSIVE = 4,
|
||||
|
||||
/** The texture is a height map.
|
||||
*
|
||||
* By convention, higher gray-scale values stand for
|
||||
* higher elevations from the base height.
|
||||
*/
|
||||
aiTextureType_HEIGHT = 0x5,
|
||||
aiTextureType_HEIGHT = 5,
|
||||
|
||||
/** The texture is a (tangent space) normal-map.
|
||||
*
|
||||
|
@ -231,7 +237,7 @@ enum aiTextureType
|
|||
* normal maps. Assimp does (intentionally) not
|
||||
* distinguish here.
|
||||
*/
|
||||
aiTextureType_NORMALS = 0x6,
|
||||
aiTextureType_NORMALS = 6,
|
||||
|
||||
/** The texture defines the glossiness of the material.
|
||||
*
|
||||
|
@ -240,21 +246,21 @@ enum aiTextureType
|
|||
* function defined to map the linear color values in the
|
||||
* texture to a suitable exponent. Have fun.
|
||||
*/
|
||||
aiTextureType_SHININESS = 0x7,
|
||||
aiTextureType_SHININESS = 7,
|
||||
|
||||
/** The texture defines per-pixel opacity.
|
||||
*
|
||||
* Usually 'white' means opaque and 'black' means
|
||||
* 'transparency'. Or quite the opposite. Have fun.
|
||||
*/
|
||||
aiTextureType_OPACITY = 0x8,
|
||||
aiTextureType_OPACITY = 8,
|
||||
|
||||
/** Displacement texture
|
||||
*
|
||||
* The exact purpose and format is application-dependent.
|
||||
* Higher color values stand for higher vertex displacements.
|
||||
*/
|
||||
aiTextureType_DISPLACEMENT = 0x9,
|
||||
aiTextureType_DISPLACEMENT = 9,
|
||||
|
||||
/** Lightmap texture (aka Ambient Occlusion)
|
||||
*
|
||||
|
@ -263,14 +269,28 @@ enum aiTextureType
|
|||
* scaling value for the final color value of a pixel. Its
|
||||
* intensity is not affected by incoming light.
|
||||
*/
|
||||
aiTextureType_LIGHTMAP = 0xA,
|
||||
aiTextureType_LIGHTMAP = 10,
|
||||
|
||||
/** Reflection texture
|
||||
*
|
||||
* Contains the color of a perfect mirror reflection.
|
||||
* Rarely used, almost never for real-time applications.
|
||||
*/
|
||||
aiTextureType_REFLECTION = 0xB,
|
||||
aiTextureType_REFLECTION = 11,
|
||||
|
||||
/** PBR Materials
|
||||
* PBR definitions from maya and other modelling packages now use this standard.
|
||||
* This was originally introduced around 2012.
|
||||
* Support for this is in game engines like Godot, Unreal or Unity3D.
|
||||
* Modelling packages which use this are very common now.
|
||||
*/
|
||||
|
||||
aiTextureType_BASE_COLOR = 12,
|
||||
aiTextureType_NORMAL_CAMERA = 13,
|
||||
aiTextureType_EMISSION_COLOR = 14,
|
||||
aiTextureType_METALNESS = 15,
|
||||
aiTextureType_DIFFUSE_ROUGHNESS = 16,
|
||||
aiTextureType_AMBIENT_OCCLUSION = 17,
|
||||
|
||||
/** Unknown texture
|
||||
*
|
||||
|
@ -278,7 +298,7 @@ enum aiTextureType
|
|||
* above is considered to be 'unknown'. It is still imported,
|
||||
* but is excluded from any further post-processing.
|
||||
*/
|
||||
aiTextureType_UNKNOWN = 0xC,
|
||||
aiTextureType_UNKNOWN = 18,
|
||||
|
||||
|
||||
#ifndef SWIG
|
||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -53,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "matrix4x4.h"
|
||||
#include "matrix3x3.h"
|
||||
#include "quaternion.h"
|
||||
#include "MathFunctions.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
@ -420,8 +419,8 @@ inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuate
|
|||
}
|
||||
|
||||
template <typename TReal>
|
||||
inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
|
||||
{
|
||||
inline
|
||||
void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const {
|
||||
ASSIMP_MATRIX4_4_DECOMPOSE_PART;
|
||||
|
||||
/*
|
||||
|
@ -442,7 +441,7 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
|
|||
*/
|
||||
|
||||
// Use a small epsilon to solve floating-point inaccuracies
|
||||
const TReal epsilon = 10e-3f;
|
||||
const TReal epsilon = Assimp::Math::getEpsilon<TReal>();
|
||||
|
||||
pRotation.y = std::asin(-vCols[0].z);// D. Angle around oY.
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Our compile configuration
|
||||
#include "defs.h"
|
||||
|
@ -65,11 +66,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "matrix4x4.h"
|
||||
#include "quaternion.h"
|
||||
|
||||
typedef int32_t ai_int32;
|
||||
typedef uint32_t ai_uint32 ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstring>
|
||||
#include <new> // for std::nothrow_t
|
||||
#include <string> // for aiString::Set(const std::string&)
|
||||
|
||||
|
||||
namespace Assimp {
|
||||
//! @cond never
|
||||
namespace Intern {
|
||||
|
@ -269,8 +274,8 @@ struct aiString
|
|||
}
|
||||
|
||||
/** Copy constructor */
|
||||
aiString(const aiString& rOther) :
|
||||
length(rOther.length)
|
||||
aiString(const aiString& rOther)
|
||||
: length(rOther.length)
|
||||
{
|
||||
// Crop the string to the maximum length
|
||||
length = length>=MAXLEN?MAXLEN-1:length;
|
||||
|
@ -280,7 +285,7 @@ struct aiString
|
|||
|
||||
/** Constructor from std::string */
|
||||
explicit aiString(const std::string& pString) :
|
||||
length(pString.length())
|
||||
length( (ai_uint32) pString.length())
|
||||
{
|
||||
length = length>=MAXLEN?MAXLEN-1:length;
|
||||
memcpy( data, pString.c_str(), length);
|
||||
|
@ -292,15 +297,15 @@ struct aiString
|
|||
if( pString.length() > MAXLEN - 1) {
|
||||
return;
|
||||
}
|
||||
length = pString.length();
|
||||
length = (ai_uint32)pString.length();
|
||||
memcpy( data, pString.c_str(), length);
|
||||
data[length] = 0;
|
||||
}
|
||||
|
||||
/** Copy a const char* to the aiString */
|
||||
void Set( const char* sz) {
|
||||
const size_t len = ::strlen(sz);
|
||||
if( len > MAXLEN - 1) {
|
||||
const ai_int32 len = (ai_uint32) ::strlen(sz);
|
||||
if( len > (ai_int32)MAXLEN - 1) {
|
||||
return;
|
||||
}
|
||||
length = len;
|
||||
|
@ -346,7 +351,7 @@ struct aiString
|
|||
|
||||
/** Append a string to the string */
|
||||
void Append (const char* app) {
|
||||
const size_t len = ::strlen(app);
|
||||
const ai_uint32 len = (ai_uint32) ::strlen(app);
|
||||
if (!len) {
|
||||
return;
|
||||
}
|
||||
|
@ -379,7 +384,7 @@ struct aiString
|
|||
/** Binary length of the string excluding the terminal 0. This is NOT the
|
||||
* logical length of strings containing UTF-8 multi-byte sequences! It's
|
||||
* the number of bytes from the beginning of the string to its end.*/
|
||||
size_t length;
|
||||
ai_uint32 length;
|
||||
|
||||
/** String buffer. Size limit is MAXLEN */
|
||||
char data[MAXLEN];
|
||||
|
|
|
@ -274,8 +274,8 @@ def hasattr_silent(object, name):
|
|||
"""
|
||||
|
||||
try:
|
||||
if not object:
|
||||
return False
|
||||
if not object:
|
||||
return False
|
||||
return hasattr(object, name)
|
||||
except AttributeError:
|
||||
return False
|
||||
|
|
|
@ -25,6 +25,7 @@ INCLUDE_DIRECTORIES(
|
|||
${Assimp_SOURCE_DIR}/include
|
||||
${Assimp_SOURCE_DIR}/code
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
${GLUT_INCLUDE_DIR}
|
||||
${Assimp_SOURCE_DIR}/samples/freeglut/include
|
||||
)
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ void reshape(int width, int height)
|
|||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
void get_bounding_box_for_node (const a<C_STRUCT iNode* nd,
|
||||
void get_bounding_box_for_node (const C_STRUCT aiNode* nd,
|
||||
C_STRUCT aiVector3D* min,
|
||||
C_STRUCT aiVector3D* max,
|
||||
C_STRUCT aiMatrix4x4* trafo
|
||||
|
@ -86,7 +86,7 @@ void get_bounding_box_for_node (const a<C_STRUCT iNode* nd,
|
|||
/* ---------------------------------------------------------------------------- */
|
||||
void get_bounding_box(C_STRUCT aiVector3D* min, C_STRUCT aiVector3D* max)
|
||||
{
|
||||
aiMatrix4x4 trafo;
|
||||
C_STRUCT aiMatrix4x4 trafo;
|
||||
aiIdentityMatrix4(&trafo);
|
||||
|
||||
min->x = min->y = min->z = 1e10f;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"scenes" : [
|
||||
{
|
||||
"nodes" : [ 0, 1, 2 ]
|
||||
}
|
||||
],
|
||||
"nodes" : [
|
||||
{
|
||||
"rotation" : [ -0.383, 0.0, 0.0, 0.92375 ],
|
||||
"mesh" : 0
|
||||
},
|
||||
{
|
||||
"translation" : [ 0.5, 0.5, 3.0 ],
|
||||
"camera" : 0
|
||||
},
|
||||
{
|
||||
"translation" : [ 0.5, 0.5, 3.0 ],
|
||||
"camera" : 1
|
||||
}
|
||||
],
|
||||
|
||||
"cameras" : [
|
||||
{
|
||||
"type": "perspective",
|
||||
"perspective": {
|
||||
"aspectRatio": 1.0,
|
||||
"yfov": 0.7,
|
||||
"zfar": 100,
|
||||
"znear": 0.01
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "orthographic",
|
||||
"orthographic": {
|
||||
"xmag": 1.0,
|
||||
"ymag": 1.0,
|
||||
"zfar": 100,
|
||||
"znear": 0.01
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"meshes" : [
|
||||
{
|
||||
"primitives" : [ {
|
||||
"attributes" : {
|
||||
"POSITION" : 1
|
||||
},
|
||||
"indices" : 0
|
||||
} ]
|
||||
}
|
||||
],
|
||||
|
||||
"buffers" : [
|
||||
{
|
||||
"uri" : "simpleSquare.bin",
|
||||
"byteLength" : 60
|
||||
}
|
||||
],
|
||||
"bufferViews" : [
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 0,
|
||||
"byteLength" : 12,
|
||||
"target" : 34963
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 12,
|
||||
"byteLength" : 48,
|
||||
"target" : 34962
|
||||
}
|
||||
],
|
||||
"accessors" : [
|
||||
{
|
||||
"bufferView" : 0,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5123,
|
||||
"count" : 6,
|
||||
"type" : "SCALAR",
|
||||
"max" : [ 3 ],
|
||||
"min" : [ 0 ]
|
||||
},
|
||||
{
|
||||
"bufferView" : 1,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 4,
|
||||
"type" : "VEC3",
|
||||
"max" : [ 1.0, 1.0, 0.0 ],
|
||||
"min" : [ 0.0, 0.0, 0.0 ]
|
||||
}
|
||||
],
|
||||
|
||||
"asset" : {
|
||||
"version" : "2.0"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 60 B |
|
@ -276,3 +276,9 @@ TEST_F(utFBXImporterExporter, importEmbeddedFragmentedAsciiTest) {
|
|||
ASSERT_TRUE(scene->mTextures[0]->pcData);
|
||||
ASSERT_EQ(968029u, scene->mTextures[0]->mWidth) << "FBX ASCII base64 compression splits data by 512Kb, it should be two parts for this texture";
|
||||
}
|
||||
|
||||
TEST_F(utFBXImporterExporter, fbxTokenizeTestTest) {
|
||||
//Assimp::Importer importer;
|
||||
//const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/transparentTest2.fbx", aiProcess_ValidateDataStructure);
|
||||
//EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
|
|
@ -375,6 +375,13 @@ TEST_F( utglTF2ImportExport, bug_import_simple_skin ) {
|
|||
EXPECT_NE( nullptr, scene );
|
||||
}
|
||||
|
||||
TEST_F(utglTF2ImportExport, import_cameras) {
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/cameras/Cameras.gltf",
|
||||
aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
}
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
|
||||
EXPECT_TRUE( exporterTest() );
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
set(PROJECT_VERSION "")
|
||||
project(assimp_qt_viewer)
|
||||
|
||||
# Qt5 requires cmake 3.1 or newer
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
FIND_PACKAGE(OpenGL QUIET)
|
||||
|
||||
# Qt5 version
|
||||
FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
|
||||
|
||||
SET(VIEWER_BUILD:BOOL FALSE)
|
||||
|
||||
IF( Qt5Widgets_FOUND AND OPENGL_FOUND)
|
||||
SET(VIEWER_BUILD TRUE)
|
||||
ELSE( Qt5Widgets_FOUND AND OPENGL_FOUND)
|
||||
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 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 OPENGL_FOUND)
|
||||
|
||||
IF(VIEWER_BUILD)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${Assimp_SOURCE_DIR}/include
|
||||
${Assimp_SOURCE_DIR}/code
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
LINK_DIRECTORIES(${Assimp_BINARY_DIR})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
|
||||
|
||||
SET(assimp_qt_viewer_SRCS
|
||||
main.cpp
|
||||
loggerview.hpp
|
||||
loggerview.cpp
|
||||
glview.hpp
|
||||
glview.cpp
|
||||
mainwindow.hpp
|
||||
mainwindow.cpp
|
||||
)
|
||||
|
||||
MESSAGE("assimp_qt_viewer use Qt5")
|
||||
INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
|
||||
qt5_wrap_ui(UISrcs mainwindow.ui)
|
||||
qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
|
||||
target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${OPENGL_LIBRARIES} assimp)
|
||||
|
||||
IF(WIN32) # Check if we are on Windows
|
||||
IF(MSVC) # Check if we are using the Visual Studio compiler
|
||||
#set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||
ELSEIF(CMAKE_COMPILER_IS_GNUCXX)
|
||||
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested
|
||||
ELSE()
|
||||
MESSAGE(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)")
|
||||
ENDIF()
|
||||
ELSEIF(UNIX)
|
||||
# Nothing special required
|
||||
ELSE()
|
||||
MESSAGE(SEND_ERROR "You are on an unsupported platform! (Not Win32 or Unix)")
|
||||
ENDIF()
|
||||
|
||||
SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
INSTALL(TARGETS assimp_qt_viewer DESTINATION "${ASSIMP_BIN_INSTALL_DIR}")
|
||||
ENDIF(VIEWER_BUILD)
|
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -1,456 +0,0 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2018, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Header files, Qt.
|
||||
#include <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
|
||||
|
||||
/**********************************/
|
||||
/************* Types **************/
|
||||
/**********************************/
|
||||
|
||||
private:
|
||||
|
||||
/// \struct SBBox
|
||||
/// Bounding box for object.
|
||||
struct SBBox
|
||||
{
|
||||
aiVector3D Minimum;///< Minimum values of coordinates.
|
||||
aiVector3D Maximum;///< Maximum values of coordinates.
|
||||
};
|
||||
|
||||
/// \struct SHelper_Mesh
|
||||
/// Helper object for fast rendering of mesh (\ref aiMesh).
|
||||
struct SHelper_Mesh
|
||||
{
|
||||
const size_t Quantity_Point;///< Quantity of points.
|
||||
const size_t Quantity_Line;///< Quantity of lines.
|
||||
const size_t Quantity_Triangle;///< Quantity of triangles.
|
||||
GLuint* Index_Point;///< Array of indices for drawing points.
|
||||
GLuint* Index_Line;///< Array of indices for drawing lines.
|
||||
GLuint* Index_Triangle;///< Array of indices for drawing triangles.
|
||||
|
||||
const SBBox BBox;///< BBox of mesh.
|
||||
|
||||
/// \fn explicit SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox = {{0, 0, 0}, {0, 0, 0}})
|
||||
/// Constructor.
|
||||
/// \param [in] pQuantity_Point - quantity of points.
|
||||
/// \param [in] pQuantity_Line - quantity of lines.
|
||||
/// \param [in] pQuantity_Triangle - quantity of triangles.
|
||||
/// \param [in] pBBox - BBox of mesh.
|
||||
explicit SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox = {{0, 0, 0}, {0, 0, 0}});
|
||||
|
||||
/// \fn ~SHelper_Mesh()
|
||||
/// Destructor.
|
||||
~SHelper_Mesh();
|
||||
};
|
||||
|
||||
/// \struct SHelper_Camera
|
||||
/// Information about position of the camera in space.
|
||||
struct SHelper_Camera
|
||||
{
|
||||
aiVector3D Position;///< Coordinates of the camera.
|
||||
aiVector3D Target;///< Target point of the camera.
|
||||
// Transformation path:
|
||||
// set Camera -> Rotation_AroundCamera -> Translation_ToScene -> Rotation_Scene -> draw Scene
|
||||
aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
|
||||
aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
|
||||
aiVector3D Translation_ToScene;///< Translation vector from camera to the scene.
|
||||
|
||||
/// \fn void SetDefault()
|
||||
/// Set default parameters of camera.
|
||||
void SetDefault();
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/// \enum ELightType
|
||||
/// Type of light source.
|
||||
enum class ELightType { Directional, Point, Spot };
|
||||
|
||||
/// \struct SLightParameters
|
||||
/// Parameters of light source.
|
||||
struct SLightParameters
|
||||
{
|
||||
aiLightSourceType Type;///< Type of light source.
|
||||
|
||||
aiColor4D Ambient;///< Ambient RGBA intensity of the light.
|
||||
aiColor4D Diffuse;///< Diffuse RGBA intensity of the light.
|
||||
aiColor4D Specular;///< Specular RGBA intensity of the light.
|
||||
|
||||
union UFor
|
||||
{
|
||||
/// \struct SDirectional
|
||||
/// Parameters of directional light source.
|
||||
struct SDirectional
|
||||
{
|
||||
aiVector3D Direction;
|
||||
|
||||
SDirectional() {}
|
||||
} Directional;
|
||||
|
||||
/// \struct SPoint
|
||||
/// Parameters of point light source.
|
||||
struct SPoint
|
||||
{
|
||||
aiVector3D Position;
|
||||
GLfloat Attenuation_Constant;
|
||||
GLfloat Attenuation_Linear;
|
||||
GLfloat Attenuation_Quadratic;
|
||||
|
||||
SPoint() {}
|
||||
} Point;
|
||||
|
||||
/// \struct SSpot
|
||||
/// Parameters of spot light source.
|
||||
struct SSpot
|
||||
{
|
||||
aiVector3D Position;
|
||||
GLfloat Attenuation_Constant;
|
||||
GLfloat Attenuation_Linear;
|
||||
GLfloat Attenuation_Quadratic;
|
||||
aiVector3D Direction;
|
||||
GLfloat CutOff;
|
||||
|
||||
SSpot() {}
|
||||
} Spot;
|
||||
|
||||
UFor() {}
|
||||
} For;
|
||||
|
||||
SLightParameters() {}
|
||||
};
|
||||
|
||||
/**********************************/
|
||||
/************ Variables ***********/
|
||||
/**********************************/
|
||||
|
||||
private:
|
||||
|
||||
#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.
|
||||
// Cameras
|
||||
SHelper_Camera mHelper_Camera;///< Information about current camera placing in space.
|
||||
SHelper_Camera mHelper_CameraDefault;///< Information about default camera initial placing in space.
|
||||
bool mCamera_DefaultAdded = true;///< If true then scene has no defined cameras and default was added, if false - scene has defined cameras.
|
||||
GLdouble mCamera_FOVY = 45.0;///< Specifies the field of view angle, in degrees, in the y direction.
|
||||
GLdouble mCamera_Viewport_AspectRatio;///< Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
|
||||
// Lighting
|
||||
bool mLightingEnabled = false;///< If true then OpenGL lighting is enabled (glEnable(GL_LIGHTING)), if false - disabled.
|
||||
///TODO: map is goooood, but not for case when one image can be used in different materials with difference in: texture transformation, targeting of the
|
||||
/// texture (ambient or emission, or even height map), texture properties.
|
||||
QMap<QString, GLuint> mTexture_IDMap;///< Map image filenames to textures ID's.
|
||||
|
||||
/**********************************/
|
||||
/************ Functions ***********/
|
||||
/**********************************/
|
||||
|
||||
private:
|
||||
|
||||
// Why in some cases pointers are used? Because: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
|
||||
template<typename TArg> void AssignIfLesser(TArg* pBaseValue, const TArg pTestValue) { if(pTestValue < *pBaseValue) *pBaseValue = pTestValue; }
|
||||
template<typename TArg> void AssignIfGreater(TArg* pBaseValue, const TArg pTestValue) { if(pTestValue > *pBaseValue) *pBaseValue = pTestValue; }
|
||||
|
||||
template<typename TArg> void AssignIfLesser(TArg& pBaseValue, const TArg pTestValue) { if(pTestValue < pBaseValue) pBaseValue = pTestValue; }
|
||||
template<typename TArg> void AssignIfGreater(TArg& pBaseValue, const TArg pTestValue) { if(pTestValue > pBaseValue) pBaseValue = pTestValue; }
|
||||
|
||||
/// \fn void Material_Apply(const aiMaterial* pMaterial)
|
||||
/// Enable pointed material.
|
||||
/// \param [in] pMaterial - pointer to material which must be used.
|
||||
void Material_Apply(const aiMaterial* pMaterial);
|
||||
|
||||
/// \fn void Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix)
|
||||
/// Calculate matrix for transforming coordinates from pointed node to root node (read as "global coordinate system").
|
||||
/// \param [in] pNode - pointer initial node from which relative coordintaes will be taken,
|
||||
/// \param [out] pOutMatrix - matrix for transform relative coordinates in \ref pNode to coordinates in root node (\ref aiScene::mRootNode).
|
||||
void Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix);
|
||||
|
||||
/// \fn void ImportTextures()
|
||||
/// Import textures.
|
||||
/// \param [in] pScenePath - path to the file of the scene.
|
||||
void ImportTextures(const QString& pScenePath);
|
||||
|
||||
/// \fn void BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParentNode_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign)
|
||||
/// Calculate BBox for pointed node. Function walk thru child nodes and apply all transformations.
|
||||
/// \param [in] pNode - reference to node for which needed BBox.
|
||||
/// \param [in] pParent_TransformationMatrix - reference to parent (parent for pNode) transformation matrix.
|
||||
/// \param [in,out] pNodeBBox - reference to where pNode BBox will be placed. It will expanded by child nodes BBoxes.
|
||||
/// \param [in] pFirstAssign - means that pNodeBBox not contain valid BBox at now and assign ('=') will used for setting new value, If
|
||||
/// false then \ref BBox_Extend will be used for setting new BBox.
|
||||
void BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParent_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign);
|
||||
|
||||
/// \fn void BBox_Extend(const SBBox& pChild, SBBox& pParent)
|
||||
/// Check and if need - extend current node BBox with BBox of child node.
|
||||
/// \param [in] pChild - reference to BBox which used for extend parent BBox.
|
||||
/// \param [in.out] pParent - BBox which will be extended using child BBox.
|
||||
void BBox_Extend(const SBBox& pChild, SBBox& pParent);
|
||||
|
||||
/// \fn void BBox_GetVertices(const SBBox& pBBox, aiVector3D pVertices[8])
|
||||
/// Get vertices of a parallelepiped which is described by BBox.
|
||||
/// \param [in] pBBox - input BBox.
|
||||
/// \param [out] pVertices - array of vertices.
|
||||
void BBox_GetVertices(const SBBox& pBBox, aiVector3D pVertices[8]);
|
||||
|
||||
/// \fn void BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVerticesQuantity, SBBox& pBBox)
|
||||
/// Calculate BBox for vertices array.
|
||||
/// \param [in] pVertices - vertices array.
|
||||
/// \param [in] pVerticesQuantity - quantity of vertices in array. If 0 then pBBox will be assigned with {{0, 0, 0}, {0, 0, 0}}.
|
||||
/// \param [out] pBBox - calculated BBox.
|
||||
void BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVerticesQuantity, SBBox& pBBox);
|
||||
|
||||
/********************************************************************/
|
||||
/************************ Logging functions *************************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void LogInfo(const QString& pMessage)
|
||||
/// Add message with severity "Warning" to log.
|
||||
void LogInfo(const QString& pMessage);
|
||||
|
||||
/// \fn void LogError(const QString& pMessage)
|
||||
/// Add message with severity "Error" to log.
|
||||
void LogError(const QString& pMessage);
|
||||
|
||||
/********************************************************************/
|
||||
/************************** Draw functions **************************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void Draw_Node(const aiNode* pNode)
|
||||
/// Apply node transformation and draw meshes assigned to this node.
|
||||
/// \param [in] pNode - pointer to node for drawing (\ref aiNode).
|
||||
void Draw_Node(const aiNode* pNode);
|
||||
|
||||
/// \fn void Draw_Mesh(const size_t pMesh_Index)
|
||||
/// Draw mesh.
|
||||
/// \param [in] pMesh_Index - index of mesh which must be drawn. Index point to mesh in \ref mHelper_Mesh.
|
||||
void Draw_Mesh(const size_t pMesh_Index);
|
||||
|
||||
/// \fn void Draw_BBox(const SBBox& pBBox)
|
||||
/// Draw bounding box using lines.
|
||||
/// \param [in] pBBox - bounding box for drawing.
|
||||
void Draw_BBox(const SBBox& pBBox);
|
||||
|
||||
/********************************************************************/
|
||||
/*********************** Override functions ************************/
|
||||
/********************************************************************/
|
||||
|
||||
protected:
|
||||
|
||||
/// \fn void drawCoordSystem()
|
||||
/// Draw axes of the coordinate system.
|
||||
void drawCoordSystem();
|
||||
|
||||
/// \fn void initializeGL() override
|
||||
/// Override function to initialise OpenGL.
|
||||
void initializeGL() override;
|
||||
|
||||
/// \fn void resizeGL(int pWidth, int pHeight) override
|
||||
/// \param [in] pWidth - new width of viewport.
|
||||
/// \param [in] pHeight - new height of viewport.
|
||||
void resizeGL(int pWidth, int pHeight) override;
|
||||
|
||||
/// \fn void paintGL() override
|
||||
/// Override function for rendering.
|
||||
void paintGL() override;
|
||||
|
||||
public:
|
||||
|
||||
/********************************************************************/
|
||||
/********************** Constructor/Destructor **********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn explicit CGLView(QWidget* pParent)
|
||||
/// Constructor.
|
||||
/// \param [in] pParent - parent widget.
|
||||
explicit CGLView(QWidget* pParent);
|
||||
|
||||
/// \fn virtual ~CGLView()
|
||||
/// Destructor.
|
||||
virtual ~CGLView();
|
||||
|
||||
/********************************************************************/
|
||||
/********************* Scene control functions **********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void FreeScene()
|
||||
/// Free all helper objects data.
|
||||
void FreeScene();
|
||||
|
||||
/// \fn void SetScene(const aiScene* pScene)
|
||||
/// Set scene for rendering.
|
||||
/// \param [in] pScene - pointer to scene.
|
||||
/// \param [in] pScenePath - path to the file of the scene.
|
||||
void SetScene(const aiScene* pScene, const QString& pScenePath);
|
||||
|
||||
/// \fn void Enable_SceneBBox(const bool pEnable)
|
||||
/// Enable drawing scene bounding box.
|
||||
/// \param [in] pEnable - if true then bbox will be drawing, if false - will not be drawing.
|
||||
void Enable_SceneBBox(const bool pEnable) { mScene_DrawBBox = pEnable; }
|
||||
|
||||
/// \fn void Enable_Textures(const bool pEnable)
|
||||
/// Control textures drawing.
|
||||
/// \param [in] pEnable - if true then enable textures, false - disable textures.
|
||||
void Enable_Textures(const bool pEnable);
|
||||
|
||||
/// \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 ********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void Lighting_Enable()
|
||||
/// Enable OpenGL lighting.
|
||||
void Lighting_Enable();
|
||||
|
||||
/// \fn void Lighting_Disable()
|
||||
/// Disable OpenGL lighting.
|
||||
void Lighting_Disable();
|
||||
|
||||
/// \fn void Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
|
||||
/// Edit light source properties.
|
||||
/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
|
||||
/// \param [in] pLightParameters - light source parameters.
|
||||
void Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters);///TODO: function set
|
||||
|
||||
/// \fn void Lighting_EnableSource(const size_t pLightNumber)
|
||||
/// Enable light source.
|
||||
/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
|
||||
void Lighting_EnableSource(const size_t pLightNumber);
|
||||
|
||||
///void Lighting_DisableSource(const size_t pLightNumber)
|
||||
/// Disable light source,
|
||||
/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
|
||||
void Lighting_DisableSource(const size_t pLightNumber);
|
||||
|
||||
/********************************************************************/
|
||||
/******************** Cameras control functions *********************/
|
||||
/********************************************************************/
|
||||
|
||||
/// \fn void Camera_Set(const size_t pCameraNumber)
|
||||
/// Set view from pointed camera.
|
||||
/// \param [in] pCamera_Index - index of the camera (\ref aiScene::mCameras).
|
||||
void Camera_Set(const size_t pCameraNumber);
|
||||
|
||||
/// \fn void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, 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.
|
||||
/// \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, 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.
|
||||
/// \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.
|
||||
/// \param [in] pTranslate_X - specifies the X coordinate of translation vector.
|
||||
/// \param [in] pTranslate_Y - specifies the Y coordinate of translation vector.
|
||||
/// \param [in] pTranslate_Z - specifies the Z coordinate of translation vector.
|
||||
void Camera_Translate(const GLfloat pTranslate_X, const GLfloat pTranslate_Y, const GLfloat pTranslate_Z);
|
||||
|
||||
/// \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)
|
||||
///< Signal. Emits when execution of \ref paintGL is end.
|
||||
/// \param [out] pPaintTime_ms - time spent for rendering, in milliseconds.
|
||||
/// \param [out] pDistance - distance between current camera and center of the scene. \sa SHelper_Camera::Translation_ToScene.
|
||||
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
|
||||
|
||||
/// \fn void SceneObject_Camera(const QString& pName)
|
||||
/// Signal. Emit for every camera found in scene. Also for default camera.
|
||||
/// \param [out] pName - name of the camera.
|
||||
void SceneObject_Camera(const QString& pName);
|
||||
|
||||
/// \fn void SceneObject_LightSource(const QString& pName)
|
||||
/// Signal. Emit for every light source found in scene. Also for default light source.
|
||||
/// \param [out] pName - name of the light source.
|
||||
void SceneObject_LightSource(const QString& pName);
|
||||
};// class CGLView
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2018, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
#include "loggerview.hpp"
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QTime>
|
||||
#include <QTextBrowser>
|
||||
|
||||
CLoggerView::CLoggerView(QTextBrowser* pOutputWidget)
|
||||
: mOutputWidget(pOutputWidget) {
|
||||
// empty
|
||||
}
|
||||
|
||||
CLoggerView::~CLoggerView() {
|
||||
mOutputWidget = nullptr;
|
||||
}
|
||||
|
||||
void CLoggerView::write(const char *pMessage) {
|
||||
if (nullptr == mOutputWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage));
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2018, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Header files, Assimp.
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
class QTextBrowser;
|
||||
|
||||
/// @class CLoggerView
|
||||
/// @brief GUI-stream for Assimp logging sub-sytem. Get data for logging and write it to output widget.
|
||||
class CLoggerView final : public ::Assimp::LogStream {
|
||||
public:
|
||||
/// @brief The class constructor.
|
||||
/// @param [in] pOutputWidget - pointer to output widget.
|
||||
explicit CLoggerView( QTextBrowser* pOutputWidget );
|
||||
|
||||
/// @brief The class destructor.
|
||||
virtual ~CLoggerView();
|
||||
|
||||
/// Write message to output widget. Used by Assimp.
|
||||
/// \param [in] pMessage - message for displaying.
|
||||
virtual void write(const char *pMessage);
|
||||
|
||||
private:
|
||||
QTextBrowser * mOutputWidget; ///< Widget for displaying messages.
|
||||
};
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2018, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// Thanks to acorn89 for support.
|
||||
|
||||
// Header files, project.
|
||||
#include "mainwindow.hpp"
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QApplication app(argc, argv);
|
||||
MainWindow win;
|
||||
win.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
|
@ -1,466 +0,0 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2018, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "mainwindow.hpp"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
// Header files, Assimp.
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
#ifndef __unused
|
||||
#define __unused __attribute__((unused))
|
||||
#endif // __unused
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
||||
void MainWindow::ImportFile(const QString &pFileName) {
|
||||
QTime time_begin = QTime::currentTime();
|
||||
|
||||
if ( mScene != nullptr ) {
|
||||
mImporter.FreeScene();
|
||||
mGLView->FreeScene();
|
||||
}
|
||||
|
||||
// Try to import scene.
|
||||
mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
|
||||
aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
|
||||
if ( mScene != nullptr ) {
|
||||
ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
|
||||
LogInfo("Import done: " + pFileName);
|
||||
// Prepare widgets for new scene.
|
||||
ui->leFileName->setText(pFileName.right(pFileName.length() - pFileName.lastIndexOf('/') - 1));
|
||||
ui->lstLight->clear();
|
||||
ui->lstCamera->clear();
|
||||
ui->cbxLighting->setChecked(true); mGLView->Lighting_Enable();
|
||||
ui->cbxBBox->setChecked(false); mGLView->Enable_SceneBBox(false);
|
||||
ui->cbxTextures->setChecked(true); mGLView->Enable_Textures(true);
|
||||
|
||||
//
|
||||
// Fill info labels
|
||||
//
|
||||
// Cameras
|
||||
ui->lblCameraCount->setText(QString::number(mScene->mNumCameras));
|
||||
// Lights
|
||||
ui->lblLightCount->setText(QString::number(mScene->mNumLights));
|
||||
// Meshes, faces, vertices.
|
||||
size_t qty_face = 0;
|
||||
size_t qty_vert = 0;
|
||||
|
||||
for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) {
|
||||
qty_face += mScene->mMeshes[idx_mesh]->mNumFaces;
|
||||
qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices;
|
||||
}
|
||||
|
||||
ui->lblMeshCount->setText(QString::number(mScene->mNumMeshes));
|
||||
ui->lblFaceCount->setText(QString::number(qty_face));
|
||||
ui->lblVertexCount->setText(QString::number(qty_vert));
|
||||
// Animation
|
||||
if(mScene->mNumAnimations)
|
||||
ui->lblHasAnimation->setText("yes");
|
||||
else
|
||||
ui->lblHasAnimation->setText("no");
|
||||
|
||||
//
|
||||
// Set scene for GL viewer.
|
||||
//
|
||||
mGLView->SetScene(mScene, pFileName);
|
||||
// Select first camera
|
||||
ui->lstCamera->setCurrentRow(0);
|
||||
mGLView->Camera_Set(0);
|
||||
// Scene is loaded, do first rendering.
|
||||
LogInfo("Scene is ready for rendering.");
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetSceneInfos();
|
||||
|
||||
QString errorMessage = QString("Error parsing \'%1\' : \'%2\'").arg(pFileName).arg(mImporter.GetErrorString());
|
||||
QMessageBox::critical(this, "Import error", errorMessage);
|
||||
LogError(errorMessage);
|
||||
}// if(mScene != nullptr)
|
||||
}
|
||||
|
||||
void MainWindow::ResetSceneInfos()
|
||||
{
|
||||
ui->lblLoadTime->clear();
|
||||
ui->leFileName->clear();
|
||||
ui->lblMeshCount->setText("0");
|
||||
ui->lblFaceCount->setText("0");
|
||||
ui->lblVertexCount->setText("0");
|
||||
ui->lblCameraCount->setText("0");
|
||||
ui->lblLightCount->setText("0");
|
||||
ui->lblHasAnimation->setText("no");
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/************************ Logging functions *************************/
|
||||
/********************************************************************/
|
||||
|
||||
void MainWindow::LogInfo(const QString& pMessage)
|
||||
{
|
||||
Assimp::DefaultLogger::get()->info(pMessage.toStdString());
|
||||
}
|
||||
|
||||
void MainWindow::LogError(const QString& pMessage)
|
||||
{
|
||||
Assimp::DefaultLogger::get()->error(pMessage.toStdString());
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/*********************** Override functions ************************/
|
||||
/********************************************************************/
|
||||
|
||||
void MainWindow::mousePressEvent(QMouseEvent* pEvent)
|
||||
{
|
||||
const QPoint ms_pt = pEvent->pos();
|
||||
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)
|
||||
mMouse_Transformation.Position_Pressed_LMB = ms_pt;
|
||||
else if(pEvent->button() & Qt::RightButton)
|
||||
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() - 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, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oZ axises.
|
||||
else
|
||||
mGLView->Camera_RotateScene(dy, dx, 0, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oY axises.
|
||||
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
if(pEvent->buttons() & Qt::RightButton)
|
||||
{
|
||||
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, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oZ axises.
|
||||
else
|
||||
mGLView->Camera_Rotate(dy, dx, 0, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oY axises.
|
||||
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::keyPressEvent(QKeyEvent* pEvent)
|
||||
{
|
||||
GLfloat step;
|
||||
|
||||
if(pEvent->modifiers() & Qt::ControlModifier)
|
||||
step = 10;
|
||||
else if(pEvent->modifiers() & Qt::AltModifier)
|
||||
step = 100;
|
||||
else
|
||||
step = 1;
|
||||
|
||||
if(pEvent->key() == Qt::Key_A)
|
||||
mGLView->Camera_Translate(-step, 0, 0);
|
||||
else if(pEvent->key() == Qt::Key_D)
|
||||
mGLView->Camera_Translate(step, 0, 0);
|
||||
else if(pEvent->key() == Qt::Key_W)
|
||||
mGLView->Camera_Translate(0, step, 0);
|
||||
else if(pEvent->key() == Qt::Key_S)
|
||||
mGLView->Camera_Translate(0, -step, 0);
|
||||
else if(pEvent->key() == Qt::Key_Up)
|
||||
mGLView->Camera_Translate(0, 0, -step);
|
||||
else if(pEvent->key() == Qt::Key_Down)
|
||||
mGLView->Camera_Translate(0, 0, step);
|
||||
|
||||
#if ASSIMP_QT4_VIEWER
|
||||
mGLView->updateGL();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/********************** Constructor/Destructor **********************/
|
||||
/********************************************************************/
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent), ui(new Ui::MainWindow),
|
||||
mScene(nullptr)
|
||||
{
|
||||
|
||||
// other variables
|
||||
mMouse_Transformation.Position_Pressed_Valid = false;
|
||||
|
||||
ui->setupUi(this);
|
||||
// Create OpenGL widget
|
||||
mGLView = new CGLView(this);
|
||||
mGLView->setMinimumSize(800, 600);
|
||||
mGLView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
|
||||
mGLView->setFocusPolicy(Qt::StrongFocus);
|
||||
// Connect to GLView signals.
|
||||
connect(mGLView, SIGNAL(Paint_Finished(size_t, GLfloat)), SLOT(Paint_Finished(size_t, GLfloat)));
|
||||
connect(mGLView, SIGNAL(SceneObject_Camera(QString)), SLOT(SceneObject_Camera(QString)));
|
||||
connect(mGLView, SIGNAL(SceneObject_LightSource(QString)), SLOT(SceneObject_LightSource(QString)));
|
||||
// and add it to layout
|
||||
ui->hlMainView->insertWidget(0, mGLView, 4);
|
||||
// Create logger
|
||||
mLoggerView = new CLoggerView(ui->tbLog);
|
||||
DefaultLogger::create("", Logger::VERBOSE);
|
||||
DefaultLogger::get()->attachStream(mLoggerView, DefaultLogger::Debugging | DefaultLogger::Info | DefaultLogger::Err | DefaultLogger::Warn);
|
||||
|
||||
ResetSceneInfos();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
using namespace Assimp;
|
||||
|
||||
DefaultLogger::get()->detatchStream(mLoggerView, DefaultLogger::Debugging | DefaultLogger::Info | DefaultLogger::Err | DefaultLogger::Warn);
|
||||
DefaultLogger::kill();
|
||||
|
||||
if(mScene != nullptr) mImporter.FreeScene();
|
||||
if(mLoggerView != nullptr) delete mLoggerView;
|
||||
if(mGLView != nullptr) delete mGLView;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
/****************************** Slots *******************************/
|
||||
/********************************************************************/
|
||||
|
||||
void MainWindow::Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance)
|
||||
{
|
||||
ui->lblRenderTime->setText(QString::number(pPaintTime_ms));
|
||||
ui->lblDistance->setText(QString::number(pDistance));
|
||||
}
|
||||
|
||||
void MainWindow::SceneObject_Camera(const QString& pName)
|
||||
{
|
||||
ui->lstCamera->addItem(pName);
|
||||
}
|
||||
|
||||
void MainWindow::SceneObject_LightSource(const QString& pName)
|
||||
{
|
||||
ui->lstLight->addItem(pName);
|
||||
// After item added "currentRow" is still contain old value (even '-1' if first item added). Because "currentRow"/"currentItem" is changed by user interaction,
|
||||
// not by "addItem". So, "currentRow" must be set manually.
|
||||
ui->lstLight->setCurrentRow(ui->lstLight->count() - 1);
|
||||
// And after "selectAll" handler of "signal itemSelectionChanged" will get right "currentItem" and "currentRow" values.
|
||||
ui->lstLight->selectAll();
|
||||
}
|
||||
|
||||
void MainWindow::on_butOpenFile_clicked() {
|
||||
aiString filter_temp;
|
||||
mImporter.GetExtensionList( filter_temp );
|
||||
|
||||
QString filename, filter;
|
||||
filter = filter_temp.C_Str();
|
||||
filter.replace(';', ' ');
|
||||
filter.append(" ;; All (*.*)");
|
||||
filename = QFileDialog::getOpenFileName(this, "Choose the file", "", filter);
|
||||
|
||||
if (!filename.isEmpty()) {
|
||||
ImportFile( filename );
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_butExport_clicked()
|
||||
{
|
||||
using namespace Assimp;
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
QString filename, filter, format_id;
|
||||
Exporter exporter;
|
||||
QTime time_begin;
|
||||
aiReturn rv;
|
||||
QStringList exportersList;
|
||||
QMap<QString, const aiExportFormatDesc*> exportersMap;
|
||||
|
||||
|
||||
if(mScene == nullptr)
|
||||
{
|
||||
QMessageBox::critical(this, "Export error", "Scene is empty");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < exporter.GetExportFormatCount(); ++i)
|
||||
{
|
||||
const aiExportFormatDesc* desc = exporter.GetExportFormatDescription(i);
|
||||
exportersList.push_back(desc->id + QString(": ") + desc->description);
|
||||
exportersMap.insert(desc->id, desc);
|
||||
}
|
||||
|
||||
// get an exporter
|
||||
bool dialogSelectExporterOk;
|
||||
QString selectedExporter = QInputDialog::getItem(this, "Export format", "Select the exporter : ", exportersList, 0, false, &dialogSelectExporterOk);
|
||||
if (!dialogSelectExporterOk)
|
||||
return;
|
||||
|
||||
// build the filter
|
||||
QString selectedId = selectedExporter.left(selectedExporter.indexOf(':'));
|
||||
filter = QString("*.") + exportersMap[selectedId]->fileExtension;
|
||||
|
||||
// get file path
|
||||
filename = QFileDialog::getSaveFileName(this, "Set file name", "", filter);
|
||||
// if it's canceled
|
||||
if (filename == "")
|
||||
return;
|
||||
|
||||
// begin export
|
||||
time_begin = QTime::currentTime();
|
||||
rv = exporter.Export(mScene, selectedId.toLocal8Bit(), filename.toLocal8Bit(), aiProcess_FlipUVs);
|
||||
ui->lblExportTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
|
||||
if(rv == aiReturn_SUCCESS)
|
||||
LogInfo("Export done: " + filename);
|
||||
else
|
||||
{
|
||||
QString errorMessage = QString("Export failed: ") + filename;
|
||||
LogError(errorMessage);
|
||||
QMessageBox::critical(this, "Export error", errorMessage);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxLighting_clicked(bool pChecked)
|
||||
{
|
||||
if(pChecked)
|
||||
mGLView->Lighting_Enable();
|
||||
else
|
||||
mGLView->Lighting_Disable();
|
||||
|
||||
mGLView->update();
|
||||
}
|
||||
|
||||
void MainWindow::on_lstLight_itemSelectionChanged()
|
||||
{
|
||||
bool selected = ui->lstLight->isItemSelected(ui->lstLight->currentItem());
|
||||
|
||||
if(selected)
|
||||
mGLView->Lighting_EnableSource(ui->lstLight->currentRow());
|
||||
else
|
||||
mGLView->Lighting_DisableSource(ui->lstLight->currentRow());
|
||||
|
||||
#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();
|
||||
#else
|
||||
mGLView->update();
|
||||
#endif // ASSIMP_QT4_VIEWER
|
||||
}
|
||||
|
||||
void MainWindow::on_cbxTextures_clicked(bool checked)
|
||||
{
|
||||
mGLView->Enable_Textures(checked);
|
||||
mGLView->update();
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2018, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Header files, Qt.
|
||||
#if defined ASSIMP_QT4_VIEWER
|
||||
# include <QMainWindow>
|
||||
#else
|
||||
# include <QtWidgets>
|
||||
#endif
|
||||
|
||||
// Header files, project.
|
||||
#include "glview.hpp"
|
||||
#include "loggerview.hpp"
|
||||
|
||||
// Header files, Assimp.
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
}
|
||||
|
||||
/// \class MainWindow
|
||||
/// Main window and algorithms.
|
||||
class MainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
struct SMouse_Transformation;
|
||||
|
||||
public:
|
||||
/// @brief The class constructor.
|
||||
/// \param [in] pParent - pointer to parent widget.
|
||||
explicit MainWindow( QWidget* pParent = 0 );
|
||||
|
||||
/// @brief The class destructor.
|
||||
~MainWindow();
|
||||
|
||||
/// Import scene from file.
|
||||
/// \param [in] pFileName - path and name of the file.
|
||||
void ImportFile(const QString& pFileName);
|
||||
|
||||
/// Reset informations about the scene
|
||||
void ResetSceneInfos();
|
||||
|
||||
/// Add message with severity "Warning" to log.
|
||||
void LogInfo(const QString& pMessage);
|
||||
|
||||
/// Add message with severity "Error" to log.
|
||||
void LogError(const QString& pMessage);
|
||||
|
||||
protected:
|
||||
/// Override function which handles mouse event "button pressed".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
void mousePressEvent(QMouseEvent* pEvent) override;
|
||||
|
||||
/// Override function which handles mouse event "button released".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
void mouseReleaseEvent(QMouseEvent *pEvent) override;
|
||||
|
||||
/// Override function which handles mouse event "move".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
void mouseMoveEvent(QMouseEvent* pEvent) override;
|
||||
|
||||
/// Override function which handles key event "key pressed".
|
||||
/// \param [in] pEvent - pointer to event data.
|
||||
void keyPressEvent(QKeyEvent* pEvent) override;
|
||||
|
||||
private slots:
|
||||
/// Show paint/render time and distance between camera and center of the scene.
|
||||
/// \param [in] pPaintTime_ms - paint time in milliseconds.
|
||||
void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
|
||||
|
||||
/// Add camera name to list.
|
||||
/// \param [in] pName - name of the camera.
|
||||
void SceneObject_Camera(const QString& pName);
|
||||
|
||||
/// Add lighting source name to list.
|
||||
/// \param [in] pName - name of the light source,
|
||||
void SceneObject_LightSource(const QString& pName);
|
||||
|
||||
void on_butOpenFile_clicked();
|
||||
void on_butExport_clicked();
|
||||
void on_cbxLighting_clicked(bool pChecked);
|
||||
void on_lstLight_itemSelectionChanged();
|
||||
void on_lstCamera_clicked(const QModelIndex &index);
|
||||
void on_cbxBBox_clicked(bool checked);
|
||||
void on_cbxTextures_clicked(bool checked);
|
||||
void on_cbxDrawAxes_clicked(bool checked);
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
CGLView *mGLView;///< Pointer to OpenGL render.
|
||||
CLoggerView *mLoggerView;///< Pointer to logging object.
|
||||
Assimp::Importer mImporter;///< Assimp importer.
|
||||
const aiScene* mScene;///< Pointer to loaded scene (\ref aiScene).
|
||||
|
||||
/// \struct SMouse_Transformation
|
||||
/// Holds data about transformation of the scene/camera when mouse us used.
|
||||
struct SMouse_Transformation {
|
||||
bool Position_Pressed_Valid;///< Mouse button pressed on GLView.
|
||||
QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button.
|
||||
QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button.
|
||||
aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
|
||||
aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
|
||||
} mMouse_Transformation;
|
||||
};
|
|
@ -1,544 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>641</width>
|
||||
<height>778</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="5,1">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="hlMainView" stretch="0">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="grpFile">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>File</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="butOpenFile">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open file</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblFileName_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>File name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="leFileName">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>160</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblLoadTime_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load time, s</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblLoadTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="butExport">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Export</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="lblExportTime_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Export time, s</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="lblExportTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="grpInfo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Info</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblRenderTime_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Render time, ms</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblRenderTime">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblMeshCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Meshes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblFaceCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Faces</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblMeshCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblFaceCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblVertexCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Vertices</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="lblVertexCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lblLightCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lights</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lblCameraCount_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cameras</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="lblHasAnimation_Label">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Animation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="lblShaderCount_Label">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Shaders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="lblLightCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="lblCameraCount">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="lblShaderCount">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="lblHasAnimation">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="lblDistance_Label">
|
||||
<property name="text">
|
||||
<string>Distance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="lblDistance">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="grpDynamics">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Dynamics</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPushButton" name="butAnimationStart">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Animation start</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="butAnimationStop">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Animation stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabInfoAndControl">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Log</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextBrowser" name="tbLog">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Lights and cameras</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QListWidget" name="lstLight">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Light sources of the scene</string>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::SelectedClicked</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="lstCamera">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Cameras of the scene</string>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Control</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="cbxLighting">
|
||||
<property name="toolTip">
|
||||
<string>Enable/Disable OpenGL lighting</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Lighting</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="cbxBBox">
|
||||
<property name="text">
|
||||
<string>Scene BBox</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="cbxTextures">
|
||||
<property name="text">
|
||||
<string>Textures</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="cbxDrawAxes">
|
||||
<property name="text">
|
||||
<string>Show Axes</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<slots>
|
||||
<signal>installEventFilter()</signal>
|
||||
</slots>
|
||||
</ui>
|
Loading…
Reference in New Issue