Merge branch 'master' into opengex_support
This commit is contained in:
@@ -51,6 +51,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
# include "../contrib/zlib/zlib.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||
|
||||
|
||||
@@ -138,6 +138,7 @@ aiString Read<aiString>(IOStream * stream)
|
||||
aiString s;
|
||||
stream->Read(&s.length,4,1);
|
||||
stream->Read(s.data,s.length,1);
|
||||
s.data[s.length] = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,638 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2012, 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 AssxmlExporter.cpp
|
||||
* ASSXML exporter main code
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
#include "AssimpPCH.h"
|
||||
#include "./../include/assimp/version.h"
|
||||
#include "ProcessHelper.h"
|
||||
|
||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||
# include <zlib.h>
|
||||
#else
|
||||
# include "../contrib/zlib/zlib.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
namespace AssxmlExport {
|
||||
|
||||
int ioprintf( IOStream * io, const char * format, ... )
|
||||
{
|
||||
char sz[4096];
|
||||
va_list va;
|
||||
va_start( va, format );
|
||||
int nSize = vsnprintf( sz, 4096, format, va );
|
||||
ai_assert( nSize < 4096 );
|
||||
va_end( va );
|
||||
|
||||
io->Write( sz, sizeof(char), nSize );
|
||||
|
||||
return nSize;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Convert a name to standard XML format
|
||||
void ConvertName(aiString& out, const aiString& in)
|
||||
{
|
||||
out.length = 0;
|
||||
for (unsigned int i = 0; i < in.length; ++i) {
|
||||
switch (in.data[i]) {
|
||||
case '<':
|
||||
out.Append("<");break;
|
||||
case '>':
|
||||
out.Append(">");break;
|
||||
case '&':
|
||||
out.Append("&");break;
|
||||
case '\"':
|
||||
out.Append(""");break;
|
||||
case '\'':
|
||||
out.Append("'");break;
|
||||
default:
|
||||
out.data[out.length++] = in.data[i];
|
||||
}
|
||||
}
|
||||
out.data[out.length] = 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Write a single node as text dump
|
||||
void WriteNode(const aiNode* node, IOStream * io, unsigned int depth)
|
||||
{
|
||||
char prefix[512];
|
||||
for (unsigned int i = 0; i < depth;++i)
|
||||
prefix[i] = '\t';
|
||||
prefix[depth] = '\0';
|
||||
|
||||
const aiMatrix4x4& m = node->mTransformation;
|
||||
|
||||
aiString name;
|
||||
ConvertName(name,node->mName);
|
||||
ioprintf(io,"%s<Node name=\"%s\"> \n"
|
||||
"%s\t<Matrix4> \n"
|
||||
"%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
|
||||
"%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
|
||||
"%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
|
||||
"%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
|
||||
"%s\t</Matrix4> \n",
|
||||
prefix,name.data,prefix,
|
||||
prefix,m.a1,m.a2,m.a3,m.a4,
|
||||
prefix,m.b1,m.b2,m.b3,m.b4,
|
||||
prefix,m.c1,m.c2,m.c3,m.c4,
|
||||
prefix,m.d1,m.d2,m.d3,m.d4,prefix);
|
||||
|
||||
if (node->mNumMeshes) {
|
||||
ioprintf(io, "%s\t<MeshRefs num=\"%i\">\n%s\t",
|
||||
prefix,node->mNumMeshes,prefix);
|
||||
|
||||
for (unsigned int i = 0; i < node->mNumMeshes;++i) {
|
||||
ioprintf(io,"%i ",node->mMeshes[i]);
|
||||
}
|
||||
ioprintf(io,"\n%s\t</MeshRefs>\n",prefix);
|
||||
}
|
||||
|
||||
if (node->mNumChildren) {
|
||||
ioprintf(io,"%s\t<NodeList num=\"%i\">\n",
|
||||
prefix,node->mNumChildren);
|
||||
|
||||
for (unsigned int i = 0; i < node->mNumChildren;++i) {
|
||||
WriteNode(node->mChildren[i],io,depth+2);
|
||||
}
|
||||
ioprintf(io,"%s\t</NodeList>\n",prefix);
|
||||
}
|
||||
ioprintf(io,"%s</Node>\n",prefix);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Some chuncks of text will need to be encoded for XML
|
||||
// http://stackoverflow.com/questions/5665231/most-efficient-way-to-escape-xml-html-in-c-string#5665377
|
||||
static std::string encodeXML(const std::string& data) {
|
||||
std::string buffer;
|
||||
buffer.reserve(data.size());
|
||||
for(size_t pos = 0; pos != data.size(); ++pos) {
|
||||
switch(data[pos]) {
|
||||
case '&': buffer.append("&"); break;
|
||||
case '\"': buffer.append("""); break;
|
||||
case '\'': buffer.append("'"); break;
|
||||
case '<': buffer.append("<"); break;
|
||||
case '>': buffer.append(">"); break;
|
||||
default: buffer.append(&data[pos], 1); break;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------
|
||||
// Write a text model dump
|
||||
void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
|
||||
{
|
||||
time_t tt = ::time(NULL);
|
||||
tm* p = ::gmtime(&tt);
|
||||
|
||||
aiString name;
|
||||
|
||||
// write header
|
||||
ioprintf(io,
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||||
"<ASSIMP format_id=\"1\">\n\n"
|
||||
|
||||
"<!-- XML Model dump produced by assimp dump\n"
|
||||
" Library version: %i.%i.%i\n"
|
||||
" %s\n"
|
||||
"-->"
|
||||
" \n\n"
|
||||
"<Scene flags=\"%i\" postprocessing=\"%i\">\n",
|
||||
|
||||
aiGetVersionMajor(),aiGetVersionMinor(),aiGetVersionRevision(),asctime(p),
|
||||
scene->mFlags,
|
||||
0 /*globalImporter->GetEffectivePostProcessing()*/);
|
||||
|
||||
// write the node graph
|
||||
WriteNode(scene->mRootNode, io, 0);
|
||||
|
||||
#if 0
|
||||
// write cameras
|
||||
for (unsigned int i = 0; i < scene->mNumCameras;++i) {
|
||||
aiCamera* cam = scene->mCameras[i];
|
||||
ConvertName(name,cam->mName);
|
||||
|
||||
// camera header
|
||||
ioprintf(io,"\t<Camera parent=\"%s\">\n"
|
||||
"\t\t<Vector3 name=\"up\" > %0 8f %0 8f %0 8f </Vector3>\n"
|
||||
"\t\t<Vector3 name=\"lookat\" > %0 8f %0 8f %0 8f </Vector3>\n"
|
||||
"\t\t<Vector3 name=\"pos\" > %0 8f %0 8f %0 8f </Vector3>\n"
|
||||
"\t\t<Float name=\"fov\" > %f </Float>\n"
|
||||
"\t\t<Float name=\"aspect\" > %f </Float>\n"
|
||||
"\t\t<Float name=\"near_clip\" > %f </Float>\n"
|
||||
"\t\t<Float name=\"far_clip\" > %f </Float>\n"
|
||||
"\t</Camera>\n",
|
||||
name.data,
|
||||
cam->mUp.x,cam->mUp.y,cam->mUp.z,
|
||||
cam->mLookAt.x,cam->mLookAt.y,cam->mLookAt.z,
|
||||
cam->mPosition.x,cam->mPosition.y,cam->mPosition.z,
|
||||
cam->mHorizontalFOV,cam->mAspect,cam->mClipPlaneNear,cam->mClipPlaneFar,i);
|
||||
}
|
||||
|
||||
// write lights
|
||||
for (unsigned int i = 0; i < scene->mNumLights;++i) {
|
||||
aiLight* l = scene->mLights[i];
|
||||
ConvertName(name,l->mName);
|
||||
|
||||
// light header
|
||||
ioprintf(io,"\t<Light parent=\"%s\"> type=\"%s\"\n"
|
||||
"\t\t<Vector3 name=\"diffuse\" > %0 8f %0 8f %0 8f </Vector3>\n"
|
||||
"\t\t<Vector3 name=\"specular\" > %0 8f %0 8f %0 8f </Vector3>\n"
|
||||
"\t\t<Vector3 name=\"ambient\" > %0 8f %0 8f %0 8f </Vector3>\n",
|
||||
name.data,
|
||||
(l->mType == aiLightSource_DIRECTIONAL ? "directional" :
|
||||
(l->mType == aiLightSource_POINT ? "point" : "spot" )),
|
||||
l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b,
|
||||
l->mColorSpecular.r,l->mColorSpecular.g,l->mColorSpecular.b,
|
||||
l->mColorAmbient.r, l->mColorAmbient.g, l->mColorAmbient.b);
|
||||
|
||||
if (l->mType != aiLightSource_DIRECTIONAL) {
|
||||
ioprintf(io,
|
||||
"\t\t<Vector3 name=\"pos\" > %0 8f %0 8f %0 8f </Vector3>\n"
|
||||
"\t\t<Float name=\"atten_cst\" > %f </Float>\n"
|
||||
"\t\t<Float name=\"atten_lin\" > %f </Float>\n"
|
||||
"\t\t<Float name=\"atten_sqr\" > %f </Float>\n",
|
||||
l->mPosition.x,l->mPosition.y,l->mPosition.z,
|
||||
l->mAttenuationConstant,l->mAttenuationLinear,l->mAttenuationQuadratic);
|
||||
}
|
||||
|
||||
if (l->mType != aiLightSource_POINT) {
|
||||
ioprintf(io,
|
||||
"\t\t<Vector3 name=\"lookat\" > %0 8f %0 8f %0 8f </Vector3>\n",
|
||||
l->mDirection.x,l->mDirection.y,l->mDirection.z);
|
||||
}
|
||||
|
||||
if (l->mType == aiLightSource_SPOT) {
|
||||
ioprintf(io,
|
||||
"\t\t<Float name=\"cone_out\" > %f </Float>\n"
|
||||
"\t\t<Float name=\"cone_inn\" > %f </Float>\n",
|
||||
l->mAngleOuterCone,l->mAngleInnerCone);
|
||||
}
|
||||
ioprintf(io,"\t</Light>\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// write textures
|
||||
if (scene->mNumTextures) {
|
||||
ioprintf(io,"<TextureList num=\"%i\">\n",scene->mNumTextures);
|
||||
for (unsigned int i = 0; i < scene->mNumTextures;++i) {
|
||||
aiTexture* tex = scene->mTextures[i];
|
||||
bool compressed = (tex->mHeight == 0);
|
||||
|
||||
// mesh header
|
||||
ioprintf(io,"\t<Texture width=\"%i\" height=\"%i\" compressed=\"%s\"> \n",
|
||||
(compressed ? -1 : tex->mWidth),(compressed ? -1 : tex->mHeight),
|
||||
(compressed ? "true" : "false"));
|
||||
|
||||
if (compressed) {
|
||||
ioprintf(io,"\t\t<Data length=\"%i\"> \n",tex->mWidth);
|
||||
|
||||
if (!shortened) {
|
||||
for (unsigned int n = 0; n < tex->mWidth;++n) {
|
||||
ioprintf(io,"\t\t\t%2x",reinterpret_cast<uint8_t*>(tex->pcData)[n]);
|
||||
if (n && !(n % 50)) {
|
||||
ioprintf(io,"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
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;
|
||||
unsigned int r = tx->r,g=tx->g,b=tx->b,a=tx->a;
|
||||
ioprintf(io,"\t\t\t%2x %2x %2x %2x",r,g,b,a);
|
||||
|
||||
// group by four for readibility
|
||||
if (0 == (x+y*tex->mWidth) % 4)
|
||||
ioprintf(io,"\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
ioprintf(io,"\t\t</Data>\n\t</Texture>\n");
|
||||
}
|
||||
ioprintf(io,"</TextureList>\n");
|
||||
}
|
||||
|
||||
// write materials
|
||||
if (scene->mNumMaterials) {
|
||||
ioprintf(io,"<MaterialList num=\"%i\">\n",scene->mNumMaterials);
|
||||
for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
|
||||
const aiMaterial* mat = scene->mMaterials[i];
|
||||
|
||||
ioprintf(io,"\t<Material>\n");
|
||||
ioprintf(io,"\t\t<MatPropertyList num=\"%i\">\n",mat->mNumProperties);
|
||||
for (unsigned int n = 0; n < mat->mNumProperties;++n) {
|
||||
|
||||
const aiMaterialProperty* prop = mat->mProperties[n];
|
||||
const char* sz = "";
|
||||
if (prop->mType == aiPTI_Float) {
|
||||
sz = "float";
|
||||
}
|
||||
else if (prop->mType == aiPTI_Integer) {
|
||||
sz = "integer";
|
||||
}
|
||||
else if (prop->mType == aiPTI_String) {
|
||||
sz = "string";
|
||||
}
|
||||
else if (prop->mType == aiPTI_Buffer) {
|
||||
sz = "binary_buffer";
|
||||
}
|
||||
|
||||
ioprintf(io,"\t\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%i\"",
|
||||
prop->mKey.data, sz,
|
||||
::TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex);
|
||||
|
||||
if (prop->mType == aiPTI_Float) {
|
||||
ioprintf(io," size=\"%i\">\n\t\t\t\t",
|
||||
static_cast<int>(prop->mDataLength/sizeof(float)));
|
||||
|
||||
for (unsigned int p = 0; p < prop->mDataLength/sizeof(float);++p) {
|
||||
ioprintf(io,"%f ",*((float*)(prop->mData+p*sizeof(float))));
|
||||
}
|
||||
}
|
||||
else if (prop->mType == aiPTI_Integer) {
|
||||
ioprintf(io," size=\"%i\">\n\t\t\t\t",
|
||||
static_cast<int>(prop->mDataLength/sizeof(int)));
|
||||
|
||||
for (unsigned int p = 0; p < prop->mDataLength/sizeof(int);++p) {
|
||||
ioprintf(io,"%i ",*((int*)(prop->mData+p*sizeof(int))));
|
||||
}
|
||||
}
|
||||
else if (prop->mType == aiPTI_Buffer) {
|
||||
ioprintf(io," size=\"%i\">\n\t\t\t\t",
|
||||
static_cast<int>(prop->mDataLength));
|
||||
|
||||
for (unsigned int p = 0; p < prop->mDataLength;++p) {
|
||||
ioprintf(io,"%2x ",prop->mData[p]);
|
||||
if (p && 0 == p%30) {
|
||||
ioprintf(io,"\n\t\t\t\t");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (prop->mType == aiPTI_String) {
|
||||
ioprintf(io,">\n\t\t\t\t\"%s\"",encodeXML(prop->mData+4).c_str() /* skip length */);
|
||||
}
|
||||
ioprintf(io,"\n\t\t\t</MatProperty>\n");
|
||||
}
|
||||
ioprintf(io,"\t\t</MatPropertyList>\n");
|
||||
ioprintf(io,"\t</Material>\n");
|
||||
}
|
||||
ioprintf(io,"</MaterialList>\n");
|
||||
}
|
||||
|
||||
// write animations
|
||||
if (scene->mNumAnimations) {
|
||||
ioprintf(io,"<AnimationList num=\"%i\">\n",scene->mNumAnimations);
|
||||
for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
|
||||
aiAnimation* anim = scene->mAnimations[i];
|
||||
|
||||
// anim header
|
||||
ConvertName(name,anim->mName);
|
||||
ioprintf(io,"\t<Animation name=\"%s\" duration=\"%e\" tick_cnt=\"%e\">\n",
|
||||
name.data, anim->mDuration, anim->mTicksPerSecond);
|
||||
|
||||
// write bone animation channels
|
||||
if (anim->mNumChannels) {
|
||||
ioprintf(io,"\t\t<NodeAnimList num=\"%i\">\n",anim->mNumChannels);
|
||||
for (unsigned int n = 0; n < anim->mNumChannels;++n) {
|
||||
aiNodeAnim* nd = anim->mChannels[n];
|
||||
|
||||
// node anim header
|
||||
ConvertName(name,nd->mNodeName);
|
||||
ioprintf(io,"\t\t\t<NodeAnim node=\"%s\">\n",name.data);
|
||||
|
||||
if (!shortened) {
|
||||
// write position keys
|
||||
if (nd->mNumPositionKeys) {
|
||||
ioprintf(io,"\t\t\t\t<PositionKeyList num=\"%i\">\n",nd->mNumPositionKeys);
|
||||
for (unsigned int a = 0; a < nd->mNumPositionKeys;++a) {
|
||||
aiVectorKey* vc = nd->mPositionKeys+a;
|
||||
ioprintf(io,"\t\t\t\t\t<PositionKey time=\"%e\">\n"
|
||||
"\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</PositionKey>\n",
|
||||
vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z);
|
||||
}
|
||||
ioprintf(io,"\t\t\t\t</PositionKeyList>\n");
|
||||
}
|
||||
|
||||
// write scaling keys
|
||||
if (nd->mNumScalingKeys) {
|
||||
ioprintf(io,"\t\t\t\t<ScalingKeyList num=\"%i\">\n",nd->mNumScalingKeys);
|
||||
for (unsigned int a = 0; a < nd->mNumScalingKeys;++a) {
|
||||
aiVectorKey* vc = nd->mScalingKeys+a;
|
||||
ioprintf(io,"\t\t\t\t\t<ScalingKey time=\"%e\">\n"
|
||||
"\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</ScalingKey>\n",
|
||||
vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z);
|
||||
}
|
||||
ioprintf(io,"\t\t\t\t</ScalingKeyList>\n");
|
||||
}
|
||||
|
||||
// write rotation keys
|
||||
if (nd->mNumRotationKeys) {
|
||||
ioprintf(io,"\t\t\t\t<RotationKeyList num=\"%i\">\n",nd->mNumRotationKeys);
|
||||
for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) {
|
||||
aiQuatKey* vc = nd->mRotationKeys+a;
|
||||
ioprintf(io,"\t\t\t\t\t<RotationKey time=\"%e\">\n"
|
||||
"\t\t\t\t\t\t%0 8f %0 8f %0 8f %0 8f\n\t\t\t\t\t</RotationKey>\n",
|
||||
vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z,vc->mValue.w);
|
||||
}
|
||||
ioprintf(io,"\t\t\t\t</RotationKeyList>\n");
|
||||
}
|
||||
}
|
||||
ioprintf(io,"\t\t\t</NodeAnim>\n");
|
||||
}
|
||||
ioprintf(io,"\t\t</NodeAnimList>\n");
|
||||
}
|
||||
ioprintf(io,"\t</Animation>\n");
|
||||
}
|
||||
ioprintf(io,"</AnimationList>\n");
|
||||
}
|
||||
|
||||
// write meshes
|
||||
if (scene->mNumMeshes) {
|
||||
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;
|
||||
|
||||
// mesh header
|
||||
ioprintf(io,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%i\">\n",
|
||||
(mesh->mPrimitiveTypes & aiPrimitiveType_POINT ? "points" : ""),
|
||||
(mesh->mPrimitiveTypes & aiPrimitiveType_LINE ? "lines" : ""),
|
||||
(mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE ? "triangles" : ""),
|
||||
(mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON ? "polygons" : ""),
|
||||
mesh->mMaterialIndex);
|
||||
|
||||
// bones
|
||||
if (mesh->mNumBones) {
|
||||
ioprintf(io,"\t\t<BoneList num=\"%i\">\n",mesh->mNumBones);
|
||||
|
||||
for (unsigned int n = 0; n < mesh->mNumBones;++n) {
|
||||
aiBone* bone = mesh->mBones[n];
|
||||
|
||||
ConvertName(name,bone->mName);
|
||||
// bone header
|
||||
ioprintf(io,"\t\t\t<Bone name=\"%s\">\n"
|
||||
"\t\t\t\t<Matrix4> \n"
|
||||
"\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
|
||||
"\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
|
||||
"\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
|
||||
"\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
|
||||
"\t\t\t\t</Matrix4> \n",
|
||||
name.data,
|
||||
bone->mOffsetMatrix.a1,bone->mOffsetMatrix.a2,bone->mOffsetMatrix.a3,bone->mOffsetMatrix.a4,
|
||||
bone->mOffsetMatrix.b1,bone->mOffsetMatrix.b2,bone->mOffsetMatrix.b3,bone->mOffsetMatrix.b4,
|
||||
bone->mOffsetMatrix.c1,bone->mOffsetMatrix.c2,bone->mOffsetMatrix.c3,bone->mOffsetMatrix.c4,
|
||||
bone->mOffsetMatrix.d1,bone->mOffsetMatrix.d2,bone->mOffsetMatrix.d3,bone->mOffsetMatrix.d4);
|
||||
|
||||
if (!shortened && bone->mNumWeights) {
|
||||
ioprintf(io,"\t\t\t\t<WeightList num=\"%i\">\n",bone->mNumWeights);
|
||||
|
||||
// bone weights
|
||||
for (unsigned int a = 0; a < bone->mNumWeights;++a) {
|
||||
aiVertexWeight* wght = bone->mWeights+a;
|
||||
|
||||
ioprintf(io,"\t\t\t\t\t<Weight index=\"%i\">\n\t\t\t\t\t\t%f\n\t\t\t\t\t</Weight>\n",
|
||||
wght->mVertexId,wght->mWeight);
|
||||
}
|
||||
ioprintf(io,"\t\t\t\t</WeightList>\n");
|
||||
}
|
||||
ioprintf(io,"\t\t\t</Bone>\n");
|
||||
}
|
||||
ioprintf(io,"\t\t</BoneList>\n");
|
||||
}
|
||||
|
||||
// faces
|
||||
if (!shortened && mesh->mNumFaces) {
|
||||
ioprintf(io,"\t\t<FaceList num=\"%i\">\n",mesh->mNumFaces);
|
||||
for (unsigned int n = 0; n < mesh->mNumFaces; ++n) {
|
||||
aiFace& f = mesh->mFaces[n];
|
||||
ioprintf(io,"\t\t\t<Face num=\"%i\">\n"
|
||||
"\t\t\t\t",f.mNumIndices);
|
||||
|
||||
for (unsigned int j = 0; j < f.mNumIndices;++j)
|
||||
ioprintf(io,"%i ",f.mIndices[j]);
|
||||
|
||||
ioprintf(io,"\n\t\t\t</Face>\n");
|
||||
}
|
||||
ioprintf(io,"\t\t</FaceList>\n");
|
||||
}
|
||||
|
||||
// vertex positions
|
||||
if (mesh->HasPositions()) {
|
||||
ioprintf(io,"\t\t<Positions num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
|
||||
if (!shortened) {
|
||||
for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
|
||||
ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
|
||||
mesh->mVertices[n].x,
|
||||
mesh->mVertices[n].y,
|
||||
mesh->mVertices[n].z);
|
||||
}
|
||||
}
|
||||
ioprintf(io,"\t\t</Positions>\n");
|
||||
}
|
||||
|
||||
// vertex normals
|
||||
if (mesh->HasNormals()) {
|
||||
ioprintf(io,"\t\t<Normals num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
|
||||
if (!shortened) {
|
||||
for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
|
||||
ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
|
||||
mesh->mNormals[n].x,
|
||||
mesh->mNormals[n].y,
|
||||
mesh->mNormals[n].z);
|
||||
}
|
||||
}
|
||||
else {
|
||||
}
|
||||
ioprintf(io,"\t\t</Normals>\n");
|
||||
}
|
||||
|
||||
// vertex tangents and bitangents
|
||||
if (mesh->HasTangentsAndBitangents()) {
|
||||
ioprintf(io,"\t\t<Tangents num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
|
||||
if (!shortened) {
|
||||
for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
|
||||
ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
|
||||
mesh->mTangents[n].x,
|
||||
mesh->mTangents[n].y,
|
||||
mesh->mTangents[n].z);
|
||||
}
|
||||
}
|
||||
ioprintf(io,"\t\t</Tangents>\n");
|
||||
|
||||
ioprintf(io,"\t\t<Bitangents num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
|
||||
if (!shortened) {
|
||||
for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
|
||||
ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
|
||||
mesh->mBitangents[n].x,
|
||||
mesh->mBitangents[n].y,
|
||||
mesh->mBitangents[n].z);
|
||||
}
|
||||
}
|
||||
ioprintf(io,"\t\t</Bitangents>\n");
|
||||
}
|
||||
|
||||
// texture coordinates
|
||||
for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
|
||||
if (!mesh->mTextureCoords[a])
|
||||
break;
|
||||
|
||||
ioprintf(io,"\t\t<TextureCoords num=\"%i\" set=\"%i\" num_components=\"%i\"> \n",mesh->mNumVertices,
|
||||
a,mesh->mNumUVComponents[a]);
|
||||
|
||||
if (!shortened) {
|
||||
if (mesh->mNumUVComponents[a] == 3) {
|
||||
for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
|
||||
ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
|
||||
mesh->mTextureCoords[a][n].x,
|
||||
mesh->mTextureCoords[a][n].y,
|
||||
mesh->mTextureCoords[a][n].z);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
|
||||
ioprintf(io,"\t\t%0 8f %0 8f\n",
|
||||
mesh->mTextureCoords[a][n].x,
|
||||
mesh->mTextureCoords[a][n].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
ioprintf(io,"\t\t</TextureCoords>\n");
|
||||
}
|
||||
|
||||
// vertex colors
|
||||
for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) {
|
||||
if (!mesh->mColors[a])
|
||||
break;
|
||||
ioprintf(io,"\t\t<Colors num=\"%i\" set=\"%i\" num_components=\"4\"> \n",mesh->mNumVertices,a);
|
||||
if (!shortened) {
|
||||
for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
|
||||
ioprintf(io,"\t\t%0 8f %0 8f %0 8f %0 8f\n",
|
||||
mesh->mColors[a][n].r,
|
||||
mesh->mColors[a][n].g,
|
||||
mesh->mColors[a][n].b,
|
||||
mesh->mColors[a][n].a);
|
||||
}
|
||||
}
|
||||
ioprintf(io,"\t\t</Colors>\n");
|
||||
}
|
||||
ioprintf(io,"\t</Mesh>\n");
|
||||
}
|
||||
ioprintf(io,"</MeshList>\n");
|
||||
}
|
||||
ioprintf(io,"</Scene>\n</ASSIMP>");
|
||||
}
|
||||
|
||||
} // end of namespace AssxmlExport
|
||||
|
||||
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
||||
{
|
||||
IOStream * out = pIOSystem->Open( pFile, "wt" );
|
||||
if (!out) return;
|
||||
|
||||
bool shortened = false;
|
||||
AssxmlExport::WriteDump( pScene, out, shortened );
|
||||
|
||||
pIOSystem->Close( out );
|
||||
}
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2012, 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 AssxmlExporter.h
|
||||
* ASSXML Exporter Main Header
|
||||
*/
|
||||
#ifndef AI_ASSXMLEXPORTER_H_INC
|
||||
#define AI_ASSXMLEXPORTER_H_INC
|
||||
|
||||
// nothing really needed here - reserved for future use like properties
|
||||
|
||||
#endif
|
||||
+28
-1
@@ -65,7 +65,6 @@ BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ):
|
||||
BMesh( mesh ),
|
||||
triMesh( NULL )
|
||||
{
|
||||
AssertValidMesh( );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -143,9 +142,21 @@ void BlenderBMeshConverter::DestroyTriMesh( )
|
||||
void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly )
|
||||
{
|
||||
const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ];
|
||||
|
||||
if ( poly.totloop == 3 || poly.totloop == 4 )
|
||||
{
|
||||
AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 );
|
||||
|
||||
// UVs are optional, so only convert when present.
|
||||
if ( BMesh->mloopuv.size() )
|
||||
{
|
||||
if ( (poly.loopstart + poly.totloop ) > static_cast<int>( BMesh->mloopuv.size() ) )
|
||||
{
|
||||
ThrowException( "BMesh uv loop array has incorrect size" );
|
||||
}
|
||||
const MLoopUV* loopUV = &BMesh->mloopuv[ poly.loopstart ];
|
||||
AddTFace( loopUV[ 0 ].uv, loopUV[ 1 ].uv, loopUV[ 2 ].uv, poly.totloop == 4 ? loopUV[ 3 ].uv : 0 );
|
||||
}
|
||||
}
|
||||
else if ( poly.totloop > 4 )
|
||||
{
|
||||
@@ -173,4 +184,20 @@ void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 )
|
||||
triMesh->totface = triMesh->mface.size( );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BlenderBMeshConverter::AddTFace( const float* uv1, const float *uv2, const float *uv3, const float* uv4 )
|
||||
{
|
||||
MTFace mtface;
|
||||
memcpy( &mtface.uv[ 0 ], uv1, sizeof(float) * 2 );
|
||||
memcpy( &mtface.uv[ 1 ], uv2, sizeof(float) * 2 );
|
||||
memcpy( &mtface.uv[ 2 ], uv3, sizeof(float) * 2 );
|
||||
|
||||
if ( uv4 )
|
||||
{
|
||||
memcpy( &mtface.uv[ 3 ], uv4, sizeof(float) * 2 );
|
||||
}
|
||||
|
||||
triMesh->mtface.push_back( mtface );
|
||||
}
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace Assimp
|
||||
void DestroyTriMesh( );
|
||||
void ConvertPolyToFaces( const Blender::MPoly& poly );
|
||||
void AddFace( int v1, int v2, int v3, int v4 = 0 );
|
||||
void AddTFace( const float* uv1, const float* uv2, const float *uv3, const float* uv4 = 0 );
|
||||
|
||||
const Blender::Mesh* BMesh;
|
||||
Blender::Mesh* triMesh;
|
||||
|
||||
@@ -659,11 +659,15 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||
ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
|
||||
)
|
||||
{
|
||||
// TODO: Resolve various problems with BMesh triangluation before re-enabling.
|
||||
// See issues #400, #373, #318 #315 and #132.
|
||||
#if defined(TODO_FIX_BMESH_CONVERSION)
|
||||
BlenderBMeshConverter BMeshConverter( mesh );
|
||||
if ( BMeshConverter.ContainsBMesh( ) )
|
||||
{
|
||||
mesh = BMeshConverter.TriangulateBMesh( );
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef std::pair<const int,size_t> MyPair;
|
||||
if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
|
||||
|
||||
@@ -324,7 +324,7 @@ void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCou
|
||||
aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const
|
||||
{
|
||||
aiVector3D sideA( 1.0f, 0.0f, 0.0f );
|
||||
if ( fabs( plane.normal * sideA ) > 0.999f )
|
||||
if ( std::fabs( plane.normal * sideA ) > 0.999f )
|
||||
{
|
||||
sideA = aiVector3D( 0.0f, 1.0f, 0.0f );
|
||||
}
|
||||
@@ -420,7 +420,7 @@ float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) con
|
||||
{
|
||||
for ( int y = 0; y < 3; ++y )
|
||||
{
|
||||
result = p2tMax( fabs( mtx[ x ][ y ] ), result );
|
||||
result = p2tMax( std::fabs( mtx[ x ][ y ] ), result );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,12 @@ SET( ASSBIN_SRCS
|
||||
)
|
||||
SOURCE_GROUP( Assbin FILES ${ASSBIN_SRCS})
|
||||
|
||||
SET( ASSXML_SRCS
|
||||
AssxmlExporter.h
|
||||
AssxmlExporter.cpp
|
||||
)
|
||||
SOURCE_GROUP( Assxml FILES ${ASSXML_SRCS})
|
||||
|
||||
SET( B3D_SRCS
|
||||
B3DImporter.cpp
|
||||
B3DImporter.h
|
||||
@@ -663,6 +669,7 @@ SET( assimp_src
|
||||
${AC_SRCS}
|
||||
${ASE_SRCS}
|
||||
${ASSBIN_SRCS}
|
||||
${ASSXML_SRCS}
|
||||
${B3D_SRCS}
|
||||
${BVH_SRCS}
|
||||
${Collada_SRCS}
|
||||
@@ -726,6 +733,13 @@ ADD_LIBRARY( assimp ${assimp_src} )
|
||||
SET_PROPERTY(TARGET assimp PROPERTY DEBUG_POSTFIX ${ASSIMP_DEBUG_POSTFIX})
|
||||
|
||||
TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES})
|
||||
|
||||
if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
set(ASSIMP_ANDROID_JNIIOSYSTEM_PATH port/AndroidJNI)
|
||||
add_subdirectory(../${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/ ../${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/)
|
||||
target_link_libraries(assimp android_jniiosystem)
|
||||
endif(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
|
||||
SET_TARGET_PROPERTIES( assimp PROPERTIES
|
||||
VERSION ${ASSIMP_VERSION}
|
||||
SOVERSION ${ASSIMP_SOVERSION} # use full version
|
||||
@@ -752,6 +766,11 @@ INSTALL( TARGETS assimp
|
||||
COMPONENT ${LIBASSIMP_COMPONENT})
|
||||
INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev)
|
||||
INSTALL( FILES ${COMPILER_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp/Compiler COMPONENT assimp-dev)
|
||||
if (ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
INSTALL(FILES ${HEADER_PATH}/../${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h
|
||||
DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}
|
||||
COMPONENT assimp-dev)
|
||||
endif(ASSIMP_ANDROID_JNIIOSYSTEM)
|
||||
|
||||
if(MSVC AND ASSIMP_INSTALL_PDB)
|
||||
install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${ASSIMP_DEBUG_POSTFIX}.pdb
|
||||
|
||||
@@ -118,7 +118,6 @@ struct Camera
|
||||
float mZNear, mZFar;
|
||||
};
|
||||
|
||||
#define aiLightSource_AMBIENT 0xdeaddead
|
||||
#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f
|
||||
|
||||
/** A collada light source. */
|
||||
|
||||
@@ -73,7 +73,7 @@ static const aiImporterDesc desc = {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
ColladaLoader::ColladaLoader()
|
||||
: noSkeletonMesh(), ignoreUpDirection(false)
|
||||
: noSkeletonMesh(), ignoreUpDirection(false), mNodeNameCounter()
|
||||
{}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -308,10 +308,6 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
|
||||
continue;
|
||||
}
|
||||
const Collada::Light* srcLight = &srcLightIt->second;
|
||||
if (srcLight->mType == aiLightSource_AMBIENT) {
|
||||
DefaultLogger::get()->error("Collada: Skipping ambient light for the moment");
|
||||
continue;
|
||||
}
|
||||
|
||||
// now fill our ai data structure
|
||||
aiLight* out = new aiLight();
|
||||
@@ -341,7 +337,7 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
|
||||
{
|
||||
// Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess ....
|
||||
// epsilon chosen to be 0.1
|
||||
out->mAngleOuterCone = AI_DEG_TO_RAD (acos(pow(0.1f,1.f/srcLight->mFalloffExponent))+
|
||||
out->mAngleOuterCone = AI_DEG_TO_RAD (std::acos(std::pow(0.1f,1.f/srcLight->mFalloffExponent))+
|
||||
srcLight->mFalloffAngle);
|
||||
}
|
||||
else {
|
||||
@@ -1547,7 +1543,7 @@ const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, c
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Finds a proper name for a node derived from the collada-node's properties
|
||||
std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode) const
|
||||
std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode)
|
||||
{
|
||||
// now setup the name of the node. We take the name if not empty, otherwise the collada ID
|
||||
// FIX: Workaround for XSI calling the instanced visual scene 'untitled' by default.
|
||||
@@ -1561,7 +1557,7 @@ std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode) const
|
||||
{
|
||||
// No need to worry. Unnamed nodes are no problem at all, except
|
||||
// if cameras or lights need to be assigned to them.
|
||||
return boost::str( boost::format( "$ColladaAutoName$_%d") % clock());
|
||||
return boost::str( boost::format( "$ColladaAutoName$_%d") % mNodeNameCounter++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ protected:
|
||||
const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
|
||||
|
||||
/** Finds a proper name for a node derived from the collada-node's properties */
|
||||
std::string FindNameForNode( const Collada::Node* pNode) const;
|
||||
std::string FindNameForNode( const Collada::Node* pNode);
|
||||
|
||||
protected:
|
||||
/** Filename, for a verbose error message */
|
||||
@@ -235,6 +235,9 @@ protected:
|
||||
|
||||
bool noSkeletonMesh;
|
||||
bool ignoreUpDirection;
|
||||
|
||||
/** Used by FindNameForNode() to generate unique node names */
|
||||
unsigned int mNodeNameCounter;
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
@@ -207,7 +207,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
||||
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,
|
||||
(asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||
(std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||
}
|
||||
}
|
||||
else if (axis * base_axis_y >= angle_epsilon) {
|
||||
@@ -215,7 +215,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
||||
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,
|
||||
(asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||
(std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||
}
|
||||
}
|
||||
else if (axis * base_axis_z >= angle_epsilon) {
|
||||
@@ -223,7 +223,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
|
||||
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,
|
||||
(asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||
(std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f);
|
||||
}
|
||||
}
|
||||
// slower code path in case the mapping axis is not one of the coordinate system axes
|
||||
|
||||
@@ -56,6 +56,9 @@ namespace Assimp {
|
||||
class DefaultIOStream : public IOStream
|
||||
{
|
||||
friend class DefaultIOSystem;
|
||||
#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
friend class AndroidJNIIOSystem;
|
||||
#endif //__ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
|
||||
protected:
|
||||
DefaultIOStream ();
|
||||
|
||||
@@ -80,6 +80,7 @@ void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
|
||||
void ExportScenePly(const char*,IOSystem*, const aiScene*);
|
||||
void ExportScene3DS(const char*, IOSystem*, const aiScene*);
|
||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*);
|
||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// global array of all export formats which Assimp supports in its current build
|
||||
@@ -122,6 +123,10 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||
Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||
Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0),
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))
|
||||
|
||||
@@ -55,14 +55,15 @@ namespace FBX {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
|
||||
: sbegin(sbegin)
|
||||
:
|
||||
#ifdef DEBUG
|
||||
contents(sbegin, static_cast<size_t>(send-sbegin)),
|
||||
#endif
|
||||
sbegin(sbegin)
|
||||
, send(send)
|
||||
, type(type)
|
||||
, line(offset)
|
||||
, column(BINARY_MARKER)
|
||||
#ifdef DEBUG
|
||||
, contents(sbegin, static_cast<size_t>(send-sbegin))
|
||||
#endif
|
||||
{
|
||||
ai_assert(sbegin);
|
||||
ai_assert(send);
|
||||
@@ -395,4 +396,4 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int le
|
||||
} // !FBX
|
||||
} // !Assimp
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -381,8 +381,6 @@ private:
|
||||
out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
|
||||
out_camera->mPosition = cam.Position();
|
||||
out_camera->mLookAt = cam.InterestPosition() - out_camera->mPosition;
|
||||
|
||||
// BUG HERE cam.FieldOfView() returns 1.0f every time. 1.0f is default value.
|
||||
out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
|
||||
}
|
||||
|
||||
@@ -499,15 +497,15 @@ private:
|
||||
bool is_id[3] = { true, true, true };
|
||||
|
||||
aiMatrix4x4 temp[3];
|
||||
if(fabs(rotation.z) > angle_epsilon) {
|
||||
if(std::fabs(rotation.z) > angle_epsilon) {
|
||||
aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(rotation.z),temp[2]);
|
||||
is_id[2] = false;
|
||||
}
|
||||
if(fabs(rotation.y) > angle_epsilon) {
|
||||
if(std::fabs(rotation.y) > angle_epsilon) {
|
||||
aiMatrix4x4::RotationY(AI_DEG_TO_RAD(rotation.y),temp[1]);
|
||||
is_id[1] = false;
|
||||
}
|
||||
if(fabs(rotation.x) > angle_epsilon) {
|
||||
if(std::fabs(rotation.x) > angle_epsilon) {
|
||||
aiMatrix4x4::RotationX(AI_DEG_TO_RAD(rotation.x),temp[0]);
|
||||
is_id[0] = false;
|
||||
}
|
||||
@@ -676,7 +674,7 @@ private:
|
||||
}
|
||||
|
||||
const aiVector3D& Scaling = PropertyGet<aiVector3D>(props,"Lcl Scaling",ok);
|
||||
if(ok && fabs(Scaling.SquareLength()-1.0f) > zero_epsilon) {
|
||||
if(ok && std::fabs(Scaling.SquareLength()-1.0f) > zero_epsilon) {
|
||||
aiMatrix4x4::Scaling(Scaling,chain[TransformationComp_Scaling]);
|
||||
}
|
||||
|
||||
@@ -686,7 +684,7 @@ private:
|
||||
}
|
||||
|
||||
const aiVector3D& GeometricScaling = PropertyGet<aiVector3D>(props, "GeometricScaling", ok);
|
||||
if (ok && fabs(GeometricScaling.SquareLength() - 1.0f) > zero_epsilon) {
|
||||
if (ok && std::fabs(GeometricScaling.SquareLength() - 1.0f) > zero_epsilon) {
|
||||
aiMatrix4x4::Scaling(GeometricScaling, chain[TransformationComp_GeometricScaling]);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
|
||||
|
||||
else if ((!extension.length() || checkSig) && pIOHandler) {
|
||||
// at least ascii FBX files usually have a 'FBX' somewhere in their head
|
||||
const char* tokens[] = {"FBX"};
|
||||
const char* tokens[] = {"fbx"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||
}
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -376,7 +376,7 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
|
||||
return SafeParse<float>(data+1, t.end());
|
||||
}
|
||||
else {
|
||||
return SafeParse<double>(data+1, t.end());
|
||||
return static_cast<float>( SafeParse<double>(data+1, t.end()) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ Property* ReadTypedProperty(const Element& element)
|
||||
else if (!strcmp(cs,"bool") || !strcmp(cs,"Bool")) {
|
||||
return new TypedProperty<bool>(ParseTokenAsInt(*tok[4]) != 0);
|
||||
}
|
||||
else if (!strcmp(cs,"int") || !strcmp(cs,"enum")) {
|
||||
else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum")) {
|
||||
return new TypedProperty<int>(ParseTokenAsInt(*tok[4]));
|
||||
}
|
||||
else if (!strcmp(cs,"ULongLong")) {
|
||||
|
||||
@@ -58,14 +58,15 @@ namespace FBX {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column)
|
||||
: sbegin(sbegin)
|
||||
:
|
||||
#ifdef DEBUG
|
||||
contents(sbegin, static_cast<size_t>(send-sbegin)),
|
||||
#endif
|
||||
sbegin(sbegin)
|
||||
, send(send)
|
||||
, type(type)
|
||||
, line(line)
|
||||
, column(column)
|
||||
#ifdef DEBUG
|
||||
, contents(sbegin, static_cast<size_t>(send-sbegin))
|
||||
#endif
|
||||
{
|
||||
ai_assert(sbegin);
|
||||
ai_assert(send);
|
||||
|
||||
@@ -221,7 +221,7 @@ AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, float epsilon);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE bool EpsilonCompare(float n, float s, float epsilon) {
|
||||
return fabs(n-s)>epsilon;
|
||||
return std::fabs(n-s)>epsilon;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -149,8 +149,8 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
|
||||
if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false;
|
||||
|
||||
// now compare the volumes of the bounding boxes
|
||||
if (::fabsf(fDelta0_x * fDelta1_yz) <
|
||||
::fabsf(fDelta1_x * fDelta1_y * fDelta1_z))
|
||||
if (std::fabs(fDelta0_x * fDelta1_yz) <
|
||||
std::fabs(fDelta1_x * fDelta1_y * fDelta1_z))
|
||||
{
|
||||
if (!DefaultLogger::isNullLogger())
|
||||
{
|
||||
|
||||
@@ -204,7 +204,7 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int
|
||||
// Slower code path if a smooth angle is set. There are many ways to achieve
|
||||
// the effect, this one is the most straightforward one.
|
||||
else {
|
||||
const float fLimit = ::cos(configMaxAngle);
|
||||
const float fLimit = std::cos(configMaxAngle);
|
||||
for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
|
||||
// Get all vertices that share this one ...
|
||||
vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
|
||||
|
||||
+5
-5
@@ -69,8 +69,8 @@ Intersect IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const I
|
||||
const IfcVector3 pdelta = e0 - p, seg = e1-e0;
|
||||
const IfcFloat dotOne = n*seg, dotTwo = -(n*pdelta);
|
||||
|
||||
if (fabs(dotOne) < 1e-6) {
|
||||
return fabs(dotTwo) < 1e-6f ? Intersect_LiesOnPlane : Intersect_No;
|
||||
if (std::fabs(dotOne) < 1e-6) {
|
||||
return std::fabs(dotTwo) < 1e-6f ? Intersect_LiesOnPlane : Intersect_No;
|
||||
}
|
||||
|
||||
const IfcFloat t = dotTwo/dotOne;
|
||||
@@ -210,7 +210,7 @@ bool IntersectsBoundaryProfile( const IfcVector3& e0, const IfcVector3& e1, cons
|
||||
// segment-segment intersection
|
||||
// solve b0 + b*s = e0 + e*t for (s,t)
|
||||
const IfcFloat det = (-b.x * e.y + e.x * b.y);
|
||||
if(fabs(det) < 1e-6) {
|
||||
if(std::fabs(det) < 1e-6) {
|
||||
// no solutions (parallel lines)
|
||||
continue;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ bool IntersectsBoundaryProfile( const IfcVector3& e0, const IfcVector3& e1, cons
|
||||
if (t >= -epsilon && (t <= 1.0+epsilon || half_open) && s >= -epsilon && s <= 1.0) {
|
||||
|
||||
if (e0_hits_border && !*e0_hits_border) {
|
||||
*e0_hits_border = fabs(t) < 1e-5f;
|
||||
*e0_hits_border = std::fabs(t) < 1e-5f;
|
||||
}
|
||||
|
||||
const IfcVector3& p = e0 + e*t;
|
||||
@@ -419,7 +419,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const IfcPolygonalBounded
|
||||
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
if (isect == Intersect_Yes) {
|
||||
const IfcFloat f = fabs((isectpos - p)*n);
|
||||
const IfcFloat f = std::fabs((isectpos - p)*n);
|
||||
ai_assert(f < 1e-5);
|
||||
}
|
||||
#endif
|
||||
|
||||
+12
-12
@@ -88,10 +88,10 @@ public:
|
||||
a *= conv.angle_scale;
|
||||
b *= conv.angle_scale;
|
||||
|
||||
a = fmod(a,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
|
||||
b = fmod(b,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
|
||||
a = std::fmod(a,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
|
||||
b = std::fmod(b,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
|
||||
const IfcFloat setting = static_cast<IfcFloat>( AI_MATH_PI * conv.settings.conicSamplingAngle / 180.0 );
|
||||
return static_cast<size_t>( ceil(abs( b-a)) / setting);
|
||||
return static_cast<size_t>( std::ceil(abs( b-a)) / setting);
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
@@ -124,8 +124,8 @@ public:
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat u) const {
|
||||
u = -conv.angle_scale * u;
|
||||
return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(::cos(u))*p[0] +
|
||||
static_cast<IfcFloat>(::sin(u))*p[1]);
|
||||
return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(std::cos(u))*p[0] +
|
||||
static_cast<IfcFloat>(std::sin(u))*p[1]);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -153,8 +153,8 @@ public:
|
||||
// --------------------------------------------------
|
||||
IfcVector3 Eval(IfcFloat u) const {
|
||||
u = -conv.angle_scale * u;
|
||||
return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(::cos(u))*p[0] +
|
||||
static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(::sin(u))*p[1];
|
||||
return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(std::cos(u))*p[0] +
|
||||
static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(std::sin(u))*p[1];
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -486,7 +486,7 @@ public:
|
||||
IfcVector3 Eval(IfcFloat p) const {
|
||||
ai_assert(InRange(p));
|
||||
|
||||
const size_t b = static_cast<size_t>(floor(p));
|
||||
const size_t b = static_cast<size_t>(std::floor(p));
|
||||
if (b == points.size()-1) {
|
||||
return points.back();
|
||||
}
|
||||
@@ -498,7 +498,7 @@ public:
|
||||
// --------------------------------------------------
|
||||
size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
|
||||
ai_assert(InRange(a) && InRange(b));
|
||||
return static_cast<size_t>( ceil(b) - floor(a) );
|
||||
return static_cast<size_t>( std::ceil(b) - std::floor(a) );
|
||||
}
|
||||
|
||||
// --------------------------------------------------
|
||||
@@ -558,7 +558,7 @@ bool Curve :: InRange(IfcFloat u) const
|
||||
if (IsClosed()) {
|
||||
return true;
|
||||
//ai_assert(range.first != std::numeric_limits<IfcFloat>::infinity() && range.second != std::numeric_limits<IfcFloat>::infinity());
|
||||
//u = range.first + fmod(u-range.first,range.second-range.first);
|
||||
//u = range.first + std::fmod(u-range.first,range.second-range.first);
|
||||
}
|
||||
const IfcFloat epsilon = 1e-5;
|
||||
return u - range.first > -epsilon && range.second - u > -epsilon;
|
||||
@@ -606,12 +606,12 @@ IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, Ifc
|
||||
}
|
||||
|
||||
ai_assert(min_diff[0] != inf && min_diff[1] != inf);
|
||||
if ( fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
|
||||
if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
|
||||
return min_point[0];
|
||||
}
|
||||
|
||||
// fix for closed curves to take their wrap-over into account
|
||||
if (cv->IsClosed() && fabs(min_point[0]-min_point[1]) > cv->GetParametricRangeDelta()*0.5 ) {
|
||||
if (cv->IsClosed() && std::fabs(min_point[0]-min_point[1]) > cv->GetParametricRangeDelta()*0.5 ) {
|
||||
const Curve::ParamRange& range = cv->GetParametricRange();
|
||||
const IfcFloat wrapdiff = (cv->Eval(range.first)-val).SquareLength();
|
||||
|
||||
|
||||
@@ -250,17 +250,17 @@ void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& resul
|
||||
|
||||
bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
|
||||
const IfcFloat max_angle = solid.Angle*conv.angle_scale;
|
||||
if(fabs(max_angle) < 1e-3) {
|
||||
if(std::fabs(max_angle) < 1e-3) {
|
||||
if(has_area) {
|
||||
result = meshout;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(16 * fabs(max_angle)/AI_MATH_HALF_PI_F));
|
||||
const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(16 * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
|
||||
const IfcFloat delta = max_angle/cnt_segments;
|
||||
|
||||
has_area = has_area && fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
|
||||
has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
|
||||
|
||||
result.verts.reserve(size*((cnt_segments+1)*4+(has_area?2:0)));
|
||||
result.vertcnt.reserve(size*cnt_segments+2);
|
||||
@@ -480,7 +480,7 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
|
||||
for (i = 0; !done && i < s-2; done || ++i) {
|
||||
for (j = i+1; j < s-1; ++j) {
|
||||
nor = -((out[i]-any_point)^(out[j]-any_point));
|
||||
if(fabs(nor.Length()) > 1e-8f) {
|
||||
if(std::fabs(nor.Length()) > 1e-8f) {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
+37
-37
@@ -303,20 +303,20 @@ void InsertWindowContours(const ContourVector& contours,
|
||||
const IfcVector2& v = contour[n];
|
||||
|
||||
bool hit = false;
|
||||
if (fabs(v.x-bb.first.x)<epsilon) {
|
||||
if (std::fabs(v.x-bb.first.x)<epsilon) {
|
||||
edge.x = bb.first.x;
|
||||
hit = true;
|
||||
}
|
||||
else if (fabs(v.x-bb.second.x)<epsilon) {
|
||||
else if (std::fabs(v.x-bb.second.x)<epsilon) {
|
||||
edge.x = bb.second.x;
|
||||
hit = true;
|
||||
}
|
||||
|
||||
if (fabs(v.y-bb.first.y)<epsilon) {
|
||||
if (std::fabs(v.y-bb.first.y)<epsilon) {
|
||||
edge.y = bb.first.y;
|
||||
hit = true;
|
||||
}
|
||||
else if (fabs(v.y-bb.second.y)<epsilon) {
|
||||
else if (std::fabs(v.y-bb.second.y)<epsilon) {
|
||||
edge.y = bb.second.y;
|
||||
hit = true;
|
||||
}
|
||||
@@ -343,17 +343,17 @@ void InsertWindowContours(const ContourVector& contours,
|
||||
|
||||
IfcVector2 corner = edge;
|
||||
|
||||
if (fabs(contour[last_hit].x-bb.first.x)<epsilon) {
|
||||
if (std::fabs(contour[last_hit].x-bb.first.x)<epsilon) {
|
||||
corner.x = bb.first.x;
|
||||
}
|
||||
else if (fabs(contour[last_hit].x-bb.second.x)<epsilon) {
|
||||
else if (std::fabs(contour[last_hit].x-bb.second.x)<epsilon) {
|
||||
corner.x = bb.second.x;
|
||||
}
|
||||
|
||||
if (fabs(contour[last_hit].y-bb.first.y)<epsilon) {
|
||||
if (std::fabs(contour[last_hit].y-bb.first.y)<epsilon) {
|
||||
corner.y = bb.first.y;
|
||||
}
|
||||
else if (fabs(contour[last_hit].y-bb.second.y)<epsilon) {
|
||||
else if (std::fabs(contour[last_hit].y-bb.second.y)<epsilon) {
|
||||
corner.y = bb.second.y;
|
||||
}
|
||||
|
||||
@@ -590,10 +590,10 @@ bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
|
||||
{
|
||||
// TODO: I'm pretty sure there is a much more compact way to check this
|
||||
const IfcFloat epsilon = 1e-5f;
|
||||
return (fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
|
||||
(fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) ||
|
||||
(fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) ||
|
||||
(fabs(bb.first.y - ibb.second.y) < epsilon && ibb.first.x <= bb.second.x && ibb.second.x >= bb.first.x);
|
||||
return (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
|
||||
(std::fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) ||
|
||||
(std::fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) ||
|
||||
(std::fabs(bb.first.y - ibb.second.y) < epsilon && ibb.first.x <= bb.second.x && ibb.second.x >= bb.first.x);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -615,11 +615,11 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||
|
||||
static const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
|
||||
|
||||
if (!(n0_to_m0.SquareLength() < e*e || fabs(n0_to_m0 * n0_to_n1) / (n0_to_m0.Length() * n0_to_n1.Length()) > 1-1e-5 )) {
|
||||
if (!(n0_to_m0.SquareLength() < e*e || std::fabs(n0_to_m0 * n0_to_n1) / (n0_to_m0.Length() * n0_to_n1.Length()) > 1-1e-5 )) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(n1_to_m1.SquareLength() < e*e || fabs(n1_to_m1 * n0_to_n1) / (n1_to_m1.Length() * n0_to_n1.Length()) > 1-1e-5 )) {
|
||||
if (!(n1_to_m1.SquareLength() < e*e || std::fabs(n1_to_m1 * n0_to_n1) / (n1_to_m1.Length() * n0_to_n1.Length()) > 1-1e-5 )) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -631,14 +631,14 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||
// the higher absolute difference is big enough as to avoid
|
||||
// divisions by zero, the case 0/0 ~ infinity is detected and
|
||||
// handled separately.
|
||||
if(fabs(n0_to_n1.x) > fabs(n0_to_n1.y)) {
|
||||
if(std::fabs(n0_to_n1.x) > std::fabs(n0_to_n1.y)) {
|
||||
s0 = n0_to_m0.x / n0_to_n1.x;
|
||||
s1 = n0_to_m1.x / n0_to_n1.x;
|
||||
|
||||
if (fabs(s0) == inf && fabs(n0_to_m0.x) < smalle) {
|
||||
if (std::fabs(s0) == inf && std::fabs(n0_to_m0.x) < smalle) {
|
||||
s0 = 0.;
|
||||
}
|
||||
if (fabs(s1) == inf && fabs(n0_to_m1.x) < smalle) {
|
||||
if (std::fabs(s1) == inf && std::fabs(n0_to_m1.x) < smalle) {
|
||||
s1 = 0.;
|
||||
}
|
||||
}
|
||||
@@ -646,10 +646,10 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||
s0 = n0_to_m0.y / n0_to_n1.y;
|
||||
s1 = n0_to_m1.y / n0_to_n1.y;
|
||||
|
||||
if (fabs(s0) == inf && fabs(n0_to_m0.y) < smalle) {
|
||||
if (std::fabs(s0) == inf && std::fabs(n0_to_m0.y) < smalle) {
|
||||
s0 = 0.;
|
||||
}
|
||||
if (fabs(s1) == inf && fabs(n0_to_m1.y) < smalle) {
|
||||
if (std::fabs(s1) == inf && std::fabs(n0_to_m1.y) < smalle) {
|
||||
s1 = 0.;
|
||||
}
|
||||
}
|
||||
@@ -664,7 +664,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
||||
s0 = std::min(1.0,s0);
|
||||
s1 = std::min(1.0,s1);
|
||||
|
||||
if (fabs(s1-s0) < e) {
|
||||
if (std::fabs(s1-s0) < e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -755,7 +755,7 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
|
||||
AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta)
|
||||
{
|
||||
const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(1e-5);
|
||||
return fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
|
||||
return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -812,9 +812,9 @@ void FindBorderContours(ContourVector::iterator current)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE bool LikelyDiagonal(IfcVector2 vdelta)
|
||||
{
|
||||
vdelta.x = fabs(vdelta.x);
|
||||
vdelta.y = fabs(vdelta.y);
|
||||
return (fabs(vdelta.x-vdelta.y) < 0.8 * std::max(vdelta.x, vdelta.y));
|
||||
vdelta.x = std::fabs(vdelta.x);
|
||||
vdelta.y = std::fabs(vdelta.y);
|
||||
return (std::fabs(vdelta.x-vdelta.y) < 0.8 * std::max(vdelta.x, vdelta.y));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -926,7 +926,7 @@ size_t CloseWindows(ContourVector& contours,
|
||||
/* debug code to check for unwanted diagonal lines in window contours
|
||||
if (cit != cbegin) {
|
||||
const IfcVector2& vdelta = proj_point - last_proj;
|
||||
if (fabs(vdelta.x-vdelta.y) < 0.5 * std::max(vdelta.x, vdelta.y)) {
|
||||
if (std::fabs(vdelta.x-vdelta.y) < 0.5 * std::max(vdelta.x, vdelta.y)) {
|
||||
//continue;
|
||||
}
|
||||
} */
|
||||
@@ -1065,7 +1065,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
||||
}
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
const IfcFloat det = m.Determinant();
|
||||
ai_assert(fabs(det-1) < 1e-5);
|
||||
ai_assert(std::fabs(det-1) < 1e-5);
|
||||
#endif
|
||||
|
||||
IfcFloat zcoord = 0;
|
||||
@@ -1085,7 +1085,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
||||
// XXX this should be guarded, but we somehow need to pick a suitable
|
||||
// epsilon
|
||||
// if(coord != -1.0f) {
|
||||
// assert(fabs(coord - vv.z) < 1e-3f);
|
||||
// assert(std::fabs(coord - vv.z) < 1e-3f);
|
||||
// }
|
||||
zcoord += vv.z;
|
||||
vmin = std::min(vv, vmin);
|
||||
@@ -1125,7 +1125,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
||||
const IfcVector3& vv = m * x;
|
||||
|
||||
out_contour2.push_back(IfcVector2(vv.x,vv.y));
|
||||
ai_assert(fabs(vv.z) < vmax.z + 1e-8);
|
||||
ai_assert(std::fabs(vv.z) < vmax.z + 1e-8);
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < out_contour.size(); ++i) {
|
||||
@@ -1188,9 +1188,9 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||
bool is_2d_source = false;
|
||||
if (opening.profileMesh2D && norm_extrusion_dir.SquareLength() > 0) {
|
||||
|
||||
if(fabs(norm_extrusion_dir * wall_extrusion_axis_norm) < 0.1) {
|
||||
if(std::fabs(norm_extrusion_dir * wall_extrusion_axis_norm) < 0.1) {
|
||||
// horizontal extrusion
|
||||
if (fabs(norm_extrusion_dir * nor) > 0.9) {
|
||||
if (std::fabs(norm_extrusion_dir * nor) > 0.9) {
|
||||
profile_data = opening.profileMesh2D.get();
|
||||
is_2d_source = true;
|
||||
}
|
||||
@@ -1200,7 +1200,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||
}
|
||||
else {
|
||||
// vertical extrusion
|
||||
if (fabs(norm_extrusion_dir * nor) > 0.9) {
|
||||
if (std::fabs(norm_extrusion_dir * nor) > 0.9) {
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
@@ -1289,7 +1289,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||
ai_assert(!is_2d_source);
|
||||
const IfcVector2 area = vpmax-vpmin;
|
||||
const IfcVector2 area2 = vpmax2-vpmin2;
|
||||
if (temp_contour.size() <= 2 || fabs(area2.x * area2.y) > fabs(area.x * area.y)) {
|
||||
if (temp_contour.size() <= 2 || std::fabs(area2.x * area2.y) > std::fabs(area.x * area.y)) {
|
||||
temp_contour.swap(temp_contour2);
|
||||
|
||||
vpmax = vpmax2;
|
||||
@@ -1301,7 +1301,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||
}
|
||||
|
||||
// TODO: This epsilon may be too large
|
||||
const IfcFloat epsilon = fabs(dmax-dmin) * 0.0001;
|
||||
const IfcFloat epsilon = std::fabs(dmax-dmin) * 0.0001;
|
||||
if (!is_2d_source && check_intersection && (0 < dmin-epsilon || 0 > dmax+epsilon)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1310,7 +1310,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
||||
|
||||
// Skip over very small openings - these are likely projection errors
|
||||
// (i.e. they don't belong to this side of the wall)
|
||||
if(fabs(vpmax.x - vpmin.x) * fabs(vpmax.y - vpmin.y) < static_cast<IfcFloat>(1e-10)) {
|
||||
if(std::fabs(vpmax.x - vpmin.x) * std::fabs(vpmax.y - vpmin.y) < static_cast<IfcFloat>(1e-10)) {
|
||||
continue;
|
||||
}
|
||||
std::vector<TempOpening*> joined_openings(1, &opening);
|
||||
@@ -1480,7 +1480,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||
// XXX this should be guarded, but we somehow need to pick a suitable
|
||||
// epsilon
|
||||
// if(coord != -1.0f) {
|
||||
// assert(fabs(coord - vv.z) < 1e-3f);
|
||||
// assert(std::fabs(coord - vv.z) < 1e-3f);
|
||||
// }
|
||||
|
||||
coord = vv.z;
|
||||
@@ -1515,7 +1515,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||
BOOST_FOREACH(const TempOpening& t,openings) {
|
||||
const IfcVector3& outernor = nors[c++];
|
||||
const IfcFloat dot = nor * outernor;
|
||||
if (fabs(dot)<1.f-1e-6f) {
|
||||
if (std::fabs(dot)<1.f-1e-6f) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1529,7 +1529,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
||||
BOOST_FOREACH(const IfcVector3& xx, t.profileMesh->verts) {
|
||||
IfcVector3 vv = m * xx, vv_extr = m * (xx + t.extrusionDir);
|
||||
|
||||
const bool is_extruded_side = fabs(vv.z - coord) > fabs(vv_extr.z - coord);
|
||||
const bool is_extruded_side = std::fabs(vv.z - coord) > std::fabs(vv_extr.z - coord);
|
||||
if (first) {
|
||||
first = false;
|
||||
if (dot > 0.f) {
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ void ProcessParametrizedProfile(const IfcParameterizedProfileDef& def, TempMesh&
|
||||
|
||||
IfcFloat angle = 0.f;
|
||||
for(size_t i = 0; i < segments; ++i, angle += delta) {
|
||||
meshout.verts.push_back( IfcVector3( cos(angle)*radius, sin(angle)*radius, 0.f ));
|
||||
meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f ));
|
||||
}
|
||||
|
||||
meshout.vertcnt.push_back(segments);
|
||||
|
||||
+1
-1
@@ -278,7 +278,7 @@ void TempMesh::RemoveAdjacentDuplicates()
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// const IfcFloat d = (d0/sqrt(l0))*(d1/sqrt(l1));
|
||||
// const IfcFloat d = (d0/std::sqrt(l0))*(d1/std::sqrt(l1));
|
||||
|
||||
// if ( d >= 1.f-dotepsilon ) {
|
||||
// v1 = v0;
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ struct FuzzyVectorCompare {
|
||||
|
||||
FuzzyVectorCompare(IfcFloat epsilon) : epsilon(epsilon) {}
|
||||
bool operator()(const IfcVector3& a, const IfcVector3& b) {
|
||||
return fabs((a-b).SquareLength()) < epsilon;
|
||||
return std::fabs((a-b).SquareLength()) < epsilon;
|
||||
}
|
||||
|
||||
const IfcFloat epsilon;
|
||||
|
||||
+24
-22
@@ -12,8 +12,6 @@
|
||||
namespace Assimp {
|
||||
namespace IFF {
|
||||
|
||||
#include "./../include/assimp/Compiler/pushpack1.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//! Describes an IFF chunk header
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -24,7 +22,7 @@ struct ChunkHeader
|
||||
|
||||
//! Length of the chunk data, in bytes
|
||||
uint32_t length;
|
||||
} PACK_STRUCT;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -37,9 +35,7 @@ struct SubChunkHeader
|
||||
|
||||
//! Length of the chunk data, in bytes
|
||||
uint16_t length;
|
||||
} PACK_STRUCT;
|
||||
|
||||
#include "./../include/assimp/Compiler/poppack1.h"
|
||||
};
|
||||
|
||||
|
||||
#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \
|
||||
@@ -52,28 +48,34 @@ struct SubChunkHeader
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//! Load a chunk header
|
||||
//! @param outFile Pointer to the file data - points to the chunk data afterwards
|
||||
//! @return Pointer to the chunk header
|
||||
//! @return Copy of the chunk header
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
inline ChunkHeader* LoadChunk(uint8_t*& outFile)
|
||||
inline ChunkHeader LoadChunk(uint8_t*& outFile)
|
||||
{
|
||||
ChunkHeader* head = (ChunkHeader*) outFile;
|
||||
AI_LSWAP4(head->length);
|
||||
AI_LSWAP4(head->type);
|
||||
outFile += sizeof(ChunkHeader);
|
||||
ChunkHeader head;
|
||||
::memcpy(&head.type, outFile, 4);
|
||||
outFile += 4;
|
||||
::memcpy(&head.length, outFile, 4);
|
||||
outFile += 4;
|
||||
AI_LSWAP4(head.length);
|
||||
AI_LSWAP4(head.type);
|
||||
return head;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//! Load a sub chunk header
|
||||
//! @param outFile Pointer to the file data - points to the chunk data afterwards
|
||||
//! @return Pointer to the sub chunk header
|
||||
//! @return Copy of the sub chunk header
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
inline SubChunkHeader* LoadSubChunk(uint8_t*& outFile)
|
||||
inline SubChunkHeader LoadSubChunk(uint8_t*& outFile)
|
||||
{
|
||||
SubChunkHeader* head = (SubChunkHeader*) outFile;
|
||||
AI_LSWAP2(head->length);
|
||||
AI_LSWAP4(head->type);
|
||||
outFile += sizeof(SubChunkHeader);
|
||||
SubChunkHeader head;
|
||||
::memcpy(&head.type, outFile, 4);
|
||||
outFile += 4;
|
||||
::memcpy(&head.length, outFile, 2);
|
||||
outFile += 2;
|
||||
AI_LSWAP2(head.length);
|
||||
AI_LSWAP4(head.type);
|
||||
return head;
|
||||
}
|
||||
|
||||
@@ -84,14 +86,14 @@ inline SubChunkHeader* LoadSubChunk(uint8_t*& outFile)
|
||||
//! @param fileType Receives the type of the file
|
||||
//! @return 0 if everything was OK, otherwise an error message
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
inline const char* ReadHeader(uint8_t* outFile,uint32_t& fileType)
|
||||
inline const char* ReadHeader(uint8_t* outFile, uint32_t& fileType)
|
||||
{
|
||||
ChunkHeader* head = LoadChunk(outFile);
|
||||
if(AI_IFF_FOURCC_FORM != head->type)
|
||||
ChunkHeader head = LoadChunk(outFile);
|
||||
if(AI_IFF_FOURCC_FORM != head.type)
|
||||
{
|
||||
return "The file is not an IFF file: FORM chunk is missing";
|
||||
}
|
||||
fileType = *((uint32_t*)(head+1));
|
||||
::memcpy(&fileType, outFile, 4);
|
||||
AI_LSWAP4(fileType);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+3
-3
@@ -470,7 +470,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
|
||||
key.mTime = i * tdelta;
|
||||
|
||||
const float t = (float) ( in.speed * key.mTime );
|
||||
key.mValue = in.circleCenter + in.circleRadius * ((vecU*::cosf(t)) + (vecV*::sinf(t)));
|
||||
key.mValue = in.circleCenter + in.circleRadius * ((vecU * std::cos(t)) + (vecV * std::sin(t)));
|
||||
}
|
||||
|
||||
// This animation is repeated and repeated ...
|
||||
@@ -533,8 +533,8 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
|
||||
aiVectorKey& key = anim->mPositionKeys[i];
|
||||
|
||||
const float dt = (i * in.speed * 0.001f );
|
||||
const float u = dt - floor(dt);
|
||||
const int idx = (int)floor(dt) % size;
|
||||
const float u = dt - std::floor(dt);
|
||||
const int idx = (int)std::floor(dt) % size;
|
||||
|
||||
// get the 4 current points to evaluate the spline
|
||||
const aiVector3D& p0 = in.splineKeys[ ClampSpline( idx - 1, size ) ].mValue;
|
||||
|
||||
@@ -49,8 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
namespace Assimp
|
||||
{
|
||||
|
||||
class JoinVerticesTest;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
/** The JoinVerticesProcess unites identical vertices in all imported meshes.
|
||||
* By default the importer returns meshes where each face addressed its own
|
||||
|
||||
+58
-40
@@ -58,30 +58,31 @@ void LWOImporter::LoadLWOBFile()
|
||||
while (running)
|
||||
{
|
||||
if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
|
||||
LE_NCONST IFF::ChunkHeader* const head = IFF::LoadChunk(mFileBuffer);
|
||||
const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
|
||||
|
||||
if (mFileBuffer + head->length > end)
|
||||
if (mFileBuffer + head.length > end)
|
||||
{
|
||||
throw DeadlyImportError("LWOB: Invalid chunk length");
|
||||
break;
|
||||
}
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
switch (head->type)
|
||||
uint8_t* const next = mFileBuffer+head.length;
|
||||
switch (head.type)
|
||||
{
|
||||
// vertex list
|
||||
case AI_LWO_PNTS:
|
||||
{
|
||||
if (!mCurLayer->mTempPoints.empty())
|
||||
DefaultLogger::get()->warn("LWO: PNTS chunk encountered twice");
|
||||
else LoadLWOPoints(head->length);
|
||||
else LoadLWOPoints(head.length);
|
||||
break;
|
||||
}
|
||||
// face list
|
||||
case AI_LWO_POLS:
|
||||
{
|
||||
|
||||
if (!mCurLayer->mFaces.empty())
|
||||
DefaultLogger::get()->warn("LWO: POLS chunk encountered twice");
|
||||
else LoadLWOBPolygons(head->length);
|
||||
else LoadLWOBPolygons(head.length);
|
||||
break;
|
||||
}
|
||||
// list of tags
|
||||
@@ -89,14 +90,14 @@ void LWOImporter::LoadLWOBFile()
|
||||
{
|
||||
if (!mTags->empty())
|
||||
DefaultLogger::get()->warn("LWO: SRFS chunk encountered twice");
|
||||
else LoadLWOTags(head->length);
|
||||
else LoadLWOTags(head.length);
|
||||
break;
|
||||
}
|
||||
|
||||
// surface chunk
|
||||
case AI_LWO_SURF:
|
||||
{
|
||||
LoadLWOBSurface(head->length);
|
||||
LoadLWOBSurface(head.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -137,14 +138,17 @@ void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& face
|
||||
{
|
||||
while (cursor < end && max--)
|
||||
{
|
||||
uint16_t numIndices = *cursor++;
|
||||
verts += numIndices;faces++;
|
||||
uint16_t numIndices;
|
||||
::memcpy(&numIndices, cursor++, 2);
|
||||
verts += numIndices;
|
||||
faces++;
|
||||
cursor += numIndices;
|
||||
int16_t surface = *cursor++;
|
||||
int16_t surface;
|
||||
::memcpy(&surface, cursor++, 2);
|
||||
if (surface < 0)
|
||||
{
|
||||
// there are detail polygons
|
||||
numIndices = *cursor++;
|
||||
::memcpy(&numIndices, cursor++, 2);
|
||||
CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
|
||||
}
|
||||
}
|
||||
@@ -159,13 +163,22 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
||||
while (cursor < end && max--)
|
||||
{
|
||||
LWO::Face& face = *it;++it;
|
||||
if((face.mNumIndices = *cursor++))
|
||||
uint16_t numIndices;
|
||||
::memcpy(&numIndices, cursor++, 2);
|
||||
face.mNumIndices = numIndices;
|
||||
if(face.mNumIndices)
|
||||
{
|
||||
if (cursor + face.mNumIndices >= end)break;
|
||||
if (cursor + face.mNumIndices >= end)
|
||||
{
|
||||
break;
|
||||
}
|
||||
face.mIndices = new unsigned int[face.mNumIndices];
|
||||
for (unsigned int i = 0; i < face.mNumIndices;++i)
|
||||
{
|
||||
unsigned int & mi = face.mIndices[i] = *cursor++;
|
||||
unsigned int & mi = face.mIndices[i];
|
||||
uint16_t index;
|
||||
::memcpy(&index, cursor++, 2);
|
||||
mi = index;
|
||||
if (mi > mCurLayer->mTempPoints.size())
|
||||
{
|
||||
DefaultLogger::get()->warn("LWOB: face index is out of range");
|
||||
@@ -174,14 +187,19 @@ void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
|
||||
}
|
||||
}
|
||||
else DefaultLogger::get()->warn("LWOB: Face has 0 indices");
|
||||
int16_t surface = *cursor++;
|
||||
int16_t surface;
|
||||
::memcpy(&surface, cursor++, 2);
|
||||
if (surface < 0)
|
||||
{
|
||||
surface = -surface;
|
||||
|
||||
// there are detail polygons.
|
||||
const uint16_t numPolygons = *cursor++;
|
||||
if (cursor < end)CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
|
||||
uint16_t numPolygons;
|
||||
::memcpy(&numPolygons, cursor++, 2);
|
||||
if (cursor < end)
|
||||
{
|
||||
CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
|
||||
}
|
||||
}
|
||||
face.surfaceIndex = surface-1;
|
||||
}
|
||||
@@ -235,7 +253,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||
if (mFileBuffer + 6 >= end)
|
||||
break;
|
||||
|
||||
IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||
IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
|
||||
|
||||
/* A single test file (sonycam.lwo) seems to have invalid surface chunks.
|
||||
* I'm assuming it's the fault of a single, unknown exporter so there are
|
||||
@@ -244,18 +262,18 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||
* We don't break if the chunk limit is exceeded. Instead, we're computing
|
||||
* how much storage is actually left and work with this value from now on.
|
||||
*/
|
||||
if (mFileBuffer + head->length > end) {
|
||||
if (mFileBuffer + head.length > end) {
|
||||
DefaultLogger::get()->error("LWOB: Invalid surface chunk length. Trying to continue.");
|
||||
head->length = (uint16_t) (end - mFileBuffer);
|
||||
head.length = (uint16_t) (end - mFileBuffer);
|
||||
}
|
||||
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
switch (head->type)
|
||||
uint8_t* const next = mFileBuffer+head.length;
|
||||
switch (head.type)
|
||||
{
|
||||
// diffuse color
|
||||
case AI_LWO_COLR:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,COLR,3);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,COLR,3);
|
||||
surf.mColor.r = GetU1() / 255.0f;
|
||||
surf.mColor.g = GetU1() / 255.0f;
|
||||
surf.mColor.b = GetU1() / 255.0f;
|
||||
@@ -264,35 +282,35 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||
// diffuse strength ...
|
||||
case AI_LWO_DIFF:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,DIFF,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,DIFF,2);
|
||||
surf.mDiffuseValue = GetU2() / 255.0f;
|
||||
break;
|
||||
}
|
||||
// specular strength ...
|
||||
case AI_LWO_SPEC:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPEC,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPEC,2);
|
||||
surf.mSpecularValue = GetU2() / 255.0f;
|
||||
break;
|
||||
}
|
||||
// luminosity ...
|
||||
case AI_LWO_LUMI:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LUMI,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LUMI,2);
|
||||
surf.mLuminosity = GetU2() / 255.0f;
|
||||
break;
|
||||
}
|
||||
// transparency
|
||||
case AI_LWO_TRAN:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TRAN,2);
|
||||
surf.mTransparency = GetU2() / 255.0f;
|
||||
break;
|
||||
}
|
||||
// surface flags
|
||||
case AI_LWO_FLAG:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,FLAG,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,FLAG,2);
|
||||
uint16_t flag = GetU2();
|
||||
if (flag & 0x4 ) surf.mMaximumSmoothAngle = 1.56207f;
|
||||
if (flag & 0x8 ) surf.mColorHighlights = 1.f;
|
||||
@@ -302,14 +320,14 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||
// maximum smoothing angle
|
||||
case AI_LWO_SMAN:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SMAN,4);
|
||||
surf.mMaximumSmoothAngle = fabs( GetF4() );
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
|
||||
surf.mMaximumSmoothAngle = std::fabs( GetF4() );
|
||||
break;
|
||||
}
|
||||
// glossiness
|
||||
case AI_LWO_GLOS:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,GLOS,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,GLOS,2);
|
||||
surf.mGlossiness = (float)GetU2();
|
||||
break;
|
||||
}
|
||||
@@ -317,42 +335,42 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||
case AI_LWO_CTEX:
|
||||
{
|
||||
pTex = SetupNewTextureLWOB(surf.mColorTextures,
|
||||
head->length);
|
||||
head.length);
|
||||
break;
|
||||
}
|
||||
// diffuse texture
|
||||
case AI_LWO_DTEX:
|
||||
{
|
||||
pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
|
||||
head->length);
|
||||
head.length);
|
||||
break;
|
||||
}
|
||||
// specular texture
|
||||
case AI_LWO_STEX:
|
||||
{
|
||||
pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
|
||||
head->length);
|
||||
head.length);
|
||||
break;
|
||||
}
|
||||
// bump texture
|
||||
case AI_LWO_BTEX:
|
||||
{
|
||||
pTex = SetupNewTextureLWOB(surf.mBumpTextures,
|
||||
head->length);
|
||||
head.length);
|
||||
break;
|
||||
}
|
||||
// transparency texture
|
||||
case AI_LWO_TTEX:
|
||||
{
|
||||
pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
|
||||
head->length);
|
||||
head.length);
|
||||
break;
|
||||
}
|
||||
// texture path
|
||||
case AI_LWO_TIMG:
|
||||
{
|
||||
if (pTex) {
|
||||
GetS0(pTex->mFileName,head->length);
|
||||
GetS0(pTex->mFileName,head.length);
|
||||
}
|
||||
else DefaultLogger::get()->warn("LWOB: Unexpected TIMG chunk");
|
||||
break;
|
||||
@@ -360,7 +378,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||
// texture strength
|
||||
case AI_LWO_TVAL:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TVAL,1);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TVAL,1);
|
||||
if (pTex) {
|
||||
pTex->mStrength = (float)GetU1()/ 255.f;
|
||||
}
|
||||
@@ -370,7 +388,7 @@ void LWOImporter::LoadLWOBSurface(unsigned int size)
|
||||
// texture flags
|
||||
case AI_LWO_TFLG:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TFLG,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TFLG,2);
|
||||
|
||||
if (pTex)
|
||||
{
|
||||
|
||||
+57
-45
@@ -503,7 +503,7 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
|
||||
// Generate vertex normals. We have O(logn) for the binary lookup, which we need
|
||||
// for n elements, thus the EXPECTED complexity is O(nlogn)
|
||||
if (surface.mMaximumSmoothAngle < 3.f && !configSpeedFlag) {
|
||||
const float fLimit = cos(surface.mMaximumSmoothAngle);
|
||||
const float fLimit = std::cos(surface.mMaximumSmoothAngle);
|
||||
|
||||
for( begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
|
||||
const aiFace& face = *begin;
|
||||
@@ -787,7 +787,8 @@ void LWOImporter::LoadLWO2Polygons(unsigned int length)
|
||||
CountVertsAndFacesLWO2(iNumVertices,iNumFaces,cursor,end);
|
||||
|
||||
// allocate the output array and copy face indices
|
||||
if (iNumFaces) {
|
||||
if (iNumFaces)
|
||||
{
|
||||
cursor = (uint16_t*)mFileBuffer;
|
||||
|
||||
mCurLayer->mFaces.resize(iNumFaces,LWO::Face(type));
|
||||
@@ -802,13 +803,18 @@ void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& face
|
||||
{
|
||||
while (cursor < end && max--)
|
||||
{
|
||||
AI_LSWAP2P(cursor);
|
||||
uint16_t numIndices = *cursor++;
|
||||
uint16_t numIndices;
|
||||
::memcpy(&numIndices, cursor++, 2);
|
||||
AI_LSWAP2(numIndices);
|
||||
numIndices &= 0x03FF;
|
||||
verts += numIndices;++faces;
|
||||
|
||||
verts += numIndices;
|
||||
++faces;
|
||||
|
||||
for(uint16_t i = 0; i < numIndices; i++)
|
||||
{
|
||||
ReadVSizedIntLWO2((uint8_t*&)cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -817,10 +823,16 @@ void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
|
||||
uint16_t*& cursor,
|
||||
const uint16_t* const end)
|
||||
{
|
||||
while (cursor < end) {
|
||||
|
||||
LWO::Face& face = *it++;;
|
||||
if((face.mNumIndices = (*cursor++) & 0x03FF)) /* byte swapping has already been done */ {
|
||||
while (cursor < end)
|
||||
{
|
||||
LWO::Face& face = *it++;
|
||||
uint16_t numIndices;
|
||||
::memcpy(&numIndices, cursor++, 2);
|
||||
AI_LSWAP2(numIndices);
|
||||
face.mNumIndices = numIndices & 0x03FF;
|
||||
|
||||
if(face.mNumIndices) /* byte swapping has already been done */
|
||||
{
|
||||
face.mIndices = new unsigned int[face.mNumIndices];
|
||||
for(unsigned int i = 0; i < face.mNumIndices; i++)
|
||||
{
|
||||
@@ -848,8 +860,8 @@ void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
|
||||
if (type != AI_LWO_SURF && type != AI_LWO_SMGP)
|
||||
return;
|
||||
|
||||
while (mFileBuffer < end) {
|
||||
|
||||
while (mFileBuffer < end)
|
||||
{
|
||||
unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
|
||||
unsigned int j = GetU2();
|
||||
|
||||
@@ -1106,19 +1118,19 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
|
||||
// first - get the index of the clip
|
||||
clip.idx = GetU4();
|
||||
|
||||
IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||
switch (head->type)
|
||||
IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
|
||||
switch (head.type)
|
||||
{
|
||||
case AI_LWO_STIL:
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,STIL,1);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,STIL,1);
|
||||
|
||||
// "Normal" texture
|
||||
GetS0(clip.path,head->length);
|
||||
GetS0(clip.path,head.length);
|
||||
clip.type = Clip::STILL;
|
||||
break;
|
||||
|
||||
case AI_LWO_ISEQ:
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,ISEQ,16);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,ISEQ,16);
|
||||
// Image sequence. We'll later take the first.
|
||||
{
|
||||
uint8_t digits = GetU1(); mFileBuffer++;
|
||||
@@ -1127,12 +1139,12 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
|
||||
|
||||
std::string s;
|
||||
std::ostringstream ss;
|
||||
GetS0(s,head->length);
|
||||
GetS0(s,head.length);
|
||||
|
||||
head->length -= (unsigned int)s.length()+1;
|
||||
head.length -= (unsigned int)s.length()+1;
|
||||
ss << s;
|
||||
ss << std::setw(digits) << offset + start;
|
||||
GetS0(s,head->length);
|
||||
GetS0(s,head.length);
|
||||
ss << s;
|
||||
clip.path = ss.str();
|
||||
clip.type = Clip::SEQ;
|
||||
@@ -1148,7 +1160,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
|
||||
break;
|
||||
|
||||
case AI_LWO_XREF:
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,XREF,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,XREF,4);
|
||||
|
||||
// Just a cross-reference to another CLIp
|
||||
clip.type = Clip::REF;
|
||||
@@ -1156,7 +1168,7 @@ void LWOImporter::LoadLWO2Clip(unsigned int length)
|
||||
break;
|
||||
|
||||
case AI_LWO_NEGA:
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,NEGA,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,NEGA,2);
|
||||
clip.negate = (0 != GetU2());
|
||||
break;
|
||||
|
||||
@@ -1194,17 +1206,17 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
|
||||
while (true)
|
||||
{
|
||||
if (mFileBuffer + 6 >= end)break;
|
||||
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||
LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
|
||||
|
||||
if (mFileBuffer + head->length > end)
|
||||
if (mFileBuffer + head.length > end)
|
||||
throw DeadlyImportError("LWO2: Invalid envelope chunk length");
|
||||
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
switch (head->type)
|
||||
uint8_t* const next = mFileBuffer+head.length;
|
||||
switch (head.type)
|
||||
{
|
||||
// Type & representation of the envelope
|
||||
case AI_LWO_TYPE:
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TYPE,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TYPE,2);
|
||||
mFileBuffer++; // skip user format
|
||||
|
||||
// Determine type of envelope
|
||||
@@ -1214,20 +1226,20 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
|
||||
|
||||
// precondition
|
||||
case AI_LWO_PRE:
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,PRE,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,PRE,2);
|
||||
envelope.pre = (LWO::PrePostBehaviour)GetU2();
|
||||
break;
|
||||
|
||||
// postcondition
|
||||
case AI_LWO_POST:
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,POST,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,POST,2);
|
||||
envelope.post = (LWO::PrePostBehaviour)GetU2();
|
||||
break;
|
||||
|
||||
// keyframe
|
||||
case AI_LWO_KEY:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,KEY,8);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,KEY,8);
|
||||
|
||||
envelope.keys.push_back(LWO::Key());
|
||||
LWO::Key& key = envelope.keys.back();
|
||||
@@ -1240,7 +1252,7 @@ void LWOImporter::LoadLWO2Envelope(unsigned int length)
|
||||
// interval interpolation
|
||||
case AI_LWO_SPAN:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPAN,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPAN,4);
|
||||
if (envelope.keys.size()<2)
|
||||
DefaultLogger::get()->warn("LWO2: Unexpected SPAN chunk");
|
||||
else {
|
||||
@@ -1286,22 +1298,22 @@ void LWOImporter::LoadLWO2File()
|
||||
while (true)
|
||||
{
|
||||
if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
|
||||
IFF::ChunkHeader* const head = IFF::LoadChunk(mFileBuffer);
|
||||
const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
|
||||
|
||||
if (mFileBuffer + head->length > end)
|
||||
if (mFileBuffer + head.length > end)
|
||||
{
|
||||
throw DeadlyImportError("LWO2: Chunk length points behind the file");
|
||||
break;
|
||||
}
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
uint8_t* const next = mFileBuffer+head.length;
|
||||
unsigned int iUnnamed = 0;
|
||||
|
||||
if(!head->length) {
|
||||
if(!head.length) {
|
||||
mFileBuffer = next;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (head->type)
|
||||
switch (head.type)
|
||||
{
|
||||
// new layer
|
||||
case AI_LWO_LAYR:
|
||||
@@ -1311,7 +1323,7 @@ void LWOImporter::LoadLWO2File()
|
||||
LWO::Layer& layer = mLayers->back();
|
||||
mCurLayer = &layer;
|
||||
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LAYR,16);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LAYR,16);
|
||||
|
||||
// layer index.
|
||||
layer.mIndex = GetU2();
|
||||
@@ -1327,7 +1339,7 @@ void LWOImporter::LoadLWO2File()
|
||||
mCurLayer->mPivot.x = GetF4();
|
||||
mCurLayer->mPivot.y = GetF4();
|
||||
mCurLayer->mPivot.z = GetF4();
|
||||
GetS0(layer.mName,head->length-16);
|
||||
GetS0(layer.mName,head.length-16);
|
||||
|
||||
// if the name is empty, generate a default name
|
||||
if (layer.mName.empty()) {
|
||||
@@ -1360,7 +1372,7 @@ void LWOImporter::LoadLWO2File()
|
||||
break;
|
||||
|
||||
unsigned int old = (unsigned int)mCurLayer->mTempPoints.size();
|
||||
LoadLWOPoints(head->length);
|
||||
LoadLWOPoints(head.length);
|
||||
mCurLayer->mPointIDXOfs = old;
|
||||
break;
|
||||
}
|
||||
@@ -1379,7 +1391,7 @@ void LWOImporter::LoadLWO2File()
|
||||
|
||||
if (mCurLayer->mTempPoints.empty())
|
||||
DefaultLogger::get()->warn("LWO2: Unexpected VMAP chunk");
|
||||
else LoadLWO2VertexMap(head->length,head->type == AI_LWO_VMAD);
|
||||
else LoadLWO2VertexMap(head.length,head.type == AI_LWO_VMAD);
|
||||
break;
|
||||
}
|
||||
// face list
|
||||
@@ -1389,7 +1401,7 @@ void LWOImporter::LoadLWO2File()
|
||||
break;
|
||||
|
||||
unsigned int old = (unsigned int)mCurLayer->mFaces.size();
|
||||
LoadLWO2Polygons(head->length);
|
||||
LoadLWO2Polygons(head.length);
|
||||
mCurLayer->mFaceIDXOfs = old;
|
||||
break;
|
||||
}
|
||||
@@ -1401,7 +1413,7 @@ void LWOImporter::LoadLWO2File()
|
||||
|
||||
if (mCurLayer->mFaces.empty())
|
||||
DefaultLogger::get()->warn("LWO2: Unexpected PTAG");
|
||||
else LoadLWO2PolygonTags(head->length);
|
||||
else LoadLWO2PolygonTags(head.length);
|
||||
break;
|
||||
}
|
||||
// list of tags
|
||||
@@ -1409,28 +1421,28 @@ void LWOImporter::LoadLWO2File()
|
||||
{
|
||||
if (!mTags->empty())
|
||||
DefaultLogger::get()->warn("LWO2: SRFS chunk encountered twice");
|
||||
else LoadLWOTags(head->length);
|
||||
else LoadLWOTags(head.length);
|
||||
break;
|
||||
}
|
||||
|
||||
// surface chunk
|
||||
case AI_LWO_SURF:
|
||||
{
|
||||
LoadLWO2Surface(head->length);
|
||||
LoadLWO2Surface(head.length);
|
||||
break;
|
||||
}
|
||||
|
||||
// clip chunk
|
||||
case AI_LWO_CLIP:
|
||||
{
|
||||
LoadLWO2Clip(head->length);
|
||||
LoadLWO2Clip(head.length);
|
||||
break;
|
||||
}
|
||||
|
||||
// envelope chunk
|
||||
case AI_LWO_ENVL:
|
||||
{
|
||||
LoadLWO2Envelope(head->length);
|
||||
LoadLWO2Envelope(head.length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -402,7 +402,9 @@ protected:
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
inline float LWOImporter::GetF4()
|
||||
{
|
||||
float f = *((float*)mFileBuffer);mFileBuffer += 4;
|
||||
float f;
|
||||
::memcpy(&f, mFileBuffer, 4);
|
||||
mFileBuffer += 4;
|
||||
AI_LSWAP4(f);
|
||||
return f;
|
||||
}
|
||||
@@ -410,7 +412,9 @@ inline float LWOImporter::GetF4()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
inline uint32_t LWOImporter::GetU4()
|
||||
{
|
||||
uint32_t f = *((uint32_t*)mFileBuffer);mFileBuffer += 4;
|
||||
uint32_t f;
|
||||
::memcpy(&f, mFileBuffer, 4);
|
||||
mFileBuffer += 4;
|
||||
AI_LSWAP4(f);
|
||||
return f;
|
||||
}
|
||||
@@ -418,7 +422,9 @@ inline uint32_t LWOImporter::GetU4()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
inline uint16_t LWOImporter::GetU2()
|
||||
{
|
||||
uint16_t f = *((uint16_t*)mFileBuffer);mFileBuffer += 2;
|
||||
uint16_t f;
|
||||
::memcpy(&f, mFileBuffer, 2);
|
||||
mFileBuffer += 2;
|
||||
AI_LSWAP2(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
+37
-37
@@ -285,7 +285,7 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
|
||||
{
|
||||
float fGloss;
|
||||
if (mIsLWO2) {
|
||||
fGloss = pow( surf.mGlossiness*10.0f+2.0f, 2.0f);
|
||||
fGloss = std::pow( surf.mGlossiness*10.0f+2.0f, 2.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -527,13 +527,13 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
|
||||
while (true)
|
||||
{
|
||||
if (mFileBuffer + 6 >= end)break;
|
||||
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||
LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
|
||||
|
||||
if (mFileBuffer + head->length > end)
|
||||
if (mFileBuffer + head.length > end)
|
||||
throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
|
||||
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
switch (head->type)
|
||||
uint8_t* const next = mFileBuffer+head.length;
|
||||
switch (head.type)
|
||||
{
|
||||
case AI_LWO_PROJ:
|
||||
tex.mapMode = (Texture::MappingMode)GetU2();
|
||||
@@ -549,7 +549,7 @@ void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
|
||||
tex.mClipIdx = GetU2();
|
||||
break;
|
||||
case AI_LWO_VMAP:
|
||||
GetS0(tex.mUVChannelIndex,head->length);
|
||||
GetS0(tex.mUVChannelIndex,head.length);
|
||||
break;
|
||||
case AI_LWO_WRPH:
|
||||
tex.wrapAmountH = GetF4();
|
||||
@@ -595,13 +595,13 @@ void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
|
||||
while (true)
|
||||
{
|
||||
if (mFileBuffer + 6 >= end)break;
|
||||
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
|
||||
|
||||
if (mFileBuffer + head->length > end)
|
||||
if (mFileBuffer + head.length > end)
|
||||
throw DeadlyImportError("LWO2: Invalid texture header chunk length");
|
||||
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
switch (head->type)
|
||||
uint8_t* const next = mFileBuffer+head.length;
|
||||
switch (head.type)
|
||||
{
|
||||
case AI_LWO_CHAN:
|
||||
tex.type = GetU4();
|
||||
@@ -698,20 +698,20 @@ void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, u
|
||||
while (true)
|
||||
{
|
||||
if (mFileBuffer + 6 >= end)break;
|
||||
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
|
||||
|
||||
if (mFileBuffer + head->length > end)
|
||||
if (mFileBuffer + head.length > end)
|
||||
throw DeadlyImportError("LWO2: Invalid shader header chunk length");
|
||||
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
switch (head->type)
|
||||
uint8_t* const next = mFileBuffer+head.length;
|
||||
switch (head.type)
|
||||
{
|
||||
case AI_LWO_ENAB:
|
||||
shader.enabled = GetU2() ? true : false;
|
||||
break;
|
||||
|
||||
case AI_LWO_FUNC:
|
||||
GetS0( shader.functionName, head->length );
|
||||
GetS0( shader.functionName, head.length );
|
||||
}
|
||||
mFileBuffer = next;
|
||||
}
|
||||
@@ -756,18 +756,18 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
||||
{
|
||||
if (mFileBuffer + 6 >= end)
|
||||
break;
|
||||
LE_NCONST IFF::SubChunkHeader* const head = IFF::LoadSubChunk(mFileBuffer);
|
||||
const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
|
||||
|
||||
if (mFileBuffer + head->length > end)
|
||||
if (mFileBuffer + head.length > end)
|
||||
throw DeadlyImportError("LWO2: Invalid surface chunk length");
|
||||
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
switch (head->type)
|
||||
uint8_t* const next = mFileBuffer+head.length;
|
||||
switch (head.type)
|
||||
{
|
||||
// diffuse color
|
||||
case AI_LWO_COLR:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,COLR,12);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,COLR,12);
|
||||
surf.mColor.r = GetF4();
|
||||
surf.mColor.g = GetF4();
|
||||
surf.mColor.b = GetF4();
|
||||
@@ -776,14 +776,14 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
||||
// diffuse strength ... hopefully
|
||||
case AI_LWO_DIFF:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,DIFF,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,DIFF,4);
|
||||
surf.mDiffuseValue = GetF4();
|
||||
break;
|
||||
}
|
||||
// specular strength ... hopefully
|
||||
case AI_LWO_SPEC:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SPEC,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPEC,4);
|
||||
surf.mSpecularValue = GetF4();
|
||||
break;
|
||||
}
|
||||
@@ -794,21 +794,21 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
||||
if (surf.mTransparency == 10e10f)
|
||||
break;
|
||||
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,TRAN,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TRAN,4);
|
||||
surf.mTransparency = GetF4();
|
||||
break;
|
||||
}
|
||||
// additive transparency
|
||||
case AI_LWO_ADTR:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,ADTR,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,ADTR,4);
|
||||
surf.mAdditiveTransparency = GetF4();
|
||||
break;
|
||||
}
|
||||
// wireframe mode
|
||||
case AI_LWO_LINE:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,LINE,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LINE,2);
|
||||
if (GetU2() & 0x1)
|
||||
surf.mWireframe = true;
|
||||
break;
|
||||
@@ -816,49 +816,49 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
||||
// glossiness
|
||||
case AI_LWO_GLOS:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,GLOS,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,GLOS,4);
|
||||
surf.mGlossiness = GetF4();
|
||||
break;
|
||||
}
|
||||
// bump intensity
|
||||
case AI_LWO_BUMP:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,BUMP,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,BUMP,4);
|
||||
surf.mBumpIntensity = GetF4();
|
||||
break;
|
||||
}
|
||||
// color highlights
|
||||
case AI_LWO_CLRH:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,CLRH,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,CLRH,4);
|
||||
surf.mColorHighlights = GetF4();
|
||||
break;
|
||||
}
|
||||
// index of refraction
|
||||
case AI_LWO_RIND:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,RIND,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,RIND,4);
|
||||
surf.mIOR = GetF4();
|
||||
break;
|
||||
}
|
||||
// polygon sidedness
|
||||
case AI_LWO_SIDE:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SIDE,2);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SIDE,2);
|
||||
surf.bDoubleSided = (3 == GetU2());
|
||||
break;
|
||||
}
|
||||
// maximum smoothing angle
|
||||
case AI_LWO_SMAN:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,SMAN,4);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
|
||||
surf.mMaximumSmoothAngle = fabs( GetF4() );
|
||||
break;
|
||||
}
|
||||
// vertex color channel to be applied to the surface
|
||||
case AI_LWO_VCOL:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,VCOL,12);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,VCOL,12);
|
||||
surf.mDiffuseValue *= GetF4(); // strength
|
||||
ReadVSizedIntLWO2(mFileBuffer); // skip envelope
|
||||
surf.mVCMapType = GetU4(); // type of the channel
|
||||
@@ -870,18 +870,18 @@ void LWOImporter::LoadLWO2Surface(unsigned int size)
|
||||
// surface bock entry
|
||||
case AI_LWO_BLOK:
|
||||
{
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head->length,BLOK,4);
|
||||
LE_NCONST IFF::SubChunkHeader* head2 = IFF::LoadSubChunk(mFileBuffer);
|
||||
AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,BLOK,4);
|
||||
IFF::SubChunkHeader head2 = IFF::LoadSubChunk(mFileBuffer);
|
||||
|
||||
switch (head2->type)
|
||||
switch (head2.type)
|
||||
{
|
||||
case AI_LWO_PROC:
|
||||
case AI_LWO_GRAD:
|
||||
case AI_LWO_IMAP:
|
||||
LoadLWO2TextureBlock(head2, head->length);
|
||||
LoadLWO2TextureBlock(&head2, head.length);
|
||||
break;
|
||||
case AI_LWO_SHDR:
|
||||
LoadLWO2ShaderBlock(head2, head->length);
|
||||
LoadLWO2ShaderBlock(&head2, head.length);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+3
-3
@@ -263,9 +263,9 @@ inline void LatLngNormalToVec3(uint16_t p_iNormal, float* p_afOut)
|
||||
lat *= 3.141926f/128.0f;
|
||||
lng *= 3.141926f/128.0f;
|
||||
|
||||
p_afOut[0] = cosf(lat) * sinf(lng);
|
||||
p_afOut[1] = sinf(lat) * sinf(lng);
|
||||
p_afOut[2] = cosf(lng);
|
||||
p_afOut[0] = std::cos(lat) * std::sin(lng);
|
||||
p_afOut[1] = std::sin(lat) * std::sin(lng);
|
||||
p_afOut[2] = std::cos(lng);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -259,7 +259,7 @@ inline void ConvertQuaternion (const aiVector3D& in, aiQuaternion& out) {
|
||||
|
||||
if (t < 0.0f)
|
||||
out.w = 0.0f;
|
||||
else out.w = sqrt (t);
|
||||
else out.w = std::sqrt (t);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
+21
-28
@@ -62,7 +62,7 @@ static const aiImporterDesc desc = {
|
||||
|
||||
static const unsigned int ObjMinSize = 16;
|
||||
|
||||
namespace Assimp {
|
||||
namespace Assimp {
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -109,9 +109,7 @@ const aiImporterDesc* ObjFileImporter::GetInfo () const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Obj-file import implementation
|
||||
void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
||||
{
|
||||
DefaultIOSystem io;
|
||||
|
||||
{
|
||||
// Read file into memory
|
||||
const std::string mode = "rb";
|
||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode));
|
||||
@@ -232,16 +230,10 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
||||
for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ )
|
||||
{
|
||||
unsigned int meshId = pObject->m_Meshes[ i ];
|
||||
aiMesh *pMesh = new aiMesh;
|
||||
createTopology( pModel, pObject, meshId, pMesh );
|
||||
if ( pMesh->mNumVertices > 0 )
|
||||
{
|
||||
aiMesh *pMesh = createTopology( pModel, pObject, meshId );
|
||||
if( pMesh && pMesh->mNumFaces > 0 ) {
|
||||
MeshArray.push_back( pMesh );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pMesh;
|
||||
}
|
||||
}
|
||||
|
||||
// Create all nodes from the sub-objects stored in the current object
|
||||
@@ -274,45 +266,44 @@ aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Create topology data
|
||||
void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
|
||||
const ObjFile::Object* pData,
|
||||
unsigned int uiMeshIndex,
|
||||
aiMesh* pMesh )
|
||||
aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||
unsigned int uiMeshIndex )
|
||||
{
|
||||
// Checking preconditions
|
||||
ai_assert( NULL != pModel );
|
||||
if( NULL == pData ) {
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create faces
|
||||
ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
|
||||
ai_assert( NULL != pObjMesh );
|
||||
|
||||
pMesh->mNumFaces = 0;
|
||||
if( !pObjMesh ) {
|
||||
return NULL;
|
||||
}
|
||||
ai_assert( NULL != pObjMesh );
|
||||
aiMesh* pMesh = new aiMesh;
|
||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
|
||||
{
|
||||
ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
|
||||
|
||||
ObjFile::Face *const inp = pObjMesh->m_Faces[ index ];
|
||||
ai_assert( NULL != inp );
|
||||
|
||||
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||
pMesh->mNumFaces += inp->m_pVertices->size() - 1;
|
||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||
}
|
||||
else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
||||
} else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
|
||||
pMesh->mNumFaces += inp->m_pVertices->size();
|
||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
|
||||
} else {
|
||||
++pMesh->mNumFaces;
|
||||
if (inp->m_pVertices->size() > 3) {
|
||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int uiIdxCount = 0u;
|
||||
unsigned int uiIdxCount( 0u );
|
||||
if ( pMesh->mNumFaces > 0 )
|
||||
{
|
||||
pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
|
||||
@@ -321,7 +312,7 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
|
||||
pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
|
||||
}
|
||||
|
||||
unsigned int outIndex = 0;
|
||||
unsigned int outIndex( 0 );
|
||||
|
||||
// Copy all data from all stored meshes
|
||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
|
||||
@@ -355,6 +346,8 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
|
||||
|
||||
// Create mesh vertices
|
||||
createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount);
|
||||
|
||||
return pMesh;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -91,8 +91,8 @@ private:
|
||||
aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
|
||||
|
||||
//! \brief Creates topology data like faces and meshes for the geometry.
|
||||
void createTopology(const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||
unsigned int uiMeshIndex, aiMesh* pMesh);
|
||||
aiMesh *createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
|
||||
unsigned int uiMeshIndex );
|
||||
|
||||
//! \brief Creates vertices from model.
|
||||
void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
|
||||
|
||||
@@ -46,13 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "ObjTools.h"
|
||||
#include "ObjFileData.h"
|
||||
#include "fast_atof.h"
|
||||
#include "ParsingUtils.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// Material specific token
|
||||
static const std::string DiffuseTexture = "map_kd";
|
||||
static const std::string AmbientTexture = "map_ka";
|
||||
static const std::string SpecularTexture = "map_ks";
|
||||
static const std::string DiffuseTexture = "map_Kd";
|
||||
static const std::string AmbientTexture = "map_Ka";
|
||||
static const std::string SpecularTexture = "map_Ks";
|
||||
static const std::string OpacityTexture = "map_d";
|
||||
static const std::string EmmissiveTexture = "map_emissive";
|
||||
static const std::string BumpTexture1 = "map_bump";
|
||||
@@ -228,7 +229,7 @@ void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
|
||||
pColor->r = r;
|
||||
|
||||
// we have to check if color is default 0 with only one token
|
||||
if( !isNewLine( *m_DataIt ) ) {
|
||||
if( !IsLineEnd( *m_DataIt ) ) {
|
||||
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, g );
|
||||
m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
|
||||
}
|
||||
@@ -257,7 +258,7 @@ void ObjFileMtlImporter::getFloatValue( float &value )
|
||||
void ObjFileMtlImporter::createMaterial()
|
||||
{
|
||||
std::string line( "" );
|
||||
while ( !isNewLine( *m_DataIt ) ) {
|
||||
while( !IsLineEnd( *m_DataIt ) ) {
|
||||
line += *m_DataIt;
|
||||
++m_DataIt;
|
||||
}
|
||||
|
||||
+16
-13
@@ -186,12 +186,12 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
|
||||
{
|
||||
size_t index = 0;
|
||||
m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
|
||||
{
|
||||
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
|
||||
pBuffer[index] = *m_DataIt;
|
||||
index++;
|
||||
if (index == length-1)
|
||||
break;
|
||||
if( index == length - 1 ) {
|
||||
break;
|
||||
}
|
||||
++m_DataIt;
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||
}
|
||||
iPos++;
|
||||
}
|
||||
else if ( isSeparator(*pPtr) )
|
||||
else if( IsSpaceOrNewLine( *pPtr ) )
|
||||
{
|
||||
iPos = 0;
|
||||
}
|
||||
@@ -463,8 +463,9 @@ void ObjFileParser::getMaterialDesc()
|
||||
return;
|
||||
|
||||
char *pStart = &(*m_DataIt);
|
||||
while ( m_DataIt != m_DataItEnd && !isSeparator(*m_DataIt) )
|
||||
++m_DataIt;
|
||||
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
|
||||
++m_DataIt;
|
||||
}
|
||||
|
||||
// Get name
|
||||
std::string strName(pStart, &(*m_DataIt));
|
||||
@@ -518,12 +519,14 @@ void ObjFileParser::getMaterialLib()
|
||||
{
|
||||
// Translate tuple
|
||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
if (m_DataIt == m_DataItEnd)
|
||||
return;
|
||||
if( m_DataIt == m_DataItEnd ) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *pStart = &(*m_DataIt);
|
||||
while (m_DataIt != m_DataItEnd && !isNewLine(*m_DataIt))
|
||||
m_DataIt++;
|
||||
while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) {
|
||||
++m_DataIt;
|
||||
}
|
||||
|
||||
// Check for existence
|
||||
const std::string strMatName(pStart, &(*m_DataIt));
|
||||
@@ -557,7 +560,7 @@ void ObjFileParser::getNewMaterial()
|
||||
|
||||
char *pStart = &(*m_DataIt);
|
||||
std::string strMat( pStart, *m_DataIt );
|
||||
while( m_DataIt != m_DataItEnd && isSeparator( *m_DataIt ) ) {
|
||||
while( m_DataIt != m_DataItEnd && IsSpaceOrNewLine( *m_DataIt ) ) {
|
||||
++m_DataIt;
|
||||
}
|
||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
|
||||
@@ -662,7 +665,7 @@ void ObjFileParser::getObjectName()
|
||||
return;
|
||||
}
|
||||
char *pStart = &(*m_DataIt);
|
||||
while( m_DataIt != m_DataItEnd && !isSeparator( *m_DataIt ) ) {
|
||||
while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
|
||||
++m_DataIt;
|
||||
}
|
||||
|
||||
|
||||
+14
-34
@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#define OBJ_TOOLS_H_INC
|
||||
|
||||
#include "fast_atof.h"
|
||||
#include "ParsingUtils.h"
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
@@ -68,28 +69,6 @@ inline bool isEndOfBuffer( char_t it, char_t end )
|
||||
return ( it == end );
|
||||
}
|
||||
|
||||
/** @brief Returns true, if token is a space on any supported platform
|
||||
* @param token Token to search in
|
||||
* @return true, if token is a space
|
||||
*/
|
||||
inline bool isSeparator( char token )
|
||||
{
|
||||
return ( token == ' ' ||
|
||||
token == '\n' ||
|
||||
token == '\f' ||
|
||||
token == '\r' ||
|
||||
token == '\t' );
|
||||
}
|
||||
|
||||
/** @brief Returns true, fi token id a new line marking token.
|
||||
* @param token Token to search in
|
||||
* @return true, if token is a newline token.
|
||||
*/
|
||||
inline bool isNewLine( char token )
|
||||
{
|
||||
return ( token == '\n' || token == '\f' || token == '\r' );
|
||||
}
|
||||
|
||||
/** @brief Returns next word separated by a space
|
||||
* @param pBuffer Pointer to data buffer
|
||||
* @param pEnd Pointer to end of buffer
|
||||
@@ -100,7 +79,7 @@ inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
|
||||
{
|
||||
while ( !isEndOfBuffer( pBuffer, pEnd ) )
|
||||
{
|
||||
if ( !isSeparator( *pBuffer ) || isNewLine( *pBuffer ) )
|
||||
if( !IsSpaceOrNewLine( *pBuffer ) || IsLineEnd( *pBuffer ) )
|
||||
break;
|
||||
pBuffer++;
|
||||
}
|
||||
@@ -117,7 +96,7 @@ inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
|
||||
{
|
||||
while ( !isEndOfBuffer( pBuffer, pEnd ) )
|
||||
{
|
||||
if ( isSeparator( *pBuffer ) )
|
||||
if( IsSpaceOrNewLine( *pBuffer ) )
|
||||
break;
|
||||
pBuffer++;
|
||||
}
|
||||
@@ -127,14 +106,14 @@ inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
|
||||
/** @brief Skips a line
|
||||
* @param it Iterator set to current position
|
||||
* @param end Iterator set to end of scratch buffer for readout
|
||||
* @param uiLine Current linenumber in format
|
||||
* @param uiLine Current line number in format
|
||||
* @return Current-iterator with new position
|
||||
*/
|
||||
template<class char_t>
|
||||
inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine )
|
||||
{
|
||||
while ( !isEndOfBuffer( it, end ) && !isNewLine( *it ) )
|
||||
++it;
|
||||
inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
|
||||
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
|
||||
++it;
|
||||
}
|
||||
if ( it != end )
|
||||
{
|
||||
++it;
|
||||
@@ -157,15 +136,16 @@ template<class char_t>
|
||||
inline char_t getName( char_t it, char_t end, std::string &name )
|
||||
{
|
||||
name = "";
|
||||
if ( isEndOfBuffer( it, end ) )
|
||||
return end;
|
||||
if( isEndOfBuffer( it, end ) ) {
|
||||
return end;
|
||||
}
|
||||
|
||||
char *pStart = &( *it );
|
||||
while ( !isEndOfBuffer( it, end ) && !isNewLine( *it ) ) {
|
||||
while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
|
||||
++it;
|
||||
}
|
||||
|
||||
while(isEndOfBuffer( it, end ) || isNewLine( *it ) || isSeparator(*it)) {
|
||||
while( isEndOfBuffer( it, end ) || IsLineEnd( *it ) || IsSpaceOrNewLine( *it ) ) {
|
||||
--it;
|
||||
}
|
||||
++it;
|
||||
@@ -196,7 +176,7 @@ inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length
|
||||
{
|
||||
size_t index = 0;
|
||||
it = getNextWord<char_t>( it, end );
|
||||
while ( !isSeparator( *it ) && !isEndOfBuffer( it, end ) )
|
||||
while( !IsSpaceOrNewLine( *it ) && !isEndOfBuffer( it, end ) )
|
||||
{
|
||||
pBuffer[index] = *it ;
|
||||
index++;
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ AI_FORCE_INLINE bool IsSpace( char_t in)
|
||||
template <class char_t>
|
||||
AI_FORCE_INLINE bool IsLineEnd( char_t in)
|
||||
{
|
||||
return (in == (char_t)'\r' || in == (char_t)'\n' || in == (char_t)'\0');
|
||||
return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f');
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------
|
||||
|
||||
+6
-6
@@ -118,9 +118,9 @@ inline bool IsCCW(T* in, size_t npoints) {
|
||||
((-in[i+2].y + in[i+1].y) *
|
||||
(-in[i+2].y + in[i+1].y));
|
||||
|
||||
b = sqrt(bb);
|
||||
c = sqrt(cc);
|
||||
theta = acos((bb + cc - aa) / (2 * b * c));
|
||||
b = std::sqrt(bb);
|
||||
c = std::sqrt(cc);
|
||||
theta = std::acos((bb + cc - aa) / (2 * b * c));
|
||||
|
||||
if (OnLeftSideOfLine2D(in[i],in[i+2],in[i+1])) {
|
||||
// if (convex(in[i].x, in[i].y,
|
||||
@@ -146,9 +146,9 @@ inline bool IsCCW(T* in, size_t npoints) {
|
||||
cc = ((in[1].x - in[0].x) * (in[1].x - in[0].x)) +
|
||||
((-in[1].y + in[0].y) * (-in[1].y + in[0].y));
|
||||
|
||||
b = sqrt(bb);
|
||||
c = sqrt(cc);
|
||||
theta = acos((bb + cc - aa) / (2 * b * c));
|
||||
b = std::sqrt(bb);
|
||||
c = std::sqrt(cc);
|
||||
theta = std::acos((bb + cc - aa) / (2 * b * c));
|
||||
|
||||
//if (convex(in[npoints-2].x, in[npoints-2].y,
|
||||
// in[0].x, in[0].y,
|
||||
|
||||
@@ -641,17 +641,17 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode
|
||||
bool res = true;
|
||||
sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ];
|
||||
if ( !pTexture ) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> supportedExtensions;
|
||||
supportedExtensions.push_back( ".jpg" );
|
||||
supportedExtensions.push_back( ".png" );
|
||||
supportedExtensions.push_back( ".tga" );
|
||||
std::vector<std::string> supportedExtensions;
|
||||
supportedExtensions.push_back( ".jpg" );
|
||||
supportedExtensions.push_back( ".png" );
|
||||
supportedExtensions.push_back( ".tga" );
|
||||
std::string textureName, ext;
|
||||
if ( expandFile( pArchive, pTexture->strName, supportedExtensions, textureName, ext ) ) {
|
||||
IOStream *pTextureStream = pArchive->Open( textureName.c_str() );
|
||||
if ( !pTextureStream ) {
|
||||
if ( pTextureStream ) {
|
||||
size_t texSize = pTextureStream->FileSize();
|
||||
aiTexture *pTexture = new aiTexture;
|
||||
pTexture->mHeight = 0;
|
||||
|
||||
@@ -91,11 +91,10 @@ void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
|
||||
{
|
||||
// If aiMesh::mNumUVComponents is *not* set assign the default value of 2
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||
if (!mesh->mTextureCoords[i])
|
||||
if (!mesh->mTextureCoords[i]) {
|
||||
mesh->mNumUVComponents[i] = 0;
|
||||
|
||||
else {
|
||||
if( !mesh->mNumUVComponents[i])
|
||||
} else {
|
||||
if (!mesh->mNumUVComponents[i])
|
||||
mesh->mNumUVComponents[i] = 2;
|
||||
|
||||
aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices;
|
||||
@@ -112,7 +111,6 @@ void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
|
||||
p->z = p->y = 0.f;
|
||||
}
|
||||
else if (3 == mesh->mNumUVComponents[i]) {
|
||||
|
||||
// Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
|
||||
for (; p != end; ++p) {
|
||||
if (p->z != 0)
|
||||
|
||||
@@ -101,7 +101,7 @@ void SkeletonMeshBuilder::CreateGeometry( const aiNode* pNode)
|
||||
aiVector3D up = aiVector3D( childpos).Normalize();
|
||||
|
||||
aiVector3D orth( 1.0f, 0.0f, 0.0f);
|
||||
if( fabs( orth * up) > 0.99f)
|
||||
if( std::fabs( orth * up) > 0.99f)
|
||||
orth.Set( 0.0f, 1.0f, 0.0f);
|
||||
|
||||
aiVector3D front = (up ^ orth).Normalize();
|
||||
|
||||
+14
-14
@@ -192,7 +192,7 @@ unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
|
||||
positions.reserve(positions.size()+60);
|
||||
|
||||
const float t = (1.f + 2.236067977f)/2.f;
|
||||
const float s = sqrt(1.f + t*t);
|
||||
const float s = std::sqrt(1.f + t*t);
|
||||
|
||||
const aiVector3D v0 = aiVector3D(t,1.f, 0.f)/s;
|
||||
const aiVector3D v1 = aiVector3D(-t,1.f, 0.f)/s;
|
||||
@@ -242,8 +242,8 @@ unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions
|
||||
positions.reserve(positions.size()+108);
|
||||
|
||||
const float a = 1.f / 1.7320508f;
|
||||
const float b = sqrt((3.f-2.23606797f)/6.f);
|
||||
const float c = sqrt((3.f+2.23606797f)/6.f);
|
||||
const float b = std::sqrt((3.f-2.23606797f)/6.f);
|
||||
const float c = std::sqrt((3.f+2.23606797f)/6.f);
|
||||
|
||||
const aiVector3D v0 = aiVector3D(a,a,a);
|
||||
const aiVector3D v1 = aiVector3D(a,a,-a);
|
||||
@@ -390,8 +390,8 @@ void StandardShapes::MakeCone(float height,float radius1,
|
||||
size_t old = positions.size();
|
||||
|
||||
// No negative radii
|
||||
radius1 = ::fabs(radius1);
|
||||
radius2 = ::fabs(radius2);
|
||||
radius1 = std::fabs(radius1);
|
||||
radius2 = std::fabs(radius2);
|
||||
|
||||
float halfHeight = height / 2;
|
||||
|
||||
@@ -415,8 +415,8 @@ void StandardShapes::MakeCone(float height,float radius1,
|
||||
const float angle_delta = (float)AI_MATH_TWO_PI / tess;
|
||||
const float angle_max = (float)AI_MATH_TWO_PI;
|
||||
|
||||
float s = 1.f; // cos(angle == 0);
|
||||
float t = 0.f; // sin(angle == 0);
|
||||
float s = 1.f; // std::cos(angle == 0);
|
||||
float t = 0.f; // std::sin(angle == 0);
|
||||
|
||||
for (float angle = 0.f; angle < angle_max; )
|
||||
{
|
||||
@@ -424,8 +424,8 @@ void StandardShapes::MakeCone(float height,float radius1,
|
||||
const aiVector3D v2 = aiVector3D (s * radius2, halfHeight, t * radius2 );
|
||||
|
||||
const float next = angle + angle_delta;
|
||||
float s2 = ::cos(next);
|
||||
float t2 = ::sin(next);
|
||||
float s2 = std::cos(next);
|
||||
float t2 = std::sin(next);
|
||||
|
||||
const aiVector3D v3 = aiVector3D (s2 * radius2, halfHeight, t2 * radius2 );
|
||||
const aiVector3D v4 = aiVector3D (s2 * radius1, -halfHeight, t2 * radius1 );
|
||||
@@ -476,7 +476,7 @@ void StandardShapes::MakeCircle(float radius, unsigned int tess,
|
||||
if (tess < 3 || !radius)
|
||||
return;
|
||||
|
||||
radius = ::fabs(radius);
|
||||
radius = std::fabs(radius);
|
||||
|
||||
// We will need 3 vertices per segment
|
||||
positions.reserve(positions.size()+tess*3);
|
||||
@@ -484,15 +484,15 @@ void StandardShapes::MakeCircle(float radius, unsigned int tess,
|
||||
const float angle_delta = (float)AI_MATH_TWO_PI / tess;
|
||||
const float angle_max = (float)AI_MATH_TWO_PI;
|
||||
|
||||
float s = 1.f; // cos(angle == 0);
|
||||
float t = 0.f; // sin(angle == 0);
|
||||
float s = 1.f; // std::cos(angle == 0);
|
||||
float t = 0.f; // std::sin(angle == 0);
|
||||
|
||||
for (float angle = 0.f; angle < angle_max; )
|
||||
{
|
||||
positions.push_back(aiVector3D(s * radius,0.f,t * radius));
|
||||
angle += angle_delta;
|
||||
s = ::cos(angle);
|
||||
t = ::sin(angle);
|
||||
s = std::cos(angle);
|
||||
t = std::sin(angle);
|
||||
positions.push_back(aiVector3D(s * radius,0.f,t * radius));
|
||||
|
||||
positions.push_back(aiVector3D(0.f,0.f,0.f));
|
||||
|
||||
@@ -116,19 +116,19 @@ struct STransformVecInfo : public aiUVTransform
|
||||
// We use a small epsilon here
|
||||
const static float epsilon = 0.05f;
|
||||
|
||||
if (fabs( mTranslation.x - other.mTranslation.x ) > epsilon ||
|
||||
fabs( mTranslation.y - other.mTranslation.y ) > epsilon)
|
||||
if (std::fabs( mTranslation.x - other.mTranslation.x ) > epsilon ||
|
||||
std::fabs( mTranslation.y - other.mTranslation.y ) > epsilon)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fabs( mScaling.x - other.mScaling.x ) > epsilon ||
|
||||
fabs( mScaling.y - other.mScaling.y ) > epsilon)
|
||||
if (std::fabs( mScaling.x - other.mScaling.x ) > epsilon ||
|
||||
std::fabs( mScaling.y - other.mScaling.y ) > epsilon)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fabs( mRotation - other.mRotation) > epsilon)
|
||||
if (std::fabs( mRotation - other.mRotation) > epsilon)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -168,8 +168,8 @@ struct STransformVecInfo : public aiUVTransform
|
||||
if (mRotation)
|
||||
{
|
||||
aiMatrix3x3 mRot;
|
||||
mRot.a1 = mRot.b2 = cos(mRotation);
|
||||
mRot.a2 = mRot.b1 = sin(mRotation);
|
||||
mRot.a1 = mRot.b2 = std::cos(mRotation);
|
||||
mRot.a2 = mRot.b1 = std::sin(mRotation);
|
||||
mRot.a2 = -mRot.a2;
|
||||
mOut *= mRot;
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
diag.Normalize();
|
||||
right.Normalize();
|
||||
|
||||
const float angle = acos(left*diag) + acos(right*diag);
|
||||
const float angle = std::acos(left*diag) + std::acos(right*diag);
|
||||
if (angle > AI_MATH_PI_F) {
|
||||
// this is the concave point
|
||||
start_vertex = i;
|
||||
@@ -486,7 +486,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
|
||||
unsigned int* i = f->mIndices;
|
||||
|
||||
// drop dumb 0-area triangles
|
||||
if (fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) {
|
||||
if (std::fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) {
|
||||
DefaultLogger::get()->debug("Dropping triangle with area 0");
|
||||
--curOut;
|
||||
|
||||
|
||||
+4
-1
@@ -248,6 +248,9 @@ inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma
|
||||
if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inf", 3) == 0)
|
||||
{
|
||||
out = std::numeric_limits<Real>::infinity();
|
||||
if (inv) {
|
||||
out = -out;
|
||||
}
|
||||
c += 3;
|
||||
if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inity", 5) == 0)
|
||||
{
|
||||
@@ -309,7 +312,7 @@ inline const char* fast_atoreal_move( const char* c, Real& out, bool check_comma
|
||||
if (einv) {
|
||||
exp = -exp;
|
||||
}
|
||||
f *= pow(static_cast<Real>(10.0), exp);
|
||||
f *= std::pow(static_cast<Real>(10.0), exp);
|
||||
}
|
||||
|
||||
if (inv) {
|
||||
|
||||
Reference in New Issue
Block a user