Merge commit '87a0e7703258576f1a7e4ba763b961da70c1cd91' into contrib
Conflicts: code/ColladaExporter.cpp
This commit is contained in:
@@ -73,6 +73,7 @@ ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
|
||||
}
|
||||
|
||||
SceneCombiner::CopyScene(pOut,pIn,true);
|
||||
ScenePriv(*pOut)->mIsCopy = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -278,19 +278,23 @@ public:
|
||||
// --------------------------------------------------------
|
||||
// field parsing for pointer or dynamic array types
|
||||
// (boost::shared_ptr or boost::shared_array)
|
||||
// The return value indicates whether the data was already cached.
|
||||
template <int error_policy, template <typename> class TOUT, typename T>
|
||||
void ReadFieldPtr(TOUT<T>& out, const char* name,
|
||||
const FileDatabase& db) const;
|
||||
bool ReadFieldPtr(TOUT<T>& out, const char* name,
|
||||
const FileDatabase& db,
|
||||
bool non_recursive = false) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// field parsing for static arrays of pointer or dynamic
|
||||
// array types (boost::shared_ptr[] or boost::shared_array[])
|
||||
// The return value indicates whether the data was already cached.
|
||||
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
||||
void ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||
bool ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||
const FileDatabase& db) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// field parsing for `normal` values
|
||||
// The return value indicates whether the data was already cached.
|
||||
template <int error_policy, typename T>
|
||||
void ReadField(T& out, const char* name,
|
||||
const FileDatabase& db) const;
|
||||
@@ -299,17 +303,18 @@ private:
|
||||
|
||||
// --------------------------------------------------------
|
||||
template <template <typename> class TOUT, typename T>
|
||||
void ResolvePointer(TOUT<T>& out, const Pointer & ptrval,
|
||||
const FileDatabase& db, const Field& f) const;
|
||||
bool ResolvePointer(TOUT<T>& out, const Pointer & ptrval,
|
||||
const FileDatabase& db, const Field& f,
|
||||
bool non_recursive = false) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
template <template <typename> class TOUT, typename T>
|
||||
void ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||
const FileDatabase& db, const Field& f) const;
|
||||
bool ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||
const FileDatabase& db, const Field& f, bool) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
void ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
||||
const FileDatabase& db, const Field& f) const;
|
||||
bool ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
||||
const FileDatabase& db, const Field& f, bool) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
inline const FileBlockHead* LocateFileBlockForAddress(
|
||||
@@ -384,10 +389,11 @@ template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> {
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------
|
||||
template <> inline void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
||||
template <> inline bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
||||
const Pointer & ptrval,
|
||||
const FileDatabase& db,
|
||||
const Field& f
|
||||
const Field& f,
|
||||
bool
|
||||
) const;
|
||||
|
||||
|
||||
|
||||
@@ -180,7 +180,8 @@ void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileD
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
template <int error_policy, template <typename> class TOUT, typename T>
|
||||
void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db) const
|
||||
bool Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabase& db,
|
||||
bool non_recursive /*= false*/) const
|
||||
{
|
||||
const StreamReaderAny::pos old = db.reader->GetCurrentPos();
|
||||
Pointer ptrval;
|
||||
@@ -203,23 +204,27 @@ void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabas
|
||||
_defaultInitializer<error_policy>()(out,e.what());
|
||||
|
||||
out.reset();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// resolve the pointer and load the corresponding structure
|
||||
ResolvePointer(out,ptrval,db,*f);
|
||||
const bool res = ResolvePointer(out,ptrval,db,*f, non_recursive);
|
||||
|
||||
// and recover the previous stream position
|
||||
db.reader->SetCurrentPos(old);
|
||||
if(!non_recursive) {
|
||||
// and recover the previous stream position
|
||||
db.reader->SetCurrentPos(old);
|
||||
}
|
||||
|
||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
++db.stats().fields_read;
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
||||
void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||
bool Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||
const FileDatabase& db) const
|
||||
{
|
||||
// XXX see if we can reduce this to call to the 'normal' ReadFieldPtr
|
||||
@@ -253,11 +258,13 @@ void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||
for(size_t i = 0; i < N; ++i) {
|
||||
out[i].reset();
|
||||
}
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool res = true;
|
||||
for(size_t i = 0; i < N; ++i) {
|
||||
// resolve the pointer and load the corresponding structure
|
||||
ResolvePointer(out[i],ptrval[i],db,*f);
|
||||
res = ResolvePointer(out[i],ptrval[i],db,*f) && res;
|
||||
}
|
||||
|
||||
// and recover the previous stream position
|
||||
@@ -266,6 +273,7 @@ void Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
++db.stats().fields_read;
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
@@ -296,11 +304,13 @@ void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) co
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
template <template <typename> class TOUT, typename T>
|
||||
void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
|
||||
bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db,
|
||||
const Field& f,
|
||||
bool non_recursive /*= false*/) const
|
||||
{
|
||||
out.reset();
|
||||
out.reset(); // ensure null pointers work
|
||||
if (!ptrval.val) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
const Structure& s = db.dna[f.type];
|
||||
// find the file block the pointer is pointing to
|
||||
@@ -318,7 +328,7 @@ void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil
|
||||
// try to retrieve the object from the cache
|
||||
db.cache(out).get(s,out,ptrval);
|
||||
if (out) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// seek to this location, but save the previous stream pointer.
|
||||
@@ -334,27 +344,36 @@ void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil
|
||||
// cache the object before we convert it to avoid cyclic recursion.
|
||||
db.cache(out).set(s,out,ptrval);
|
||||
|
||||
for (size_t i = 0; i < num; ++i,++o) {
|
||||
s.Convert(*o,db);
|
||||
}
|
||||
// if the non_recursive flag is set, we don't do anything but leave
|
||||
// the cursor at the correct position to resolve the object.
|
||||
if (!non_recursive) {
|
||||
for (size_t i = 0; i < num; ++i,++o) {
|
||||
s.Convert(*o,db);
|
||||
}
|
||||
|
||||
db.reader->SetCurrentPos(pold);
|
||||
db.reader->SetCurrentPos(pold);
|
||||
}
|
||||
|
||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
if(out) {
|
||||
++db.stats().pointers_resolved;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, const FileDatabase& db, const Field& /*f*/) const
|
||||
inline bool Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
||||
const FileDatabase& db,
|
||||
const Field&,
|
||||
bool) const
|
||||
{
|
||||
// Currently used exclusively by PackedFile::data to represent
|
||||
// a simple offset into the mapped BLEND file.
|
||||
out.reset();
|
||||
if (!ptrval.val) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// find the file block the pointer is pointing to
|
||||
@@ -362,11 +381,15 @@ inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, c
|
||||
|
||||
out = boost::shared_ptr< FileOffset > (new FileOffset());
|
||||
out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
template <template <typename> class TOUT, typename T>
|
||||
void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
|
||||
bool Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||
const FileDatabase& db,
|
||||
const Field& f,
|
||||
bool) const
|
||||
{
|
||||
// This is a function overload, not a template specialization. According to
|
||||
// the partial ordering rules, it should be selected by the compiler
|
||||
@@ -374,7 +397,7 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||
|
||||
out.reset();
|
||||
if (!ptrval.val) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// find the file block the pointer is pointing to
|
||||
@@ -385,6 +408,7 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||
const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
|
||||
db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
|
||||
|
||||
bool res = false;
|
||||
// allocate raw storage for the array
|
||||
out.resize(num);
|
||||
for (size_t i = 0; i< num; ++i) {
|
||||
@@ -392,17 +416,19 @@ void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||
Convert(val,db);
|
||||
|
||||
// and resolve the pointees
|
||||
ResolvePointer(out[i],val,db,f);
|
||||
res = ResolvePointer(out[i],val,db,f) && res;
|
||||
}
|
||||
|
||||
db.reader->SetCurrentPos(pold);
|
||||
return res;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
||||
template <> bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
||||
const Pointer & ptrval,
|
||||
const FileDatabase& db,
|
||||
const Field& /*f*/
|
||||
const Field&,
|
||||
bool
|
||||
) const
|
||||
{
|
||||
// Special case when the data type needs to be determined at runtime.
|
||||
@@ -410,7 +436,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||
|
||||
out.reset();
|
||||
if (!ptrval.val) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// find the file block the pointer is pointing to
|
||||
@@ -422,7 +448,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||
// try to retrieve the object from the cache
|
||||
db.cache(out).get(s,out,ptrval);
|
||||
if (out) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// seek to this location, but save the previous stream pointer.
|
||||
@@ -440,7 +466,7 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||
DefaultLogger::get()->warn((Formatter::format(),
|
||||
"Failed to find a converter for the `",s.name,"` structure"
|
||||
));
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// allocate the object hull
|
||||
@@ -459,11 +485,11 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||
// to perform additional type checking.
|
||||
out->dna_type = s.name.c_str();
|
||||
|
||||
|
||||
|
||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
++db.stats().pointers_resolved;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
@@ -446,9 +446,43 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
|
||||
else {
|
||||
name = aiString( img->name );
|
||||
}
|
||||
out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
|
||||
conv_data.next_texture[aiTextureType_DIFFUSE]++)
|
||||
);
|
||||
|
||||
aiTextureType texture_type = aiTextureType_UNKNOWN;
|
||||
MTex::MapType map_type = tex->mapto;
|
||||
|
||||
if (map_type & MTex::MapType_COL)
|
||||
texture_type = aiTextureType_DIFFUSE;
|
||||
else if (map_type & MTex::MapType_NORM) {
|
||||
if (tex->tex->imaflag & Tex::ImageFlags_NORMALMAP) {
|
||||
texture_type = aiTextureType_NORMALS;
|
||||
}
|
||||
else {
|
||||
texture_type = aiTextureType_HEIGHT;
|
||||
}
|
||||
out->AddProperty(&tex->norfac,1,AI_MATKEY_BUMPSCALING);
|
||||
}
|
||||
else if (map_type & MTex::MapType_COLSPEC)
|
||||
texture_type = aiTextureType_SPECULAR;
|
||||
else if (map_type & MTex::MapType_COLMIR)
|
||||
texture_type = aiTextureType_REFLECTION;
|
||||
//else if (map_type & MTex::MapType_REF)
|
||||
else if (map_type & MTex::MapType_SPEC)
|
||||
texture_type = aiTextureType_SHININESS;
|
||||
else if (map_type & MTex::MapType_EMIT)
|
||||
texture_type = aiTextureType_EMISSIVE;
|
||||
//else if (map_type & MTex::MapType_ALPHA)
|
||||
//else if (map_type & MTex::MapType_HAR)
|
||||
//else if (map_type & MTex::MapType_RAYMIRR)
|
||||
//else if (map_type & MTex::MapType_TRANSLU)
|
||||
else if (map_type & MTex::MapType_AMB)
|
||||
texture_type = aiTextureType_AMBIENT;
|
||||
else if (map_type & MTex::MapType_DISPLACE)
|
||||
texture_type = aiTextureType_DISPLACEMENT;
|
||||
//else if (map_type & MTex::MapType_WARP)
|
||||
|
||||
out->AddProperty(&name,AI_MATKEY_TEXTURE(texture_type,
|
||||
conv_data.next_texture[texture_type]++));
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -958,19 +992,41 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* /*obj*/, const Camera* /*mesh*/, ConversionData& /*conv_data*/)
|
||||
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* camera, ConversionData& /*conv_data*/)
|
||||
{
|
||||
ScopeGuard<aiCamera> out(new aiCamera());
|
||||
|
||||
return NULL ; //out.dismiss();
|
||||
out->mName = obj->id.name+2;
|
||||
out->mPosition = aiVector3D(0.f, 0.f, 0.f);
|
||||
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
||||
out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
|
||||
return out.dismiss();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* /*obj*/, const Lamp* /*mesh*/, ConversionData& /*conv_data*/)
|
||||
aiLight* BlenderImporter::ConvertLight(const Scene& in, const Object* obj, const Lamp* lamp, ConversionData& conv_data)
|
||||
{
|
||||
ScopeGuard<aiLight> out(new aiLight());
|
||||
out->mName = obj->id.name+2;
|
||||
|
||||
return NULL ; //out.dismiss();
|
||||
switch (lamp->type)
|
||||
{
|
||||
case Lamp::Type_Local:
|
||||
out->mType = aiLightSource_POINT;
|
||||
break;
|
||||
case Lamp::Type_Sun:
|
||||
out->mType = aiLightSource_DIRECTIONAL;
|
||||
|
||||
// blender orients directional lights as facing toward -z
|
||||
out->mDirection = aiVector3D(0.f, 0.f, -1.f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
out->mColorAmbient = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||
out->mColorSpecular = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||
out->mColorDiffuse = aiColor3D(lamp->r, lamp->g, lamp->b) * lamp->energy;
|
||||
return out.dismiss();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -598,6 +598,18 @@ struct Tex : ElemBase {
|
||||
,Type_VOXELDATA = 15
|
||||
};
|
||||
|
||||
enum ImageFlags {
|
||||
ImageFlags_INTERPOL = 1
|
||||
,ImageFlags_USEALPHA = 2
|
||||
,ImageFlags_MIPMAP = 4
|
||||
,ImageFlags_IMAROT = 16
|
||||
,ImageFlags_CALCALPHA = 32
|
||||
,ImageFlags_NORMALMAP = 2048
|
||||
,ImageFlags_GAUSS_MIP = 4096
|
||||
,ImageFlags_FILTER_MIN = 8192
|
||||
,ImageFlags_DERIVATIVEMAP = 16384
|
||||
};
|
||||
|
||||
ID id FAIL;
|
||||
// AnimData *adt;
|
||||
|
||||
@@ -618,7 +630,8 @@ struct Tex : ElemBase {
|
||||
//short noisedepth, noisetype;
|
||||
//short noisebasis, noisebasis2;
|
||||
|
||||
//short imaflag, flag;
|
||||
//short flag;
|
||||
ImageFlags imaflag;
|
||||
Type type FAIL;
|
||||
//short stype;
|
||||
|
||||
@@ -685,7 +698,25 @@ struct MTex : ElemBase {
|
||||
,BlendType_BLEND_COLOR = 13
|
||||
};
|
||||
|
||||
// short texco, mapto, maptoneg;
|
||||
enum MapType {
|
||||
MapType_COL = 1
|
||||
,MapType_NORM = 2
|
||||
,MapType_COLSPEC = 4
|
||||
,MapType_COLMIR = 8
|
||||
,MapType_REF = 16
|
||||
,MapType_SPEC = 32
|
||||
,MapType_EMIT = 64
|
||||
,MapType_ALPHA = 128
|
||||
,MapType_HAR = 256
|
||||
,MapType_RAYMIRR = 512
|
||||
,MapType_TRANSLU = 1024
|
||||
,MapType_AMB = 2048
|
||||
,MapType_DISPLACE = 4096
|
||||
,MapType_WARP = 8192
|
||||
};
|
||||
|
||||
// short texco, maptoneg;
|
||||
MapType mapto;
|
||||
|
||||
BlendType blendtype;
|
||||
boost::shared_ptr<Object> object;
|
||||
@@ -705,7 +736,8 @@ struct MTex : ElemBase {
|
||||
|
||||
//float colfac, varfac;
|
||||
|
||||
//float norfac, dispfac, warpfac;
|
||||
float norfac;
|
||||
//float dispfac, warpfac;
|
||||
float colspecfac, mirrfac, alphafac;
|
||||
float difffac, specfac, emitfac, hardfac;
|
||||
//float raymirrfac, translfac, ambfac;
|
||||
|
||||
@@ -47,204 +47,204 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
namespace Assimp {
|
||||
namespace Blender {
|
||||
|
||||
|
||||
template <> void Structure :: Convert<Object> (
|
||||
Object& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Group> (
|
||||
Group& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MTex> (
|
||||
MTex& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<TFace> (
|
||||
TFace& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<SubsurfModifierData> (
|
||||
SubsurfModifierData& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MFace> (
|
||||
MFace& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Lamp> (
|
||||
Lamp& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MDeformWeight> (
|
||||
MDeformWeight& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<PackedFile> (
|
||||
PackedFile& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Base> (
|
||||
Base& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MTFace> (
|
||||
MTFace& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Material> (
|
||||
Material& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MTexPoly> (
|
||||
MTexPoly& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Mesh> (
|
||||
Mesh& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MDeformVert> (
|
||||
MDeformVert& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<World> (
|
||||
World& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MLoopCol> (
|
||||
MLoopCol& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MVert> (
|
||||
MVert& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MEdge> (
|
||||
MEdge& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MLoopUV> (
|
||||
MLoopUV& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<GroupObject> (
|
||||
GroupObject& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<ListBase> (
|
||||
ListBase& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MLoop> (
|
||||
MLoop& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<ModifierData> (
|
||||
ModifierData& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<ID> (
|
||||
ID& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MCol> (
|
||||
MCol& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MPoly> (
|
||||
MPoly& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Scene> (
|
||||
Scene& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Library> (
|
||||
Library& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Tex> (
|
||||
Tex& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Camera> (
|
||||
Camera& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MirrorModifierData> (
|
||||
MirrorModifierData& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Image> (
|
||||
Image& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Object> (
|
||||
Object& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Group> (
|
||||
Group& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MTex> (
|
||||
MTex& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<TFace> (
|
||||
TFace& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<SubsurfModifierData> (
|
||||
SubsurfModifierData& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MFace> (
|
||||
MFace& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Lamp> (
|
||||
Lamp& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MDeformWeight> (
|
||||
MDeformWeight& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<PackedFile> (
|
||||
PackedFile& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Base> (
|
||||
Base& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MTFace> (
|
||||
MTFace& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Material> (
|
||||
Material& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MTexPoly> (
|
||||
MTexPoly& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Mesh> (
|
||||
Mesh& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MDeformVert> (
|
||||
MDeformVert& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<World> (
|
||||
World& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MLoopCol> (
|
||||
MLoopCol& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MVert> (
|
||||
MVert& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MEdge> (
|
||||
MEdge& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MLoopUV> (
|
||||
MLoopUV& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<GroupObject> (
|
||||
GroupObject& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<ListBase> (
|
||||
ListBase& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MLoop> (
|
||||
MLoop& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<ModifierData> (
|
||||
ModifierData& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<ID> (
|
||||
ID& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MCol> (
|
||||
MCol& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MPoly> (
|
||||
MPoly& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Scene> (
|
||||
Scene& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Library> (
|
||||
Library& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Tex> (
|
||||
Tex& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Camera> (
|
||||
Camera& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<MirrorModifierData> (
|
||||
MirrorModifierData& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
template <> void Structure :: Convert<Image> (
|
||||
Image& dest,
|
||||
const FileDatabase& db
|
||||
) const
|
||||
;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -311,16 +311,15 @@ void ColladaExporter::WriteMaterials()
|
||||
|
||||
aiString name;
|
||||
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
|
||||
name = "mat";
|
||||
if(material_names.find(name.C_Str()) != material_names.end()) {
|
||||
materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + "_" + name.C_Str();
|
||||
material_names.insert(materials[a].name);
|
||||
} else {
|
||||
materials[a].name = name.C_Str();
|
||||
}
|
||||
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it )
|
||||
if( !isalnum( *it) )
|
||||
name = "mat";
|
||||
materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
|
||||
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
|
||||
// isalnum on MSVC asserts for code points in [0,255]. Thus prevent unwanted promotion
|
||||
// of char to signed int and take the unsigned char value.
|
||||
if( !isalnum( static_cast<uint8_t>(*it) ) ) {
|
||||
*it = '_';
|
||||
}
|
||||
}
|
||||
|
||||
aiShadingMode shading;
|
||||
materials[a].shading_model = "phong";
|
||||
|
||||
@@ -88,7 +88,7 @@ Exporter::ExportFormatEntry gExporters[] =
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
||||
Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
|
||||
aiProcess_GenNormals /*| aiProcess_PreTransformVertices */),
|
||||
aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */),
|
||||
#endif
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
||||
@@ -227,11 +227,47 @@ const aiExportDataBlob* Exporter :: ExportToBlob( const aiScene* pScene, const
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool IsVerboseFormat(const aiMesh* mesh)
|
||||
{
|
||||
// avoid slow vector<bool> specialization
|
||||
std::vector<unsigned int> seen(mesh->mNumVertices,0);
|
||||
for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
|
||||
const aiFace& f = mesh->mFaces[i];
|
||||
for(unsigned int j = 0; j < f.mNumIndices; ++j) {
|
||||
if(++seen[f.mIndices[j]] == 2) {
|
||||
// found a duplicate index
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool IsVerboseFormat(const aiScene* pScene)
|
||||
{
|
||||
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||
if(!IsVerboseFormat(pScene->mMeshes[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing )
|
||||
{
|
||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||
|
||||
// when they create scenes from scratch, users will likely create them not in verbose
|
||||
// format. They will likely not be aware that there is a flag in the scene to indicate
|
||||
// this, however. To avoid surprises and bug reports, we check for duplicates in
|
||||
// meshes upfront.
|
||||
const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
|
||||
|
||||
pimpl->mError = "";
|
||||
for (size_t i = 0; i < pimpl->mExporters.size(); ++i) {
|
||||
const Exporter::ExportFormatEntry& exp = pimpl->mExporters[i];
|
||||
@@ -253,20 +289,21 @@ aiReturn Exporter :: Export( const aiScene* pScene, const char* pFormatId, const
|
||||
const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded;
|
||||
|
||||
// Erase all pp steps that were already applied to this scene
|
||||
unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv
|
||||
const unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv && !priv->mIsCopy
|
||||
? (priv->mPPStepsApplied & ~nonIdempotentSteps)
|
||||
: 0u);
|
||||
|
||||
// If no extra postprocessing was specified, and we obtained this scene from an
|
||||
// Assimp importer, apply the reverse steps automatically.
|
||||
if (!pPreprocessing && priv) {
|
||||
pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
|
||||
}
|
||||
// TODO: either drop this, or document it. Otherwise it is just a bad surprise.
|
||||
//if (!pPreprocessing && priv) {
|
||||
// pp |= (nonIdempotentSteps & priv->mPPStepsApplied);
|
||||
//}
|
||||
|
||||
// If the input scene is not in verbose format, but there is at least postprocessing step that relies on it,
|
||||
// we need to run the MakeVerboseFormat step first.
|
||||
bool must_join_again = false;
|
||||
if (scenecopy->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
|
||||
if (!is_verbose_format) {
|
||||
|
||||
bool verbosify = false;
|
||||
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
||||
|
||||
@@ -290,14 +290,19 @@ void Document::ReadHeader()
|
||||
const Scope& shead = *ehead->Compound();
|
||||
fbxVersion = ParseTokenAsInt(GetRequiredToken(GetRequiredElement(shead,"FBXVersion",ehead),0));
|
||||
|
||||
|
||||
if(fbxVersion < 7200 || fbxVersion > 7300) {
|
||||
// while we maye have some success with newer files, we don't support
|
||||
// the older 6.n fbx format
|
||||
if(fbxVersion < 7200) {
|
||||
DOMError("unsupported, old format version, supported are only FBX 2012 and FBX 2013");
|
||||
}
|
||||
if(fbxVersion > 7300) {
|
||||
if(Settings().strictMode) {
|
||||
DOMError("unsupported format version, supported are only FBX 2012 and FBX 2013"\
|
||||
" in ASCII format (turn off strict mode to try anyhow) ");
|
||||
DOMError("unsupported, newer format version, supported are only FBX 2012 and FBX 2013"
|
||||
" (turn off strict mode to try anyhow) ");
|
||||
}
|
||||
else {
|
||||
DOMWarning("unsupported format version, supported are only FBX 2012 and FBX 2013, trying to read it nevertheless");
|
||||
DOMWarning("unsupported, newer format version, supported are only FBX 2012 and FBX 2013,"
|
||||
" trying to read it nevertheless");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
||||
|
||||
#include "IRRMeshLoader.h"
|
||||
#include "ParsingUtils.h"
|
||||
@@ -512,4 +512,4 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
|
||||
AI_DEBUG_INVALIDATE_PTR(reader);
|
||||
}
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER
|
||||
|
||||
@@ -45,7 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "AssimpPCH.h"
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
//This section should be excluded only if both the Irrlicht AND the Irrlicht Mesh importers were omitted.
|
||||
#if !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER))
|
||||
|
||||
#include "IRRShared.h"
|
||||
#include "ParsingUtils.h"
|
||||
@@ -497,4 +498,4 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
|
||||
return mat;
|
||||
}
|
||||
|
||||
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||
#endif // !(defined(ASSIMP_BUILD_NO_IRR_IMPORTER) && defined(ASSIMP_BUILD_NO_IRRMESH_IMPORTER))
|
||||
|
||||
@@ -1296,6 +1296,11 @@ void LWOImporter::LoadLWO2File()
|
||||
uint8_t* const next = mFileBuffer+head->length;
|
||||
unsigned int iUnnamed = 0;
|
||||
|
||||
if(!head->length) {
|
||||
mFileBuffer = next;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (head->type)
|
||||
{
|
||||
// new layer
|
||||
|
||||
@@ -167,19 +167,21 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
|
||||
// The older LWOB format does not use indirect references to clips.
|
||||
// The file name of a texture is directly specified in the tex chunk.
|
||||
if (mIsLWO2) {
|
||||
// find the corresponding clip
|
||||
ClipList::iterator clip = mClips.begin();
|
||||
// find the corresponding clip (take the last one if multiple
|
||||
// share the same index)
|
||||
ClipList::iterator end = mClips.end(), candidate = end;
|
||||
temp = (*it).mClipIdx;
|
||||
for (ClipList::iterator end = mClips.end(); clip != end; ++clip) {
|
||||
if ((*clip).idx == temp)
|
||||
break;
|
||||
for (ClipList::iterator clip = mClips.begin(); clip != end; ++clip) {
|
||||
if ((*clip).idx == temp) {
|
||||
candidate = clip;
|
||||
}
|
||||
|
||||
}
|
||||
if (mClips.end() == clip) {
|
||||
if (candidate == end) {
|
||||
DefaultLogger::get()->error("LWO2: Clip index is out of bounds");
|
||||
temp = 0;
|
||||
|
||||
// fixme: appearently some LWO files shipping with Doom3 don't
|
||||
// fixme: apparently some LWO files shipping with Doom3 don't
|
||||
// have clips at all ... check whether that's true or whether
|
||||
// it's a bug in the loader.
|
||||
|
||||
@@ -188,16 +190,16 @@ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTex
|
||||
//continue;
|
||||
}
|
||||
else {
|
||||
if (Clip::UNSUPPORTED == (*clip).type) {
|
||||
if (Clip::UNSUPPORTED == (*candidate).type) {
|
||||
DefaultLogger::get()->error("LWO2: Clip type is not supported");
|
||||
continue;
|
||||
}
|
||||
AdjustTexturePath((*clip).path);
|
||||
s.Set((*clip).path);
|
||||
AdjustTexturePath((*candidate).path);
|
||||
s.Set((*candidate).path);
|
||||
|
||||
// Additional image settings
|
||||
int flags = 0;
|
||||
if ((*clip).negate) {
|
||||
if ((*candidate).negate) {
|
||||
flags |= aiTextureFlags_Invert;
|
||||
}
|
||||
pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur));
|
||||
|
||||
@@ -61,14 +61,14 @@ void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
|
||||
if(outfile == NULL) {
|
||||
throw DeadlyExportError("could not open output .obj file: " + std::string(pFile));
|
||||
}
|
||||
}
|
||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||
}
|
||||
{
|
||||
boost::scoped_ptr<IOStream> outfile (pIOSystem->Open(exporter.GetMaterialLibFileName(),"wt"));
|
||||
if(outfile == NULL) {
|
||||
throw DeadlyExportError("could not open output .mtl file: " + std::string(exporter.GetMaterialLibFileName()));
|
||||
}
|
||||
}
|
||||
outfile->Write( exporter.mOutputMat.str().c_str(), static_cast<size_t>(exporter.mOutputMat.tellp()),1);
|
||||
}
|
||||
}
|
||||
@@ -199,6 +199,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||
AddNode(pScene->mRootNode,mBase);
|
||||
|
||||
// write vertex positions
|
||||
vpMap.getVectors(vp);
|
||||
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
||||
BOOST_FOREACH(const aiVector3D& v, vp) {
|
||||
mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
|
||||
@@ -206,6 +207,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||
mOutput << endl;
|
||||
|
||||
// write uv coordinates
|
||||
vtMap.getVectors(vt);
|
||||
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
||||
BOOST_FOREACH(const aiVector3D& v, vt) {
|
||||
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
||||
@@ -213,6 +215,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||
mOutput << endl;
|
||||
|
||||
// write vertex normals
|
||||
vnMap.getVectors(vn);
|
||||
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
||||
BOOST_FOREACH(const aiVector3D& v, vn) {
|
||||
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
||||
@@ -252,6 +255,31 @@ void ObjExporter :: WriteGeometryFile()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int ObjExporter::vecIndexMap::getIndex(const aiVector3D& vec)
|
||||
{
|
||||
vecIndexMap::dataType::iterator vertIt = vecMap.find(vec);
|
||||
if(vertIt != vecMap.end()){// vertex already exists, so reference it
|
||||
return vertIt->second;
|
||||
}
|
||||
vecMap[vec] = mNextIndex;
|
||||
int ret = mNextIndex;
|
||||
mNextIndex++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObjExporter::vecIndexMap::getVectors( std::vector<aiVector3D>& vecs )
|
||||
{
|
||||
vecs.resize(vecMap.size());
|
||||
for(vecIndexMap::dataType::iterator it = vecMap.begin(); it != vecMap.end(); it++){
|
||||
vecs[it->second-1] = it->first;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
|
||||
{
|
||||
@@ -262,6 +290,7 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
|
||||
mesh.matname = GetMaterialName(m->mMaterialIndex);
|
||||
|
||||
mesh.faces.resize(m->mNumFaces);
|
||||
|
||||
for(unsigned int i = 0; i < m->mNumFaces; ++i) {
|
||||
const aiFace& f = m->mFaces[i];
|
||||
|
||||
@@ -281,21 +310,22 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
|
||||
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||
const unsigned int idx = f.mIndices[a];
|
||||
|
||||
// XXX need a way to check if this is an unique vertex or if we had it already,
|
||||
// in which case we should instead reference the previous occurrence.
|
||||
ai_assert(m->mVertices);
|
||||
vp.push_back( mat * m->mVertices[idx] );
|
||||
face.indices[a].vp = vp.size();
|
||||
aiVector3D vert = mat * m->mVertices[idx];
|
||||
face.indices[a].vp = vpMap.getIndex(vert);
|
||||
|
||||
if (m->mNormals) {
|
||||
vn.push_back( m->mNormals[idx] );
|
||||
face.indices[a].vn = vnMap.getIndex(m->mNormals[idx]);
|
||||
}
|
||||
else{
|
||||
face.indices[a].vn = 0;
|
||||
}
|
||||
face.indices[a].vn = vn.size();
|
||||
|
||||
if (m->mTextureCoords[0]) {
|
||||
vt.push_back( m->mTextureCoords[0][idx] );
|
||||
face.indices[a].vt = vtMap.getIndex(m->mTextureCoords[0][idx]);
|
||||
}
|
||||
else{
|
||||
face.indices[a].vt = 0;
|
||||
}
|
||||
face.indices[a].vt = vt.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +112,36 @@ private:
|
||||
const aiScene* const pScene;
|
||||
|
||||
std::vector<aiVector3D> vp, vn, vt;
|
||||
|
||||
|
||||
struct aiVectorCompare
|
||||
{
|
||||
bool operator() (const aiVector3D& a, const aiVector3D& b) const
|
||||
{
|
||||
if(a.x < b.x) return true;
|
||||
if(a.x > b.x) return false;
|
||||
if(a.y < b.y) return true;
|
||||
if(a.y > b.y) return false;
|
||||
if(a.z < b.z) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class vecIndexMap
|
||||
{
|
||||
int mNextIndex;
|
||||
typedef std::map<aiVector3D, int, aiVectorCompare> dataType;
|
||||
dataType vecMap;
|
||||
public:
|
||||
|
||||
vecIndexMap():mNextIndex(1)
|
||||
{}
|
||||
|
||||
int getIndex(const aiVector3D& vec);
|
||||
void getVectors( std::vector<aiVector3D>& vecs );
|
||||
};
|
||||
|
||||
vecIndexMap vpMap, vnMap, vtMap;
|
||||
std::vector<MeshInstance> meshes;
|
||||
|
||||
// this endl() doesn't flush() the stream
|
||||
|
||||
@@ -276,14 +276,23 @@ void ObjFileImporter::createTopology(const ObjFile::Model* pModel,
|
||||
for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
|
||||
{
|
||||
ObjFile::Face* const inp = pObjMesh->m_Faces[ index ];
|
||||
|
||||
if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
|
||||
pMesh->mNumFaces += inp->m_pVertices->size() - 1;
|
||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
|
||||
}
|
||||
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 {
|
||||
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,7 +393,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||
pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
|
||||
|
||||
// Copy all normals
|
||||
if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty())
|
||||
if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_pNormals->size())
|
||||
{
|
||||
const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex );
|
||||
if ( normal >= pModel->m_Normals.size() )
|
||||
@@ -394,21 +403,16 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
||||
}
|
||||
|
||||
// Copy all texture coordinates
|
||||
if ( !pModel->m_TextureCoord.empty() )
|
||||
if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_pTexturCoords->size())
|
||||
{
|
||||
if ( !pSourceFace->m_pTexturCoords->empty() )
|
||||
{
|
||||
const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
|
||||
ai_assert( tex < pModel->m_TextureCoord.size() );
|
||||
for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ )
|
||||
{
|
||||
if ( tex >= pModel->m_TextureCoord.size() )
|
||||
throw DeadlyImportError("OBJ: texture coord index out of range");
|
||||
const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex );
|
||||
ai_assert( tex < pModel->m_TextureCoord.size() );
|
||||
|
||||
if ( tex >= pModel->m_TextureCoord.size() )
|
||||
throw DeadlyImportError("OBJ: texture coord index out of range");
|
||||
|
||||
aiVector2D coord2d = pModel->m_TextureCoord[ tex ];
|
||||
pMesh->mTextureCoords[ i ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 );
|
||||
}
|
||||
}
|
||||
aiVector2D coord2d = pModel->m_TextureCoord[ tex ];
|
||||
pMesh->mTextureCoords[ 0 ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 );
|
||||
}
|
||||
|
||||
ai_assert( pMesh->mNumVertices > newIndex );
|
||||
@@ -587,15 +591,12 @@ void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
|
||||
|
||||
// Assign parent to child
|
||||
pChild->mParent = pParent;
|
||||
size_t sNumChildren = 0;
|
||||
(void)sNumChildren; // remove warning on release build
|
||||
|
||||
// If already children was assigned to the parent node, store them in a
|
||||
std::vector<aiNode*> temp;
|
||||
if (pParent->mChildren != NULL)
|
||||
{
|
||||
sNumChildren = pParent->mNumChildren;
|
||||
ai_assert( 0 != sNumChildren );
|
||||
ai_assert( 0 != pParent->mNumChildren );
|
||||
for (size_t index = 0; index < pParent->mNumChildren; index++)
|
||||
{
|
||||
temp.push_back(pParent->mChildren [ index ] );
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
//! \brief Appends the supported extention.
|
||||
//! \brief Appends the supported extension.
|
||||
const aiImporterDesc* GetInfo () const;
|
||||
|
||||
//! \brief File import implementation.
|
||||
@@ -104,18 +104,15 @@ private:
|
||||
//! \brief Material creation.
|
||||
void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
|
||||
|
||||
//! \brief Appends a child node to a parentnode and updates the datastructures.
|
||||
//! \brief Appends a child node to a parent node and updates the data structures.
|
||||
void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
|
||||
|
||||
//! \brief TODO!
|
||||
void createAnimations();
|
||||
|
||||
private:
|
||||
//! Data buffer
|
||||
std::vector<char> m_Buffer;
|
||||
//! Pointer to root object instance
|
||||
ObjFile::Object *m_pRootObject;
|
||||
//! Absolute pathname of model in filesystem
|
||||
//! Absolute pathname of model in file system
|
||||
std::string m_strAbsPath;
|
||||
};
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ void ObjFileParser::parseFile()
|
||||
case 'v': // Parse a vertex texture coordinate
|
||||
{
|
||||
++m_DataIt;
|
||||
if (*m_DataIt == ' ')
|
||||
if (*m_DataIt == ' ' || *m_DataIt == '\t')
|
||||
{
|
||||
// Read in vertex definition
|
||||
getVector3(m_pModel->m_Vertices);
|
||||
@@ -200,6 +200,8 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
|
||||
break;
|
||||
++m_DataIt;
|
||||
}
|
||||
|
||||
ai_assert(index < length);
|
||||
pBuffer[index] = '\0';
|
||||
}
|
||||
|
||||
@@ -207,16 +209,30 @@ void ObjFileParser::copyNextWord(char *pBuffer, size_t length)
|
||||
// Copy the next line into a temporary buffer
|
||||
void ObjFileParser::copyNextLine(char *pBuffer, size_t length)
|
||||
{
|
||||
size_t index = 0;
|
||||
while (m_DataIt != m_DataItEnd)
|
||||
{
|
||||
if (*m_DataIt == '\n' || *m_DataIt == '\r' || index == length-1)
|
||||
break;
|
||||
size_t index = 0u;
|
||||
|
||||
pBuffer[ index ] = *m_DataIt;
|
||||
++index;
|
||||
++m_DataIt;
|
||||
// some OBJ files have line continuations using \ (such as in C++ et al)
|
||||
bool continuation = false;
|
||||
for (;m_DataIt != m_DataItEnd && index < length-1; ++m_DataIt)
|
||||
{
|
||||
const char c = *m_DataIt;
|
||||
if (c == '\\') {
|
||||
continuation = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == '\n' || c == '\r') {
|
||||
if(continuation) {
|
||||
pBuffer[ index++ ] = ' ';
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
continuation = false;
|
||||
pBuffer[ index++ ] = c;
|
||||
}
|
||||
ai_assert(index < length);
|
||||
pBuffer[ index ] = '\0';
|
||||
}
|
||||
|
||||
@@ -274,6 +290,10 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
|
||||
bool hasNormal = false;
|
||||
|
||||
const int vSize = m_pModel->m_Vertices.size();
|
||||
const int vtSize = m_pModel->m_TextureCoord.size();
|
||||
const int vnSize = m_pModel->m_Normals.size();
|
||||
|
||||
const bool vt = (!m_pModel->m_TextureCoord.empty());
|
||||
const bool vn = (!m_pModel->m_Normals.empty());
|
||||
int iStep = 0, iPos = 0;
|
||||
@@ -307,7 +327,11 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||
{
|
||||
//OBJ USES 1 Base ARRAYS!!!!
|
||||
const int iVal = atoi( pPtr );
|
||||
|
||||
// increment iStep position based off of the sign and # of digits
|
||||
int tmp = iVal;
|
||||
if (iVal < 0)
|
||||
++iStep;
|
||||
while ( ( tmp = tmp / 10 )!=0 )
|
||||
++iStep;
|
||||
|
||||
@@ -332,6 +356,27 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||
reportErrorTokenInFace();
|
||||
}
|
||||
}
|
||||
else if ( iVal < 0 )
|
||||
{
|
||||
// Store relatively index
|
||||
if ( 0 == iPos )
|
||||
{
|
||||
pIndices->push_back( vSize + iVal );
|
||||
}
|
||||
else if ( 1 == iPos )
|
||||
{
|
||||
pTexID->push_back( vtSize + iVal );
|
||||
}
|
||||
else if ( 2 == iPos )
|
||||
{
|
||||
pNormalID->push_back( vnSize + iVal );
|
||||
hasNormal = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
reportErrorTokenInFace();
|
||||
}
|
||||
}
|
||||
}
|
||||
pPtr += iStep;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
|
||||
|
||||
mOutput << "ply" << endl;
|
||||
mOutput << "format ascii 1.0" << endl;
|
||||
mOutput << "Created by Open Asset Import Library - http://assimp.sf.net (v"
|
||||
mOutput << "comment Created by Open Asset Import Library - http://assimp.sf.net (v"
|
||||
<< aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
|
||||
<< aiGetVersionRevision() << ")" << endl;
|
||||
|
||||
@@ -159,7 +159,7 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
|
||||
}
|
||||
|
||||
mOutput << "element face " << faces << endl;
|
||||
mOutput << "property list uint uint vertex_indices" << endl;
|
||||
mOutput << "property list uint uint vertex_index" << endl;
|
||||
mOutput << "end_header" << endl;
|
||||
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||
|
||||
@@ -86,7 +86,12 @@ bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
|
||||
if (IsBinarySTL(buffer, fileSize))
|
||||
return false;
|
||||
|
||||
if (fileSize < 5)
|
||||
const char* bufferEnd = buffer + fileSize;
|
||||
|
||||
if (!SkipSpaces(&buffer))
|
||||
return false;
|
||||
|
||||
if (buffer + 5 >= bufferEnd)
|
||||
return false;
|
||||
|
||||
return strncmp(buffer, "solid", 5) == 0;
|
||||
@@ -209,7 +214,11 @@ void STLImporter::LoadASCIIFile()
|
||||
{
|
||||
aiMesh* pMesh = pScene->mMeshes[0];
|
||||
|
||||
const char* sz = mBuffer + 5; // skip the "solid"
|
||||
const char* sz = mBuffer;
|
||||
SkipSpaces(&sz);
|
||||
ai_assert(!IsLineEnd(sz));
|
||||
|
||||
sz += 5; // skip the "solid"
|
||||
SkipSpaces(&sz);
|
||||
const char* szMe = sz;
|
||||
while (!::IsSpaceOrNewLine(*sz)) {
|
||||
|
||||
@@ -53,6 +53,7 @@ struct ScenePrivateData {
|
||||
ScenePrivateData()
|
||||
: mOrigImporter()
|
||||
, mPPStepsApplied()
|
||||
, mIsCopy()
|
||||
{}
|
||||
|
||||
// Importer that originally loaded the scene though the C-API
|
||||
@@ -61,6 +62,13 @@ struct ScenePrivateData {
|
||||
|
||||
// List of postprocessing steps already applied to the scene.
|
||||
unsigned int mPPStepsApplied;
|
||||
|
||||
// true if the scene is a copy made with aiCopyScene()
|
||||
// or the corresponding C++ API. This means that user code
|
||||
// may have made modifications to it, so mPPStepsApplied
|
||||
// and mOrigImporter are no longer safe to rely on and only
|
||||
// serve informative purposes.
|
||||
bool mIsCopy;
|
||||
};
|
||||
|
||||
// Access private data stored in the scene
|
||||
|
||||
Reference in New Issue
Block a user