Merge branch 'master' into new_obj_stream_handling
commit
cbe2e9af49
|
@ -31,6 +31,7 @@ assimp-config-version.cmake
|
|||
|
||||
# MakeFile
|
||||
Makefile
|
||||
code/Makefile
|
||||
test/Makefile
|
||||
test/headercheck/Makefile
|
||||
tools/assimp_cmd/Makefile
|
||||
|
|
|
@ -40,20 +40,20 @@ cmake_minimum_required( VERSION 2.8 )
|
|||
PROJECT( Assimp )
|
||||
|
||||
# All supported options ###############################################
|
||||
OPTION( BUILD_SHARED_LIBS
|
||||
"Build package with shared libraries."
|
||||
OPTION( BUILD_SHARED_LIBS
|
||||
"Build package with shared libraries."
|
||||
ON
|
||||
)
|
||||
OPTION( ASSIMP_DOUBLE_PRECISION
|
||||
"Set to ON to enable double precision processing"
|
||||
OFF
|
||||
)
|
||||
OPTION( ASSIMP_OPT_BUILD_PACKAGES
|
||||
"Set to ON to generate CPack configuration files and packaging targets"
|
||||
OPTION( ASSIMP_OPT_BUILD_PACKAGES
|
||||
"Set to ON to generate CPack configuration files and packaging targets"
|
||||
OFF
|
||||
)
|
||||
OPTION( ASSIMP_ANDROID_JNIIOSYSTEM
|
||||
"Android JNI IOSystem support is active"
|
||||
OPTION( ASSIMP_ANDROID_JNIIOSYSTEM
|
||||
"Android JNI IOSystem support is active"
|
||||
OFF
|
||||
)
|
||||
OPTION( ASSIMP_NO_EXPORT
|
||||
|
@ -77,6 +77,7 @@ OPTION ( ASSIMP_BUILD_TESTS
|
|||
ON
|
||||
)
|
||||
IF(MSVC)
|
||||
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
||||
OPTION( ASSIMP_INSTALL_PDB
|
||||
"Install MSVC debug files."
|
||||
ON
|
||||
|
@ -336,10 +337,10 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
|||
# Why here? Maybe user do not want Qt viewer and have no Qt.
|
||||
# Why assimp_qt_viewer/CMakeLists.txt still contain similar check?
|
||||
# Because viewer can be build independently of Assimp.
|
||||
FIND_PACKAGE(Qt5 QUIET)
|
||||
FIND_PACKAGE(Qt5Widgets QUIET)
|
||||
FIND_PACKAGE(DevIL QUIET)
|
||||
FIND_PACKAGE(OpenGL QUIET)
|
||||
IF ( Qt5_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
||||
ELSE()
|
||||
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
|
||||
|
@ -356,7 +357,7 @@ IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
|||
ENDIF (NOT OPENGL_FOUND)
|
||||
|
||||
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
|
||||
ENDIF ( Qt5_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
ENDIF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||
|
||||
IF ( ASSIMP_BUILD_SAMPLES)
|
||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
// Header files, Assimp.
|
||||
#include "SceneCombiner.h"
|
||||
#include "StandardShapes.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
// Header files, stdlib.
|
||||
#include <algorithm>
|
||||
|
@ -950,7 +951,7 @@ nl_clean_loop:
|
|||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
||||
for(const SPP_Texture& tex_convd: mTexture_Converted)
|
||||
{
|
||||
const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + std::to_string(idx));
|
||||
const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + to_string(idx));
|
||||
const int mode = aiTextureOp_Multiply;
|
||||
const int repeat = tex_convd.Tiled ? 1 : 0;
|
||||
|
||||
|
|
|
@ -70,11 +70,11 @@ ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
|
|||
}
|
||||
|
||||
aiExportFormatDesc *desc = new aiExportFormatDesc;
|
||||
desc->description = new char[ strlen( orig->description ) + 1 ];
|
||||
desc->description = new char[ strlen( orig->description ) + 1 ]();
|
||||
::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) );
|
||||
desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ];
|
||||
desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]();
|
||||
::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) );
|
||||
desc->id = new char[ strlen( orig->id ) + 1 ];
|
||||
desc->id = new char[ strlen( orig->id ) + 1 ]();
|
||||
::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) );
|
||||
|
||||
return desc;
|
||||
|
|
|
@ -299,7 +299,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
|
|||
else if (!shortened){
|
||||
ioprintf(io,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4);
|
||||
|
||||
// const unsigned int width = (unsigned int)log10((double)std::max(tex->mHeight,tex->mWidth))+1;
|
||||
// const unsigned int width = (unsigned int)std::log10((double)std::max(tex->mHeight,tex->mWidth))+1;
|
||||
for (unsigned int y = 0; y < tex->mHeight;++y) {
|
||||
for (unsigned int x = 0; x < tex->mWidth;++x) {
|
||||
aiTexel* tx = tex->pcData + y*tex->mWidth+x;
|
||||
|
@ -457,7 +457,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
|
|||
ioprintf(io,"<MeshList num=\"%i\">\n",scene->mNumMeshes);
|
||||
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
|
||||
aiMesh* mesh = scene->mMeshes[i];
|
||||
// const unsigned int width = (unsigned int)log10((double)mesh->mNumVertices)+1;
|
||||
// const unsigned int width = (unsigned int)std::log10((double)mesh->mNumVertices)+1;
|
||||
|
||||
// mesh header
|
||||
ioprintf(io,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%i\">\n",
|
||||
|
|
|
@ -1143,7 +1143,7 @@ aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj,
|
|||
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
||||
out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
|
||||
if (cam->sensor_x && cam->lens) {
|
||||
out->mHorizontalFOV = atan2(cam->sensor_x, 2.f * cam->lens);
|
||||
out->mHorizontalFOV = std::atan2(cam->sensor_x, 2.f * cam->lens);
|
||||
}
|
||||
out->mClipPlaneNear = cam->clipsta;
|
||||
out->mClipPlaneFar = cam->clipend;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @file aiFileIO -> IOSystem wrapper*/
|
||||
|
||||
#include "CInterfaceIOWrapper.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
CIOStreamWrapper::~CIOStreamWrapper(void)
|
||||
{
|
||||
/* Various places depend on this destructor to close the file */
|
||||
if (mFile) {
|
||||
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
|
||||
mFile = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
size_t CIOStreamWrapper::Read(void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount
|
||||
){
|
||||
// need to typecast here as C has no void*
|
||||
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
size_t CIOStreamWrapper::Write(const void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount
|
||||
){
|
||||
// need to typecast here as C has no void*
|
||||
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
aiReturn CIOStreamWrapper::Seek(size_t pOffset,
|
||||
aiOrigin pOrigin
|
||||
){
|
||||
return mFile->SeekProc(mFile,pOffset,pOrigin);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
size_t CIOStreamWrapper::Tell(void) const {
|
||||
return mFile->TellProc(mFile);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
size_t CIOStreamWrapper::FileSize() const {
|
||||
return mFile->FileSizeProc(mFile);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
void CIOStreamWrapper::Flush () {
|
||||
return mFile->FlushProc(mFile);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Custom IOStream implementation for the C-API
|
||||
bool CIOSystemWrapper::Exists( const char* pFile) const {
|
||||
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
|
||||
if (p){
|
||||
mFileSystem->CloseProc(mFileSystem,p);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
char CIOSystemWrapper::getOsSeparator() const {
|
||||
#ifndef _WIN32
|
||||
return '/';
|
||||
#else
|
||||
return '\\';
|
||||
#endif
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
IOStream* CIOSystemWrapper::Open(const char* pFile,const char* pMode) {
|
||||
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
return new CIOStreamWrapper(p, this);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
void CIOSystemWrapper::Close( IOStream* pFile) {
|
||||
if (!pFile) {
|
||||
return;
|
||||
}
|
||||
delete pFile;
|
||||
}
|
||||
|
||||
}
|
|
@ -50,106 +50,43 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace Assimp {
|
||||
|
||||
class CIOSystemWrapper;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Custom IOStream implementation for the C-API
|
||||
class CIOStreamWrapper : public IOStream
|
||||
{
|
||||
friend class CIOSystemWrapper;
|
||||
public:
|
||||
|
||||
explicit CIOStreamWrapper(aiFile* pFile)
|
||||
: mFile(pFile)
|
||||
explicit CIOStreamWrapper(aiFile* pFile, CIOSystemWrapper* io)
|
||||
: mFile(pFile),
|
||||
mIO(io)
|
||||
{}
|
||||
~CIOStreamWrapper(void);
|
||||
|
||||
// ...................................................................
|
||||
size_t Read(void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount
|
||||
){
|
||||
// need to typecast here as C has no void*
|
||||
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
size_t Write(const void* pvBuffer,
|
||||
size_t pSize,
|
||||
size_t pCount
|
||||
){
|
||||
// need to typecast here as C has no void*
|
||||
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
aiReturn Seek(size_t pOffset,
|
||||
aiOrigin pOrigin
|
||||
){
|
||||
return mFile->SeekProc(mFile,pOffset,pOrigin);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
size_t Tell(void) const {
|
||||
return mFile->TellProc(mFile);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
size_t FileSize() const {
|
||||
return mFile->FileSizeProc(mFile);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
void Flush () {
|
||||
return mFile->FlushProc(mFile);
|
||||
}
|
||||
size_t Read(void* pvBuffer, size_t pSize, size_t pCount);
|
||||
size_t Write(const void* pvBuffer, size_t pSize, size_t pCount);
|
||||
aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
|
||||
size_t Tell(void) const;
|
||||
size_t FileSize() const;
|
||||
void Flush();
|
||||
|
||||
private:
|
||||
aiFile* mFile;
|
||||
CIOSystemWrapper* mIO;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Custom IOStream implementation for the C-API
|
||||
class CIOSystemWrapper : public IOSystem
|
||||
{
|
||||
friend class CIOStreamWrapper;
|
||||
public:
|
||||
explicit CIOSystemWrapper(aiFileIO* pFile)
|
||||
: mFileSystem(pFile)
|
||||
{}
|
||||
|
||||
// ...................................................................
|
||||
bool Exists( const char* pFile) const {
|
||||
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
|
||||
if (p){
|
||||
mFileSystem->CloseProc(mFileSystem,p);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
char getOsSeparator() const {
|
||||
#ifndef _WIN32
|
||||
return '/';
|
||||
#else
|
||||
return '\\';
|
||||
#endif
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
IOStream* Open(const char* pFile,const char* pMode = "rb") {
|
||||
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
return new CIOStreamWrapper(p);
|
||||
}
|
||||
|
||||
// ...................................................................
|
||||
void Close( IOStream* pFile) {
|
||||
if (!pFile) {
|
||||
return;
|
||||
}
|
||||
mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
|
||||
delete pFile;
|
||||
}
|
||||
bool Exists( const char* pFile) const;
|
||||
char getOsSeparator() const;
|
||||
IOStream* Open(const char* pFile,const char* pMode = "rb");
|
||||
void Close( IOStream* pFile);
|
||||
private:
|
||||
aiFileIO* mFileSystem;
|
||||
};
|
||||
|
|
|
@ -128,6 +128,7 @@ SET( Common_SRCS
|
|||
DefaultIOStream.h
|
||||
DefaultIOSystem.cpp
|
||||
DefaultIOSystem.h
|
||||
CInterfaceIOWrapper.cpp
|
||||
CInterfaceIOWrapper.h
|
||||
Hash.h
|
||||
Importer.cpp
|
||||
|
|
|
@ -256,7 +256,7 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
|
|||
}
|
||||
std::vector<unsigned int> verticesFound;
|
||||
|
||||
const float fLimit = cosf(configMaxAngle);
|
||||
const float fLimit = std::cos(configMaxAngle);
|
||||
std::vector<unsigned int> closeVertices;
|
||||
|
||||
// in the second pass we now smooth out all tangents and bitangents at the same local position
|
||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "fast_atof.h"
|
||||
#include "SceneCombiner.h"
|
||||
#include "DefaultIOSystem.h"
|
||||
#include "StringUtils.h"
|
||||
#include "XMLTools.h"
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/Exporter.hpp>
|
||||
|
@ -637,7 +638,7 @@ void ColladaExporter::WriteMaterials()
|
|||
aiString name;
|
||||
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
|
||||
name = "mat";
|
||||
materials[a].name = std::string( "m") + std::to_string(a) + name.C_Str();
|
||||
materials[a].name = std::string( "m") + to_string(a) + name.C_Str();
|
||||
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
|
||||
if( !isalnum_C( *it ) ) {
|
||||
*it = '_';
|
||||
|
@ -813,7 +814,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
|
|||
{
|
||||
if( mesh->HasTextureCoords( a) )
|
||||
{
|
||||
WriteFloatArray( idstr + "-tex" + std::to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
|
||||
WriteFloatArray( idstr + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
|
||||
(ai_real*) mesh->mTextureCoords[a], mesh->mNumVertices);
|
||||
}
|
||||
}
|
||||
|
@ -822,7 +823,7 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
|
|||
for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a)
|
||||
{
|
||||
if( mesh->HasVertexColors( a) )
|
||||
WriteFloatArray( idstr + "-color" + std::to_string(a), FloatType_Color, (ai_real*) mesh->mColors[a], mesh->mNumVertices);
|
||||
WriteFloatArray( idstr + "-color" + to_string(a), FloatType_Color, (ai_real*) mesh->mColors[a], mesh->mNumVertices);
|
||||
}
|
||||
|
||||
// assemble vertex structure
|
||||
|
|
|
@ -53,6 +53,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
struct aiScene;
|
||||
struct aiNode;
|
||||
|
||||
|
@ -122,7 +124,9 @@ protected:
|
|||
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
|
||||
|
||||
/// Creates a mesh ID for the given mesh
|
||||
std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + std::to_string(pIndex); }
|
||||
std::string GetMeshId( size_t pIndex) const {
|
||||
return std::string( "meshId" ) + to_string(pIndex);
|
||||
}
|
||||
|
||||
public:
|
||||
/// Stringstream to write all output into
|
||||
|
|
|
@ -420,13 +420,13 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
|
|||
out->mHorizontalFOV = srcCamera->mHorFov;
|
||||
|
||||
if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) {
|
||||
out->mAspect = tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
|
||||
tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
|
||||
out->mAspect = std::tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
|
||||
std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
|
||||
}
|
||||
}
|
||||
else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) {
|
||||
out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(atan(srcCamera->mAspect *
|
||||
tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
|
||||
out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(std::atan(srcCamera->mAspect *
|
||||
std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
|
||||
}
|
||||
|
||||
// Collada uses degrees, we use radians
|
||||
|
@ -1181,7 +1181,7 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
|
|||
const ai_real last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time);
|
||||
const ai_real delta = std::abs(cur_key_angle - last_eval_angle);
|
||||
if (delta >= 180.0) {
|
||||
const int subSampleCount = static_cast<int>(floorf(delta / 90.0));
|
||||
const int subSampleCount = static_cast<int>(std::floor(delta / 90.0));
|
||||
if (cur_key_time != time) {
|
||||
const ai_real nextSampleTime = time + (cur_key_time - time) / subSampleCount;
|
||||
nextTime = std::min(nextTime, nextSampleTime);
|
||||
|
|
|
@ -300,7 +300,7 @@ void ColladaParser::ReadAnimationClipLibrary()
|
|||
else if (indexID >= 0)
|
||||
animName = mReader->getAttributeValue(indexID);
|
||||
else
|
||||
animName = std::string("animation_") + std::to_string(mAnimationClipLibrary.size());
|
||||
animName = std::string("animation_") + to_string(mAnimationClipLibrary.size());
|
||||
|
||||
std::pair<std::string, std::vector<std::string> > clip;
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
|||
// lon = arctan (y/x)
|
||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
||||
out[pnt] = aiVector3D((atan2 (diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||
out[pnt] = aiVector3D((std::atan2(diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||
(std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
|||
// ... just the same again
|
||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
||||
out[pnt] = aiVector3D((atan2 (diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||
out[pnt] = aiVector3D((std::atan2(diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||
(std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||
}
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
|||
// ... just the same again
|
||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||
const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
|
||||
out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||
out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||
(std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||
}
|
||||
}
|
||||
|
@ -234,8 +234,8 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
|||
// again the same, except we're applying a transformation now
|
||||
for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
|
||||
const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize();
|
||||
out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||
(asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||
out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
|
||||
(std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
|
|||
aiVector3D& uv = out[pnt];
|
||||
|
||||
uv.y = (pos.x - min.x) / diff;
|
||||
uv.x = (atan2 ( pos.z - center.z, pos.y - center.y) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
||||
uv.x = (std::atan2( pos.z - center.z, pos.y - center.y) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
||||
}
|
||||
}
|
||||
else if (axis * base_axis_y >= angle_epsilon) {
|
||||
|
@ -281,7 +281,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
|
|||
aiVector3D& uv = out[pnt];
|
||||
|
||||
uv.y = (pos.y - min.y) / diff;
|
||||
uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
||||
uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
||||
}
|
||||
}
|
||||
else if (axis * base_axis_z >= angle_epsilon) {
|
||||
|
@ -294,7 +294,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
|
|||
aiVector3D& uv = out[pnt];
|
||||
|
||||
uv.y = (pos.z - min.z) / diff;
|
||||
uv.x = (atan2 ( pos.y - center.y, pos.x - center.x) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
||||
uv.x = (std::atan2( pos.y - center.y, pos.x - center.x) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
||||
}
|
||||
}
|
||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||
|
@ -310,7 +310,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
|
|||
aiVector3D& uv = out[pnt];
|
||||
|
||||
uv.y = (pos.y - min.y) / diff;
|
||||
uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
||||
uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,8 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
#include <contrib/unzip/unzip.h>
|
||||
#include "irrXMLWrapper.h"
|
||||
#include "StringComparison.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
|
@ -61,10 +59,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <assimp/ai_assert.h>
|
||||
|
||||
#include "D3MFOpcPackage.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
|
||||
#include "D3MFOpcPackage.h"
|
||||
#include <contrib/unzip/unzip.h>
|
||||
#include "irrXMLWrapper.h"
|
||||
|
||||
namespace Assimp {
|
||||
namespace D3MF {
|
||||
|
||||
|
@ -113,7 +113,7 @@ public:
|
|||
std::vector<aiNode*> children;
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::model))
|
||||
{
|
||||
{
|
||||
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::object)
|
||||
{
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(scene->mRootNode->mName.length == 0)
|
||||
scene->mRootNode->mName.Set("3MF");
|
||||
|
@ -143,24 +143,31 @@ public:
|
|||
|
||||
private:
|
||||
aiNode* ReadObject(aiScene* scene)
|
||||
{
|
||||
{
|
||||
ScopeGuard<aiNode> node(new aiNode());
|
||||
|
||||
std::vector<unsigned long> meshIds;
|
||||
|
||||
int id = std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::id.c_str()));
|
||||
std::string name(xmlReader->getAttributeValue(D3MF::XmlTag::name.c_str()));
|
||||
std::string type(xmlReader->getAttributeValue(D3MF::XmlTag::type.c_str()));
|
||||
const char *attrib( nullptr );
|
||||
std::string name, type;
|
||||
attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
|
||||
if ( nullptr != attrib ) {
|
||||
name = attrib;
|
||||
}
|
||||
attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
|
||||
if ( nullptr != attrib ) {
|
||||
type = attrib;
|
||||
}
|
||||
|
||||
node->mParent = scene->mRootNode;
|
||||
node->mName.Set(name);
|
||||
node->mName.Set(name);
|
||||
|
||||
unsigned long meshIdx = meshes.size();
|
||||
size_t meshIdx = meshes.size();
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::object))
|
||||
{
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::mesh)
|
||||
{
|
||||
{
|
||||
auto mesh = ReadMesh();
|
||||
|
||||
mesh->mName.Set(name);
|
||||
|
@ -186,7 +193,7 @@ private:
|
|||
aiMesh* mesh = new aiMesh();
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::mesh))
|
||||
{
|
||||
{
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::vertices)
|
||||
{
|
||||
ImportVertices(mesh);
|
||||
|
@ -204,12 +211,12 @@ private:
|
|||
|
||||
void ImportVertices(aiMesh* mesh)
|
||||
{
|
||||
std::vector<aiVector3D> vertices;
|
||||
std::vector<aiVector3D> vertices;
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::vertices))
|
||||
{
|
||||
{
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::vertex)
|
||||
{
|
||||
{
|
||||
vertices.push_back(ReadVertex());
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +227,7 @@ private:
|
|||
|
||||
}
|
||||
aiVector3D ReadVertex()
|
||||
{
|
||||
{
|
||||
aiVector3D vertex;
|
||||
vertex.x = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::x.c_str()), nullptr);
|
||||
vertex.y = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::y.c_str()), nullptr);
|
||||
|
@ -231,7 +238,7 @@ private:
|
|||
|
||||
void ImportTriangles(aiMesh* mesh)
|
||||
{
|
||||
std::vector<aiFace> faces;
|
||||
std::vector<aiFace> faces;
|
||||
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::triangles))
|
||||
|
@ -337,7 +344,7 @@ D3MFImporter::~D3MFImporter()
|
|||
}
|
||||
|
||||
bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const
|
||||
{
|
||||
{
|
||||
const std::string extension = GetExtension(pFile);
|
||||
if(extension == "3mf") {
|
||||
return true;
|
||||
|
|
|
@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "D3MFOpcPackage.h"
|
||||
#include "Exceptional.h"
|
||||
|
||||
#include <contrib/unzip/unzip.h>
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
@ -57,6 +56,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
|
||||
#include <contrib/unzip/unzip.h>
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
namespace D3MF {
|
||||
|
|
|
@ -120,7 +120,7 @@ size_t DefaultIOStream::FileSize() const
|
|||
//
|
||||
// See here for details:
|
||||
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
|
||||
#if defined _WIN32 && !defined __GNUC__
|
||||
#if defined _WIN32
|
||||
struct __stat64 fileStat;
|
||||
int err = _stat64( mFilename.c_str(), &fileStat );
|
||||
if (0 != err)
|
||||
|
|
|
@ -55,6 +55,46 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
enum Flag
|
||||
{
|
||||
e_unknown_0 = 1 << 0,
|
||||
e_unknown_1 = 1 << 1,
|
||||
e_unknown_2 = 1 << 2,
|
||||
e_unknown_3 = 1 << 3,
|
||||
e_unknown_4 = 1 << 4,
|
||||
e_unknown_5 = 1 << 5,
|
||||
e_unknown_6 = 1 << 6,
|
||||
e_unknown_7 = 1 << 7,
|
||||
e_unknown_8 = 1 << 8,
|
||||
e_unknown_9 = 1 << 9,
|
||||
e_unknown_10 = 1 << 10,
|
||||
e_unknown_11 = 1 << 11,
|
||||
e_unknown_12 = 1 << 12,
|
||||
e_unknown_13 = 1 << 13,
|
||||
e_unknown_14 = 1 << 14,
|
||||
e_unknown_15 = 1 << 15,
|
||||
e_unknown_16 = 1 << 16,
|
||||
e_unknown_17 = 1 << 17,
|
||||
e_unknown_18 = 1 << 18,
|
||||
e_unknown_19 = 1 << 19,
|
||||
e_unknown_20 = 1 << 20,
|
||||
e_unknown_21 = 1 << 21,
|
||||
e_unknown_22 = 1 << 22,
|
||||
e_unknown_23 = 1 << 23,
|
||||
e_flag_field_size_64_bit = 1 << 24, // Not sure what is
|
||||
e_unknown_25 = 1 << 25,
|
||||
e_unknown_26 = 1 << 26,
|
||||
e_unknown_27 = 1 << 27,
|
||||
e_unknown_28 = 1 << 28,
|
||||
e_unknown_29 = 1 << 29,
|
||||
e_unknown_30 = 1 << 30,
|
||||
e_unknown_31 = 1 << 31
|
||||
};
|
||||
|
||||
bool check_flag(uint32_t flags, Flag to_check)
|
||||
{
|
||||
return (flags & to_check) != 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
|
||||
|
@ -118,6 +158,21 @@ uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
|
|||
return word;
|
||||
}
|
||||
|
||||
uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end)
|
||||
{
|
||||
const size_t k_to_read = sizeof(uint64_t);
|
||||
if(Offset(cursor, end) < k_to_read) {
|
||||
TokenizeError("cannot ReadDoubleWord, out of bounds",input, cursor);
|
||||
}
|
||||
|
||||
uint64_t dword = *reinterpret_cast<const uint64_t*>(cursor);
|
||||
AI_SWAP8(dword);
|
||||
|
||||
cursor += k_to_read;
|
||||
|
||||
return dword;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
|
||||
|
@ -287,10 +342,10 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
|
|||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end)
|
||||
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, uint32_t const flags)
|
||||
{
|
||||
// the first word contains the offset at which this block ends
|
||||
const uint32_t end_offset = ReadWord(input, cursor, end);
|
||||
const uint64_t end_offset = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
||||
|
||||
// we may get 0 if reading reached the end of the file -
|
||||
// fbx files have a mysterious extra footer which I don't know
|
||||
|
@ -308,10 +363,10 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
|||
}
|
||||
|
||||
// the second data word contains the number of properties in the scope
|
||||
const uint32_t prop_count = ReadWord(input, cursor, end);
|
||||
const uint64_t prop_count = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
||||
|
||||
// the third data word contains the length of the property list
|
||||
const uint32_t prop_length = ReadWord(input, cursor, end);
|
||||
const uint64_t prop_length = check_flag(flags, e_flag_field_size_64_bit) ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
|
||||
|
||||
// now comes the name of the scope/key
|
||||
const char* sbeg, *send;
|
||||
|
@ -337,29 +392,28 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
|
|||
|
||||
// at the end of each nested block, there is a NUL record to indicate
|
||||
// that the sub-scope exists (i.e. to distinguish between P: and P : {})
|
||||
// this NUL record is 13 bytes long.
|
||||
#define BLOCK_SENTINEL_LENGTH 13
|
||||
// this NUL record is 13 bytes long on 32 bit version and 25 bytes long on 64 bit.
|
||||
const size_t sentinel_block_length = check_flag(flags, e_flag_field_size_64_bit) ? (sizeof(uint64_t) * 3 + 1) : (sizeof(uint32_t) * 3 + 1);
|
||||
|
||||
if (Offset(input, cursor) < end_offset) {
|
||||
|
||||
if (end_offset - Offset(input, cursor) < BLOCK_SENTINEL_LENGTH) {
|
||||
if (end_offset - Offset(input, cursor) < sentinel_block_length) {
|
||||
TokenizeError("insufficient padding bytes at block end",input, cursor);
|
||||
}
|
||||
|
||||
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) ));
|
||||
|
||||
// XXX this is vulnerable to stack overflowing ..
|
||||
while(Offset(input, cursor) < end_offset - BLOCK_SENTINEL_LENGTH) {
|
||||
ReadScope(output_tokens, input, cursor, input + end_offset - BLOCK_SENTINEL_LENGTH);
|
||||
while(Offset(input, cursor) < end_offset - sentinel_block_length) {
|
||||
ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, flags);
|
||||
}
|
||||
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
|
||||
|
||||
for (unsigned int i = 0; i < BLOCK_SENTINEL_LENGTH; ++i) {
|
||||
for (unsigned int i = 0; i < sentinel_block_length; ++i) {
|
||||
if(cursor[i] != '\0') {
|
||||
TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor);
|
||||
}
|
||||
}
|
||||
cursor += BLOCK_SENTINEL_LENGTH;
|
||||
cursor += sentinel_block_length;
|
||||
}
|
||||
|
||||
if (Offset(input, cursor) != end_offset) {
|
||||
|
@ -386,12 +440,17 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
|||
}
|
||||
|
||||
|
||||
//uint32_t offset = 0x1b;
|
||||
//uint32_t offset = 0x15;
|
||||
const char* cursor = input + 0x15;
|
||||
|
||||
const char* cursor = input + 0x1b;
|
||||
const uint32_t flags = ReadWord(input, cursor, input + length);
|
||||
|
||||
while (cursor < input + length) {
|
||||
if(!ReadScope(output_tokens, input, cursor, input + length)) {
|
||||
const uint8_t padding_0 = ReadByte(input, cursor, input + length); // unused
|
||||
const uint8_t padding_1 = ReadByte(input, cursor, input + length); // unused
|
||||
|
||||
while (cursor < input + length)
|
||||
{
|
||||
if(!ReadScope(output_tokens, input, cursor, input + length, flags)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,9 +148,9 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
|
|||
// Check whether this is a planar surface
|
||||
const float fDelta1_yz = fDelta1_y * fDelta1_z;
|
||||
|
||||
if (fDelta1_x < 0.05f * sqrtf( fDelta1_yz ))return false;
|
||||
if (fDelta1_y < 0.05f * sqrtf( fDelta1_z * fDelta1_x ))return false;
|
||||
if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false;
|
||||
if (fDelta1_x < 0.05f * std::sqrt( fDelta1_yz ))return false;
|
||||
if (fDelta1_y < 0.05f * std::sqrt( fDelta1_z * fDelta1_x ))return false;
|
||||
if (fDelta1_z < 0.05f * std::sqrt( fDelta1_y * fDelta1_x ))return false;
|
||||
|
||||
// now compare the volumes of the bounding boxes
|
||||
if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) <
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -160,7 +160,7 @@ void AnimResolver::UpdateAnimRangeSetup()
|
|||
case LWO::PrePostBehaviour_Repeat:
|
||||
case LWO::PrePostBehaviour_Oscillate:
|
||||
{
|
||||
const double start_time = delta - fmod(my_first-first,delta);
|
||||
const double start_time = delta - std::fmod(my_first-first,delta);
|
||||
std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(),(*it).keys.end(),
|
||||
std::bind1st(std::greater<double>(),start_time)),m;
|
||||
|
||||
|
|
|
@ -851,7 +851,7 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
|||
case AI_LWO_SMAN:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
|
||||
surf.mMaximumSmoothAngle = fabs( GetF4() );
|
||||
surf.mMaximumSmoothAngle = std::fabs( GetF4() );
|
||||
break;
|
||||
}
|
||||
// vertex color channel to be applied to the surface
|
||||
|
|
|
@ -298,10 +298,10 @@ inline void Vec3NormalToLatLng( const aiVector3D& p_vIn, uint16_t& p_iOut )
|
|||
{
|
||||
int a, b;
|
||||
|
||||
a = int(57.2957795f * ( atan2f( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f ));
|
||||
a = int(57.2957795f * ( std::atan2( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f ));
|
||||
a &= 0xff;
|
||||
|
||||
b = int(57.2957795f * ( acosf( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
|
||||
b = int(57.2957795f * ( std::acos( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
|
||||
b &= 0xff;
|
||||
|
||||
((unsigned char*)&p_iOut)[0] = b; // longitude
|
||||
|
|
|
@ -195,7 +195,7 @@ bool MD5Parser::ParseSection(Section& out)
|
|||
#define AI_MD5_SKIP_SPACES() if(!SkipSpaces(&sz)) \
|
||||
MD5Parser::ReportWarning("Unexpected end of line",elem.iLineNumber);
|
||||
|
||||
// read a triple float in brackets: (1.0 1.0 1.0)
|
||||
// read a triple float in brackets: (1.0 1.0 1.0)
|
||||
#define AI_MD5_READ_TRIPLE(vec) \
|
||||
AI_MD5_SKIP_SPACES(); \
|
||||
if ('(' != *sz++) \
|
||||
|
@ -210,7 +210,7 @@ bool MD5Parser::ParseSection(Section& out)
|
|||
if (')' != *sz++) \
|
||||
MD5Parser::ReportWarning("Unexpected token: ) was expected",elem.iLineNumber);
|
||||
|
||||
// parse a string, enclosed in quotation marks or not
|
||||
// parse a string, enclosed in quotation marks or not
|
||||
#define AI_MD5_PARSE_STRING(out) \
|
||||
bool bQuota = (*sz == '\"'); \
|
||||
const char* szStart = sz; \
|
||||
|
@ -228,6 +228,15 @@ bool MD5Parser::ParseSection(Section& out)
|
|||
::memcpy(out.data,szStart,out.length); \
|
||||
out.data[out.length] = '\0';
|
||||
|
||||
// parse a string, enclosed in quotation marks
|
||||
#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
|
||||
while('\"'!=*sz)++sz; \
|
||||
const char* szStart = ++sz; \
|
||||
while('\"'!=*sz)++sz; \
|
||||
const char* szEnd = (sz++); \
|
||||
out.length = (size_t)(szEnd - szStart); \
|
||||
::memcpy(out.data,szStart,out.length); \
|
||||
out.data[out.length] = '\0';
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// .MD5MESH parsing function
|
||||
MD5MeshParser::MD5MeshParser(SectionList& mSections)
|
||||
|
@ -247,9 +256,9 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
|
|||
for (const auto & elem : (*iter).mElements){
|
||||
mJoints.push_back(BoneDesc());
|
||||
BoneDesc& desc = mJoints.back();
|
||||
|
||||
|
||||
const char* sz = elem.szStart;
|
||||
AI_MD5_PARSE_STRING(desc.mName);
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
|
||||
// negative values, at least -1, is allowed here
|
||||
|
@ -269,7 +278,7 @@ MD5MeshParser::MD5MeshParser(SectionList& mSections)
|
|||
// shader attribute
|
||||
if (TokenMatch(sz,"shader",6)) {
|
||||
AI_MD5_SKIP_SPACES();
|
||||
AI_MD5_PARSE_STRING(desc.mShader);
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader);
|
||||
}
|
||||
// numverts attribute
|
||||
else if (TokenMatch(sz,"numverts",8)) {
|
||||
|
@ -362,7 +371,7 @@ MD5AnimParser::MD5AnimParser(SectionList& mSections)
|
|||
AnimBoneDesc& desc = mAnimatedBones.back();
|
||||
|
||||
const char* sz = elem.szStart;
|
||||
AI_MD5_PARSE_STRING(desc.mName);
|
||||
AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
|
||||
AI_MD5_SKIP_SPACES();
|
||||
|
||||
// parent index - negative values are allowed (at least -1)
|
||||
|
|
5658
code/Makefile
5658
code/Makefile
File diff suppressed because it is too large
Load Diff
|
@ -184,9 +184,14 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
|
|||
|
||||
case 'm': // Parse a material library or merging group ('mg')
|
||||
{
|
||||
std::string name;
|
||||
std::string name;
|
||||
|
||||
getName(m_DataIt, m_DataItEnd, name);
|
||||
|
||||
size_t nextSpace = name.find(" ");
|
||||
if (nextSpace != std::string::npos)
|
||||
name = name.substr(0, nextSpace);
|
||||
|
||||
getName(m_DataIt, m_DataItEnd, name);
|
||||
if (name == "mg")
|
||||
getGroupNumberAndResolution();
|
||||
else if(name == "mtllib")
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace Grammar {
|
|||
MaterialToken,
|
||||
ColorToken,
|
||||
ParamToken,
|
||||
TextureToken,
|
||||
TextureToken,
|
||||
AttenToken
|
||||
};
|
||||
|
||||
|
@ -237,7 +237,7 @@ OpenGEXImporter::VertexContainer::~VertexContainer() {
|
|||
delete[] m_vertices;
|
||||
delete[] m_colors;
|
||||
delete[] m_normals;
|
||||
|
||||
|
||||
for(auto &texcoords : m_textureCoords) {
|
||||
delete [] texcoords;
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
|
|||
case Grammar::ColorToken:
|
||||
handleColorNode( *it, pScene );
|
||||
break;
|
||||
|
||||
|
||||
case Grammar::ParamToken:
|
||||
handleParamNode( *it, pScene );
|
||||
break;
|
||||
|
@ -479,7 +479,7 @@ void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene *pScene ) {
|
|||
}
|
||||
|
||||
const std::string name( val->getString() );
|
||||
if( m_tokenType == Grammar::GeometryNodeToken || m_tokenType == Grammar::LightNodeToken
|
||||
if( m_tokenType == Grammar::GeometryNodeToken || m_tokenType == Grammar::LightNodeToken
|
||||
|| m_tokenType == Grammar::CameraNodeToken ) {
|
||||
m_currentNode->mName.Set( name.c_str() );
|
||||
} else if( m_tokenType == Grammar::MaterialToken ) {
|
||||
|
@ -515,7 +515,7 @@ void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene *pScene ) {
|
|||
|
||||
std::vector<std::string> objRefNames;
|
||||
getRefNames( node, objRefNames );
|
||||
|
||||
|
||||
// when we are dealing with a geometry node prepare the mesh cache
|
||||
if ( m_tokenType == Grammar::GeometryNodeToken ) {
|
||||
m_currentNode->mNumMeshes = objRefNames.size();
|
||||
|
@ -596,7 +596,7 @@ void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) {
|
|||
//------------------------------------------------------------------------------------------------
|
||||
void OpenGEXImporter::handleCameraObject( ODDLParser::DDLNode *node, aiScene *pScene ) {
|
||||
// parameters will be parsed normally in the tree, so just go for it
|
||||
|
||||
|
||||
handleNodes( node, pScene );
|
||||
}
|
||||
|
||||
|
@ -757,7 +757,6 @@ static void fillColor4( aiColor4D *col4, Value *vals ) {
|
|||
ai_assert( nullptr != col4 );
|
||||
ai_assert( nullptr != vals );
|
||||
|
||||
float r( 0.0f ), g( 0.0f ), b( 0.0f ), a ( 1.0f );
|
||||
Value *next( vals );
|
||||
col4->r = next->getFloat();
|
||||
next = next->m_next;
|
||||
|
@ -1169,7 +1168,7 @@ void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
|
|||
if ( nullptr == node ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ChildInfo *info( nullptr );
|
||||
if( m_nodeStack.empty() ) {
|
||||
node->mParent = pScene->mRootNode;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
|
||||
|
||||
//#include <windows.h>
|
||||
#include "DefaultIOSystem.h"
|
||||
#include "Q3BSPFileImporter.h"
|
||||
#include "Q3BSPZipArchive.h"
|
||||
|
@ -76,14 +75,6 @@ static const aiImporterDesc desc = {
|
|||
|
||||
namespace Assimp {
|
||||
|
||||
/*
|
||||
static void getSupportedExtensions(std::vector<std::string> &supportedExtensions) {
|
||||
supportedExtensions.push_back( ".jpg" );
|
||||
supportedExtensions.push_back( ".png" );
|
||||
supportedExtensions.push_back( ".tga" );
|
||||
}
|
||||
*/
|
||||
|
||||
using namespace Q3BSP;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -175,7 +166,7 @@ Q3BSPFileImporter::~Q3BSPFileImporter() {
|
|||
bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const
|
||||
{
|
||||
if(!checkSig) {
|
||||
return SimpleExtensionCheck( rFile, "pk3" );
|
||||
return SimpleExtensionCheck( rFile, "pk3", "bsp" );
|
||||
}
|
||||
// TODO perhaps add keyword based detection
|
||||
return false;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2008, assimp team
|
||||
Copyright (c) 2006-2016, assimp team
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
@ -58,24 +58,15 @@ namespace Q3BSP {
|
|||
/// \brief
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class IOSystem2Unzip {
|
||||
|
||||
public:
|
||||
|
||||
static voidpf open(voidpf opaque, const char* filename, int mode);
|
||||
|
||||
static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size);
|
||||
|
||||
static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size);
|
||||
|
||||
static long tell(voidpf opaque, voidpf stream);
|
||||
|
||||
static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
|
||||
|
||||
static int close(voidpf opaque, voidpf stream);
|
||||
|
||||
static int testerror(voidpf opaque, voidpf stream);
|
||||
|
||||
static zlib_filefunc_def get(IOSystem* pIOHandler);
|
||||
public:
|
||||
static voidpf open(voidpf opaque, const char* filename, int mode);
|
||||
static uLong read(voidpf opaque, voidpf stream, void* buf, uLong size);
|
||||
static uLong write(voidpf opaque, voidpf stream, const void* buf, uLong size);
|
||||
static long tell(voidpf opaque, voidpf stream);
|
||||
static long seek(voidpf opaque, voidpf stream, uLong offset, int origin);
|
||||
static int close(voidpf opaque, voidpf stream);
|
||||
static int testerror(voidpf opaque, voidpf stream);
|
||||
static zlib_filefunc_def get(IOSystem* pIOHandler);
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -85,32 +76,21 @@ class IOSystem2Unzip {
|
|||
/// \brief
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class ZipFile : public IOStream {
|
||||
|
||||
friend class Q3BSPZipArchive;
|
||||
|
||||
public:
|
||||
public:
|
||||
explicit ZipFile(size_t size);
|
||||
~ZipFile();
|
||||
size_t Read(void* pvBuffer, size_t pSize, size_t pCount );
|
||||
size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/);
|
||||
size_t FileSize() const;
|
||||
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/);
|
||||
size_t Tell() const;
|
||||
void Flush();
|
||||
|
||||
explicit ZipFile(size_t size);
|
||||
|
||||
~ZipFile();
|
||||
|
||||
size_t Read(void* pvBuffer, size_t pSize, size_t pCount );
|
||||
|
||||
size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/);
|
||||
|
||||
size_t FileSize() const;
|
||||
|
||||
aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/);
|
||||
|
||||
size_t Tell() const;
|
||||
|
||||
void Flush();
|
||||
|
||||
private:
|
||||
|
||||
void* m_Buffer;
|
||||
|
||||
size_t m_Size;
|
||||
private:
|
||||
void* m_Buffer;
|
||||
size_t m_Size;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -121,39 +101,25 @@ class ZipFile : public IOStream {
|
|||
/// from a P3K archive ( Quake level format ).
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class Q3BSPZipArchive : public Assimp::IOSystem {
|
||||
public:
|
||||
static const unsigned int FileNameSize = 256;
|
||||
|
||||
public:
|
||||
public:
|
||||
Q3BSPZipArchive(IOSystem* pIOHandler, const std::string & rFile);
|
||||
~Q3BSPZipArchive();
|
||||
bool Exists(const char* pFile) const;
|
||||
char getOsSeparator() const;
|
||||
IOStream* Open(const char* pFile, const char* pMode = "rb");
|
||||
void Close(IOStream* pFile);
|
||||
bool isOpen() const;
|
||||
void getFileList(std::vector<std::string> &rFileList);
|
||||
|
||||
static const unsigned int FileNameSize = 256;
|
||||
|
||||
public:
|
||||
|
||||
Q3BSPZipArchive(IOSystem* pIOHandler, const std::string & rFile);
|
||||
|
||||
~Q3BSPZipArchive();
|
||||
|
||||
bool Exists(const char* pFile) const;
|
||||
|
||||
char getOsSeparator() const;
|
||||
|
||||
IOStream* Open(const char* pFile, const char* pMode = "rb");
|
||||
|
||||
void Close(IOStream* pFile);
|
||||
|
||||
bool isOpen() const;
|
||||
|
||||
void getFileList(std::vector<std::string> &rFileList);
|
||||
|
||||
private:
|
||||
|
||||
bool mapArchive();
|
||||
|
||||
private:
|
||||
|
||||
unzFile m_ZipFileHandle;
|
||||
|
||||
std::map<std::string, ZipFile*> m_ArchiveMap;
|
||||
private:
|
||||
bool mapArchive();
|
||||
|
||||
private:
|
||||
unzFile m_ZipFileHandle;
|
||||
std::map<std::string, ZipFile*> m_ArchiveMap;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -710,8 +710,8 @@ static void ReadLightInfo(aiLight* light, StreamReaderLE* stream)
|
|||
// OpenGL: I = cos(angle)^E
|
||||
// Solving: angle = acos(I^(1/E))
|
||||
ai_real E = 1.0 / std::max(spotExponent, (ai_real)0.00001);
|
||||
ai_real inner = acos(pow((ai_real)0.99, E));
|
||||
ai_real outer = acos(pow((ai_real)0.01, E));
|
||||
ai_real inner = std::acos(std::pow((ai_real)0.99, E));
|
||||
ai_real outer = std::acos(std::pow((ai_real)0.01, E));
|
||||
|
||||
// Apply the cutoff.
|
||||
outer = std::min(outer, AI_DEG_TO_RAD(spotCutoff));
|
||||
|
|
|
@ -72,7 +72,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "LineSplitter.h"
|
||||
|
||||
|
||||
// uncomment this to have the loader evaluate all entities upon loading.
|
||||
// this is intended as stress test - by default, entities are evaluated
|
||||
// lazily and therefore not unless needed.
|
||||
|
@ -118,15 +117,13 @@ namespace STEP {
|
|||
|
||||
// ********************************************************************************
|
||||
|
||||
|
||||
namespace STEP {
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Exception class used by the STEP loading & parsing code. It is typically
|
||||
* coupled with a line number. */
|
||||
// -------------------------------------------------------------------------------
|
||||
struct SyntaxError : DeadlyImportError
|
||||
{
|
||||
struct SyntaxError : DeadlyImportError {
|
||||
enum {
|
||||
LINE_NOT_SPECIFIED = 0xffffffffffffffffLL
|
||||
};
|
||||
|
@ -253,7 +250,7 @@ namespace STEP {
|
|||
{
|
||||
public:
|
||||
|
||||
// This is the type that will ultimatively be used to
|
||||
// This is the type that will cd ultimatively be used to
|
||||
// expose this data type to the user.
|
||||
typedef T Out;
|
||||
|
||||
|
@ -1001,26 +998,20 @@ namespace STEP {
|
|||
refs.insert(std::make_pair(who,by_whom));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
HeaderInfo header;
|
||||
ObjectMap objects;
|
||||
ObjectMapByType objects_bytype;
|
||||
RefMap refs;
|
||||
InverseWhitelist inv_whitelist;
|
||||
|
||||
std::shared_ptr<StreamReaderLE> reader;
|
||||
LineSplitter splitter;
|
||||
|
||||
uint64_t evaluated_count;
|
||||
|
||||
const EXPRESS::ConversionSchema* schema;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // end Assimp
|
||||
#endif
|
||||
|
||||
#endif // INCLUDED_AI_STEPFILE_H
|
||||
|
|
|
@ -43,6 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <cstdarg>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
@ -103,7 +104,7 @@ float ai_strtof( const char *begin, const char *end ) {
|
|||
std::string token( begin, len );
|
||||
val = static_cast< float >( ::atof( token.c_str() ) );
|
||||
}
|
||||
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
// Header files, Assimp.
|
||||
#include "Exceptional.h"
|
||||
#include "StringUtils.h"
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "X3DImporter.hpp"
|
||||
#include "X3DImporter_Macro.hpp"
|
||||
#include "StringUtils.h"
|
||||
|
||||
// Header files, Assimp.
|
||||
#include "DefaultIOSystem.h"
|
||||
|
@ -55,11 +56,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
|
||||
/// \var aiImporterDesc X3DImporter::Description
|
||||
/// Conastant which hold importer description
|
||||
/// Constant which holds the importer description
|
||||
const aiImporterDesc X3DImporter::Description = {
|
||||
"Extensible 3D(X3D) Importer",
|
||||
"smalcom",
|
||||
|
@ -87,7 +87,7 @@ void X3DImporter::Clear()
|
|||
|
||||
X3DImporter::~X3DImporter()
|
||||
{
|
||||
if(mReader != nullptr) delete mReader;
|
||||
delete mReader;
|
||||
// Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
|
||||
Clear();
|
||||
}
|
||||
|
@ -114,13 +114,16 @@ bool X3DImporter::FindNodeElement_FromRoot(const std::string& pID, const CX3DImp
|
|||
bool X3DImporter::FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, const std::string& pID,
|
||||
const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
|
||||
{
|
||||
bool found = false;// flag: true - if requested element is found.
|
||||
bool found = false;// flag: true - if requested element is found.
|
||||
|
||||
// Check if pStartNode - this is the element, we are looking for.
|
||||
if((pStartNode->Type == pType) && (pStartNode->ID == pID))
|
||||
{
|
||||
found = true;
|
||||
if(pElement != nullptr) *pElement = pStartNode;
|
||||
if ( pElement != nullptr )
|
||||
{
|
||||
*pElement = pStartNode;
|
||||
}
|
||||
|
||||
goto fne_fn_end;
|
||||
}// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID))
|
||||
|
@ -129,7 +132,10 @@ bool found = false;// flag: true - if requested element is found.
|
|||
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ch_it++)
|
||||
{
|
||||
found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement);
|
||||
if(found) break;
|
||||
if ( found )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = it->Child.begin(); ch_it != it->Child.end(); ch_it++)
|
||||
|
||||
fne_fn_end:
|
||||
|
@ -150,7 +156,6 @@ bool X3DImporter::FindNodeElement(const std::string& pID, const CX3DImporter_Nod
|
|||
if(((CX3DImporter_NodeElement_Group*)tnd)->Static)
|
||||
{
|
||||
static_search = true;// Flag found, stop walking up. Node with static flag will holded in tnd variable.
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -159,10 +164,14 @@ bool X3DImporter::FindNodeElement(const std::string& pID, const CX3DImporter_Nod
|
|||
}// while(tnd != nullptr)
|
||||
|
||||
// at now call appropriate search function.
|
||||
if(static_search)
|
||||
return FindNodeElement_FromNode(tnd, pID, pType, pElement);
|
||||
else
|
||||
return FindNodeElement_FromRoot(pID, pType, pElement);
|
||||
if ( static_search )
|
||||
{
|
||||
return FindNodeElement_FromNode( tnd, pID, pType, pElement );
|
||||
}
|
||||
else
|
||||
{
|
||||
return FindNodeElement_FromRoot( pID, pType, pElement );
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************************************************************/
|
||||
|
@ -775,7 +784,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list<
|
|||
|
||||
aiVector3D X3DImporter::GeometryHelper_Make_Point2D(const float pAngle, const float pRadius)
|
||||
{
|
||||
return aiVector3D(pRadius * cosf(pAngle), pRadius * sinf(pAngle), 0);
|
||||
return aiVector3D(pRadius * std::cos(pAngle), pRadius * std::sin(pAngle), 0);
|
||||
}
|
||||
|
||||
void X3DImporter::GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments,
|
||||
|
@ -786,7 +795,7 @@ void X3DImporter::GeometryHelper_Make_Arc2D(const float pStartAngle, const float
|
|||
{
|
||||
Throw_ArgOutOfRange( "GeometryHelper_Make_Arc2D.pStartAngle" );
|
||||
}
|
||||
if ( ( pEndAngle < -AI_MATH_TWO_PI_F ) || ( pEndAngle > AI_MATH_TWO_PI_F ) )
|
||||
if ( ( pEndAngle < -AI_MATH_TWO_PI_F ) || ( pEndAngle > AI_MATH_TWO_PI_F ) )
|
||||
{
|
||||
Throw_ArgOutOfRange( "GeometryHelper_Make_Arc2D.pEndAngle" );
|
||||
}
|
||||
|
@ -796,7 +805,7 @@ void X3DImporter::GeometryHelper_Make_Arc2D(const float pStartAngle, const float
|
|||
}
|
||||
|
||||
// calculate arc angle and check type of arc
|
||||
float angle_full = fabs(pEndAngle - pStartAngle);
|
||||
float angle_full = std::fabs(pEndAngle - pStartAngle);
|
||||
if ( ( angle_full > AI_MATH_TWO_PI_F ) || ( angle_full == 0.0f ) )
|
||||
{
|
||||
angle_full = AI_MATH_TWO_PI_F;
|
||||
|
@ -968,8 +977,8 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
|
|||
{
|
||||
if(pColors.size() < pMesh.mNumVertices)
|
||||
{
|
||||
throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + std::to_string(pColors.size()) + ") can not be less than Vertices count(" +
|
||||
std::to_string(pMesh.mNumVertices) + ").");
|
||||
throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + to_string(pColors.size()) + ") can not be less than Vertices count(" +
|
||||
to_string(pMesh.mNumVertices) + ").");
|
||||
}
|
||||
|
||||
// copy colors to mesh
|
||||
|
@ -980,8 +989,8 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
|
|||
{
|
||||
if(pColors.size() < pMesh.mNumFaces)
|
||||
{
|
||||
throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + std::to_string(pColors.size()) + ") can not be less than Faces count(" +
|
||||
std::to_string(pMesh.mNumFaces) + ").");
|
||||
throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + to_string(pColors.size()) + ") can not be less than Faces count(" +
|
||||
to_string(pMesh.mNumFaces) + ").");
|
||||
}
|
||||
|
||||
// copy colors to mesh
|
||||
|
@ -989,7 +998,10 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D
|
|||
for(size_t fi = 0; fi < pMesh.mNumFaces; fi++)
|
||||
{
|
||||
// apply color to all vertices of face
|
||||
for(size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) pMesh.mColors[0][pMesh.mFaces[fi].mIndices[vi]] = *col_it;
|
||||
for ( size_t vi = 0, vi_e = pMesh.mFaces[ fi ].mNumIndices; vi < vi_e; vi++ )
|
||||
{
|
||||
pMesh.mColors[ 0 ][ pMesh.mFaces[ fi ].mIndices[ vi ] ] = *col_it;
|
||||
}
|
||||
|
||||
col_it++;
|
||||
}
|
||||
|
@ -1037,16 +1049,25 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
|
|||
// check indices array count.
|
||||
if(pColorIdx.size() < pCoordIdx.size())
|
||||
{
|
||||
throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + std::to_string(pColorIdx.size()) +
|
||||
") can not be less than Coords inidces count(" + std::to_string(pCoordIdx.size()) + ").");
|
||||
throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + to_string(pColorIdx.size()) +
|
||||
") can not be less than Coords inidces count(" + to_string(pCoordIdx.size()) + ").");
|
||||
}
|
||||
// create list with colors for every vertex.
|
||||
col_tgt_arr.resize(pMesh.mNumVertices);
|
||||
for(std::list<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++)
|
||||
{
|
||||
if(*colidx_it == (-1)) continue;// skip faces delimiter
|
||||
if((unsigned int)(*coordidx_it) > pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddColor2. Coordinate idx is out of range.");
|
||||
if((unsigned int)*colidx_it > pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddColor2. Color idx is out of range.");
|
||||
if ( *colidx_it == ( -1 ) )
|
||||
{
|
||||
continue;// skip faces delimiter
|
||||
}
|
||||
if ( ( unsigned int ) ( *coordidx_it ) > pMesh.mNumVertices )
|
||||
{
|
||||
throw DeadlyImportError( "MeshGeometry_AddColor2. Coordinate idx is out of range." );
|
||||
}
|
||||
if ( ( unsigned int ) *colidx_it > pMesh.mNumVertices )
|
||||
{
|
||||
throw DeadlyImportError( "MeshGeometry_AddColor2. Color idx is out of range." );
|
||||
}
|
||||
|
||||
col_tgt_arr[*coordidx_it] = col_arr_copy[*colidx_it];
|
||||
}
|
||||
|
@ -1057,12 +1078,15 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
|
|||
// check indices array count.
|
||||
if(pColors.size() < pMesh.mNumVertices)
|
||||
{
|
||||
throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + std::to_string(pColors.size()) + ") can not be less than Vertices count(" +
|
||||
std::to_string(pMesh.mNumVertices) + ").");
|
||||
throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + to_string(pColors.size()) + ") can not be less than Vertices count(" +
|
||||
to_string(pMesh.mNumVertices) + ").");
|
||||
}
|
||||
// create list with colors for every vertex.
|
||||
col_tgt_arr.resize(pMesh.mNumVertices);
|
||||
for(size_t i = 0; i < pMesh.mNumVertices; i++) col_tgt_arr[i] = col_arr_copy[i];
|
||||
for ( size_t i = 0; i < pMesh.mNumVertices; i++ )
|
||||
{
|
||||
col_tgt_arr[ i ] = col_arr_copy[ i ];
|
||||
}
|
||||
}// if(pColorIdx.size() > 0) else
|
||||
}// if(pColorPerVertex)
|
||||
else
|
||||
|
@ -1072,8 +1096,8 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
|
|||
// check indices array count.
|
||||
if(pColorIdx.size() < pMesh.mNumFaces)
|
||||
{
|
||||
throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + std::to_string(pColorIdx.size()) +
|
||||
") can not be less than Faces count(" + std::to_string(pMesh.mNumFaces) + ").");
|
||||
throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + to_string(pColorIdx.size()) +
|
||||
") can not be less than Faces count(" + to_string(pMesh.mNumFaces) + ").");
|
||||
}
|
||||
// create list with colors for every vertex using faces indices.
|
||||
col_tgt_arr.resize(pMesh.mNumFaces);
|
||||
|
@ -1092,8 +1116,8 @@ void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>&
|
|||
// check indices array count.
|
||||
if(pColors.size() < pMesh.mNumFaces)
|
||||
{
|
||||
throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + std::to_string(pColors.size()) + ") can not be less than Faces count(" +
|
||||
std::to_string(pMesh.mNumFaces) + ").");
|
||||
throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + to_string(pColors.size()) + ") can not be less than Faces count(" +
|
||||
to_string(pMesh.mNumFaces) + ").");
|
||||
}
|
||||
// create list with colors for every vertex using faces indices.
|
||||
col_tgt_arr.resize(pMesh.mNumFaces);
|
||||
|
@ -1148,8 +1172,8 @@ void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<int32_t>
|
|||
for(size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++)
|
||||
{
|
||||
if(tind[i] >= norm_arr_copy.size())
|
||||
throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + std::to_string(tind[i]) +
|
||||
") is out of range. Normals count: " + std::to_string(norm_arr_copy.size()) + ".");
|
||||
throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + to_string(tind[i]) +
|
||||
") is out of range. Normals count: " + to_string(norm_arr_copy.size()) + ".");
|
||||
|
||||
pMesh.mNormals[i] = norm_arr_copy[tind[i]];
|
||||
}
|
||||
|
@ -1249,7 +1273,7 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<int32_
|
|||
for(size_t fi = 0, fi_e = faces.size(); fi < fi_e; fi++)
|
||||
{
|
||||
if(pMesh.mFaces[fi].mNumIndices != faces.at(fi).mNumIndices)
|
||||
throw DeadlyImportError("Number of indices in texture face and mesh face must be equal. Invalid face index: " + std::to_string(fi) + ".");
|
||||
throw DeadlyImportError("Number of indices in texture face and mesh face must be equal. Invalid face index: " + to_string(fi) + ".");
|
||||
|
||||
for(size_t ii = 0; ii < pMesh.mFaces[fi].mNumIndices; ii++)
|
||||
{
|
||||
|
@ -1288,10 +1312,8 @@ void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVect
|
|||
|
||||
aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::list<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const
|
||||
{
|
||||
aiMesh* tmesh( nullptr );
|
||||
std::vector<aiFace> faces;
|
||||
unsigned int prim_type = 0;
|
||||
size_t ts;
|
||||
|
||||
// create faces array from input string with vertices indices.
|
||||
GeometryHelper_CoordIdxStr2FacesArr(pCoordIdx, faces, prim_type);
|
||||
|
@ -1303,8 +1325,8 @@ aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::list<int32_t>& pCoordIdx
|
|||
//
|
||||
// Create new mesh and copy geometry data.
|
||||
//
|
||||
tmesh = new aiMesh;
|
||||
ts = faces.size();
|
||||
aiMesh *tmesh = new aiMesh;
|
||||
size_t ts = faces.size();
|
||||
// faces
|
||||
tmesh->mFaces = new aiFace[ts];
|
||||
tmesh->mNumFaces = ts;
|
||||
|
@ -1457,7 +1479,7 @@ void X3DImporter::ParseNode_Head()
|
|||
{
|
||||
XML_CheckNode_MustBeEmpty();
|
||||
|
||||
// adding metada from <head> as MetaString from <Scene>
|
||||
// adding metadata from <head> as MetaString from <Scene>
|
||||
CX3DImporter_NodeElement_MetaString* ms = new CX3DImporter_NodeElement_MetaString(NodeElement_Cur);
|
||||
|
||||
ms->Name = mReader->getAttributeValueSafe("name");
|
||||
|
@ -1466,8 +1488,10 @@ void X3DImporter::ParseNode_Head()
|
|||
{
|
||||
ms->Value.push_back(mReader->getAttributeValueSafe("content"));
|
||||
NodeElement_List.push_back(ms);
|
||||
if(NodeElement_Cur != nullptr) NodeElement_Cur->Child.push_back(ms);
|
||||
|
||||
if ( NodeElement_Cur != nullptr )
|
||||
{
|
||||
NodeElement_Cur->Child.push_back( ms );
|
||||
}
|
||||
}
|
||||
}// if(XML_CheckNode_NameEqual("meta"))
|
||||
}// if(mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||
|
@ -1476,14 +1500,15 @@ void X3DImporter::ParseNode_Head()
|
|||
if(XML_CheckNode_NameEqual("head"))
|
||||
{
|
||||
close_found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}// if(mReader->getNodeType() == irr::io::EXN_ELEMENT) else
|
||||
}// while(mReader->read())
|
||||
|
||||
if(!close_found) Throw_CloseNotFound("head");
|
||||
|
||||
if ( !close_found )
|
||||
{
|
||||
Throw_CloseNotFound( "head" );
|
||||
}
|
||||
}
|
||||
|
||||
void X3DImporter::ParseNode_Scene()
|
||||
|
@ -1501,10 +1526,10 @@ auto GroupCounter_Decrease = [&](size_t& pCounter, const char* pGroupName) -> vo
|
|||
pCounter--;
|
||||
};
|
||||
|
||||
const char* GroupName_Group = "Group";
|
||||
const char* GroupName_StaticGroup = "StaticGroup";
|
||||
const char* GroupName_Transform = "Transform";
|
||||
const char* GroupName_Switch = "Switch";
|
||||
static const char* GroupName_Group = "Group";
|
||||
static const char* GroupName_StaticGroup = "StaticGroup";
|
||||
static const char* GroupName_Transform = "Transform";
|
||||
static const char* GroupName_Switch = "Switch";
|
||||
|
||||
bool close_found = false;
|
||||
size_t counter_group = 0;
|
||||
|
@ -1550,7 +1575,7 @@ size_t counter_switch = 0;
|
|||
if(mReader->isEmptyElement()) GroupCounter_Decrease(counter_switch, GroupName_Switch);
|
||||
}
|
||||
else if(XML_CheckNode_NameEqual("DirectionalLight"))
|
||||
{
|
||||
{
|
||||
ParseNode_Lighting_DirectionalLight();
|
||||
}
|
||||
else if(XML_CheckNode_NameEqual("PointLight"))
|
||||
|
|
|
@ -157,7 +157,7 @@ void X3DImporter::ParseNode_Geometry2D_ArcClose2D()
|
|||
// create point list of geometry object.
|
||||
GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);///TODO: IME - AI_CONFIG for NumSeg
|
||||
// add chord or two radiuses only if not a circle was defined
|
||||
if(!((fabs(endAngle - startAngle) >= AI_MATH_TWO_PI_F) || (endAngle == startAngle)))
|
||||
if(!((std::fabs(endAngle - startAngle) >= AI_MATH_TWO_PI_F) || (endAngle == startAngle)))
|
||||
{
|
||||
std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias.
|
||||
|
||||
|
|
|
@ -46,9 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "X3DImporter.hpp"
|
||||
#include "X3DImporter_Macro.hpp"
|
||||
#include "StringUtils.h"
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
|
||||
// <DirectionalLight
|
||||
// DEF="" ID
|
||||
|
@ -95,7 +95,7 @@ void X3DImporter::ParseNode_Lighting_DirectionalLight()
|
|||
if(!def.empty())
|
||||
ne->ID = def;
|
||||
else
|
||||
ne->ID = "DirectionalLight_" + std::to_string((size_t)ne);// make random name
|
||||
ne->ID = "DirectionalLight_" + to_string((size_t)ne);// make random name
|
||||
|
||||
((CX3DImporter_NodeElement_Light*)ne)->AmbientIntensity = ambientIntensity;
|
||||
((CX3DImporter_NodeElement_Light*)ne)->Color = color;
|
||||
|
@ -178,7 +178,7 @@ void X3DImporter::ParseNode_Lighting_PointLight()
|
|||
// Assimp want a node with name similar to a light. "Why? I don't no." )
|
||||
ParseHelper_Group_Begin(false);
|
||||
// make random name
|
||||
if(ne->ID.empty()) ne->ID = "PointLight_" + std::to_string((size_t)ne);
|
||||
if(ne->ID.empty()) ne->ID = "PointLight_" + to_string((size_t)ne);
|
||||
|
||||
NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element.
|
||||
ParseHelper_Node_Exit();
|
||||
|
@ -268,7 +268,7 @@ void X3DImporter::ParseNode_Lighting_SpotLight()
|
|||
// Assimp want a node with name similar to a light. "Why? I don't no." )
|
||||
ParseHelper_Group_Begin(false);
|
||||
// make random name
|
||||
if(ne->ID.empty()) ne->ID = "SpotLight_" + std::to_string((size_t)ne);
|
||||
if(ne->ID.empty()) ne->ID = "SpotLight_" + to_string((size_t)ne);
|
||||
|
||||
NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element.
|
||||
ParseHelper_Node_Exit();
|
||||
|
|
|
@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
// Header files, Assimp.
|
||||
#include "StandardShapes.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
// Header files, stdlib.
|
||||
#include <algorithm>
|
||||
|
@ -174,7 +175,7 @@ void X3DImporter::Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeEl
|
|||
|
||||
break;
|
||||
default:
|
||||
throw DeadlyImportError("Postprocess_BuildLight. Unknown type of light: " + std::to_string(pNodeElement.Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildLight. Unknown type of light: " + to_string(pNodeElement.Type) + ".");
|
||||
}
|
||||
|
||||
pSceneLightList.push_back(new_light);
|
||||
|
@ -296,7 +297,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
|
||||
MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + std::to_string((*ch_it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
|
@ -333,7 +334,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
|
||||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + std::to_string((*ch_it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
|
@ -363,7 +364,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{} // skip because already read when mesh created.
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + std::to_string((*ch_it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
|
@ -401,7 +402,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \
|
||||
IndexedTriangleStripSet: " + std::to_string((*ch_it)->Type) + ".");
|
||||
IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
|
@ -451,7 +452,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{} // skip because already read when mesh created.
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + std::to_string((*ch_it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
|
@ -480,7 +481,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
|
||||
{} // skip because already read when mesh created.
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + std::to_string((*ch_it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
|
@ -514,7 +515,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
|
||||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + std::to_string((*ch_it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
|
@ -557,7 +558,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
|
||||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + std::to_string((*ch_it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
|
@ -591,13 +592,13 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
|
|||
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
|
||||
MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
|
||||
else
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + std::to_string((*ch_it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + ".");
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
|
||||
|
||||
return;// mesh is build, nothing to do anymore.
|
||||
}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet)
|
||||
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown mesh type: " + std::to_string(pNodeElement.Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildMesh. Unknown mesh type: " + to_string(pNodeElement.Type) + ".");
|
||||
}
|
||||
|
||||
void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list<aiMesh*>& pSceneMeshList,
|
||||
|
@ -659,7 +660,7 @@ void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeEle
|
|||
}
|
||||
else if(!PostprocessHelper_ElementIsMetadata((*it)->Type))// skip metadata
|
||||
{
|
||||
throw DeadlyImportError("Postprocess_BuildNode. Unknown type: " + std::to_string((*it)->Type) + ".");
|
||||
throw DeadlyImportError("Postprocess_BuildNode. Unknown type: " + to_string((*it)->Type) + ".");
|
||||
}
|
||||
}// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
|
||||
|
||||
|
|
|
@ -731,7 +731,7 @@ void XFileParser::ParseDataObjectMaterial( Material* pMaterial)
|
|||
std::string matName;
|
||||
readHeadOfDataObject( &matName);
|
||||
if( matName.empty())
|
||||
matName = std::string( "material") + std::to_string( mLineNumber );
|
||||
matName = std::string( "material") + to_string( mLineNumber );
|
||||
pMaterial->mName = matName;
|
||||
pMaterial->mIsReference = false;
|
||||
|
||||
|
|
|
@ -501,7 +501,7 @@ aiMatrix4x4 XGLImporter::ReadTrafo()
|
|||
up.Normalize();
|
||||
|
||||
right = forward ^ up;
|
||||
if (fabs(up * forward) > 1e-4) {
|
||||
if (std::fabs(up * forward) > 1e-4) {
|
||||
// this is definitely wrong - a degenerate coordinate space ruins everything
|
||||
// so subtitute identity transform.
|
||||
LogError("<forward> and <up> vectors in <transform> are skewing, ignoring trafo");
|
||||
|
|
|
@ -811,6 +811,8 @@ namespace glTF
|
|||
Ref<Skin> skin; //!< The ID of the skin referenced by this node.
|
||||
std::string jointName; //!< Name used when this node is a joint in a skin.
|
||||
|
||||
Ref<Node> parent; //!< This is not part of the glTF specification. Used as a helper.
|
||||
|
||||
Node() {}
|
||||
void Read(Value& obj, Asset& r);
|
||||
};
|
||||
|
@ -852,7 +854,7 @@ namespace glTF
|
|||
{
|
||||
Nullable<mat4> bindShapeMatrix; //!< Floating-point 4x4 transformation matrix stored in column-major order.
|
||||
Ref<Accessor> inverseBindMatrices; //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices.
|
||||
std::vector<std::string/*Ref<Node>*/> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin.
|
||||
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() {}
|
||||
|
|
|
@ -292,14 +292,14 @@ inline void Buffer::Read(Value& obj, Asset& r)
|
|||
this->mData.reset(data);
|
||||
|
||||
if (statedLength > 0 && this->byteLength != statedLength) {
|
||||
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + std::to_string(statedLength) +
|
||||
" bytes, but found " + std::to_string(dataURI.dataLength));
|
||||
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
|
||||
" bytes, but found " + to_string(dataURI.dataLength));
|
||||
}
|
||||
}
|
||||
else { // assume raw data
|
||||
if (statedLength != dataURI.dataLength) {
|
||||
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + std::to_string(statedLength) +
|
||||
" bytes, but found " + std::to_string(dataURI.dataLength));
|
||||
throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
|
||||
" bytes, but found " + to_string(dataURI.dataLength));
|
||||
}
|
||||
|
||||
this->mData.reset(new uint8_t[dataURI.dataLength]);
|
||||
|
@ -991,7 +991,7 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
|
|||
|
||||
break;
|
||||
default:
|
||||
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + std::to_string(ifs.GetFloatAttributeType(idx)));
|
||||
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(idx)));
|
||||
}
|
||||
|
||||
tval *= ifs.GetFloatAttributeDim(idx) * sizeof(o3dgc::Real);// After checking count of objects we can get size of array.
|
||||
|
@ -1003,11 +1003,10 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
|
|||
{
|
||||
// size = number_of_elements * components_per_element * size_of_component. See float attributes note.
|
||||
size_t tval = ifs.GetNIntAttribute(idx);
|
||||
|
||||
switch(ifs.GetIntAttributeType(idx))
|
||||
switch( ifs.GetIntAttributeType( idx ) )
|
||||
{
|
||||
default:
|
||||
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + std::to_string(ifs.GetIntAttributeType(idx)));
|
||||
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(idx)));
|
||||
}
|
||||
|
||||
tval *= ifs.GetIntAttributeDim(idx) * sizeof(long);// See float attributes note.
|
||||
|
@ -1046,7 +1045,7 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
|
|||
|
||||
break;
|
||||
default:
|
||||
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + std::to_string(ifs.GetFloatAttributeType(idx)));
|
||||
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(idx)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1056,7 +1055,7 @@ Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
|
|||
{
|
||||
// ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint)));
|
||||
default:
|
||||
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + std::to_string(ifs.GetIntAttributeType(idx)));
|
||||
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(idx)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1621,6 +1620,4 @@ namespace Util {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // ns glTF
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace glTF {
|
|||
inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
|
||||
val.SetArray();
|
||||
val.Reserve(r.size(), al);
|
||||
for (int i = 0; i < r.size(); ++i) {
|
||||
for (unsigned int i = 0; i < r.size(); ++i) {
|
||||
val.PushBack(r[i], al);
|
||||
}
|
||||
return val;
|
||||
|
@ -436,7 +436,7 @@ namespace glTF {
|
|||
vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl);
|
||||
|
||||
for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) {
|
||||
vJointNames.PushBack(StringRef(b.jointNames[i]), w.mAl);
|
||||
vJointNames.PushBack(StringRef(b.jointNames[i]->jointName), w.mAl);
|
||||
}
|
||||
obj.AddMember("jointNames", vJointNames, w.mAl);
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
|
|||
ExportMaterials();
|
||||
|
||||
if (mScene->mRootNode) {
|
||||
ExportNode(mScene->mRootNode);
|
||||
ExportNodeHierarchy(mScene->mRootNode);
|
||||
}
|
||||
|
||||
ExportMeshes();
|
||||
|
@ -152,7 +152,10 @@ glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiSc
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy a 4x4 matrix from struct aiMatrix to typedef mat4.
|
||||
* Also converts from row-major to column-major storage.
|
||||
*/
|
||||
static void CopyValue(const aiMatrix4x4& v, glTF::mat4& o)
|
||||
{
|
||||
o[ 0] = v.a1; o[ 1] = v.b1; o[ 2] = v.c1; o[ 3] = v.d1;
|
||||
|
@ -161,6 +164,14 @@ static void CopyValue(const aiMatrix4x4& v, glTF::mat4& o)
|
|||
o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4;
|
||||
}
|
||||
|
||||
static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o)
|
||||
{
|
||||
o.a1 = v.a1; o.a2 = v.a2; o.a3 = v.a3; o.a4 = v.a4;
|
||||
o.b1 = v.b1; o.b2 = v.b2; o.b3 = v.b3; o.b4 = v.b4;
|
||||
o.c1 = v.c1; o.c2 = v.c2; o.c3 = v.c3; o.c4 = v.c4;
|
||||
o.d1 = v.d1; o.d2 = v.d2; o.d3 = v.d3; o.d4 = v.d4;
|
||||
}
|
||||
|
||||
static void IdentityMatrix4(glTF::mat4& o)
|
||||
{
|
||||
o[ 0] = 1; o[ 1] = 0; o[ 2] = 0; o[ 3] = 0;
|
||||
|
@ -201,30 +212,29 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
|
|||
// calculate min and max values
|
||||
{
|
||||
// Allocate and initialize with large values.
|
||||
float float_MAX = 10000000000000;
|
||||
for (int i = 0 ; i < numCompsOut ; i++) {
|
||||
float float_MAX = 10000000000000.0f;
|
||||
for (unsigned int i = 0 ; i < numCompsOut ; i++) {
|
||||
acc->min.push_back( float_MAX);
|
||||
acc->max.push_back(-float_MAX);
|
||||
}
|
||||
|
||||
// Search and set extreme values.
|
||||
float valueTmp;
|
||||
for (int i = 0 ; i < count ; i++) {
|
||||
for (int j = 0 ; j < numCompsOut ; j++) {
|
||||
for (unsigned int i = 0 ; i < count ; i++) {
|
||||
for (unsigned int j = 0 ; j < numCompsOut ; j++) {
|
||||
if (numCompsOut == 1) {
|
||||
valueTmp = static_cast<unsigned short*>(data)[i];
|
||||
} else {
|
||||
valueTmp = static_cast<aiVector3D*>(data)[i][j];
|
||||
}
|
||||
|
||||
if (numCompsOut == 1) {
|
||||
valueTmp = static_cast<unsigned short*>(data)[i];
|
||||
} else {
|
||||
valueTmp = static_cast<aiVector3D*>(data)[i][j];
|
||||
if (valueTmp < acc->min[j]) {
|
||||
acc->min[j] = valueTmp;
|
||||
}
|
||||
if (valueTmp > acc->max[j]) {
|
||||
acc->max[j] = valueTmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (valueTmp < acc->min[j]) {
|
||||
acc->min[j] = valueTmp;
|
||||
}
|
||||
if (valueTmp > acc->max[j]) {
|
||||
acc->max[j] = valueTmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,20 +374,61 @@ void glTFExporter::ExportMaterials()
|
|||
}
|
||||
}
|
||||
|
||||
void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef)
|
||||
/*
|
||||
* Search through node hierarchy and find the node containing the given meshID.
|
||||
* Returns true on success, and false otherwise.
|
||||
*/
|
||||
bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
|
||||
{
|
||||
std::string skinName = aim->mName.C_Str();
|
||||
skinName = mAsset.FindUniqueID(skinName, "skin");
|
||||
Ref<Skin> skinRef = mAsset.skins.Create(skinName);
|
||||
skinRef->name = skinName;
|
||||
for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
|
||||
if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
|
||||
meshNode = nodeIn;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
mat4* inverseBindMatricesData = new mat4[aim->mNumBones];
|
||||
for (unsigned int i = 0; i < nodeIn->children.size(); ++i) {
|
||||
if(FindMeshNode(nodeIn->children[i], meshNode, meshID)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the root joint of the skeleton.
|
||||
* Starts will any joint node and traces up the tree,
|
||||
* until a parent is found that does not have a jointName.
|
||||
* Returns the first parent Ref<Node> found that does not have a jointName.
|
||||
*/
|
||||
Ref<Node> FindSkeletonRootJoint(Ref<Skin>& skinRef)
|
||||
{
|
||||
Ref<Node> startNodeRef;
|
||||
Ref<Node> parentNodeRef;
|
||||
|
||||
// Arbitrarily use the first joint to start the search.
|
||||
startNodeRef = skinRef->jointNames[0];
|
||||
parentNodeRef = skinRef->jointNames[0];
|
||||
|
||||
do {
|
||||
startNodeRef = parentNodeRef;
|
||||
parentNodeRef = startNodeRef->parent;
|
||||
} while (!parentNodeRef->jointName.empty());
|
||||
|
||||
return parentNodeRef;
|
||||
}
|
||||
|
||||
void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef, Ref<Skin>& skinRef, std::vector<aiMatrix4x4>& inverseBindMatricesData)
|
||||
{
|
||||
if (aim->mNumBones < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Store the vertex joint and weight data.
|
||||
vec4* vertexJointData = new vec4[aim->mNumVertices];
|
||||
vec4* vertexWeightData = new vec4[aim->mNumVertices];
|
||||
unsigned int* jointsPerVertex = new unsigned int[aim->mNumVertices];
|
||||
int* jointsPerVertex = new int[aim->mNumVertices];
|
||||
for (size_t i = 0; i < aim->mNumVertices; ++i) {
|
||||
jointsPerVertex[i] = 0;
|
||||
for (size_t j = 0; j < 4; ++j) {
|
||||
|
@ -392,48 +443,49 @@ void ExportSkin(Asset& mAsset, const aiMesh* aim, Ref<Mesh>& meshRef, Ref<Buffer
|
|||
// aib->mName =====> skinRef->jointNames
|
||||
// Find the node with id = mName.
|
||||
Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
|
||||
nodeRef->jointName = "joint_" + std::to_string(idx_bone);
|
||||
skinRef->jointNames.push_back("joint_" + std::to_string(idx_bone));
|
||||
nodeRef->jointName = nodeRef->id;
|
||||
|
||||
// Identity Matrix =====> skinRef->bindShapeMatrix
|
||||
// Temporary. Hard-coded identity matrix here
|
||||
skinRef->bindShapeMatrix.isPresent = true;
|
||||
IdentityMatrix4(skinRef->bindShapeMatrix.value);
|
||||
unsigned int jointNamesIndex;
|
||||
bool addJointToJointNames = true;
|
||||
for (int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
|
||||
if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
|
||||
addJointToJointNames = false;
|
||||
jointNamesIndex = idx_joint;
|
||||
}
|
||||
}
|
||||
|
||||
// aib->mOffsetMatrix =====> skinRef->inverseBindMatrices
|
||||
CopyValue(aib->mOffsetMatrix, inverseBindMatricesData[idx_bone]);
|
||||
if (addJointToJointNames) {
|
||||
skinRef->jointNames.push_back(nodeRef);
|
||||
|
||||
// aib->mOffsetMatrix =====> skinRef->inverseBindMatrices
|
||||
aiMatrix4x4 tmpMatrix4;
|
||||
CopyValue(aib->mOffsetMatrix, tmpMatrix4);
|
||||
inverseBindMatricesData.push_back(tmpMatrix4);
|
||||
jointNamesIndex = inverseBindMatricesData.size() - 1;
|
||||
}
|
||||
|
||||
// aib->mWeights =====> vertexWeightData
|
||||
for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) {
|
||||
aiVertexWeight tmpVertWeight = aib->mWeights[idx_weights];
|
||||
vertexJointData[tmpVertWeight.mVertexId][jointsPerVertex[tmpVertWeight.mVertexId]] = idx_bone;
|
||||
vertexWeightData[tmpVertWeight.mVertexId][jointsPerVertex[tmpVertWeight.mVertexId]] = tmpVertWeight.mWeight;
|
||||
unsigned int vertexId = aib->mWeights[idx_weights].mVertexId;
|
||||
float vertWeight = aib->mWeights[idx_weights].mWeight;
|
||||
|
||||
jointsPerVertex[tmpVertWeight.mVertexId] += 1;
|
||||
// A vertex can only have at most four joint weights. Ignore all others.
|
||||
if (jointsPerVertex[vertexId] > 3) { continue; }
|
||||
|
||||
vertexJointData[vertexId][jointsPerVertex[vertexId]] = jointNamesIndex;
|
||||
vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
|
||||
|
||||
jointsPerVertex[vertexId] += 1;
|
||||
}
|
||||
|
||||
} // End: for-loop mNumMeshes
|
||||
|
||||
// Create the Accessor for skinRef->inverseBindMatrices
|
||||
Ref<Accessor> invBindMatrixAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumBones, inverseBindMatricesData, AttribType::MAT4, AttribType::MAT4, ComponentType_FLOAT);
|
||||
if (invBindMatrixAccessor) skinRef->inverseBindMatrices = invBindMatrixAccessor;
|
||||
|
||||
|
||||
Mesh::Primitive& p = meshRef->primitives.back();
|
||||
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aim->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
if (vertexJointAccessor) p.attributes.joint.push_back(vertexJointAccessor);
|
||||
|
||||
Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinName, bufferRef, aim->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinRef->id, bufferRef, aim->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
if (vertexWeightAccessor) p.attributes.weight.push_back(vertexWeightAccessor);
|
||||
|
||||
|
||||
// Create the skinned mesh instance node.
|
||||
Ref<Node> node = mAsset.nodes.Create(mAsset.FindUniqueID(skinName, "node"));
|
||||
// Ref<Node> node = mAsset.nodes.Get(aim->mBones[0]->mName.C_Str());
|
||||
node->meshes.push_back(meshRef);
|
||||
node->name = node->id;
|
||||
node->skeletons.push_back(mAsset.nodes.Get(aim->mBones[0]->mName.C_Str()));
|
||||
node->skin = skinRef;
|
||||
}
|
||||
|
||||
void glTFExporter::ExportMeshes()
|
||||
|
@ -463,6 +515,26 @@ void glTFExporter::ExportMeshes()
|
|||
b = mAsset->buffers.Create(bufferId);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Initialize variables for the skin
|
||||
bool createSkin = false;
|
||||
for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
|
||||
const aiMesh* aim = mScene->mMeshes[idx_mesh];
|
||||
if(aim->HasBones()) {
|
||||
createSkin = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Skin> skinRef;
|
||||
std::string skinName = mAsset->FindUniqueID("skin", "skin");
|
||||
std::vector<aiMatrix4x4> inverseBindMatricesData;
|
||||
if(createSkin) {
|
||||
skinRef = mAsset->skins.Create(skinName);
|
||||
skinRef->name = skinName;
|
||||
}
|
||||
//----------------------------------------
|
||||
|
||||
for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
|
||||
const aiMesh* aim = mScene->mMeshes[idx_mesh];
|
||||
|
||||
|
@ -558,10 +630,9 @@ void glTFExporter::ExportMeshes()
|
|||
}
|
||||
|
||||
/*************** Skins ****************/
|
||||
///TODO: Fix skinning animation
|
||||
// if(aim->HasBones()) {
|
||||
// ExportSkin(*mAsset, aim, m, b);
|
||||
// }
|
||||
if(aim->HasBones()) {
|
||||
ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData);
|
||||
}
|
||||
|
||||
/****************** Compression ******************/
|
||||
///TODO: animation: weights, joints.
|
||||
|
@ -655,9 +726,41 @@ void glTFExporter::ExportMeshes()
|
|||
#endif
|
||||
}// if(comp_allow)
|
||||
}// for (unsigned int i = 0; i < mScene->mNumMeshes; ++i)
|
||||
|
||||
//----------------------------------------
|
||||
// Finish the skin
|
||||
// Create the Accessor for skinRef->inverseBindMatrices
|
||||
if (createSkin) {
|
||||
mat4* invBindMatrixData = new mat4[inverseBindMatricesData.size()];
|
||||
for (int idx_joint = 0; idx_joint < inverseBindMatricesData.size(); ++idx_joint) {
|
||||
CopyValue(inverseBindMatricesData[idx_joint], invBindMatrixData[idx_joint]);
|
||||
}
|
||||
|
||||
Ref<Accessor> invBindMatrixAccessor = ExportData(*mAsset, skinName, b, inverseBindMatricesData.size(), invBindMatrixData, AttribType::MAT4, AttribType::MAT4, ComponentType_FLOAT);
|
||||
if (invBindMatrixAccessor) skinRef->inverseBindMatrices = invBindMatrixAccessor;
|
||||
|
||||
// Identity Matrix =====> skinRef->bindShapeMatrix
|
||||
// Temporary. Hard-coded identity matrix here
|
||||
skinRef->bindShapeMatrix.isPresent = true;
|
||||
IdentityMatrix4(skinRef->bindShapeMatrix.value);
|
||||
|
||||
// Find node that contains this mesh and add "skeletons" and "skin" attributes to that node.
|
||||
Ref<Node> rootNode = mAsset->nodes.Get(unsigned(0));
|
||||
Ref<Node> meshNode;
|
||||
std::string meshID = mAsset->meshes.Get(unsigned(0))->id;
|
||||
FindMeshNode(rootNode, meshNode, meshID);
|
||||
|
||||
Ref<Node> rootJoint = FindSkeletonRootJoint(skinRef);
|
||||
meshNode->skeletons.push_back(rootJoint);
|
||||
meshNode->skin = skinRef;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int glTFExporter::ExportNode(const aiNode* n)
|
||||
/*
|
||||
* Export the root node of the node hierarchy.
|
||||
* Calls ExportNode for all children.
|
||||
*/
|
||||
unsigned int glTFExporter::ExportNodeHierarchy(const aiNode* n)
|
||||
{
|
||||
Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
|
||||
|
||||
|
@ -671,7 +774,34 @@ unsigned int glTFExporter::ExportNode(const aiNode* n)
|
|||
}
|
||||
|
||||
for (unsigned int i = 0; i < n->mNumChildren; ++i) {
|
||||
unsigned int idx = ExportNode(n->mChildren[i]);
|
||||
unsigned int idx = ExportNode(n->mChildren[i], node);
|
||||
node->children.push_back(mAsset->nodes.Get(idx));
|
||||
}
|
||||
|
||||
return node.GetIndex();
|
||||
}
|
||||
|
||||
/*
|
||||
* Export node and recursively calls ExportNode for all children.
|
||||
* Since these nodes are not the root node, we also export the parent Ref<Node>
|
||||
*/
|
||||
unsigned int glTFExporter::ExportNode(const aiNode* n, Ref<Node>& parent)
|
||||
{
|
||||
Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
|
||||
|
||||
node->parent = parent;
|
||||
|
||||
if (!n->mTransformation.IsIdentity()) {
|
||||
node->matrix.isPresent = true;
|
||||
CopyValue(n->mTransformation, node->matrix.value);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
|
||||
node->meshes.push_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));
|
||||
}
|
||||
|
||||
|
@ -753,9 +883,12 @@ inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animati
|
|||
//-------------------------------------------------------
|
||||
// Extract rotation parameter data
|
||||
if(nodeChannel->mNumRotationKeys > 0) {
|
||||
C_STRUCT aiQuaternion* rotationData = new aiQuaternion[nodeChannel->mNumRotationKeys];
|
||||
vec4* rotationData = new vec4[nodeChannel->mNumRotationKeys];
|
||||
for (size_t i = 0; i < nodeChannel->mNumRotationKeys; ++i) {
|
||||
rotationData[i] = nodeChannel->mRotationKeys[i].mValue;
|
||||
rotationData[i][0] = nodeChannel->mRotationKeys[i].mValue.x;
|
||||
rotationData[i][1] = nodeChannel->mRotationKeys[i].mValue.y;
|
||||
rotationData[i][2] = nodeChannel->mRotationKeys[i].mValue.z;
|
||||
rotationData[i][3] = nodeChannel->mRotationKeys[i].mValue.w;
|
||||
}
|
||||
|
||||
Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, nodeChannel->mNumRotationKeys, rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
|
||||
|
@ -780,7 +913,7 @@ void glTFExporter::ExportAnimations()
|
|||
|
||||
// It appears that assimp stores this type of animation as multiple animations.
|
||||
// where each aiNodeAnim in mChannels animates a specific node.
|
||||
std::string name = nameAnim + "_" + std::to_string(channelIndex);
|
||||
std::string name = nameAnim + "_" + to_string(channelIndex);
|
||||
name = mAsset->FindUniqueID(name, "animation");
|
||||
Ref<Animation> animRef = mAsset->animations.Create(name);
|
||||
|
||||
|
|
|
@ -58,8 +58,12 @@ struct aiMaterial;
|
|||
|
||||
namespace glTF
|
||||
{
|
||||
template<class T>
|
||||
class Ref;
|
||||
|
||||
class Asset;
|
||||
struct TexProperty;
|
||||
struct Node;
|
||||
}
|
||||
|
||||
namespace Assimp
|
||||
|
@ -98,7 +102,8 @@ namespace Assimp
|
|||
void ExportMetadata();
|
||||
void ExportMaterials();
|
||||
void ExportMeshes();
|
||||
unsigned int ExportNode(const aiNode* node);
|
||||
unsigned int ExportNodeHierarchy(const aiNode* n);
|
||||
unsigned int ExportNode(const aiNode* node, glTF::Ref<glTF::Node>& parent);
|
||||
void ExportScene();
|
||||
void ExportAnimations();
|
||||
};
|
||||
|
|
|
@ -41,8 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
|
||||
|
||||
#include "glTFImporter.h"
|
||||
|
||||
#include "StringComparison.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
|
@ -285,7 +285,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"" + std::to_string(cur_ext->Type) +
|
||||
throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"" + to_string(cur_ext->Type) +
|
||||
"\"), only Open3DGC is supported.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef AI_FILEIO_H_INC
|
||||
#define AI_FILEIO_H_INC
|
||||
|
||||
#include "types.h"
|
||||
#include <assimp/types.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -54,15 +54,15 @@ struct aiFileIO;
|
|||
struct aiFile;
|
||||
|
||||
// aiFile callbacks
|
||||
typedef size_t (*aiFileWriteProc) (C_STRUCT aiFile*, const char*, size_t, size_t);
|
||||
typedef size_t (*aiFileReadProc) (C_STRUCT aiFile*, char*, size_t,size_t);
|
||||
typedef size_t (*aiFileTellProc) (C_STRUCT aiFile*);
|
||||
typedef void (*aiFileFlushProc) (C_STRUCT aiFile*);
|
||||
typedef aiReturn (*aiFileSeek)(C_STRUCT aiFile*, size_t, aiOrigin);
|
||||
typedef size_t (*aiFileWriteProc) (C_STRUCT aiFile*, const char*, size_t, size_t);
|
||||
typedef size_t (*aiFileReadProc) (C_STRUCT aiFile*, char*, size_t,size_t);
|
||||
typedef size_t (*aiFileTellProc) (C_STRUCT aiFile*);
|
||||
typedef void (*aiFileFlushProc) (C_STRUCT aiFile*);
|
||||
typedef C_ENUM aiReturn (*aiFileSeek) (C_STRUCT aiFile*, size_t, C_ENUM aiOrigin);
|
||||
|
||||
// aiFileIO callbacks
|
||||
typedef aiFile* (*aiFileOpenProc) (C_STRUCT aiFileIO*, const char*, const char*);
|
||||
typedef void (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*);
|
||||
typedef C_STRUCT aiFile* (*aiFileOpenProc) (C_STRUCT aiFileIO*, const char*, const char*);
|
||||
typedef void (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*);
|
||||
|
||||
// Represents user-defined data
|
||||
typedef char* aiUserData;
|
||||
|
|
|
@ -367,21 +367,21 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
|
|||
// Use a small epsilon to solve floating-point inaccuracies
|
||||
const TReal epsilon = 10e-3f;
|
||||
|
||||
pRotation.y = asin(vCols[2].x);// D. Angle around oY.
|
||||
pRotation.y = std::asin(vCols[2].x);// D. Angle around oY.
|
||||
|
||||
TReal C = cos(pRotation.y);
|
||||
TReal C = std::cos(pRotation.y);
|
||||
|
||||
if(fabs(C) > epsilon)
|
||||
if(std::fabs(C) > epsilon)
|
||||
{
|
||||
// Finding angle around oX.
|
||||
TReal tan_x = vCols[2].z / C;// A
|
||||
TReal tan_y = -vCols[2].y / C;// B
|
||||
|
||||
pRotation.x = atan2(tan_y, tan_x);
|
||||
pRotation.x = std::atan2(tan_y, tan_x);
|
||||
// Finding angle around oZ.
|
||||
tan_x = vCols[0].x / C;// E
|
||||
tan_y = -vCols[1].x / C;// F
|
||||
pRotation.z = atan2(tan_y, tan_x);
|
||||
pRotation.z = std::atan2(tan_y, tan_x);
|
||||
}
|
||||
else
|
||||
{// oY is fixed.
|
||||
|
@ -391,7 +391,7 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
|
|||
TReal tan_x = vCols[1].y;// -BDF+AE => E
|
||||
TReal tan_y = vCols[0].y;// BDE+AF => F
|
||||
|
||||
pRotation.z = atan2(tan_y, tan_x);
|
||||
pRotation.z = std::atan2(tan_y, tan_x);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,14 +407,14 @@ aiQuaterniont<TReal> pRotation;
|
|||
pRotation.Normalize();
|
||||
|
||||
TReal angle_cos = pRotation.w;
|
||||
TReal angle_sin = sqrt(1.0f - angle_cos * angle_cos);
|
||||
TReal angle_sin = std::sqrt(1.0f - angle_cos * angle_cos);
|
||||
|
||||
pRotationAngle = acos(angle_cos) * 2;
|
||||
pRotationAngle = std::acos(angle_cos) * 2;
|
||||
|
||||
// Use a small epsilon to solve floating-point inaccuracies
|
||||
const TReal epsilon = 10e-3f;
|
||||
|
||||
if(fabs(angle_sin) < epsilon) angle_sin = 1;
|
||||
if(std::fabs(angle_sin) < epsilon) angle_sin = 1;
|
||||
|
||||
pRotationAxis.x = pRotation.x / angle_sin;
|
||||
pRotationAxis.y = pRotation.y / angle_sin;
|
||||
|
|
|
@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
// Some runtime headers
|
||||
#include <sys/types.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
|
|
@ -3,12 +3,12 @@ set(PROJECT_VERSION "")
|
|||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
find_package(Qt4 REQUIRED)
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(DevIL REQUIRED)
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
include_directories(
|
||||
${QT_INCLUDES}
|
||||
${Qt5Widgets_INCLUDES}
|
||||
${Assimp_SOURCE_DIR}/include
|
||||
${Assimp_SOURCE_DIR}/code
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
@ -21,15 +21,16 @@ link_directories(${Assimp_BINARY_DIR})
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
|
||||
|
||||
set(assimp_qt_viewer_SRCS main.cpp loggerview.cpp glview.cpp mainwindow.cpp)
|
||||
qt4_wrap_ui(UISrcs mainwindow.ui)
|
||||
qt4_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
|
||||
qt5_wrap_ui(UISrcs mainwindow.ui)
|
||||
qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
|
||||
target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTOPENGL_LIBRARY} ${IL_LIBRARIES} ${OPENGL_LIBRARIES} assimp)
|
||||
|
||||
qt5_use_modules(${PROJECT_NAME} Widgets OpenGL)
|
||||
if(WIN32) # Check if we are on Windows
|
||||
if(MSVC) # Check if we are using the Visual Studio compiler
|
||||
set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||
#set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested
|
||||
else()
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <GL/glu.h>
|
||||
|
||||
// Header files, DevIL.
|
||||
#include <IL/il.h>
|
||||
#include <il.h>
|
||||
|
||||
// Header files, Assimp.
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
@ -56,15 +56,15 @@ void CGLView::SHelper_Camera::SetDefault()
|
|||
|
||||
void CGLView::Material_Apply(const aiMaterial* pMaterial)
|
||||
{
|
||||
GLfloat tcol[4];
|
||||
aiColor4D taicol;
|
||||
unsigned int max;
|
||||
int ret1, ret2;
|
||||
int texture_index = 0;
|
||||
aiString texture_path;
|
||||
GLfloat tcol[4];
|
||||
aiColor4D taicol;
|
||||
unsigned int max;
|
||||
int ret1, ret2;
|
||||
int texture_index = 0;
|
||||
aiString texture_path;
|
||||
|
||||
auto set_float4 = [](float f[4], float a, float b, float c, float d) { f[0] = a, f[1] = b, f[2] = c, f[3] = d; };
|
||||
auto color4_to_float4 = [](const aiColor4D *c, float f[4]) { f[0] = c->r, f[1] = c->g, f[2] = c->b, f[3] = c->a; };
|
||||
auto set_float4 = [](float f[4], float a, float b, float c, float d) { f[0] = a, f[1] = b, f[2] = c, f[3] = d; };
|
||||
auto color4_to_float4 = [](const aiColor4D *c, float f[4]) { f[0] = c->r, f[1] = c->g, f[2] = c->b, f[3] = c->a; };
|
||||
|
||||
///TODO: cache materials
|
||||
// Disable color material because glMaterial is used.
|
||||
|
@ -158,124 +158,127 @@ std::list<aiMatrix4x4> mat_list;
|
|||
} while(node_cur != nullptr);
|
||||
}
|
||||
|
||||
// multiplicate all matrices in reverse order
|
||||
for(std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); rit++) pOutMatrix = pOutMatrix * (*rit);
|
||||
// multiply all matrices in reverse order
|
||||
for ( std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); rit++)
|
||||
{
|
||||
pOutMatrix = pOutMatrix * (*rit);
|
||||
}
|
||||
}
|
||||
|
||||
void CGLView::ImportTextures(const QString& pScenePath)
|
||||
{
|
||||
auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation.
|
||||
{
|
||||
ILboolean success;
|
||||
GLuint id_ogl_texture;// OpenGL texture ID.
|
||||
auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation.
|
||||
{
|
||||
ILboolean success;
|
||||
GLuint id_ogl_texture;// OpenGL texture ID.
|
||||
|
||||
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
|
||||
{
|
||||
ILuint id_image;// DevIL image ID.
|
||||
QString basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
|
||||
QString fileloc = (basepath + pFileName);
|
||||
if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
|
||||
{
|
||||
ILuint id_image;// DevIL image ID.
|
||||
QString basepath = pScenePath.left(pScenePath.lastIndexOf('/') + 1);// path with '/' at the end.
|
||||
QString fileloc = (basepath + pFileName);
|
||||
|
||||
fileloc.replace('\\', "/");
|
||||
ilGenImages(1, &id_image);// Generate DevIL image ID.
|
||||
ilBindImage(id_image);
|
||||
success = ilLoadImage(fileloc.toLocal8Bit());
|
||||
if(!success)
|
||||
{
|
||||
LogError(QString("Couldn't load Image: %1").arg(fileloc));
|
||||
fileloc.replace('\\', "/");
|
||||
ilGenImages(1, &id_image);// Generate DevIL image ID.
|
||||
ilBindImage(id_image);
|
||||
success = ilLoadImage(fileloc.toLocal8Bit());
|
||||
if(!success)
|
||||
{
|
||||
LogError(QString("Couldn't load Image: %1").arg(fileloc));
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA.
|
||||
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
|
||||
if(!success)
|
||||
{
|
||||
LogError("Couldn't convert image.");
|
||||
// Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA.
|
||||
success = ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
|
||||
if(!success)
|
||||
{
|
||||
LogError("Couldn't convert image.");
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
glGenTextures(1, &id_ogl_texture);// Texture ID generation.
|
||||
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
|
||||
glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
|
||||
// Redefine standard texture values
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0,
|
||||
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
|
||||
glGenTextures(1, &id_ogl_texture);// Texture ID generation.
|
||||
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
|
||||
glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
|
||||
// Redefine standard texture values
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), 0,
|
||||
ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());// Texture specification.
|
||||
|
||||
//Cleanup
|
||||
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
|
||||
}
|
||||
else
|
||||
{
|
||||
struct SPixel_Description
|
||||
{
|
||||
const char* FormatHint;
|
||||
const GLint Image_InternalFormat;
|
||||
const GLint Pixel_Format;
|
||||
};
|
||||
//Cleanup
|
||||
ilDeleteImages(1, &id_image);// Because we have already copied image data into texture data we can release memory used by image.
|
||||
}
|
||||
else
|
||||
{
|
||||
struct SPixel_Description
|
||||
{
|
||||
const char* FormatHint;
|
||||
const GLint Image_InternalFormat;
|
||||
const GLint Pixel_Format;
|
||||
};
|
||||
|
||||
constexpr SPixel_Description Pixel_Description[] = {
|
||||
{"rgba8880", GL_RGB, GL_RGB},
|
||||
{"rgba8888", GL_RGBA, GL_RGBA}
|
||||
};
|
||||
constexpr SPixel_Description Pixel_Description[] = {
|
||||
{"rgba8880", GL_RGB, GL_RGB},
|
||||
{"rgba8888", GL_RGBA, GL_RGBA}
|
||||
};
|
||||
|
||||
constexpr size_t Pixel_Description_Count = sizeof(Pixel_Description) / sizeof(SPixel_Description);
|
||||
constexpr size_t Pixel_Description_Count = sizeof(Pixel_Description) / sizeof(SPixel_Description);
|
||||
|
||||
size_t idx_description;
|
||||
// Get texture index.
|
||||
bool ok;
|
||||
size_t idx_texture = pFileName.right(strlen(AI_EMBEDDED_TEXNAME_PREFIX)).toULong(&ok);
|
||||
size_t idx_description;
|
||||
// Get texture index.
|
||||
bool ok;
|
||||
size_t idx_texture = pFileName.right(strlen(AI_EMBEDDED_TEXNAME_PREFIX)).toULong(&ok);
|
||||
|
||||
if(!ok)
|
||||
{
|
||||
LogError("Can not get index of the embedded texture from path in material.");
|
||||
if(!ok)
|
||||
{
|
||||
LogError("Can not get index of the embedded texture from path in material.");
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create alias for conveniance.
|
||||
const aiTexture& als = *mScene->mTextures[idx_texture];
|
||||
// Create alias for conveniance.
|
||||
const aiTexture& als = *mScene->mTextures[idx_texture];
|
||||
|
||||
if(als.mHeight == 0)// Compressed texture.
|
||||
{
|
||||
LogError("IME: compressed embedded textures are not implemented.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
for(size_t idx = 0; idx < Pixel_Description_Count; idx++)
|
||||
{
|
||||
if(als.CheckFormat(Pixel_Description[idx].FormatHint))
|
||||
{
|
||||
idx_description = idx;
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(als.mHeight == 0)// Compressed texture.
|
||||
{
|
||||
LogError("IME: compressed embedded textures are not implemented.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
for(size_t idx = 0; idx < Pixel_Description_Count; idx++)
|
||||
{
|
||||
if(als.CheckFormat(Pixel_Description[idx].FormatHint))
|
||||
{
|
||||
idx_description = idx;
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ok)
|
||||
{
|
||||
LogError(QString("Unsupported format hint for embedded texture: [%1]").arg(als.achFormatHint));
|
||||
if(!ok)
|
||||
{
|
||||
LogError(QString("Unsupported format hint for embedded texture: [%1]").arg(als.achFormatHint));
|
||||
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
glGenTextures(1, &id_ogl_texture);// Texture ID generation.
|
||||
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
|
||||
glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
|
||||
// Redefine standard texture values
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
|
||||
// Texture specification.
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, Pixel_Description[idx_description].Image_InternalFormat, als.mWidth, als.mHeight, 0,
|
||||
Pixel_Description[idx_description].Pixel_Format, GL_UNSIGNED_BYTE, (uint8_t*)als.pcData);
|
||||
}// if(als.mHeight == 0) else
|
||||
}// if(!filename.startsWith(AI_EMBEDDED_TEXNAME_PREFIX)) else
|
||||
glGenTextures(1, &id_ogl_texture);// Texture ID generation.
|
||||
mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
|
||||
glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
|
||||
// Redefine standard texture values
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
|
||||
// Texture specification.
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, Pixel_Description[idx_description].Image_InternalFormat, als.mWidth, als.mHeight, 0,
|
||||
Pixel_Description[idx_description].Pixel_Format, GL_UNSIGNED_BYTE, (uint8_t*)als.pcData);
|
||||
}// if(als.mHeight == 0) else
|
||||
}// if(!filename.startsWith(AI_EMBEDDED_TEXNAME_PREFIX)) else
|
||||
|
||||
return true;
|
||||
};// auto LoadTexture = [&](const aiString& pPath)
|
||||
return true;
|
||||
};// auto LoadTexture = [&](const aiString& pPath)
|
||||
|
||||
if(mScene == nullptr)
|
||||
{
|
||||
|
|
|
@ -325,7 +325,7 @@ bool selected = ui->lstLight->isItemSelected(ui->lstLight->currentItem());
|
|||
mGLView->updateGL();
|
||||
}
|
||||
|
||||
void MainWindow::on_lstCamera_clicked(__unused const QModelIndex &index)
|
||||
void MainWindow::on_lstCamera_clicked( const QModelIndex &)
|
||||
{
|
||||
mGLView->Camera_Set(ui->lstLight->currentRow());
|
||||
mGLView->updateGL();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#pragma once
|
||||
|
||||
// Header files, Qt.
|
||||
#include <QMainWindow>
|
||||
#include <QtWidgets>
|
||||
|
||||
// Header files, project.
|
||||
#include "glview.hpp"
|
||||
|
|
Loading…
Reference in New Issue