Merge branch 'master' into new_obj_stream_handling

pull/1043/head
Kim Kulling 2016-10-22 21:04:02 +02:00
commit cbe2e9af49
58 changed files with 840 additions and 11256 deletions

1
.gitignore vendored
View File

@ -31,6 +31,7 @@ assimp-config-version.cmake
# MakeFile
Makefile
code/Makefile
test/Makefile
test/headercheck/Makefile
tools/assimp_cmd/Makefile

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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",

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;
};

View File

@ -128,6 +128,7 @@ SET( Common_SRCS
DefaultIOStream.h
DefaultIOSystem.cpp
DefaultIOSystem.h
CInterfaceIOWrapper.cpp
CInterfaceIOWrapper.h
Hash.h
Importer.cpp

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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 {

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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")

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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;
};
// ------------------------------------------------------------------------------------------------

View File

@ -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));

View File

@ -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

View File

@ -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;
}

View File

@ -10,6 +10,7 @@
// Header files, Assimp.
#include "Exceptional.h"
#include "StringUtils.h"
#include <assimp/Exporter.hpp>
#include <assimp/IOSystem.hpp>

View File

@ -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"))

View File

@ -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.

View File

@ -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();

View File

@ -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++)

View File

@ -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;

View File

@ -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");

View File

@ -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() {}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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();
};

View File

@ -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.");
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

@ -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()

View File

@ -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)
{

View File

@ -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();

View File

@ -6,7 +6,7 @@
#pragma once
// Header files, Qt.
#include <QMainWindow>
#include <QtWidgets>
// Header files, project.
#include "glview.hpp"