Merge branch 'master' into deprecated_gltfpbr_macros
commit
d704824be3
67
.travis.sh
67
.travis.sh
|
@ -1,67 +0,0 @@
|
|||
#---------------------------------------------------------------------------
|
||||
#Open Asset Import Library (assimp)
|
||||
#---------------------------------------------------------------------------
|
||||
# Copyright (c) 2006-2020, assimp team
|
||||
#
|
||||
# License see LICENSE file
|
||||
#
|
||||
function generate() {
|
||||
OPTIONS="-DASSIMP_WERROR=ON"
|
||||
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
|
||||
|
||||
if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
|
||||
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"
|
||||
else
|
||||
OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
|
||||
fi
|
||||
|
||||
if [ "$SHARED_BUILD" = "ON" ] ; then
|
||||
OPTIONS="$OPTIONS -DBUILD_SHARED_LIBS=ON"
|
||||
else
|
||||
OPTIONS="$OPTIONS -DBUILD_SHARED_LIBS=OFF"
|
||||
fi
|
||||
|
||||
if [ "$ENABLE_COVERALLS" = "ON" ] ; then
|
||||
OPTIONS="$OPTIONS -DASSIMP_COVERALLS=ON"
|
||||
else
|
||||
OPTIONS="$OPTIONS -DASSIMP_COVERALLS=OFF"
|
||||
fi
|
||||
|
||||
if [ "$ASAN" = "ON" ] ; then
|
||||
OPTIONS="$OPTIONS -DASSIMP_ASAN=ON"
|
||||
else
|
||||
OPTIONS="$OPTIONS -DASSIMP_ASAN=OFF"
|
||||
fi
|
||||
|
||||
if [ "$UBSAN" = "ON" ] ; then
|
||||
OPTIONS="$OPTIONS -DASSIMP_UBSAN=ON"
|
||||
fi
|
||||
|
||||
cmake -G "Unix Makefiles" $OPTIONS
|
||||
}
|
||||
# build and run unittests, if not android
|
||||
if [ $ANDROID ]; then
|
||||
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
||||
fi
|
||||
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
if [ $ANALYZE = "ON" ] ; then
|
||||
if [ "$CC" = "clang" ]; then
|
||||
scan-build cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=OFF -DASSIMP_BUILD_TESTS=OFF
|
||||
scan-build --status-bugs make -j2
|
||||
else
|
||||
cppcheck --version
|
||||
generate \
|
||||
&& cppcheck --error-exitcode=1 -j2 -Iinclude -Icode code 2> cppcheck.txt
|
||||
if [ -s cppcheck.txt ]; then
|
||||
cat cppcheck.txt
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
generate \
|
||||
&& make -j4 \
|
||||
&& sudo make install \
|
||||
&& sudo ldconfig \
|
||||
&& (cd test/unit; ../../bin/unit)
|
||||
fi
|
||||
fi
|
78
.travis.yml
78
.travis.yml
|
@ -1,78 +0,0 @@
|
|||
sudo: required
|
||||
language: cpp
|
||||
|
||||
cache: ccache
|
||||
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake cppcheck && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
|
||||
- 'if [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
if brew ls --versions cmake > /dev/null; then
|
||||
echo cmake already installed.;
|
||||
else
|
||||
brew install cmake;
|
||||
fi;
|
||||
brew install python3;
|
||||
brew install homebrew/x11/freeglut;
|
||||
fi'
|
||||
- echo -e "#ifndef A_R_H_INC\n#define A_R_H_INC\n#define GitVersion ${TRAVIS_JOB_ID}\n#define GitBranch \"${TRAVIS_BRANCH}\"\n#endif // A_R_H_INC" > revision.h
|
||||
# install latest LCOV (1.9 was failing)
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz && tar xf lcov_1.11.orig.tar.gz && sudo make -C lcov-1.11/ install && gem install coveralls-lcov && lcov --version && g++ --version ; fi
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
env:
|
||||
global:
|
||||
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
|
||||
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: ASAN=ON
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: UBSAN=ON
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: SHARED_BUILD=ON
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: ANALYZE=ON
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: ENABLE_COVERALLS=ON
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: SHARED_BUILD=ON
|
||||
|
||||
install:
|
||||
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
||||
|
||||
before_script:
|
||||
cmake . -DASSIMP_ENABLE_BOOST_WORKAROUND=YES
|
||||
|
||||
script:
|
||||
- export COVERALLS_SERVICE_NAME=travis-ci
|
||||
- export COVERALLS_REPO_TOKEN=abc12345
|
||||
- . ./.travis.sh
|
||||
|
||||
after_success:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then cd ${TRAVIS_BUILD_DIR} && lcov --directory . --capture --output-file coverage.info && lcov --remove coverage.info '/usr/*' 'contrib/*' 'test/*' --output-file coverage.info && lcov --list coverage.info && coveralls-lcov --source-encoding=ISO-8859-1 --repo-token=${COVERALLS_TOKEN} coverage.info ; fi
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "assimp/assimp"
|
||||
notification_email: kim.kulling@googlemail.com
|
||||
build_command_prepend: "cmake ./"
|
||||
build_command: "make -j4"
|
||||
branch_pattern: coverity_scan
|
|
@ -10,16 +10,15 @@
|
|||
:: Also see: https://github.com/assimp/assimp/pull/2646
|
||||
|
||||
SET SOURCE_DIR=.
|
||||
SET GENERATOR=Visual Studio 16 2019
|
||||
|
||||
:: 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%
|
||||
SET BINARIES_DIR="./build/Win32"
|
||||
cmake . -G "%GENERATOR%" -A Win32 -S %SOURCE_DIR% -B %BINARIES_DIR%
|
||||
cmake --build %BINARIES_DIR% --config debug
|
||||
cmake --build %BINARIES_DIR% --config release
|
||||
|
||||
SET BINARIES_DIR="./BINARIES/x64"
|
||||
cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR%
|
||||
SET BINARIES_DIR="./build/x64"
|
||||
cmake . -G "%GENERATOR%" -A x64 -S %SOURCE_DIR% -B %BINARIES_DIR%
|
||||
cmake --build %BINARIES_DIR% --config debug
|
||||
cmake --build %BINARIES_DIR% --config release
|
||||
|
||||
|
|
|
@ -49,14 +49,14 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
|
|||
IF(ASSIMP_HUNTER_ENABLED)
|
||||
include("cmake-modules/HunterGate.cmake")
|
||||
HunterGate(
|
||||
URL "https://github.com/cpp-pm/hunter/archive/v0.23.311.tar.gz"
|
||||
SHA1 "1a82b9b73055879181cb1466b2ab5d48ee8ae410"
|
||||
URL "https://github.com/cpp-pm/hunter/archive/v0.24.0.tar.gz"
|
||||
SHA1 "a3d7f4372b1dcd52faa6ff4a3bd5358e1d0e5efd"
|
||||
)
|
||||
|
||||
add_definitions(-DASSIMP_USE_HUNTER)
|
||||
ENDIF()
|
||||
|
||||
PROJECT(Assimp VERSION 5.1.6)
|
||||
PROJECT(Assimp VERSION 5.2.0)
|
||||
|
||||
# All supported options ###############################################
|
||||
|
||||
|
@ -134,12 +134,12 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
|
|||
OFF
|
||||
)
|
||||
|
||||
IF ( WIN32 )
|
||||
IF (WIN32)
|
||||
# Use subset of Windows.h
|
||||
ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
|
||||
|
||||
IF(MSVC)
|
||||
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
|
||||
OPTION (ASSIMP_BUILD_ASSIMP_VIEW
|
||||
"If the Assimp view tool is built. (requires DirectX)"
|
||||
OFF )
|
||||
|
||||
|
@ -243,6 +243,13 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
|||
IF( UNIX )
|
||||
# Use GNUInstallDirs for Unix predefined directories
|
||||
INCLUDE(GNUInstallDirs)
|
||||
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
|
||||
IF( ${OPERATING_SYSTEM} MATCHES "Android")
|
||||
ELSE()
|
||||
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Grouped compiler settings ########################################
|
||||
|
@ -341,9 +348,24 @@ INCLUDE (FindPkgMacros)
|
|||
INCLUDE (PrecompiledHeader)
|
||||
|
||||
# Set Assimp project output directory variables.
|
||||
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for runtime output files")
|
||||
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for library output files")
|
||||
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib" CACHE STRING "Path for archive output files")
|
||||
# Will respect top-level CMAKE_*_OUTPUT_DIRECTORY variables if any are set.
|
||||
IF(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for runtime output files")
|
||||
ELSE()
|
||||
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} CACHE STRING "Path for runtime output files")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY)
|
||||
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin" CACHE STRING "Path for library output files")
|
||||
ELSE()
|
||||
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} CACHE STRING "Path for runtime output files")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY)
|
||||
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib" CACHE STRING "Path for library output files")
|
||||
ELSE()
|
||||
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} CACHE STRING "Path for runtime output files")
|
||||
ENDIF()
|
||||
|
||||
# Macro used to set the output directories of a target to the
|
||||
# respective Assimp output directories.
|
||||
|
@ -672,11 +694,13 @@ ENDIF()
|
|||
ADD_SUBDIRECTORY( code/ )
|
||||
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||
# The viewer for windows only
|
||||
IF ( WIN32 )
|
||||
IF (WIN32)
|
||||
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" OFF )
|
||||
IF ( ASSIMP_BUILD_ASSIMP_VIEW )
|
||||
ADD_SUBDIRECTORY( tools/assimp_view/ )
|
||||
ENDIF ()
|
||||
ELSE()
|
||||
MESSAGE("Building Assimp Viewer only supported on Windows.")
|
||||
ENDIF ()
|
||||
# The command line tool
|
||||
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
||||
|
|
|
@ -112,6 +112,7 @@ using namespace Assimp::ASE;
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
Parser::Parser(const char *szFile, unsigned int fileFormatDefault) {
|
||||
ai_assert(nullptr != szFile);
|
||||
|
||||
filePtr = szFile;
|
||||
iFileFormat = fileFormatDefault;
|
||||
|
||||
|
@ -486,7 +487,7 @@ void Parser::ParseLV1MaterialListBlock() {
|
|||
ParseLV4MeshLong(iIndex);
|
||||
|
||||
if (iIndex >= iMaterialCount) {
|
||||
LogError("Out of range: material index is too large");
|
||||
LogWarning("Out of range: material index is too large");
|
||||
iIndex = iMaterialCount - 1;
|
||||
return;
|
||||
}
|
||||
|
@ -905,7 +906,6 @@ void Parser::ParseLV2LightSettingsBlock(ASE::Light &light) {
|
|||
}
|
||||
AI_ASE_HANDLE_SECTION("2", "LIGHT_SETTINGS");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -1782,7 +1782,9 @@ void Parser::ParseLV4MeshFace(ASE::Face &out) {
|
|||
|
||||
// *MESH_MTLID is optional, too
|
||||
while (true) {
|
||||
if ('*' == *filePtr) break;
|
||||
if ('*' == *filePtr) {
|
||||
break;
|
||||
}
|
||||
if (IsLineEnd(*filePtr)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1831,8 +1833,9 @@ void Parser::ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut) {
|
|||
void Parser::ParseLV4MeshFloatTriple(ai_real *apOut) {
|
||||
ai_assert(nullptr != apOut);
|
||||
|
||||
for (unsigned int i = 0; i < 3; ++i)
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
ParseLV4MeshFloat(apOut[i]);
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Parser::ParseLV4MeshFloat(ai_real &fOut) {
|
||||
|
|
|
@ -182,6 +182,8 @@ inline size_t Write<aiVertexWeight>(IOStream *stream, const aiVertexWeight &v) {
|
|||
return t + Write<float>(stream, v.mWeight);
|
||||
}
|
||||
|
||||
constexpr size_t MatrixSize = 64;
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Serialize a mat4x4
|
||||
template <>
|
||||
|
@ -192,7 +194,7 @@ inline size_t Write<aiMatrix4x4>(IOStream *stream, const aiMatrix4x4 &m) {
|
|||
}
|
||||
}
|
||||
|
||||
return 64;
|
||||
return MatrixSize;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
|
|
|
@ -66,11 +66,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
// zlib is needed for compressed blend files
|
||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||
# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||
#include "Common/Compression.h"
|
||||
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||
# include <zlib.h>
|
||||
# else
|
||||
# include "../contrib/zlib/zlib.h"
|
||||
# endif
|
||||
# endif*/
|
||||
#endif
|
||||
|
||||
namespace Assimp {
|
||||
|
@ -141,7 +142,7 @@ void BlenderImporter::SetupProperties(const Importer * /*pImp*/) {
|
|||
void BlenderImporter::InternReadFile(const std::string &pFile,
|
||||
aiScene *pScene, IOSystem *pIOHandler) {
|
||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||
std::vector<Bytef> uncompressed;
|
||||
std::vector<char> uncompressed;
|
||||
#endif
|
||||
|
||||
FileDatabase file;
|
||||
|
@ -159,7 +160,6 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
|
|||
#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||
ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
|
||||
#else
|
||||
|
||||
if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
|
||||
ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
|
||||
}
|
||||
|
@ -173,42 +173,12 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
|
|||
stream->Seek(0L, aiOrigin_SET);
|
||||
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
|
||||
|
||||
// build a zlib stream
|
||||
z_stream zstream;
|
||||
zstream.opaque = Z_NULL;
|
||||
zstream.zalloc = Z_NULL;
|
||||
zstream.zfree = Z_NULL;
|
||||
zstream.data_type = Z_BINARY;
|
||||
|
||||
// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
|
||||
inflateInit2(&zstream, 16 + MAX_WBITS);
|
||||
|
||||
zstream.next_in = reinterpret_cast<Bytef *>(reader->GetPtr());
|
||||
zstream.avail_in = (uInt)reader->GetRemainingSize();
|
||||
|
||||
size_t total = 0l;
|
||||
|
||||
// TODO: be smarter about this, decompress directly into heap buffer
|
||||
// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
|
||||
#define MYBLOCK 1024
|
||||
Bytef block[MYBLOCK];
|
||||
int ret;
|
||||
do {
|
||||
zstream.avail_out = MYBLOCK;
|
||||
zstream.next_out = block;
|
||||
ret = inflate(&zstream, Z_NO_FLUSH);
|
||||
|
||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
||||
ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .BLEND file");
|
||||
size_t total = 0;
|
||||
Compression compression;
|
||||
if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, 16 + Compression::MaxWBits)) {
|
||||
total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), uncompressed);
|
||||
compression.close();
|
||||
}
|
||||
const size_t have = MYBLOCK - zstream.avail_out;
|
||||
total += have;
|
||||
uncompressed.resize(total);
|
||||
memcpy(uncompressed.data() + total - have, block, have);
|
||||
} while (ret != Z_STREAM_END);
|
||||
|
||||
// terminate zlib
|
||||
inflateEnd(&zstream);
|
||||
|
||||
// replace the input stream with a memory stream
|
||||
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
|
||||
|
|
|
@ -357,9 +357,9 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
|
|||
out->mAngleInnerCone = AI_DEG_TO_RAD(srcLight->mFalloffAngle);
|
||||
|
||||
// ... some extension magic.
|
||||
if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - 1e-6f)) {
|
||||
if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - ai_epsilon)) {
|
||||
// ... some deprecation magic.
|
||||
if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - 1e-6f)) {
|
||||
if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - ai_epsilon)) {
|
||||
// Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess ....
|
||||
// epsilon chosen to be 0.1
|
||||
float f = 1.0f;
|
||||
|
@ -1065,7 +1065,7 @@ void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, floa
|
|||
return;
|
||||
}
|
||||
for (unsigned int i = 0; i < values.size(); i++) {
|
||||
if (std::abs(time - values[i].mTime) < 1e-6f) {
|
||||
if (std::abs(time - values[i].mTime) < ai_epsilon) {
|
||||
values[i].mKeys.push_back(k);
|
||||
return;
|
||||
} else if (time > values[i].mTime && time < values[i + 1].mTime) {
|
||||
|
|
|
@ -80,8 +80,10 @@ enum TransformInheritance {
|
|||
|
||||
TransformInheritance_MAX // end-of-enum sentinel
|
||||
};
|
||||
|
||||
} // namespace FBX
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
|
||||
#endif // AI_FBXCOMMON_H_INC
|
||||
|
|
|
@ -653,7 +653,7 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
|||
const PropertyTable &props = model.Props();
|
||||
bool ok;
|
||||
|
||||
const float zero_epsilon = 1e-6f;
|
||||
const float zero_epsilon = ai_epsilon;
|
||||
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||
|
@ -1267,7 +1267,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
|||
const std::vector<aiVector3D> &normals = mesh.GetNormals();
|
||||
if (normals.size()) {
|
||||
ai_assert(normals.size() == vertices.size());
|
||||
out_mesh->mNormals = new aiVector3D[vertices.size()];
|
||||
out_mesh->mNormals = new aiVector3D[count_vertices];
|
||||
}
|
||||
|
||||
// allocate tangents, binormals.
|
||||
|
@ -1295,8 +1295,8 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
|||
ai_assert(tangents.size() == vertices.size());
|
||||
ai_assert(binormals->size() == vertices.size());
|
||||
|
||||
out_mesh->mTangents = new aiVector3D[vertices.size()];
|
||||
out_mesh->mBitangents = new aiVector3D[vertices.size()];
|
||||
out_mesh->mTangents = new aiVector3D[count_vertices];
|
||||
out_mesh->mBitangents = new aiVector3D[count_vertices];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1308,7 +1308,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
|||
break;
|
||||
}
|
||||
|
||||
out_mesh->mTextureCoords[i] = new aiVector3D[vertices.size()];
|
||||
out_mesh->mTextureCoords[i] = new aiVector3D[count_vertices];
|
||||
out_mesh->mNumUVComponents[i] = 2;
|
||||
}
|
||||
|
||||
|
@ -1320,7 +1320,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
|||
break;
|
||||
}
|
||||
|
||||
out_mesh->mColors[i] = new aiColor4D[vertices.size()];
|
||||
out_mesh->mColors[i] = new aiColor4D[count_vertices];
|
||||
}
|
||||
|
||||
unsigned int cursor = 0, in_cursor = 0;
|
||||
|
@ -3187,7 +3187,8 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
|||
}
|
||||
|
||||
bool ok = false;
|
||||
const float zero_epsilon = 1e-6f;
|
||||
|
||||
const float zero_epsilon = ai_epsilon;
|
||||
|
||||
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
||||
if (ok && preRotation.SquareLength() > zero_epsilon) {
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -46,11 +45,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||
# include <zlib.h>
|
||||
#else
|
||||
# include "../contrib/zlib/zlib.h"
|
||||
#endif
|
||||
//#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||
#include "Common/Compression.h"
|
||||
//# include <zlib.h>
|
||||
//#else
|
||||
//# include "../contrib/zlib/zlib.h"
|
||||
//#endif
|
||||
|
||||
#include "FBXTokenizer.h"
|
||||
#include "FBXParser.h"
|
||||
|
@ -115,9 +115,7 @@ namespace Assimp {
|
|||
namespace FBX {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Element::Element(const Token& key_token, Parser& parser)
|
||||
: key_token(key_token)
|
||||
{
|
||||
Element::Element(const Token& key_token, Parser& parser) : key_token(key_token) {
|
||||
TokenPtr n = nullptr;
|
||||
do {
|
||||
n = parser.AdvanceToNextToken();
|
||||
|
@ -210,8 +208,7 @@ Scope::Scope(Parser& parser,bool topLevel)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Scope::~Scope()
|
||||
{
|
||||
Scope::~Scope() {
|
||||
for(ElementMap::value_type& v : elements) {
|
||||
delete v.second;
|
||||
}
|
||||
|
@ -527,9 +524,7 @@ void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uin
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// read binary data array, assume cursor points to the 'compression mode' field (i.e. behind the header)
|
||||
void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end,
|
||||
std::vector<char>& buff,
|
||||
const Element& /*el*/)
|
||||
{
|
||||
std::vector<char>& buff, const Element& /*el*/) {
|
||||
BE_NCONST uint32_t encmode = SafeParse<uint32_t>(data, end);
|
||||
AI_SWAP4(encmode);
|
||||
data += 4;
|
||||
|
@ -571,31 +566,11 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
|
|||
else if(encmode == 1) {
|
||||
// zlib/deflate, next comes ZIP head (0x78 0x01)
|
||||
// see http://www.ietf.org/rfc/rfc1950.txt
|
||||
|
||||
z_stream zstream;
|
||||
zstream.opaque = Z_NULL;
|
||||
zstream.zalloc = Z_NULL;
|
||||
zstream.zfree = Z_NULL;
|
||||
zstream.data_type = Z_BINARY;
|
||||
|
||||
// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
|
||||
if(Z_OK != inflateInit(&zstream)) {
|
||||
ParseError("failure initializing zlib");
|
||||
Compression compress;
|
||||
if (compress.open(Compression::Format::Binary, Compression::FlushMode::Finish, 0)) {
|
||||
compress.decompress(data, comp_len, buff);
|
||||
compress.close();
|
||||
}
|
||||
|
||||
zstream.next_in = reinterpret_cast<Bytef*>( const_cast<char*>(data) );
|
||||
zstream.avail_in = comp_len;
|
||||
|
||||
zstream.avail_out = static_cast<uInt>(buff.size());
|
||||
zstream.next_out = reinterpret_cast<Bytef*>(&*buff.begin());
|
||||
const int ret = inflate(&zstream, Z_FINISH);
|
||||
|
||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
||||
ParseError("failure decompressing compressed data section");
|
||||
}
|
||||
|
||||
// terminate zlib
|
||||
inflateEnd(&zstream);
|
||||
}
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
else {
|
||||
|
@ -701,7 +676,6 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// read an array of color4 tuples
|
||||
void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
|
||||
|
@ -786,8 +760,7 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// read an array of float2 tuples
|
||||
void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
|
||||
{
|
||||
void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) {
|
||||
out.resize( 0 );
|
||||
const TokenList& tok = el.Tokens();
|
||||
if(tok.empty()) {
|
||||
|
@ -831,8 +804,7 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
|
|||
out.push_back(aiVector2D(static_cast<float>(d[0]),
|
||||
static_cast<float>(d[1])));
|
||||
}
|
||||
}
|
||||
else if (type == 'f') {
|
||||
} else if (type == 'f') {
|
||||
const float* f = reinterpret_cast<const float*>(&buff[0]);
|
||||
for (unsigned int i = 0; i < count2; ++i, f += 2) {
|
||||
out.push_back(aiVector2D(f[0],f[1]));
|
||||
|
@ -865,8 +837,7 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// read an array of ints
|
||||
void ParseVectorDataArray(std::vector<int>& out, const Element& el)
|
||||
{
|
||||
void ParseVectorDataArray(std::vector<int>& out, const Element& el) {
|
||||
out.resize( 0 );
|
||||
const TokenList& tok = el.Tokens();
|
||||
if(tok.empty()) {
|
||||
|
|
|
@ -275,7 +275,9 @@ void HMPImporter::InternReadFile_HMP7() {
|
|||
|
||||
// now load all vertices from the file
|
||||
aiVector3D *pcVertOut = pcMesh->mVertices;
|
||||
ai_assert(pcVertOut != nullptr);
|
||||
aiVector3D *pcNorOut = pcMesh->mNormals;
|
||||
ai_assert(pcNorOut != nullptr);
|
||||
const HMP::Vertex_HMP7 *src = (const HMP::Vertex_HMP7 *)szCurrent;
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int x = 0; x < width; ++x) {
|
||||
|
@ -327,7 +329,10 @@ void HMPImporter::CreateMaterial(const unsigned char *szCurrent,
|
|||
|
||||
// now read the first skin and skip all others
|
||||
ReadFirstSkin(pcHeader->numskins, szCurrent, &szCurrent);
|
||||
} else {
|
||||
*szCurrentOut = szCurrent;
|
||||
return;
|
||||
}
|
||||
|
||||
// generate a default material
|
||||
const int iMode = (int)aiShadingMode_Gouraud;
|
||||
aiMaterial *pcHelper = new aiMaterial();
|
||||
|
@ -349,7 +354,6 @@ void HMPImporter::CreateMaterial(const unsigned char *szCurrent,
|
|||
pScene->mNumMaterials = 1;
|
||||
pScene->mMaterials = new aiMaterial *[1];
|
||||
pScene->mMaterials[0] = pcHelper;
|
||||
}
|
||||
*szCurrentOut = szCurrent;
|
||||
}
|
||||
|
||||
|
@ -373,27 +377,36 @@ void HMPImporter::CreateOutputFaceList(unsigned int width, unsigned int height)
|
|||
aiVector3D *pcUVOut(pcUVs);
|
||||
|
||||
// Build the terrain square
|
||||
const unsigned int upperBound = pcMesh->mNumVertices;
|
||||
unsigned int iCurrent = 0;
|
||||
for (unsigned int y = 0; y < height - 1; ++y) {
|
||||
const size_t offset0 = y * width;
|
||||
const size_t offset1 = (y + 1) * width;
|
||||
for (unsigned int x = 0; x < width - 1; ++x, ++pcFaceOut) {
|
||||
pcFaceOut->mNumIndices = 4;
|
||||
pcFaceOut->mIndices = new unsigned int[4];
|
||||
if ((offset0 + x + 1) >= upperBound){
|
||||
continue;
|
||||
}
|
||||
if ((offset1 + x + 1) >= upperBound){
|
||||
continue;
|
||||
}
|
||||
|
||||
*pcVertOut++ = pcMesh->mVertices[y * width + x];
|
||||
*pcVertOut++ = pcMesh->mVertices[(y + 1) * width + x];
|
||||
*pcVertOut++ = pcMesh->mVertices[(y + 1) * width + x + 1];
|
||||
*pcVertOut++ = pcMesh->mVertices[y * width + x + 1];
|
||||
*pcVertOut++ = pcMesh->mVertices[offset0 + x];
|
||||
*pcVertOut++ = pcMesh->mVertices[offset1 + x];
|
||||
*pcVertOut++ = pcMesh->mVertices[offset1 + x + 1];
|
||||
*pcVertOut++ = pcMesh->mVertices[offset0 + x + 1];
|
||||
|
||||
*pcNorOut++ = pcMesh->mNormals[y * width + x];
|
||||
*pcNorOut++ = pcMesh->mNormals[(y + 1) * width + x];
|
||||
*pcNorOut++ = pcMesh->mNormals[(y + 1) * width + x + 1];
|
||||
*pcNorOut++ = pcMesh->mNormals[y * width + x + 1];
|
||||
*pcNorOut++ = pcMesh->mNormals[offset0 + x];
|
||||
*pcNorOut++ = pcMesh->mNormals[offset1 + x];
|
||||
*pcNorOut++ = pcMesh->mNormals[offset1 + x + 1];
|
||||
*pcNorOut++ = pcMesh->mNormals[offset0 + x + 1];
|
||||
|
||||
if (pcMesh->mTextureCoords[0]) {
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][y * width + x];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][(y + 1) * width + x];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][(y + 1) * width + x + 1];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][y * width + x + 1];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][offset0 + x];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][offset1 + x];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][offset1 + x + 1];
|
||||
*pcUVOut++ = pcMesh->mTextureCoords[0][offset0 + x + 1];
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
|
|
|
@ -66,12 +66,12 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe
|
|||
|
||||
// if segment ends on plane, do not report a hit. We stay on that side until a following segment starting at this
|
||||
// point leaves the plane through the other side
|
||||
if (std::abs(dotOne + dotTwo) < 1e-6)
|
||||
if (std::abs(dotOne + dotTwo) < ai_epsilon)
|
||||
return false;
|
||||
|
||||
// if segment starts on the plane, report a hit only if the end lies on the *other* side
|
||||
if (std::abs(dotTwo) < 1e-6) {
|
||||
if ((assumeStartOnWhiteSide && dotOne + dotTwo < 1e-6) || (!assumeStartOnWhiteSide && dotOne + dotTwo > -1e-6)) {
|
||||
if (std::abs(dotTwo) < ai_epsilon) {
|
||||
if ((assumeStartOnWhiteSide && dotOne + dotTwo < ai_epsilon) || (!assumeStartOnWhiteSide && dotOne + dotTwo > -ai_epsilon)) {
|
||||
out = e0;
|
||||
return true;
|
||||
} else {
|
||||
|
@ -81,7 +81,7 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe
|
|||
|
||||
// ignore if segment is parallel to plane and far away from it on either side
|
||||
// Warning: if there's a few thousand of such segments which slowly accumulate beyond the epsilon, no hit would be registered
|
||||
if (std::abs(dotOne) < 1e-6)
|
||||
if (std::abs(dotOne) < ai_epsilon)
|
||||
return false;
|
||||
|
||||
// t must be in [0..1] if the intersection point is within the given segment
|
||||
|
@ -163,7 +163,7 @@ void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs,
|
|||
for (iit = begin; iit != end; vidx += *iit++) {
|
||||
|
||||
unsigned int newcount = 0;
|
||||
bool isAtWhiteSide = (in[vidx] - p) * n > -1e-6;
|
||||
bool isAtWhiteSide = (in[vidx] - p) * n > -ai_epsilon;
|
||||
for (unsigned int i = 0; i < *iit; ++i) {
|
||||
const IfcVector3 &e0 = in[vidx + i], e1 = in[vidx + (i + 1) % *iit];
|
||||
|
||||
|
@ -259,7 +259,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
|
|||
// segment-segment intersection
|
||||
// solve b0 + b*s = e0 + e*t for (s,t)
|
||||
const IfcFloat det = (-b.x * e.y + e.x * b.y);
|
||||
if (std::abs(det) < 1e-6) {
|
||||
if (std::abs(det) < ai_epsilon) {
|
||||
// no solutions (parallel lines)
|
||||
continue;
|
||||
}
|
||||
|
@ -316,7 +316,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
|
|||
|
||||
// for a valid intersection, s and t should be in range [0,1]. Including a bit of epsilon on s, potential double
|
||||
// hits on two consecutive boundary segments are filtered
|
||||
if (s >= -1e-6 * b_sqlen_inv && s <= 1.0 + 1e-6 * b_sqlen_inv && t >= 0.0 && (t <= 1.0 || halfOpen)) {
|
||||
if (s >= -ai_epsilon * b_sqlen_inv && s <= 1.0 + ai_epsilon * b_sqlen_inv && t >= 0.0 && (t <= 1.0 || halfOpen)) {
|
||||
// only insert the point into the list if it is sufficiently far away from the previous intersection point.
|
||||
// This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments.
|
||||
if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
|
||||
|
@ -431,14 +431,14 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
|
|||
|
||||
// if the poly is parallel to the plane, put it completely on the black or white side
|
||||
if (std::abs(polyNormal * n) > 0.9999) {
|
||||
bool isOnWhiteSide = (srcVertices[0] - p) * n > -1e-6;
|
||||
bool isOnWhiteSide = (srcVertices[0] - p) * n > -ai_epsilon;
|
||||
std::vector<IfcVector3> &targetSide = isOnWhiteSide ? whiteside : blackside;
|
||||
targetSide.insert(targetSide.end(), srcVertices, srcVertices + srcVtxCount);
|
||||
} else {
|
||||
// otherwise start building one polygon for each side. Whenever the current line segment intersects the plane
|
||||
// we put a point there as an end of the current segment. Then we switch to the other side, put a point there, too,
|
||||
// as a beginning of the current segment, and simply continue accumulating vertices.
|
||||
bool isCurrentlyOnWhiteSide = ((srcVertices[0]) - p) * n > -1e-6;
|
||||
bool isCurrentlyOnWhiteSide = ((srcVertices[0]) - p) * n > -ai_epsilon;
|
||||
for (size_t a = 0; a < srcVtxCount; ++a) {
|
||||
IfcVector3 e0 = srcVertices[a];
|
||||
IfcVector3 e1 = srcVertices[(a + 1) % srcVtxCount];
|
||||
|
|
|
@ -380,21 +380,19 @@ void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh&
|
|||
bool take_any = false;
|
||||
|
||||
for (unsigned int j = 0; j < 2; ++j, take_any = true) {
|
||||
if ((last_dir == 0 || take_any) && std::abs(d.x) > 1e-6) {
|
||||
if ((last_dir == 0 || take_any) && std::abs(d.x) > ai_epsilon) {
|
||||
q.y = startvec.y;
|
||||
q.z = startvec.z;
|
||||
q.x = -(d.y * q.y + d.z * q.z) / d.x;
|
||||
last_dir = 0;
|
||||
break;
|
||||
}
|
||||
else if ((last_dir == 1 || take_any) && std::abs(d.y) > 1e-6) {
|
||||
} else if ((last_dir == 1 || take_any) && std::abs(d.y) > ai_epsilon) {
|
||||
q.x = startvec.x;
|
||||
q.z = startvec.z;
|
||||
q.y = -(d.x * q.x + d.z * q.z) / d.y;
|
||||
last_dir = 1;
|
||||
break;
|
||||
}
|
||||
else if ((last_dir == 2 && std::abs(d.z) > 1e-6) || take_any) {
|
||||
} else if ((last_dir == 2 && std::abs(d.z) > ai_epsilon) || take_any) {
|
||||
q.y = startvec.y;
|
||||
q.x = startvec.x;
|
||||
q.z = -(d.y * q.y + d.x * q.x) / d.z;
|
||||
|
@ -529,7 +527,7 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
|||
return m;
|
||||
}
|
||||
|
||||
const auto closeDistance = 1e-6;
|
||||
const auto closeDistance = ai_epsilon;
|
||||
|
||||
bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt2) {
|
||||
if(pt1.Coordinates.size() != pt2.Coordinates.size())
|
||||
|
@ -561,7 +559,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
|
|||
// Outline: 'curve' is now a list of vertex points forming the underlying profile, extrude along the given axis,
|
||||
// forming new triangles.
|
||||
const bool has_area = solid.SweptArea->ProfileType == "AREA" && curve.mVerts.size() > 2;
|
||||
if( solid.Depth < 1e-6 ) {
|
||||
if (solid.Depth < ai_epsilon) {
|
||||
if( has_area ) {
|
||||
result.Append(curve);
|
||||
}
|
||||
|
|
|
@ -1133,7 +1133,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
|||
}
|
||||
|
||||
for(size_t i = 0; i < out_contour.size(); ++i) {
|
||||
ai_assert((out_contour[i]-out_contour2[i]).SquareLength() < 1e-6);
|
||||
ai_assert((out_contour[i] - out_contour2[i]).SquareLength() < ai_epsilon);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1435,7 +1435,7 @@ std::vector<IfcVector2> GetContourInPlane2D(std::shared_ptr<TempMesh> mesh,IfcMa
|
|||
|
||||
const auto outernor = ((mesh->mVerts[2] - mesh->mVerts[0]) ^ (mesh->mVerts[1] - mesh->mVerts[0])).Normalize();
|
||||
const IfcFloat dot = planeNor * outernor;
|
||||
if(std::fabs(dot) < 1.f - 1e-6f) {
|
||||
if (std::fabs(dot) < 1.f - ai_epsilon) {
|
||||
std::stringstream msg;
|
||||
msg << "Skipping: Unaligned opening (" << planeNor.x << ", " << planeNor.y << ", " << planeNor.z << ")";
|
||||
msg << " . ( " << outernor.x << ", " << outernor.y << ", " << outernor.z << ") = " << dot;
|
||||
|
@ -1476,7 +1476,7 @@ std::vector<IfcVector2> GetContourInPlane2D(std::shared_ptr<TempMesh> mesh,IfcMa
|
|||
return contour;
|
||||
}
|
||||
|
||||
const float close { 1e-6f };
|
||||
const float close{ ai_epsilon };
|
||||
|
||||
static bool isClose(IfcVector2 first,IfcVector2 second) {
|
||||
auto diff = (second - first);
|
||||
|
|
|
@ -228,25 +228,24 @@ void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Compute the normal of the last polygon in the given mesh
|
||||
IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const
|
||||
{
|
||||
IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const {
|
||||
return ComputePolygonNormal(&mVerts[mVerts.size() - mVertcnt.back()], mVertcnt.back(), normalize);
|
||||
}
|
||||
|
||||
struct CompareVector
|
||||
{
|
||||
bool operator () (const IfcVector3& a, const IfcVector3& b) const
|
||||
{
|
||||
struct CompareVector {
|
||||
bool operator () (const IfcVector3& a, const IfcVector3& b) const {
|
||||
IfcVector3 d = a - b;
|
||||
IfcFloat eps = 1e-6;
|
||||
IfcFloat eps = ai_epsilon;
|
||||
return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps);
|
||||
}
|
||||
};
|
||||
struct FindVector
|
||||
{
|
||||
|
||||
struct FindVector {
|
||||
IfcVector3 v;
|
||||
FindVector(const IfcVector3& p) : v(p) { }
|
||||
bool operator () (const IfcVector3& p) { return FuzzyVectorCompare(1e-6)(p, v); }
|
||||
bool operator()(const IfcVector3 &p) {
|
||||
return FuzzyVectorCompare(ai_epsilon)(p, v);
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -357,8 +356,7 @@ void TempMesh::FixupFaceOrientation()
|
|||
// to reverse the neighbour
|
||||
nb_vidx = (nb_vidx + 1) % nbvc;
|
||||
size_t oursideidx = (a + 1) % vc;
|
||||
if( FuzzyVectorCompare(1e-6)(mVerts[vsi + oursideidx], mVerts[nbvsi + nb_vidx]) )
|
||||
{
|
||||
if (FuzzyVectorCompare(ai_epsilon)(mVerts[vsi + oursideidx], mVerts[nbvsi + nb_vidx])) {
|
||||
std::reverse(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc);
|
||||
std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc);
|
||||
for (size_t aa = 0; aa < nbvc - 1; ++aa) {
|
||||
|
@ -564,7 +562,7 @@ void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in)
|
|||
out[static_cast<unsigned int>(i)] = in.DirectionRatios[i];
|
||||
}
|
||||
const IfcFloat len = out.Length();
|
||||
if (len<1e-6) {
|
||||
if (len < ai_epsilon) {
|
||||
IFCImporter::LogWarn("direction vector magnitude too small, normalization would result in a division by zero");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -83,9 +83,13 @@ AnimResolver::AnimResolver(std::list<Envelope> &_envelopes, double tick) :
|
|||
(*it).old_first = 0;
|
||||
(*it).old_last = (*it).keys.size() - 1;
|
||||
|
||||
if ((*it).keys.empty()) continue;
|
||||
if ((*it).keys.empty()) {
|
||||
continue;
|
||||
}
|
||||
if ((int)(*it).type < 1 || (int)(*it).type>EnvelopeType_Unknown) {
|
||||
continue;
|
||||
}
|
||||
switch ((*it).type) {
|
||||
|
||||
// translation
|
||||
case LWO::EnvelopeType_Position_X:
|
||||
trans_x = &*it;
|
||||
|
|
|
@ -195,6 +195,9 @@ struct Material {
|
|||
//! PBR Anisotropy
|
||||
ai_real anisotropy;
|
||||
|
||||
//! bump map multipler (normal map scalar)(-bm)
|
||||
ai_real bump_multiplier;
|
||||
|
||||
//! Constructor
|
||||
Material() :
|
||||
diffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
|
||||
|
@ -208,7 +211,8 @@ struct Material {
|
|||
sheen(ai_real(1.0), ai_real(1.0), ai_real(1.0)),
|
||||
clearcoat_thickness(ai_real(0.0)),
|
||||
clearcoat_roughness(ai_real(0.0)),
|
||||
anisotropy(ai_real(0.0)) {
|
||||
anisotropy(ai_real(0.0)),
|
||||
bump_multiplier(ai_real(1.0)) {
|
||||
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/scene.h>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/ObjMaterial.h>
|
||||
#include <memory>
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
|
@ -604,6 +605,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
|
|||
|
||||
mat->AddProperty<int>(&sm, 1, AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
// Preserve the original illum value
|
||||
mat->AddProperty<int>(&pCurrentMaterial->illumination_model, 1, AI_MATKEY_OBJ_ILLUM);
|
||||
|
||||
// Adding material colors
|
||||
mat->AddProperty(&pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT);
|
||||
mat->AddProperty(&pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||
|
@ -657,6 +661,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
|
|||
if (0 != pCurrentMaterial->textureBump.length) {
|
||||
mat->AddProperty(&pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0));
|
||||
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_HEIGHT(0));
|
||||
if (pCurrentMaterial->bump_multiplier != 1.0) {
|
||||
mat->AddProperty(&pCurrentMaterial->bump_multiplier, 1, AI_MATKEY_OBJ_BUMPMULT_HEIGHT(0));
|
||||
}
|
||||
if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) {
|
||||
addTextureMappingModeProperty(mat, aiTextureType_HEIGHT);
|
||||
}
|
||||
|
@ -665,6 +672,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
|
|||
if (0 != pCurrentMaterial->textureNormal.length) {
|
||||
mat->AddProperty(&pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0));
|
||||
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_NORMALS(0));
|
||||
if (pCurrentMaterial->bump_multiplier != 1.0) {
|
||||
mat->AddProperty(&pCurrentMaterial->bump_multiplier, 1, AI_MATKEY_OBJ_BUMPMULT_NORMALS(0));
|
||||
}
|
||||
if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) {
|
||||
addTextureMappingModeProperty(mat, aiTextureType_NORMALS);
|
||||
}
|
||||
|
|
|
@ -472,7 +472,11 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
|
|||
}
|
||||
|
||||
skipToken = 2;
|
||||
} else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
|
||||
} else if (!ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))) {
|
||||
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
getFloat(it, m_DataItEnd, m_pModel->m_pCurrentMaterial->bump_multiplier);
|
||||
skipToken = 2;
|
||||
} else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
|
||||
skipToken = 2;
|
||||
} else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size()))) {
|
||||
skipToken = 3;
|
||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -60,25 +58,11 @@ using namespace Assimp::Formatter;
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
|
||||
|
||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||
#include <zlib.h>
|
||||
#else
|
||||
#include "../contrib/zlib/zlib.h"
|
||||
#endif
|
||||
#include "Common/Compression.h"
|
||||
|
||||
// Magic identifier for MSZIP compressed data
|
||||
#define MSZIP_MAGIC 0x4B43
|
||||
#define MSZIP_BLOCK 32786
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Dummy memory wrappers for use with zlib
|
||||
static void *dummy_alloc(void * /*opaque*/, unsigned int items, unsigned int size) {
|
||||
return ::operator new(items *size);
|
||||
}
|
||||
|
||||
static void dummy_free(void * /*opaque*/, void *address) {
|
||||
return ::operator delete(address);
|
||||
}
|
||||
constexpr unsigned int MSZIP_MAGIC = 0x4B43;
|
||||
constexpr size_t MSZIP_BLOCK = 32786l;
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
|
||||
|
||||
|
@ -133,13 +117,13 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
|
|||
mIsBinaryFormat = true;
|
||||
compressed = true;
|
||||
} else
|
||||
ThrowException("Unsupported xfile format '", mP[8], mP[9], mP[10], mP[11], "'");
|
||||
ThrowException("Unsupported x-file format '", mP[8], mP[9], mP[10], mP[11], "'");
|
||||
|
||||
// float size
|
||||
mBinaryFloatSize = (unsigned int)(mP[12] - 48) * 1000 + (unsigned int)(mP[13] - 48) * 100 + (unsigned int)(mP[14] - 48) * 10 + (unsigned int)(mP[15] - 48);
|
||||
|
||||
if (mBinaryFloatSize != 32 && mBinaryFloatSize != 64)
|
||||
ThrowException("Unknown float size ", mBinaryFloatSize, " specified in xfile header.");
|
||||
ThrowException("Unknown float size ", mBinaryFloatSize, " specified in x-file header.");
|
||||
|
||||
// The x format specifies size in bits, but we work in bytes
|
||||
mBinaryFloatSize /= 8;
|
||||
|
@ -171,16 +155,6 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
|
|||
* ///////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
// build a zlib stream
|
||||
z_stream stream;
|
||||
stream.opaque = nullptr;
|
||||
stream.zalloc = &dummy_alloc;
|
||||
stream.zfree = &dummy_free;
|
||||
stream.data_type = (mIsBinaryFormat ? Z_BINARY : Z_ASCII);
|
||||
|
||||
// initialize the inflation algorithm
|
||||
::inflateInit2(&stream, -MAX_WBITS);
|
||||
|
||||
// skip unknown data (checksum, flags?)
|
||||
mP += 6;
|
||||
|
||||
|
@ -207,12 +181,15 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
|
|||
|
||||
// and advance to the next offset
|
||||
P1 += ofs;
|
||||
est_out += MSZIP_BLOCK; // one decompressed block is 32786 in size
|
||||
est_out += MSZIP_BLOCK; // one decompressed block is 327861 in size
|
||||
}
|
||||
|
||||
// Allocate storage and terminating zero and do the actual uncompressing
|
||||
Compression compression;
|
||||
uncompressed.resize(est_out + 1);
|
||||
char *out = &uncompressed.front();
|
||||
if (compression.open(mIsBinaryFormat ? Compression::Format::Binary : Compression::Format::ASCII,
|
||||
Compression::FlushMode::SyncFlush, -Compression::MaxWBits)) {
|
||||
while (mP + 3 < mEnd) {
|
||||
uint16_t ofs = *((uint16_t *)mP);
|
||||
AI_SWAP2(ofs);
|
||||
|
@ -221,28 +198,11 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
|
|||
if (mP + ofs > mEnd + 2) {
|
||||
throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
|
||||
}
|
||||
|
||||
// push data to the stream
|
||||
stream.next_in = (Bytef *)mP;
|
||||
stream.avail_in = ofs;
|
||||
stream.next_out = (Bytef *)out;
|
||||
stream.avail_out = MSZIP_BLOCK;
|
||||
|
||||
// and decompress the data ....
|
||||
int ret = ::inflate(&stream, Z_SYNC_FLUSH);
|
||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||
throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
|
||||
|
||||
::inflateReset(&stream);
|
||||
::inflateSetDictionary(&stream, (const Bytef *)out, MSZIP_BLOCK - stream.avail_out);
|
||||
|
||||
// and advance to the next offset
|
||||
out += MSZIP_BLOCK - stream.avail_out;
|
||||
out += compression.decompressBlock(mP, ofs, out, MSZIP_BLOCK);
|
||||
mP += ofs;
|
||||
}
|
||||
|
||||
// terminate zlib
|
||||
::inflateEnd(&stream);
|
||||
compression.close();
|
||||
}
|
||||
|
||||
// ok, update pointers to point to the uncompressed file data
|
||||
mP = &uncompressed[0];
|
||||
|
@ -279,15 +239,16 @@ void XFileParser::ParseFile() {
|
|||
while (running) {
|
||||
// read name of next object
|
||||
std::string objectName = GetNextToken();
|
||||
if (objectName.length() == 0)
|
||||
if (objectName.length() == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// parse specific object
|
||||
if (objectName == "template")
|
||||
if (objectName == "template") {
|
||||
ParseDataObjectTemplate();
|
||||
else if (objectName == "Frame")
|
||||
} else if (objectName == "Frame") {
|
||||
ParseDataObjectFrame(nullptr);
|
||||
else if (objectName == "Mesh") {
|
||||
} else if (objectName == "Mesh") {
|
||||
// some meshes have no frames at all
|
||||
Mesh *mesh = new Mesh;
|
||||
ParseDataObjectMesh(mesh);
|
||||
|
@ -326,12 +287,14 @@ void XFileParser::ParseDataObjectTemplate() {
|
|||
while (running) {
|
||||
std::string s = GetNextToken();
|
||||
|
||||
if (s == "}")
|
||||
if (s == "}") {
|
||||
break;
|
||||
}
|
||||
|
||||
if (s.length() == 0)
|
||||
if (s.length() == 0) {
|
||||
ThrowException("Unexpected end of file reached while parsing template definition");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -500,7 +463,7 @@ void XFileParser::ParseDataObjectSkinWeights(Mesh *pMesh) {
|
|||
bone.mWeights.reserve(numWeights);
|
||||
|
||||
for (unsigned int a = 0; a < numWeights; a++) {
|
||||
BoneWeight weight;
|
||||
BoneWeight weight = {};
|
||||
weight.mVertex = ReadInt();
|
||||
bone.mWeights.push_back(weight);
|
||||
}
|
||||
|
|
|
@ -44,28 +44,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
|
||||
|
||||
#include "XGLLoader.h"
|
||||
#include "Common/Compression.h"
|
||||
|
||||
#include <assimp/ParsingUtils.h>
|
||||
#include <assimp/fast_atof.h>
|
||||
|
||||
#include <assimp/MemoryIOWrapper.h>
|
||||
#include <assimp/StreamReader.h>
|
||||
#include <assimp/importerdesc.h>
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <cctype>
|
||||
#include <memory>
|
||||
//#include <cctype>
|
||||
//#include <memory>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
// zlib is needed for compressed XGL files
|
||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
|
||||
# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||
# include <zlib.h>
|
||||
# else
|
||||
# include <contrib/zlib/zlib.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
|
||||
|
||||
template <>
|
||||
|
@ -73,6 +65,7 @@ const char *LogFunctions<XGLImporter>::Prefix() {
|
|||
static auto prefix = "XGL: ";
|
||||
return prefix;
|
||||
}
|
||||
|
||||
} // namespace Assimp
|
||||
|
||||
static const aiImporterDesc desc = {
|
||||
|
@ -118,8 +111,8 @@ const aiImporterDesc *XGLImporter::GetInfo() const {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Imports the given file into the given scene structure.
|
||||
void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
|
||||
std::vector<Bytef> uncompressed;
|
||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
|
||||
std::vector<char> uncompressed;
|
||||
#endif
|
||||
|
||||
m_scene = pScene;
|
||||
|
@ -137,48 +130,16 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
|||
#else
|
||||
std::unique_ptr<StreamReaderLE> raw_reader(new StreamReaderLE(stream));
|
||||
|
||||
// build a zlib stream
|
||||
z_stream zstream;
|
||||
zstream.opaque = Z_NULL;
|
||||
zstream.zalloc = Z_NULL;
|
||||
zstream.zfree = Z_NULL;
|
||||
zstream.data_type = Z_BINARY;
|
||||
|
||||
// raw decompression without a zlib or gzip header
|
||||
inflateInit2(&zstream, -MAX_WBITS);
|
||||
|
||||
Compression compression;
|
||||
size_t total = 0l;
|
||||
if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, -Compression::MaxWBits)) {
|
||||
// skip two extra bytes, zgl files do carry a crc16 upfront (I think)
|
||||
raw_reader->IncPtr(2);
|
||||
|
||||
zstream.next_in = reinterpret_cast<Bytef *>(raw_reader->GetPtr());
|
||||
zstream.avail_in = (uInt) raw_reader->GetRemainingSize();
|
||||
|
||||
size_t total = 0l;
|
||||
|
||||
// TODO: be smarter about this, decompress directly into heap buffer
|
||||
// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
|
||||
#define MYBLOCK 1024
|
||||
Bytef block[MYBLOCK];
|
||||
int ret;
|
||||
do {
|
||||
zstream.avail_out = MYBLOCK;
|
||||
zstream.next_out = block;
|
||||
ret = inflate(&zstream, Z_NO_FLUSH);
|
||||
|
||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
||||
ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .XGL file");
|
||||
total = compression.decompress((unsigned char *)raw_reader->GetPtr(), raw_reader->GetRemainingSize(), uncompressed);
|
||||
compression.close();
|
||||
}
|
||||
const size_t have = MYBLOCK - zstream.avail_out;
|
||||
total += have;
|
||||
uncompressed.resize(total);
|
||||
memcpy(uncompressed.data() + total - have, block, have);
|
||||
} while (ret != Z_STREAM_END);
|
||||
|
||||
// terminate zlib
|
||||
inflateEnd(&zstream);
|
||||
|
||||
// replace the input stream with a memory stream
|
||||
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
|
||||
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(uncompressed.data()), total));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -239,7 +200,7 @@ void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) {
|
|||
if (!nd) {
|
||||
ThrowException("failure reading <world>");
|
||||
}
|
||||
if (!nd->mName.length) {
|
||||
if (nd->mName.length == 0) {
|
||||
nd->mName.Set("WORLD");
|
||||
}
|
||||
|
||||
|
@ -291,7 +252,8 @@ aiNode *XGLImporter::ReadObject(XmlNode &node, TempScope &scope) {
|
|||
const std::string &s = ai_stdStrToLower(child.name());
|
||||
if (s == "mesh") {
|
||||
const size_t prev = scope.meshes_linear.size();
|
||||
if (ReadMesh(child, scope)) {
|
||||
bool empty;
|
||||
if (ReadMesh(child, scope, empty)) {
|
||||
const size_t newc = scope.meshes_linear.size();
|
||||
for (size_t i = 0; i < newc - prev; ++i) {
|
||||
meshes.push_back(static_cast<unsigned int>(i + prev));
|
||||
|
@ -475,12 +437,12 @@ aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) {
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
|
||||
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) {
|
||||
TempMesh t;
|
||||
|
||||
std::map<unsigned int, TempMaterialMesh> bymat;
|
||||
const unsigned int mesh_id = ReadIDAttr(node);
|
||||
|
||||
bool empty_mesh = true;
|
||||
for (XmlNode &child : node.children()) {
|
||||
const std::string &s = ai_stdStrToLower(child.name());
|
||||
|
||||
|
@ -539,6 +501,9 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
|
|||
mid = ResolveMaterialRef(sub_child, scope);
|
||||
}
|
||||
}
|
||||
if (has[0] || has[1] || has[2]) {
|
||||
empty_mesh = false;
|
||||
}
|
||||
|
||||
if (mid == ~0u) {
|
||||
ThrowException("missing material index");
|
||||
|
@ -590,6 +555,11 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
|
|||
scope.meshes.insert(std::pair<unsigned int, aiMesh *>(mesh_id, m));
|
||||
}
|
||||
}
|
||||
if (empty_mesh) {
|
||||
LogWarn("Mesh is empty, skipping.");
|
||||
empty = empty_mesh;
|
||||
return false;
|
||||
}
|
||||
|
||||
// no id == not a reference, insert this mesh right *here*
|
||||
return mesh_id == ~0u;
|
||||
|
@ -759,7 +729,7 @@ aiVector2D XGLImporter::ReadVec2(XmlNode &node) {
|
|||
std::string val;
|
||||
XmlParser::getValueAsString(node, val);
|
||||
const char *s = val.c_str();
|
||||
ai_real v[2];
|
||||
ai_real v[2] = {};
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!SkipSpaces(&s)) {
|
||||
LogError("unexpected EOL, failed to parse vec2");
|
||||
|
@ -814,4 +784,4 @@ aiColor3D XGLImporter::ReadCol3(XmlNode &node) {
|
|||
return aiColor3D(v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // ASSIMP_BUILD_NO_XGL_IMPORTER
|
||||
|
|
|
@ -186,7 +186,7 @@ private:
|
|||
void ReadLighting(XmlNode &node, TempScope &scope);
|
||||
aiLight *ReadDirectionalLight(XmlNode &node);
|
||||
aiNode *ReadObject(XmlNode &node, TempScope &scope);
|
||||
bool ReadMesh(XmlNode &node, TempScope &scope);
|
||||
bool ReadMesh(XmlNode &node, TempScope &scope, bool &empty);
|
||||
void ReadMaterial(XmlNode &node, TempScope &scope);
|
||||
aiVector2D ReadVec2(XmlNode &node);
|
||||
aiVector3D ReadVec3(XmlNode &node);
|
||||
|
|
|
@ -260,20 +260,9 @@ public:
|
|||
VEC4,
|
||||
MAT2,
|
||||
MAT3,
|
||||
MAT4 };
|
||||
|
||||
private:
|
||||
static const size_t NUM_VALUES = static_cast<size_t>(MAT4) + 1;
|
||||
|
||||
struct Info {
|
||||
const char *name;
|
||||
unsigned int numComponents;
|
||||
MAT4
|
||||
};
|
||||
|
||||
template <int N>
|
||||
struct data { static const Info infos[NUM_VALUES]; };
|
||||
|
||||
public:
|
||||
inline static Value FromString(const char *str) {
|
||||
for (size_t i = 0; i < NUM_VALUES; ++i) {
|
||||
if (strcmp(data<0>::infos[i].name, str) == 0) {
|
||||
|
@ -290,40 +279,31 @@ public:
|
|||
inline static unsigned int GetNumComponents(Value type) {
|
||||
return data<0>::infos[static_cast<size_t>(type)].numComponents;
|
||||
}
|
||||
|
||||
private:
|
||||
static const size_t NUM_VALUES = static_cast<size_t>(MAT4) + 1;
|
||||
struct Info {
|
||||
const char *name;
|
||||
unsigned int numComponents;
|
||||
};
|
||||
|
||||
template <int N>
|
||||
struct data {
|
||||
static const Info infos[NUM_VALUES];
|
||||
};
|
||||
};
|
||||
|
||||
// must match the order of the AttribTypeTraits::Value enum!
|
||||
template <int N>
|
||||
const AttribType::Info
|
||||
AttribType::data<N>::infos[AttribType::NUM_VALUES] = {
|
||||
{ "SCALAR", 1 }, { "VEC2", 2 }, { "VEC3", 3 }, { "VEC4", 4 }, { "MAT2", 4 }, { "MAT3", 9 }, { "MAT4", 16 }
|
||||
};
|
||||
|
||||
/*
|
||||
//! A reference to one top-level object, which is valid
|
||||
//! until the Asset instance is destroyed
|
||||
template<class T>
|
||||
class Ref
|
||||
{
|
||||
std::vector<T*>* vector;
|
||||
unsigned int index;
|
||||
|
||||
public:
|
||||
Ref() : vector(0), index(0) {}
|
||||
Ref(std::vector<T*>& vec, unsigned int idx) : vector(&vec), index(idx) {}
|
||||
|
||||
inline unsigned int GetIndex() const
|
||||
{ return index; }
|
||||
|
||||
operator bool() const
|
||||
{ return vector != 0; }
|
||||
|
||||
T* operator->()
|
||||
{ return (*vector)[index]; }
|
||||
|
||||
T& operator*()
|
||||
{ return *((*vector)[index]); }
|
||||
};*/
|
||||
const AttribType::Info AttribType::data<N>::infos[AttribType::NUM_VALUES] = {
|
||||
{ "SCALAR", 1 },
|
||||
{ "VEC2", 2 },
|
||||
{ "VEC3", 3 },
|
||||
{ "VEC4", 4 },
|
||||
{ "MAT2", 4 },
|
||||
{ "MAT3", 9 },
|
||||
{ "MAT4", 16 }
|
||||
};
|
||||
|
||||
//! Base class for all glTF top-level objects
|
||||
struct Object {
|
||||
|
@ -333,6 +313,7 @@ struct Object {
|
|||
//! Objects marked as special are not exported (used to emulate the binary body buffer)
|
||||
virtual bool IsSpecial() const { return false; }
|
||||
|
||||
Object() = default;
|
||||
virtual ~Object() {}
|
||||
|
||||
//! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
|
||||
|
@ -401,21 +382,19 @@ struct Accessor : public Object {
|
|||
return Indexer(*this);
|
||||
}
|
||||
|
||||
Accessor() {}
|
||||
Accessor() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
|
||||
//! A buffer points to binary geometry, animation, or skins.
|
||||
struct Buffer : public Object {
|
||||
/********************* Types *********************/
|
||||
public:
|
||||
enum Type {
|
||||
Type_arraybuffer,
|
||||
Type_text
|
||||
};
|
||||
|
||||
/// \struct SEncodedRegion
|
||||
/// Descriptor of encoded region in "bufferView".
|
||||
/// @brief Descriptor of encoded region in "bufferView".
|
||||
struct SEncodedRegion {
|
||||
const size_t Offset; ///< Offset from begin of "bufferView" to encoded region, in bytes.
|
||||
const size_t EncodedData_Length; ///< Size of encoded region, in bytes.
|
||||
|
@ -423,8 +402,7 @@ public:
|
|||
const size_t DecodedData_Length; ///< Size of decoded region, in bytes.
|
||||
const std::string ID; ///< ID of the region.
|
||||
|
||||
/// \fn SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
|
||||
/// Constructor.
|
||||
/// @brief Constructor.
|
||||
/// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
|
||||
/// \param [in] pEncodedData_Length - size of encoded region, in bytes.
|
||||
/// \param [in] pDecodedData - pointer to decoded data array.
|
||||
|
@ -433,16 +411,13 @@ public:
|
|||
SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) :
|
||||
Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID) {}
|
||||
|
||||
/// \fn ~SEncodedRegion()
|
||||
/// Destructor.
|
||||
~SEncodedRegion() { delete[] DecodedData; }
|
||||
};
|
||||
|
||||
/******************* Variables *******************/
|
||||
|
||||
//std::string uri; //!< The uri of the buffer. Can be a filepath, a data uri, etc. (required)
|
||||
size_t byteLength; //!< The length of the buffer in bytes. (default: 0)
|
||||
//std::string type; //!< XMLHttpRequest responseType (default: "arraybuffer")
|
||||
|
||||
Type type;
|
||||
|
||||
|
@ -486,7 +461,6 @@ public:
|
|||
|
||||
bool LoadFromStream(IOStream &stream, size_t length = 0, size_t baseOffset = 0);
|
||||
|
||||
/// \fn void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID)
|
||||
/// Mark region of "bufferView" as encoded. When data is request from such region then "bufferView" use decoded data.
|
||||
/// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
|
||||
/// \param [in] pEncodedData_Length - size of encoded region, in bytes.
|
||||
|
@ -495,12 +469,10 @@ public:
|
|||
/// \param [in] pID - ID of the region.
|
||||
void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID);
|
||||
|
||||
/// \fn void EncodedRegion_SetCurrent(const std::string& pID)
|
||||
/// Select current encoded region by ID. \sa EncodedRegion_Current.
|
||||
/// \param [in] pID - ID of the region.
|
||||
void EncodedRegion_SetCurrent(const std::string &pID);
|
||||
|
||||
/// \fn bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
|
||||
/// Replace part of buffer data. Pay attention that function work with original array of data (\ref mData) not with encoded regions.
|
||||
/// \param [in] pBufferData_Offset - index of first element in buffer from which new data will be placed.
|
||||
/// \param [in] pBufferData_Count - count of bytes in buffer which will be replaced.
|
||||
|
@ -558,37 +530,29 @@ struct Camera : public Object {
|
|||
} ortographic;
|
||||
};
|
||||
|
||||
Camera() {}
|
||||
Camera() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
|
||||
//! Image data used to create a texture.
|
||||
struct Image : public Object {
|
||||
std::string uri; //! The uri of the image, that can be a file path, a data URI, etc.. (required)
|
||||
|
||||
Ref<BufferView> bufferView;
|
||||
|
||||
std::string mimeType;
|
||||
|
||||
int width, height;
|
||||
|
||||
private:
|
||||
std::unique_ptr<uint8_t[]> mData;
|
||||
size_t mDataLength;
|
||||
|
||||
public:
|
||||
Image();
|
||||
void Read(Value &obj, Asset &r);
|
||||
|
||||
inline bool HasData() const { return mDataLength > 0; }
|
||||
|
||||
inline size_t GetDataLength() const { return mDataLength; }
|
||||
|
||||
inline const uint8_t *GetData() const { return mData.get(); }
|
||||
|
||||
inline uint8_t *StealData();
|
||||
|
||||
inline void SetData(uint8_t *data, size_t length, Asset &r);
|
||||
|
||||
private:
|
||||
std::unique_ptr<uint8_t[]> mData;
|
||||
size_t mDataLength;
|
||||
};
|
||||
|
||||
//! Holds a material property that can be a texture or a color
|
||||
|
@ -671,6 +635,7 @@ struct Mesh : public Object {
|
|||
};
|
||||
|
||||
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
|
||||
|
||||
/// \struct SCompression_Open3DGC
|
||||
/// Compression of mesh data using Open3DGC algorithm.
|
||||
struct SCompression_Open3DGC : public SExtension {
|
||||
|
@ -703,7 +668,6 @@ struct Mesh : public Object {
|
|||
|
||||
Mesh() {}
|
||||
|
||||
/// \fn ~Mesh()
|
||||
/// Destructor.
|
||||
~Mesh() {
|
||||
for (std::list<SExtension *>::iterator it = Extension.begin(), it_end = Extension.end(); it != it_end; it++) {
|
||||
|
@ -711,15 +675,13 @@ struct Mesh : public Object {
|
|||
};
|
||||
}
|
||||
|
||||
/// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)
|
||||
/// Get mesh data from JSON-object and place them to root asset.
|
||||
/// @brief Get mesh data from JSON-object and place them to root asset.
|
||||
/// \param [in] pJSON_Object - reference to pJSON-object from which data are read.
|
||||
/// \param [out] pAsset_Root - reference to root asset where data will be stored.
|
||||
void Read(Value &pJSON_Object, Asset &pAsset_Root);
|
||||
|
||||
#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
|
||||
/// \fn void Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root)
|
||||
/// Decode part of "buffer" which encoded with Open3DGC algorithm.
|
||||
/// @brief Decode part of "buffer" which encoded with Open3DGC algorithm.
|
||||
/// \param [in] pCompression_Open3DGC - reference to structure which describe encoded region.
|
||||
/// \param [out] pAsset_Root - reference to root assed where data will be stored.
|
||||
void Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DGC, Asset &pAsset_Root);
|
||||
|
@ -759,7 +721,7 @@ struct Sampler : public Object {
|
|||
SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required)
|
||||
SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required)
|
||||
|
||||
Sampler() {}
|
||||
Sampler() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
void SetDefaults();
|
||||
};
|
||||
|
@ -767,12 +729,12 @@ struct Sampler : public Object {
|
|||
struct Scene : public Object {
|
||||
std::vector<Ref<Node>> nodes;
|
||||
|
||||
Scene() {}
|
||||
Scene() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
|
||||
struct Shader : public Object {
|
||||
Shader() {}
|
||||
Shader() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
|
||||
|
@ -782,7 +744,7 @@ struct Skin : public Object {
|
|||
std::vector<Ref<Node>> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin.
|
||||
std::string name; //!< The user-defined name of this object.
|
||||
|
||||
Skin() {}
|
||||
Skin() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
|
||||
|
@ -796,7 +758,7 @@ struct Technique : public Object {
|
|||
struct Functions {
|
||||
};
|
||||
|
||||
Technique() {}
|
||||
Technique() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
|
||||
|
@ -805,13 +767,7 @@ struct Texture : public Object {
|
|||
Ref<Sampler> sampler; //!< The ID of the sampler used by this texture. (required)
|
||||
Ref<Image> source; //!< The ID of the image used by this texture. (required)
|
||||
|
||||
//TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA)
|
||||
//TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA)
|
||||
|
||||
//TextureTarget target; //!< The target that the WebGL texture should be bound to. (default: TextureTarget_TEXTURE_2D)
|
||||
//TextureType type; //!< Texel datatype. (default: TextureType_UNSIGNED_BYTE)
|
||||
|
||||
Texture() {}
|
||||
Texture() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
|
||||
|
@ -826,7 +782,6 @@ struct Light : public Object {
|
|||
};
|
||||
|
||||
Type type;
|
||||
|
||||
vec4 color;
|
||||
float distance;
|
||||
float constantAttenuation;
|
||||
|
@ -835,9 +790,8 @@ struct Light : public Object {
|
|||
float falloffAngle;
|
||||
float falloffExponent;
|
||||
|
||||
Light() {}
|
||||
Light() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
|
||||
void SetDefaults();
|
||||
};
|
||||
|
||||
|
@ -865,15 +819,11 @@ struct Animation : public Object {
|
|||
Ref<Accessor> translation; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
|
||||
};
|
||||
|
||||
// AnimChannel Channels[3]; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
|
||||
// AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
|
||||
// AnimSampler Samplers[3]; //!< The parameterized inputs representing the key-frame data.
|
||||
|
||||
std::vector<AnimChannel> Channels; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
|
||||
AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
|
||||
std::vector<AnimSampler> Samplers; //!< The parameterized inputs representing the key-frame data.
|
||||
|
||||
Animation() {}
|
||||
Animation() = default;
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
|
||||
|
@ -963,13 +913,11 @@ struct AssetMetadata {
|
|||
|
||||
//! Root object for a glTF asset
|
||||
class Asset {
|
||||
typedef std::gltf_unordered_map<std::string, int> IdMap;
|
||||
using IdMap = std::gltf_unordered_map<std::string, int>;
|
||||
|
||||
template <class T>
|
||||
friend class LazyDict;
|
||||
|
||||
friend struct Buffer; // To access OpenFile
|
||||
|
||||
friend class AssetWriter;
|
||||
|
||||
private:
|
||||
|
@ -1010,12 +958,9 @@ public:
|
|||
LazyDict<Material> materials;
|
||||
LazyDict<Mesh> meshes;
|
||||
LazyDict<Node> nodes;
|
||||
//LazyDict<Program> programs;
|
||||
LazyDict<Sampler> samplers;
|
||||
LazyDict<Scene> scenes;
|
||||
//LazyDict<Shader> shaders;
|
||||
LazyDict<Skin> skins;
|
||||
//LazyDict<Technique> techniques;
|
||||
LazyDict<Texture> textures;
|
||||
|
||||
LazyDict<Light> lights; // KHR_materials_common ext
|
||||
|
@ -1024,16 +969,20 @@ public:
|
|||
|
||||
public:
|
||||
Asset(IOSystem *io = 0) :
|
||||
mIOSystem(io), asset(), accessors(*this, "accessors"), animations(*this, "animations"), buffers(*this, "buffers"), bufferViews(*this, "bufferViews"), cameras(*this, "cameras"), images(*this, "images"), materials(*this, "materials"), meshes(*this, "meshes"), nodes(*this, "nodes")
|
||||
//, programs (*this, "programs")
|
||||
,
|
||||
mIOSystem(io),
|
||||
asset(),
|
||||
accessors(*this, "accessors"),
|
||||
animations(*this, "animations"),
|
||||
buffers(*this, "buffers"),
|
||||
bufferViews(*this, "bufferViews"),
|
||||
cameras(*this, "cameras"),
|
||||
images(*this, "images"),
|
||||
materials(*this, "materials"),
|
||||
meshes(*this, "meshes"),
|
||||
nodes(*this, "nodes"),
|
||||
samplers(*this, "samplers"),
|
||||
scenes(*this, "scenes")
|
||||
//, shaders (*this, "shaders")
|
||||
,
|
||||
skins(*this, "skins")
|
||||
//, techniques (*this, "techniques")
|
||||
,
|
||||
scenes(*this, "scenes"),
|
||||
skins(*this, "skins"),
|
||||
textures(*this, "textures"),
|
||||
lights(*this, "lights", "KHR_materials_common") {
|
||||
memset(&extensionsUsed, 0, sizeof(extensionsUsed));
|
||||
|
|
|
@ -237,8 +237,6 @@ bool ParseDataURI(const char *const_uri, size_t uriLen, DataURI &out);
|
|||
#define CHECK_EXT(EXT) \
|
||||
if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
|
||||
|
||||
|
||||
|
||||
//! Helper struct to represent values that might not be present
|
||||
template <class T>
|
||||
struct Nullable {
|
||||
|
|
|
@ -1087,29 +1087,11 @@ class Asset {
|
|||
|
||||
template <class T>
|
||||
friend class LazyDict;
|
||||
|
||||
friend struct Buffer; // To access OpenFile
|
||||
|
||||
friend class AssetWriter;
|
||||
|
||||
private:
|
||||
IOSystem *mIOSystem;
|
||||
rapidjson::IRemoteSchemaDocumentProvider *mSchemaDocumentProvider;
|
||||
|
||||
std::string mCurrentAssetDir;
|
||||
|
||||
size_t mSceneLength;
|
||||
size_t mBodyOffset, mBodyLength;
|
||||
|
||||
std::vector<LazyDictBase *> mDicts;
|
||||
|
||||
IdMap mUsedIds;
|
||||
|
||||
Ref<Buffer> mBodyBuffer;
|
||||
|
||||
Asset(Asset &);
|
||||
Asset &operator=(const Asset &);
|
||||
|
||||
public:
|
||||
//! Keeps info about the enabled extensions
|
||||
struct Extensions {
|
||||
|
@ -1125,16 +1107,36 @@ public:
|
|||
bool KHR_draco_mesh_compression;
|
||||
bool FB_ngon_encoding;
|
||||
bool KHR_texture_basisu;
|
||||
|
||||
Extensions() :
|
||||
KHR_materials_pbrSpecularGlossiness(false),
|
||||
KHR_materials_unlit(false),
|
||||
KHR_lights_punctual(false),
|
||||
KHR_texture_transform(false),
|
||||
KHR_materials_sheen(false),
|
||||
KHR_materials_clearcoat(false),
|
||||
KHR_materials_transmission(false),
|
||||
KHR_materials_volume(false),
|
||||
KHR_materials_ior(false),
|
||||
KHR_draco_mesh_compression(false),
|
||||
FB_ngon_encoding(false),
|
||||
KHR_texture_basisu(false) {
|
||||
// empty
|
||||
}
|
||||
} extensionsUsed;
|
||||
|
||||
//! Keeps info about the required extensions
|
||||
struct RequiredExtensions {
|
||||
bool KHR_draco_mesh_compression;
|
||||
bool KHR_texture_basisu;
|
||||
|
||||
RequiredExtensions() : KHR_draco_mesh_compression(false), KHR_texture_basisu(false) {
|
||||
// empty
|
||||
}
|
||||
} extensionsRequired;
|
||||
|
||||
AssetMetadata asset;
|
||||
Value *extras = nullptr;
|
||||
Value *extras;
|
||||
|
||||
// Dictionaries for each type of object
|
||||
|
||||
|
@ -1157,9 +1159,11 @@ public:
|
|||
|
||||
public:
|
||||
Asset(IOSystem *io = nullptr, rapidjson::IRemoteSchemaDocumentProvider *schemaDocumentProvider = nullptr) :
|
||||
mIOSystem(io),
|
||||
mSchemaDocumentProvider(schemaDocumentProvider),
|
||||
mDicts(),
|
||||
extensionsUsed(),
|
||||
extensionsRequired(),
|
||||
asset(),
|
||||
extras(nullptr),
|
||||
accessors(*this, "accessors"),
|
||||
animations(*this, "animations"),
|
||||
buffers(*this, "buffers"),
|
||||
|
@ -1173,9 +1177,10 @@ public:
|
|||
samplers(*this, "samplers"),
|
||||
scenes(*this, "scenes"),
|
||||
skins(*this, "skins"),
|
||||
textures(*this, "textures") {
|
||||
memset(&extensionsUsed, 0, sizeof(extensionsUsed));
|
||||
memset(&extensionsRequired, 0, sizeof(extensionsRequired));
|
||||
textures(*this, "textures") ,
|
||||
mIOSystem(io),
|
||||
mSchemaDocumentProvider(schemaDocumentProvider) {
|
||||
// empty
|
||||
}
|
||||
|
||||
//! Main function
|
||||
|
@ -1192,18 +1197,31 @@ public:
|
|||
|
||||
Ref<Buffer> GetBodyBuffer() { return mBodyBuffer; }
|
||||
|
||||
Asset(Asset &) = delete;
|
||||
Asset &operator=(const Asset &) = delete;
|
||||
|
||||
private:
|
||||
void ReadBinaryHeader(IOStream &stream, std::vector<char> &sceneData);
|
||||
|
||||
//! Obtain a JSON document from the stream.
|
||||
// \param second argument is a buffer used by the document. It must be kept
|
||||
// alive while the document is in use.
|
||||
/// Obtain a JSON document from the stream.
|
||||
/// \param second argument is a buffer used by the document. It must be kept
|
||||
/// alive while the document is in use.
|
||||
Document ReadDocument(IOStream& stream, bool isBinary, std::vector<char>& sceneData);
|
||||
|
||||
void ReadExtensionsUsed(Document &doc);
|
||||
void ReadExtensionsRequired(Document &doc);
|
||||
|
||||
IOStream *OpenFile(const std::string &path, const char *mode, bool absolute = false);
|
||||
|
||||
private:
|
||||
IOSystem *mIOSystem;
|
||||
rapidjson::IRemoteSchemaDocumentProvider *mSchemaDocumentProvider;
|
||||
std::string mCurrentAssetDir;
|
||||
size_t mSceneLength;
|
||||
size_t mBodyOffset;
|
||||
size_t mBodyLength;
|
||||
IdMap mUsedIds;
|
||||
Ref<Buffer> mBodyBuffer;
|
||||
};
|
||||
|
||||
inline std::string getContextForErrorMessages(const std::string &id, const std::string &name) {
|
||||
|
|
|
@ -515,7 +515,10 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, float &prop, const char
|
|||
}
|
||||
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) {
|
||||
if (mat.GetTextureCount(tt) > 0) {
|
||||
if (mat.GetTextureCount(tt) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
aiString tex;
|
||||
|
||||
// Read texcoord (UV map index)
|
||||
|
@ -583,17 +586,11 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsi
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial &mat, TextureInfo &prop, aiTextureType tt, unsigned int slot = 0) {
|
||||
Ref<Texture> &texture = prop.texture;
|
||||
|
||||
GetMatTex(mat, texture, prop.texCoord, tt, slot);
|
||||
|
||||
//if (texture) {
|
||||
// GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
|
||||
//}
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, aiTextureType tt, unsigned int slot = 0) {
|
||||
|
@ -681,12 +678,14 @@ bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlo
|
|||
|
||||
bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) {
|
||||
// Return true if got any valid Sheen properties or textures
|
||||
if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS)
|
||||
if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Default Sheen color factor {0,0,0} disables Sheen, so do not export
|
||||
if (sheen.sheenColorFactor == defaultSheenFactor)
|
||||
if (sheen.sheenColorFactor == defaultSheenFactor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mat.Get(AI_MATKEY_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
|
||||
|
||||
|
@ -781,9 +780,7 @@ void glTF2Exporter::ExportMaterials() {
|
|||
aiColor4D specularColor;
|
||||
ai_real shininess;
|
||||
|
||||
if (
|
||||
mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS &&
|
||||
mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
|
||||
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS && mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
|
||||
// convert specular color to luminance
|
||||
float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
|
||||
//normalize shininess (assuming max is 1000) with an inverse exponentional curve
|
||||
|
@ -916,7 +913,8 @@ Ref<Node> FindSkeletonRootJoint(Ref<Skin> &skinRef) {
|
|||
return parentNodeRef;
|
||||
}
|
||||
|
||||
void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buffer> &bufferRef, Ref<Skin> &skinRef, std::vector<aiMatrix4x4> &inverseBindMatricesData) {
|
||||
void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buffer> &bufferRef, Ref<Skin> &skinRef,
|
||||
std::vector<aiMatrix4x4> &inverseBindMatricesData) {
|
||||
if (aimesh->mNumBones < 1) {
|
||||
return;
|
||||
}
|
||||
|
@ -986,7 +984,8 @@ void ExportSkin(Asset &mAsset, const aiMesh *aimesh, Ref<Mesh> &meshRef, Ref<Buf
|
|||
} // End: for-loop mNumMeshes
|
||||
|
||||
Mesh::Primitive &p = meshRef->primitives.back();
|
||||
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices,
|
||||
vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
if (vertexJointAccessor) {
|
||||
size_t offset = vertexJointAccessor->bufferView->byteOffset;
|
||||
size_t bytesLen = vertexJointAccessor->bufferView->byteLength;
|
||||
|
@ -1069,8 +1068,11 @@ void glTF2Exporter::ExportMeshes() {
|
|||
p.ngonEncoded = (aim->mPrimitiveTypes & aiPrimitiveType_NGONEncodingFlag) != 0;
|
||||
|
||||
/******************* Vertices ********************/
|
||||
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||
if (v) p.attributes.position.push_back(v);
|
||||
Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3,
|
||||
AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||
if (v) {
|
||||
p.attributes.position.push_back(v);
|
||||
}
|
||||
|
||||
/******************** Normals ********************/
|
||||
// Normalize all normals as the validator can emit a warning otherwise
|
||||
|
@ -1080,13 +1082,17 @@ void glTF2Exporter::ExportMeshes() {
|
|||
}
|
||||
}
|
||||
|
||||
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||
if (n) p.attributes.normal.push_back(n);
|
||||
Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3,
|
||||
AttribType::VEC3, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||
if (n) {
|
||||
p.attributes.normal.push_back(n);
|
||||
}
|
||||
|
||||
/************** Texture coordinates **************/
|
||||
for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||
if (!aim->HasTextureCoords(i))
|
||||
if (!aim->HasTextureCoords(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Flip UV y coords
|
||||
if (aim->mNumUVComponents[i] > 1) {
|
||||
|
@ -1098,17 +1104,22 @@ void glTF2Exporter::ExportMeshes() {
|
|||
if (aim->mNumUVComponents[i] > 0) {
|
||||
AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
|
||||
|
||||
Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||
if (tc) p.attributes.texcoord.push_back(tc);
|
||||
Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i],
|
||||
AttribType::VEC3, type, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||
if (tc) {
|
||||
p.attributes.texcoord.push_back(tc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************** Vertex colors ****************/
|
||||
for (unsigned int indexColorChannel = 0; indexColorChannel < aim->GetNumColorChannels(); ++indexColorChannel) {
|
||||
Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel], AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||
if (c)
|
||||
Ref<Accessor> c = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mColors[indexColorChannel],
|
||||
AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT, BufferViewTarget_ARRAY_BUFFER);
|
||||
if (c) {
|
||||
p.attributes.color.push_back(c);
|
||||
}
|
||||
}
|
||||
|
||||
/*************** Vertices indices ****************/
|
||||
if (aim->mNumFaces > 0) {
|
||||
|
@ -1121,7 +1132,8 @@ void glTF2Exporter::ExportMeshes() {
|
|||
}
|
||||
}
|
||||
|
||||
p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
|
||||
p.indices = ExportData(*mAsset, meshId, b, indices.size(), &indices[0], AttribType::SCALAR, AttribType::SCALAR,
|
||||
ComponentType_UNSIGNED_INT, BufferViewTarget_ELEMENT_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
switch (aim->mPrimitiveTypes) {
|
||||
|
@ -1136,6 +1148,7 @@ void glTF2Exporter::ExportMeshes() {
|
|||
break;
|
||||
default: // aiPrimitiveType_TRIANGLE
|
||||
p.mode = PrimitiveMode_TRIANGLES;
|
||||
break;
|
||||
}
|
||||
|
||||
/*************** Skins ****************/
|
||||
|
@ -1155,8 +1168,9 @@ void glTF2Exporter::ExportMeshes() {
|
|||
p.targets.resize(aim->mNumAnimMeshes);
|
||||
for (unsigned int am = 0; am < aim->mNumAnimMeshes; ++am) {
|
||||
aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am];
|
||||
if (bExportTargetNames)
|
||||
m->targetNames.push_back(pAnimMesh->mName.data);
|
||||
if (bExportTargetNames) {
|
||||
m->targetNames.emplace_back(pAnimMesh->mName.data);
|
||||
}
|
||||
// position
|
||||
if (pAnimMesh->HasPositions()) {
|
||||
// NOTE: in gltf it is the diff stored
|
||||
|
@ -1319,12 +1333,12 @@ unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode *n) {
|
|||
}
|
||||
|
||||
for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
|
||||
node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
|
||||
node->meshes.emplace_back(mAsset->meshes.Get(n->mMeshes[i]));
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
||||
unsigned int idx = ExportNode(n->mChildren[i], node);
|
||||
node->children.push_back(mAsset->nodes.Get(idx));
|
||||
node->children.emplace_back(mAsset->nodes.Get(idx));
|
||||
}
|
||||
|
||||
return node.GetIndex();
|
||||
|
@ -1366,12 +1380,12 @@ unsigned int glTF2Exporter::ExportNode(const aiNode *n, Ref<Node> &parent) {
|
|||
}
|
||||
|
||||
for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
|
||||
node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
|
||||
node->meshes.emplace_back(mAsset->meshes.Get(n->mMeshes[i]));
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
||||
unsigned int idx = ExportNode(n->mChildren[i], node);
|
||||
node->children.push_back(mAsset->nodes.Get(idx));
|
||||
node->children.emplace_back(mAsset->nodes.Get(idx));
|
||||
}
|
||||
|
||||
return node.GetIndex();
|
||||
|
@ -1386,7 +1400,7 @@ void glTF2Exporter::ExportScene() {
|
|||
|
||||
// root node will be the first one exported (idx 0)
|
||||
if (mAsset->nodes.Size() > 0) {
|
||||
scene->nodes.push_back(mAsset->nodes.Get(0u));
|
||||
scene->nodes.emplace_back(mAsset->nodes.Get(0u));
|
||||
}
|
||||
|
||||
// set as the default scene
|
||||
|
@ -1521,12 +1535,6 @@ void glTF2Exporter::ExportAnimations() {
|
|||
AddSampler(animRef, animNode, scaleSampler, AnimationPath_SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
// Assimp documentation states this is not used (not implemented)
|
||||
// for (unsigned int channelIndex = 0; channelIndex < anim->mNumMeshChannels; ++channelIndex) {
|
||||
// const aiMeshAnim* meshChannel = anim->mMeshChannels[channelIndex];
|
||||
// }
|
||||
|
||||
} // End: for-loop mNumAnimations
|
||||
}
|
||||
|
||||
|
|
|
@ -166,6 +166,8 @@ SET( Logging_SRCS
|
|||
SOURCE_GROUP(Logging FILES ${Logging_SRCS})
|
||||
|
||||
SET( Common_SRCS
|
||||
Common/Compression.cpp
|
||||
Common/Compression.h
|
||||
Common/BaseImporter.cpp
|
||||
Common/BaseProcess.cpp
|
||||
Common/BaseProcess.h
|
||||
|
@ -1315,11 +1317,10 @@ ENDIF ()
|
|||
|
||||
INSTALL( TARGETS assimp
|
||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
|
||||
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
|
||||
COMPONENT ${LIBASSIMP_COMPONENT}
|
||||
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT}
|
||||
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP-DEV_COMPONENT}
|
||||
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT}
|
||||
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT}
|
||||
INCLUDES DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}
|
||||
)
|
||||
INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2021, assimp team
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -57,7 +57,7 @@ static const uint8_t tableDecodeBase64[128] = {
|
|||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const char* tableEncodeBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
static const char *tableEncodeBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
|
||||
static inline char EncodeChar(uint8_t b) {
|
||||
return tableEncodeBase64[size_t(b)];
|
||||
|
@ -104,17 +104,16 @@ void Encode(const uint8_t *in, size_t inLength, std::string &out) {
|
|||
}
|
||||
}
|
||||
|
||||
void Encode(const std::vector<uint8_t>& in, std::string &out) {
|
||||
Encode (in.data (), in.size (), out);
|
||||
void Encode(const std::vector<uint8_t> &in, std::string &out) {
|
||||
Encode(in.data(), in.size(), out);
|
||||
}
|
||||
|
||||
std::string Encode (const std::vector<uint8_t>& in) {
|
||||
std::string Encode(const std::vector<uint8_t> &in) {
|
||||
std::string encoded;
|
||||
Encode (in, encoded);
|
||||
Encode(in, encoded);
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
size_t Decode(const char *in, size_t inLength, uint8_t *&out) {
|
||||
if (inLength % 4 != 0) {
|
||||
throw DeadlyImportError("Invalid base64 encoded data: \"", std::string(in, std::min(size_t(32), inLength)), "\", length:", inLength);
|
||||
|
@ -159,23 +158,22 @@ size_t Decode(const char *in, size_t inLength, uint8_t *&out) {
|
|||
return outLength;
|
||||
}
|
||||
|
||||
size_t Decode(const std::string& in, std::vector<uint8_t>& out) {
|
||||
uint8_t* outPtr = nullptr;
|
||||
size_t decodedSize = Decode (in.data (), in.size (), outPtr);
|
||||
size_t Decode(const std::string &in, std::vector<uint8_t> &out) {
|
||||
uint8_t *outPtr = nullptr;
|
||||
size_t decodedSize = Decode(in.data(), in.size(), outPtr);
|
||||
if (outPtr == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
out.assign (outPtr, outPtr + decodedSize);
|
||||
out.assign(outPtr, outPtr + decodedSize);
|
||||
delete[] outPtr;
|
||||
return decodedSize;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Decode (const std::string& in) {
|
||||
std::vector<uint8_t> Decode(const std::string &in) {
|
||||
std::vector<uint8_t> result;
|
||||
Decode (in, result);
|
||||
Decode(in, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace Base64
|
||||
} // namespace Assimp
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, 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 "Compression.h"
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/Exceptional.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
struct Compression::impl {
|
||||
bool mOpen;
|
||||
z_stream mZSstream;
|
||||
FlushMode mFlushMode;
|
||||
|
||||
impl() :
|
||||
mOpen(false),
|
||||
mZSstream(),
|
||||
mFlushMode(Compression::FlushMode::NoFlush) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
Compression::Compression() :
|
||||
mImpl(new impl) {
|
||||
// empty
|
||||
}
|
||||
|
||||
Compression::~Compression() {
|
||||
ai_assert(mImpl != nullptr);
|
||||
|
||||
delete mImpl;
|
||||
}
|
||||
|
||||
bool Compression::open(Format format, FlushMode flush, int windowBits) {
|
||||
ai_assert(mImpl != nullptr);
|
||||
|
||||
if (mImpl->mOpen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// build a zlib stream
|
||||
mImpl->mZSstream.opaque = Z_NULL;
|
||||
mImpl->mZSstream.zalloc = Z_NULL;
|
||||
mImpl->mZSstream.zfree = Z_NULL;
|
||||
mImpl->mFlushMode = flush;
|
||||
if (format == Format::Binary) {
|
||||
mImpl->mZSstream.data_type = Z_BINARY;
|
||||
} else {
|
||||
mImpl->mZSstream.data_type = Z_ASCII;
|
||||
}
|
||||
|
||||
// raw decompression without a zlib or gzip header
|
||||
if (windowBits == 0) {
|
||||
inflateInit(&mImpl->mZSstream);
|
||||
} else {
|
||||
inflateInit2(&mImpl->mZSstream, windowBits);
|
||||
}
|
||||
mImpl->mOpen = true;
|
||||
|
||||
return mImpl->mOpen;
|
||||
}
|
||||
|
||||
static int getFlushMode(Compression::FlushMode flush) {
|
||||
int z_flush = 0;
|
||||
switch (flush) {
|
||||
case Compression::FlushMode::NoFlush:
|
||||
z_flush = Z_NO_FLUSH;
|
||||
break;
|
||||
case Compression::FlushMode::Block:
|
||||
z_flush = Z_BLOCK;
|
||||
break;
|
||||
case Compression::FlushMode::Tree:
|
||||
z_flush = Z_TREES;
|
||||
break;
|
||||
case Compression::FlushMode::SyncFlush:
|
||||
z_flush = Z_SYNC_FLUSH;
|
||||
break;
|
||||
case Compression::FlushMode::Finish:
|
||||
z_flush = Z_FINISH;
|
||||
break;
|
||||
default:
|
||||
ai_assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return z_flush;
|
||||
}
|
||||
|
||||
constexpr size_t MYBLOCK = 32786;
|
||||
|
||||
size_t Compression::decompress(const void *data, size_t in, std::vector<char> &uncompressed) {
|
||||
ai_assert(mImpl != nullptr);
|
||||
if (data == nullptr || in == 0) {
|
||||
return 0l;
|
||||
}
|
||||
|
||||
mImpl->mZSstream.next_in = (Bytef*)(data);
|
||||
mImpl->mZSstream.avail_in = (uInt)in;
|
||||
|
||||
int ret = 0;
|
||||
size_t total = 0l;
|
||||
const int flushMode = getFlushMode(mImpl->mFlushMode);
|
||||
if (flushMode == Z_FINISH) {
|
||||
mImpl->mZSstream.avail_out = static_cast<uInt>(uncompressed.size());
|
||||
mImpl->mZSstream.next_out = reinterpret_cast<Bytef *>(&*uncompressed.begin());
|
||||
ret = inflate(&mImpl->mZSstream, Z_FINISH);
|
||||
|
||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
||||
throw DeadlyImportError("Compression", "Failure decompressing this file using gzip.");
|
||||
}
|
||||
total = mImpl->mZSstream.avail_out;
|
||||
} else {
|
||||
do {
|
||||
Bytef block[MYBLOCK] = {};
|
||||
mImpl->mZSstream.avail_out = MYBLOCK;
|
||||
mImpl->mZSstream.next_out = block;
|
||||
|
||||
ret = inflate(&mImpl->mZSstream, flushMode);
|
||||
|
||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
||||
throw DeadlyImportError("Compression", "Failure decompressing this file using gzip.");
|
||||
}
|
||||
const size_t have = MYBLOCK - mImpl->mZSstream.avail_out;
|
||||
total += have;
|
||||
uncompressed.resize(total);
|
||||
::memcpy(uncompressed.data() + total - have, block, have);
|
||||
} while (ret != Z_STREAM_END);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
size_t Compression::decompressBlock(const void *data, size_t in, char *out, size_t availableOut) {
|
||||
ai_assert(mImpl != nullptr);
|
||||
if (data == nullptr || in == 0 || out == nullptr || availableOut == 0) {
|
||||
return 0l;
|
||||
}
|
||||
|
||||
// push data to the stream
|
||||
mImpl->mZSstream.next_in = (Bytef *)data;
|
||||
mImpl->mZSstream.avail_in = (uInt)in;
|
||||
mImpl->mZSstream.next_out = (Bytef *)out;
|
||||
mImpl->mZSstream.avail_out = (uInt)availableOut;
|
||||
|
||||
// and decompress the data ....
|
||||
int ret = ::inflate(&mImpl->mZSstream, Z_SYNC_FLUSH);
|
||||
if (ret != Z_OK && ret != Z_STREAM_END) {
|
||||
throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
|
||||
}
|
||||
|
||||
::inflateReset(&mImpl->mZSstream);
|
||||
::inflateSetDictionary(&mImpl->mZSstream, (const Bytef *)out, (uInt)availableOut - mImpl->mZSstream.avail_out);
|
||||
|
||||
return availableOut - (size_t)mImpl->mZSstream.avail_out;
|
||||
}
|
||||
|
||||
bool Compression::isOpen() const {
|
||||
ai_assert(mImpl != nullptr);
|
||||
|
||||
return mImpl->mOpen;
|
||||
}
|
||||
|
||||
bool Compression::close() {
|
||||
ai_assert(mImpl != nullptr);
|
||||
|
||||
if (!mImpl->mOpen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inflateEnd(&mImpl->mZSstream);
|
||||
mImpl->mOpen = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Assimp
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, 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
|
||||
|
||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||
#include <zlib.h>
|
||||
#else
|
||||
#include "../contrib/zlib/zlib.h"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <cstddef> // size_t
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
/// @brief This class provides the decompression of zlib-compressed data.
|
||||
class Compression {
|
||||
public:
|
||||
static const int MaxWBits = MAX_WBITS;
|
||||
|
||||
/// @brief Describes the format data type
|
||||
enum class Format {
|
||||
InvalidFormat = -1, ///< Invalid enum type.
|
||||
Binary = 0, ///< Binary format.
|
||||
ASCII, ///< ASCII format.
|
||||
|
||||
NumFormats ///< The number of supported formats.
|
||||
};
|
||||
|
||||
/// @brief The supported flush mode, used for blocked access.
|
||||
enum class FlushMode {
|
||||
InvalidFormat = -1, ///< Invalid enum type.
|
||||
NoFlush = 0, ///< No flush, will be done on inflate end.
|
||||
Block, ///< Assists in combination of compress.
|
||||
Tree, ///< Assists in combination of compress and returns if stream is finish.
|
||||
SyncFlush, ///< Synced flush mode.
|
||||
Finish, ///< Finish mode, all in once, no block access.
|
||||
|
||||
NumModes ///< The number of supported modes.
|
||||
};
|
||||
|
||||
/// @brief The class constructor.
|
||||
Compression();
|
||||
|
||||
/// @brief The class destructor.
|
||||
~Compression();
|
||||
|
||||
/// @brief Will open the access to the compression.
|
||||
/// @param[in] format The format type
|
||||
/// @param[in] flush The flush mode.
|
||||
/// @param[in] windowBits The windows history working size, shall be between 8 and 15.
|
||||
/// @return true if close was successful, false if not.
|
||||
bool open(Format format, FlushMode flush, int windowBits);
|
||||
|
||||
/// @brief Will return the open state.
|
||||
/// @return true if the access is opened, false if not.
|
||||
bool isOpen() const;
|
||||
|
||||
/// @brief Will close the decompress access.
|
||||
/// @return true if close was successful, false if not.
|
||||
bool close();
|
||||
|
||||
/// @brief Will decompress the data buffer in one step.
|
||||
/// @param[in] data The data to decompress
|
||||
/// @param[in] in The size of the data.
|
||||
/// @param[out uncompressed A std::vector containing the decompressed data.
|
||||
size_t decompress(const void *data, size_t in, std::vector<char> &uncompressed);
|
||||
|
||||
/// @brief Will decompress the data buffer block-wise.
|
||||
/// @param[in] data The compressed data
|
||||
/// @param[in] in The size of the data buffer
|
||||
/// @param[out] out The output buffer
|
||||
/// @param[out] availableOut The upper limit of the output buffer.
|
||||
/// @return The size of the decompressed data buffer.
|
||||
size_t decompressBlock(const void *data, size_t in, char *out, size_t availableOut);
|
||||
|
||||
private:
|
||||
struct impl;
|
||||
impl *mImpl;
|
||||
};
|
||||
|
||||
} // namespace Assimp
|
|
@ -3,7 +3,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2019, assimp team
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -53,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
static const char *LEGAL_INFORMATION =
|
||||
"Open Asset Import Library (Assimp).\n"
|
||||
"A free C/C++ library to import various 3D file formats into applications\n\n"
|
||||
"(c) 2006-2021, Assimp team\n"
|
||||
"(c) 2006-2022, Assimp team\n"
|
||||
"License under the terms and conditions of the 3-clause BSD license\n"
|
||||
"https://www.assimp.org\n";
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -191,9 +191,9 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) {
|
|||
tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
|
||||
tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
|
||||
tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
|
||||
bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
|
||||
bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
|
||||
bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
|
||||
bitangent.x = (- w.x * sx + v.x * tx) * dirCorrection;
|
||||
bitangent.y = (- w.y * sx + v.y * tx) * dirCorrection;
|
||||
bitangent.z = (- w.z * sx + v.z * tx) * dirCorrection;
|
||||
|
||||
// store for every vertex of that face
|
||||
for (unsigned int b = 0; b < face.mNumIndices; ++b) {
|
||||
|
@ -201,7 +201,7 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) {
|
|||
|
||||
// project tangent and bitangent into the plane formed by the vertex' normal
|
||||
aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
|
||||
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
|
||||
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]) - localTangent * (bitangent * localTangent);
|
||||
localTangent.NormalizeSafe();
|
||||
localBitangent.NormalizeSafe();
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
|
|||
if ( mConfigCheckAreaOfTriangle ) {
|
||||
if ( face.mNumIndices == 3 ) {
|
||||
ai_real area = calculateAreaOfTriangle( face, mesh );
|
||||
if ( area < 1e-6 ) {
|
||||
if (area < ai_epsilon) {
|
||||
if ( mConfigRemoveDegenerates ) {
|
||||
remove_me[ a ] = true;
|
||||
++deg;
|
||||
|
|
|
@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace Base64 {
|
||||
|
||||
/// @brief Will encode the given
|
||||
/// @param in
|
||||
/// @param inLength
|
||||
/// @param out
|
||||
void Encode(const uint8_t *in, size_t inLength, std::string &out);
|
||||
void Encode(const std::vector<uint8_t>& in, std::string &out);
|
||||
std::string Encode(const std::vector<uint8_t>& in);
|
||||
|
|
|
@ -211,7 +211,7 @@ template <typename T> struct ByteSwap::_swapper<T,8> {
|
|||
// --------------------------------------------------------------------------------------
|
||||
#if (defined AI_BUILD_BIG_ENDIAN)
|
||||
# define AI_LE(t) (t)
|
||||
# define AI_BE(t) ByteSwap::Swapped(t)
|
||||
# define AI_BE(t) Assimp::ByteSwap::Swapped(t)
|
||||
# define AI_LSWAP2(p)
|
||||
# define AI_LSWAP4(p)
|
||||
# define AI_LSWAP8(p)
|
||||
|
@ -219,16 +219,16 @@ template <typename T> struct ByteSwap::_swapper<T,8> {
|
|||
# define AI_LSWAP4P(p)
|
||||
# define AI_LSWAP8P(p)
|
||||
# define LE_NCONST const
|
||||
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
|
||||
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
|
||||
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
|
||||
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
|
||||
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
|
||||
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
|
||||
# define AI_SWAP2(p) Assimp::ByteSwap::Swap2(&(p))
|
||||
# define AI_SWAP4(p) Assimp::ByteSwap::Swap4(&(p))
|
||||
# define AI_SWAP8(p) Assimp::ByteSwap::Swap8(&(p))
|
||||
# define AI_SWAP2P(p) Assimp::ByteSwap::Swap2((p))
|
||||
# define AI_SWAP4P(p) Assimp::ByteSwap::Swap4((p))
|
||||
# define AI_SWAP8P(p) Assimp::ByteSwap::Swap8((p))
|
||||
# define BE_NCONST
|
||||
#else
|
||||
# define AI_BE(t) (t)
|
||||
# define AI_LE(t) ByteSwap::Swapped(t)
|
||||
# define AI_LE(t) Assimp::ByteSwap::Swapped(t)
|
||||
# define AI_SWAP2(p)
|
||||
# define AI_SWAP4(p)
|
||||
# define AI_SWAP8(p)
|
||||
|
@ -236,12 +236,12 @@ template <typename T> struct ByteSwap::_swapper<T,8> {
|
|||
# define AI_SWAP4P(p)
|
||||
# define AI_SWAP8P(p)
|
||||
# define BE_NCONST const
|
||||
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
|
||||
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
|
||||
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
|
||||
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
|
||||
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
|
||||
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
|
||||
# define AI_LSWAP2(p) Assimp::ByteSwap::Swap2(&(p))
|
||||
# define AI_LSWAP4(p) Assimp::ByteSwap::Swap4(&(p))
|
||||
# define AI_LSWAP8(p) Assimp::ByteSwap::Swap8(&(p))
|
||||
# define AI_LSWAP2P(p) Assimp::ByteSwap::Swap2((p))
|
||||
# define AI_LSWAP4P(p) Assimp::ByteSwap::Swap4((p))
|
||||
# define AI_LSWAP8P(p) Assimp::ByteSwap::Swap8((p))
|
||||
# define LE_NCONST
|
||||
#endif
|
||||
|
||||
|
|
|
@ -98,10 +98,6 @@ public:
|
|||
DeadlyErrorBase(Assimp::Formatter::format(), std::forward<T>(args)...) {
|
||||
// empty
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && defined(__clang__)
|
||||
DeadlyImportError(DeadlyImportError& other) = delete;
|
||||
#endif
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -114,10 +110,6 @@ public:
|
|||
template<typename... T>
|
||||
explicit DeadlyExportError(T&&... args) :
|
||||
DeadlyErrorBase(Assimp::Formatter::format(), std::forward<T>(args)...) {}
|
||||
|
||||
#if defined(_MSC_VER) && defined(__clang__)
|
||||
DeadlyExportError(DeadlyExportError& other) = delete;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
|||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -76,6 +75,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) {
|
||||
uint32_t tmp;
|
||||
int rem;
|
||||
size_t offset;
|
||||
|
||||
if (!data) return 0;
|
||||
if (!len)len = (uint32_t)::strlen(data);
|
||||
|
@ -96,7 +96,11 @@ int rem;
|
|||
switch (rem) {
|
||||
case 3: hash += get16bits (data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= data[sizeof (uint16_t)] << 18;
|
||||
offset = static_cast<size_t>(sizeof(uint16_t));
|
||||
if (offset < 0) {
|
||||
return 0;
|
||||
}
|
||||
hash ^= data[offset] << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += get16bits (data);
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, 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.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file OBJMATERIAL.h
|
||||
* @brief Obj-specific material macros
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AI_OBJMATERIAL_H_INC
|
||||
#define AI_OBJMATERIAL_H_INC
|
||||
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#include <assimp/material.h>
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// the original illum property
|
||||
#define AI_MATKEY_OBJ_ILLUM "$mat.illum", 0, 0
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Pure key names for all obj texture-related properties
|
||||
//! @cond MATS_DOC_FULL
|
||||
|
||||
// support for bump -bm
|
||||
#define _AI_MATKEY_OBJ_BUMPMULT_BASE "$tex.bumpmult"
|
||||
//! @endcond
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
#define AI_MATKEY_OBJ_BUMPMULT(type, N) _AI_MATKEY_OBJ_BUMPMULT_BASE, type, N
|
||||
|
||||
//! @cond MATS_DOC_FULL
|
||||
#define AI_MATKEY_OBJ_BUMPMULT_NORMALS(N) \
|
||||
AI_MATKEY_OBJ_BUMPMULT(aiTextureType_NORMALS, N)
|
||||
|
||||
#define AI_MATKEY_OBJ_BUMPMULT_HEIGHT(N) \
|
||||
AI_MATKEY_OBJ_BUMPMULT(aiTextureType_HEIGHT, N)
|
||||
|
||||
//! @endcond
|
||||
|
||||
|
||||
#endif
|
|
@ -119,29 +119,41 @@ public:
|
|||
* work for const references, so many function prototypes will
|
||||
* include const basic_formatter<T>& s but might still want to
|
||||
* modify the formatted string without the need for a full copy.*/
|
||||
template <typename TToken>
|
||||
const basic_formatter& operator << (const TToken& s) const {
|
||||
template <typename TToken, typename std::enable_if<!std::is_base_of<std::exception, TToken>::value>::type * = nullptr>
|
||||
const basic_formatter &operator<<(const TToken &s) const {
|
||||
underlying << s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename TToken>
|
||||
basic_formatter& operator << (const TToken& s) {
|
||||
template <typename TToken, typename std::enable_if<std::is_base_of<std::exception, TToken>::value>::type * = nullptr>
|
||||
const basic_formatter &operator<<(const TToken &s) const {
|
||||
underlying << s.what();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename TToken, typename std::enable_if<!std::is_base_of<std::exception, TToken>::value>::type * = nullptr>
|
||||
basic_formatter &operator<<(const TToken &s) {
|
||||
underlying << s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename TToken, typename std::enable_if<std::is_base_of<std::exception, TToken>::value>::type * = nullptr>
|
||||
basic_formatter &operator<<(const TToken &s) {
|
||||
underlying << s.what();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// comma operator overloaded as well, choose your preferred way.
|
||||
template <typename TToken>
|
||||
const basic_formatter& operator, (const TToken& s) const {
|
||||
underlying << s;
|
||||
*this << s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename TToken>
|
||||
basic_formatter& operator, (const TToken& s) {
|
||||
underlying << s;
|
||||
*this << s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -149,7 +161,7 @@ public:
|
|||
// See https://sourceforge.net/projects/assimp/forums/forum/817654/topic/4372824
|
||||
template <typename TToken>
|
||||
basic_formatter& operator, (TToken& s) {
|
||||
underlying << s;
|
||||
*this << s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -279,11 +279,11 @@ typedef unsigned int ai_uint;
|
|||
#define AI_MATH_HALF_PI_F (AI_MATH_PI_F * 0.5f)
|
||||
|
||||
/* Tiny macro to convert from radians to degrees and back */
|
||||
#define AI_DEG_TO_RAD(x) ((x) * (ai_real)0.0174532925)
|
||||
#define AI_RAD_TO_DEG(x) ((x) * (ai_real)57.2957795)
|
||||
#define AI_DEG_TO_RAD(x) ((x) * (ai_real) 0.0174532925)
|
||||
#define AI_RAD_TO_DEG(x) ((x) * (ai_real) 57.2957795)
|
||||
|
||||
/* Numerical limits */
|
||||
static const ai_real ai_epsilon = (ai_real)0.00001;
|
||||
static const ai_real ai_epsilon = (ai_real) 1e-6;
|
||||
|
||||
/* Support for big-endian builds */
|
||||
#if defined(__BYTE_ORDER__)
|
||||
|
|
|
@ -95,7 +95,7 @@ public:
|
|||
bool operator== (const aiMatrix3x3t<TReal>& m) const;
|
||||
bool operator!= (const aiMatrix3x3t<TReal>& m) const;
|
||||
|
||||
bool Equal(const aiMatrix3x3t<TReal>& m, TReal epsilon = 1e-6) const;
|
||||
bool Equal(const aiMatrix3x3t<TReal> &m, TReal epsilon = ai_epsilon) const;
|
||||
|
||||
template <typename TOther>
|
||||
operator aiMatrix3x3t<TOther> () const;
|
||||
|
|
|
@ -110,7 +110,7 @@ public:
|
|||
bool operator== (const aiMatrix4x4t& m) const;
|
||||
bool operator!= (const aiMatrix4x4t& m) const;
|
||||
|
||||
bool Equal(const aiMatrix4x4t& m, TReal epsilon = 1e-6) const;
|
||||
bool Equal(const aiMatrix4x4t &m, TReal epsilon = ai_epsilon) const;
|
||||
|
||||
// matrix multiplication.
|
||||
aiMatrix4x4t& operator *= (const aiMatrix4x4t& m);
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
// transform vector by matrix
|
||||
aiQuaterniont& operator *= (const aiMatrix4x4t<TReal>& mat);
|
||||
|
||||
bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const;
|
||||
bool Equal(const aiQuaterniont &o, TReal epsilon = ai_epsilon) const;
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ public:
|
|||
bool operator== (const aiVector2t& other) const;
|
||||
bool operator!= (const aiVector2t& other) const;
|
||||
|
||||
bool Equal(const aiVector2t& other, TReal epsilon = 1e-6) const;
|
||||
bool Equal(const aiVector2t &other, TReal epsilon = ai_epsilon) const;
|
||||
|
||||
aiVector2t& operator= (TReal f);
|
||||
const aiVector2t SymMul(const aiVector2t& o);
|
||||
|
|
|
@ -114,7 +114,7 @@ public:
|
|||
bool operator < (const aiVector3t& other) const;
|
||||
|
||||
/// @brief
|
||||
bool Equal(const aiVector3t& other, TReal epsilon = 1e-6) const;
|
||||
bool Equal(const aiVector3t &other, TReal epsilon = ai_epsilon) const;
|
||||
|
||||
template <typename TOther>
|
||||
operator aiVector3t<TOther> () const;
|
||||
|
|
|
@ -60,7 +60,7 @@ protected:
|
|||
};
|
||||
|
||||
TEST_F(utMesh, emptyMeshHasNoContentTest) {
|
||||
EXPECT_EQ(0, mesh->mName.length);
|
||||
EXPECT_EQ(0u, mesh->mName.length);
|
||||
EXPECT_FALSE(mesh->HasPositions());
|
||||
EXPECT_FALSE(mesh->HasFaces());
|
||||
EXPECT_FALSE(mesh->HasNormals());
|
||||
|
@ -69,8 +69,8 @@ TEST_F(utMesh, emptyMeshHasNoContentTest) {
|
|||
EXPECT_FALSE(mesh->HasVertexColors(AI_MAX_NUMBER_OF_COLOR_SETS));
|
||||
EXPECT_FALSE(mesh->HasTextureCoords(0));
|
||||
EXPECT_FALSE(mesh->HasTextureCoords(AI_MAX_NUMBER_OF_TEXTURECOORDS));
|
||||
EXPECT_EQ(0, mesh->GetNumUVChannels());
|
||||
EXPECT_EQ(0, mesh->GetNumColorChannels());
|
||||
EXPECT_EQ(0u, mesh->GetNumUVChannels());
|
||||
EXPECT_EQ(0u, mesh->GetNumColorChannels());
|
||||
EXPECT_FALSE(mesh->HasBones());
|
||||
EXPECT_FALSE(mesh->HasTextureCoordsName(0));
|
||||
EXPECT_FALSE(mesh->HasTextureCoordsName(AI_MAX_NUMBER_OF_TEXTURECOORDS));
|
||||
|
@ -80,8 +80,8 @@ TEST_F(utMesh, setTextureCoordsName) {
|
|||
EXPECT_FALSE(mesh->HasTextureCoordsName(0));
|
||||
const aiString texcoords_name("texcoord_name");
|
||||
mesh->SetTextureCoordsName(0, texcoords_name);
|
||||
EXPECT_TRUE(mesh->HasTextureCoordsName(0));
|
||||
EXPECT_FALSE(mesh->HasTextureCoordsName(1));
|
||||
EXPECT_TRUE(mesh->HasTextureCoordsName(0u));
|
||||
EXPECT_FALSE(mesh->HasTextureCoordsName(1u));
|
||||
ASSERT_NE(nullptr, mesh->mTextureCoordsNames);
|
||||
ASSERT_NE(nullptr, mesh->mTextureCoordsNames[0]);
|
||||
EXPECT_STREQ(texcoords_name.C_Str(), mesh->mTextureCoordsNames[0]->C_Str());
|
||||
|
@ -94,3 +94,4 @@ TEST_F(utMesh, setTextureCoordsName) {
|
|||
EXPECT_EQ(nullptr, mesh->mTextureCoordsNames[0]);
|
||||
EXPECT_EQ(nullptr, mesh->GetTextureCoordsName(0));
|
||||
}
|
||||
|
||||
|
|
|
@ -124,9 +124,9 @@ TEST_F(utColladaExport, testExportLight) {
|
|||
ASSERT_NE(pTest, nullptr);
|
||||
ASSERT_TRUE(pTest->HasLights());
|
||||
|
||||
const unsigned int origNumLights(pTest->mNumLights);
|
||||
const unsigned int origNumLights = pTest->mNumLights;
|
||||
// There are FIVE!!! LIGHTS!!!
|
||||
EXPECT_EQ(5, origNumLights) << "lights.dae should contain five lights";
|
||||
EXPECT_EQ(5u, origNumLights) << "lights.dae should contain five lights";
|
||||
|
||||
std::vector<aiLight> origLights(5);
|
||||
for (size_t i = 0; i < origNumLights; i++) {
|
||||
|
|
|
@ -53,7 +53,7 @@ using namespace Assimp;
|
|||
|
||||
class utFBXImporterExporter : public AbstractImportExportBase {
|
||||
public:
|
||||
virtual bool importerTest() {
|
||||
bool importerTest() override {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/spider.fbx", aiProcess_ValidateDataStructure);
|
||||
return nullptr != scene;
|
||||
|
|
|
@ -48,12 +48,12 @@ TEST_F( utVersion, aiGetLegalStringTest ) {
|
|||
EXPECT_NE( lv, nullptr );
|
||||
std::string text( lv );
|
||||
|
||||
size_t pos = text.find(std::string("2021"));
|
||||
size_t pos = text.find(std::string("2022"));
|
||||
EXPECT_NE(pos, std::string::npos);
|
||||
}
|
||||
|
||||
TEST_F( utVersion, aiGetVersionMinorTest ) {
|
||||
EXPECT_EQ(aiGetVersionMinor(), 1U);
|
||||
EXPECT_EQ(aiGetVersionMinor(), 2U);
|
||||
}
|
||||
|
||||
TEST_F( utVersion, aiGetVersionMajorTest ) {
|
||||
|
@ -61,7 +61,7 @@ TEST_F( utVersion, aiGetVersionMajorTest ) {
|
|||
}
|
||||
|
||||
TEST_F( utVersion, aiGetVersionPatchTest ) {
|
||||
EXPECT_EQ(aiGetVersionPatch(), 6U );
|
||||
EXPECT_EQ(aiGetVersionPatch(), 0U );
|
||||
}
|
||||
|
||||
TEST_F( utVersion, aiGetCompileFlagsTest ) {
|
||||
|
|
|
@ -573,7 +573,7 @@ TEST_F(utglTF2ImportExport, export_normalized_normals) {
|
|||
scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxBadNormals-glTF-Binary/BoxBadNormals_out.glb", aiProcess_ValidateDataStructure);
|
||||
for ( auto i = 0u; i < scene->mMeshes[0]->mNumVertices; ++i ) {
|
||||
const auto length = scene->mMeshes[0]->mNormals[i].Length();
|
||||
EXPECT_TRUE(abs(length) < 1e-6 || abs(length - 1) < 1e-6);
|
||||
EXPECT_TRUE(abs(length) < 1e-6 || abs(length - 1) < ai_epsilon);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue