blender loader now reads basic material colors and even simple textures, be them embedded into the BLEND file or not.
adding some test files. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@735 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
2a6b4d1d17
commit
188aa3da37
|
@ -111,6 +111,15 @@ struct Pointer
|
|||
uint64_t val;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Represents a generic offset within a BLEND file */
|
||||
// -------------------------------------------------------------------------------
|
||||
struct FileOffset
|
||||
{
|
||||
FileOffset() : val() {}
|
||||
uint64_t val;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
/** Dummy derivate of std::vector to be able to use it in templates simultaenously
|
||||
* with boost::shared_ptr, which takes only one template argument
|
||||
|
@ -263,6 +272,13 @@ public:
|
|||
void ReadFieldPtr(TOUT<T>& out, const char* name,
|
||||
const FileDatabase& db) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// field parsing for static arrays of pointer or dynamic
|
||||
// array types (boost::shared_ptr[] or boost::shared_array[])
|
||||
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
||||
void ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||
const FileDatabase& db) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
// field parsing for `normal` values
|
||||
template <int error_policy, typename T>
|
||||
|
@ -281,6 +297,10 @@ private:
|
|||
void ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||
const FileDatabase& db, const Field& f) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
void ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
||||
const FileDatabase& db, const Field& f) const;
|
||||
|
||||
// --------------------------------------------------------
|
||||
inline const FileBlockHead* LocateFileBlockForAddress(
|
||||
const Pointer & ptrval,
|
||||
|
|
|
@ -181,8 +181,7 @@ void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabas
|
|||
// sanity check, should never happen if the genblenddna script is right
|
||||
if (!(f->flags & FieldFlag_Pointer)) {
|
||||
throw Error((Formatter::format(),"Field `",name,"` of structure `",
|
||||
this->name,"` ought to be a pointer"
|
||||
));
|
||||
this->name,"` ought to be a pointer"));
|
||||
}
|
||||
|
||||
db.reader->IncPtr(f->offset);
|
||||
|
@ -204,9 +203,57 @@ void Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabas
|
|||
db.reader->SetCurrentPos(old);
|
||||
|
||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
if (out) {
|
||||
++db.stats().pointers_resolved;
|
||||
++db.stats().fields_read;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
||||
void 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
|
||||
const StreamReaderAny::pos old = db.reader->GetCurrentPos();
|
||||
Pointer ptrval[N];
|
||||
const Field* f;
|
||||
try {
|
||||
f = &(*this)[name];
|
||||
|
||||
// sanity check, should never happen if the genblenddna script is right
|
||||
if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) {
|
||||
throw Error((Formatter::format(),"Field `",name,"` of structure `",
|
||||
this->name,"` ought to be a pointer AND an array"));
|
||||
}
|
||||
|
||||
db.reader->IncPtr(f->offset);
|
||||
|
||||
size_t i = 0;
|
||||
for(; i < std::min(f->array_sizes[0],N); ++i) {
|
||||
Convert(ptrval[i],db);
|
||||
}
|
||||
for(; i < N; ++i) {
|
||||
_defaultInitializer<ErrorPolicy_Igno>()(ptrval[i]);
|
||||
}
|
||||
|
||||
// actually it is meaningless on which Structure the Convert is called
|
||||
// because the `Pointer` argument triggers a special implementation.
|
||||
}
|
||||
catch (const Error& e) {
|
||||
_defaultInitializer<error_policy>()(out,e.what());
|
||||
for(size_t i = 0; i < N; ++i) {
|
||||
out[i].reset();
|
||||
}
|
||||
return;
|
||||
}
|
||||
for(size_t i = 0; i < N; ++i) {
|
||||
// resolve the pointer and load the corresponding structure
|
||||
ResolvePointer(out[i],ptrval[i],db,*f);
|
||||
}
|
||||
|
||||
// and recover the previous stream position
|
||||
db.reader->SetCurrentPos(old);
|
||||
|
||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
++db.stats().fields_read;
|
||||
#endif
|
||||
}
|
||||
|
@ -282,6 +329,29 @@ void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil
|
|||
}
|
||||
|
||||
db.reader->SetCurrentPos(pold);
|
||||
|
||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
if(out) {
|
||||
++db.stats().pointers_resolved;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
inline void Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
|
||||
{
|
||||
// Currently used exclusively by PackedFile::data to represent
|
||||
// a simple offset into the mapped BLEND file.
|
||||
out.reset();
|
||||
if (!ptrval.val) {
|
||||
return;
|
||||
}
|
||||
|
||||
// find the file block the pointer is pointing to
|
||||
const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
|
||||
|
||||
out = boost::shared_ptr< FileOffset > (new FileOffset());
|
||||
out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
@ -372,6 +442,10 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
|||
// cache the object now that construction is complete
|
||||
// FIXME we need to do this in ConvertBlobToStructure
|
||||
db.cache(out).set(s,out,ptrval);
|
||||
|
||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||
++db.stats().pointers_resolved;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
|
|
@ -75,9 +75,12 @@ static const aiLoaderDesc blenderDesc = {
|
|||
namespace Assimp {
|
||||
namespace Blender {
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
|
||||
// --------------------------------------------------------------------
|
||||
template <template <typename,typename> class TCLASS, typename T>
|
||||
struct TempArray {
|
||||
typedef TCLASS< T*,std::allocator<T*> > mywrap;
|
||||
|
||||
TempArray() {
|
||||
}
|
||||
|
@ -92,19 +95,23 @@ namespace Blender {
|
|||
arr.clear();
|
||||
}
|
||||
|
||||
TCLASS< T*,std::allocator<T*> >* operator -> () {
|
||||
mywrap* operator -> () {
|
||||
return &arr;
|
||||
}
|
||||
|
||||
operator TCLASS< T*,std::allocator<T*> > () {
|
||||
operator mywrap& () {
|
||||
return arr;
|
||||
}
|
||||
|
||||
TCLASS< T*,std::allocator<T*> >& get () {
|
||||
operator const mywrap& () const {
|
||||
return arr;
|
||||
}
|
||||
|
||||
const TCLASS< T*,std::allocator<T*> >& get () const {
|
||||
mywrap& get () {
|
||||
return arr;
|
||||
}
|
||||
|
||||
const mywrap& get () const {
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
@ -121,24 +128,73 @@ namespace Blender {
|
|||
}
|
||||
|
||||
private:
|
||||
TCLASS< T*,std::allocator<T*> > arr;
|
||||
mywrap arr;
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable:4351)
|
||||
#endif
|
||||
// --------------------------------------------------------------------
|
||||
/** ConversionData acts as intermediate storage location for
|
||||
* the various ConvertXXX routines in BlenderImporter.*/
|
||||
struct ConversionData {
|
||||
// --------------------------------------------------------------------
|
||||
struct ConversionData
|
||||
{
|
||||
ConversionData(const FileDatabase& db)
|
||||
: sentinel_cnt()
|
||||
, next_texture()
|
||||
, db(db)
|
||||
{}
|
||||
|
||||
std::set<const Object*> objects;
|
||||
|
||||
TempArray <std::vector, aiMesh> meshes;
|
||||
TempArray <std::vector, aiCamera> cameras;
|
||||
TempArray <std::vector, aiLight> lights;
|
||||
TempArray <std::vector, aiMaterial> materials;
|
||||
TempArray <std::vector, aiTexture> textures;
|
||||
|
||||
// set of all materials referenced by at least one mesh in the scene
|
||||
std::deque< boost::shared_ptr< Material > > materials_raw;
|
||||
|
||||
// counter to name sentinel textures inserted as substitutes for procedural textures.
|
||||
unsigned int sentinel_cnt;
|
||||
|
||||
// next texture ID for each texture type, respectively
|
||||
unsigned int next_texture[aiTextureType_UNKNOWN+1];
|
||||
|
||||
// original file data
|
||||
const FileDatabase& db;
|
||||
};
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(default:4351)
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const char* GetTextureTypeDisplayString(Tex::Type t)
|
||||
{
|
||||
switch (t) {
|
||||
case Tex::Type_CLOUDS : return "Clouds";
|
||||
case Tex::Type_WOOD : return "Wood";
|
||||
case Tex::Type_MARBLE : return "Marble";
|
||||
case Tex::Type_MAGIC : return "Magic";
|
||||
case Tex::Type_BLEND : return "Blend";
|
||||
case Tex::Type_STUCCI : return "Stucci";
|
||||
case Tex::Type_NOISE : return "Noise";
|
||||
case Tex::Type_PLUGIN : return "Plugin";
|
||||
case Tex::Type_MUSGRAVE : return "Musgrave";
|
||||
case Tex::Type_VORONOI : return "Voronoi";
|
||||
case Tex::Type_DISTNOISE : return "DistortedNoise";
|
||||
case Tex::Type_ENVMAP : return "EnvMap";
|
||||
case Tex::Type_IMAGE : return "Image";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "<Unknown>";
|
||||
}
|
||||
}
|
||||
|
||||
} // ! Blender
|
||||
} // ! Assimp
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
|
@ -220,7 +276,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
|
|||
Scene scene;
|
||||
ExtractScene(scene,file);
|
||||
|
||||
ConvertBlendFile(pScene,scene);
|
||||
ConvertBlendFile(pScene,scene,file);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -294,9 +350,9 @@ void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in)
|
||||
void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileDatabase& file)
|
||||
{
|
||||
ConversionData conv;
|
||||
ConversionData conv(file);
|
||||
|
||||
// FIXME it must be possible to take the hierarchy directly from
|
||||
// the file. This is terrible. Here, we're first looking for
|
||||
|
@ -357,6 +413,11 @@ void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in)
|
|||
conv.materials.dismiss();
|
||||
}
|
||||
|
||||
if (conv.textures->size()) {
|
||||
out->mTextures = new aiTexture*[out->mNumTextures = static_cast<unsigned int>( conv.textures->size() )];
|
||||
std::copy(conv.textures->begin(),conv.textures->end(),out->mTextures);
|
||||
conv.textures.dismiss();
|
||||
}
|
||||
|
||||
// acknowledge that the scene might come out incomplete
|
||||
// by Assimps definition of `complete`: blender scenes
|
||||
|
@ -367,6 +428,113 @@ void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in)
|
|||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BlenderImporter::ResolveImage(MaterialHelper* out, const Material* mat, const MTex* tex, const Image* img, ConversionData& conv_data)
|
||||
{
|
||||
mat; tex; conv_data;
|
||||
aiString name;
|
||||
|
||||
// check if the file contents are bundled with the BLEND file
|
||||
if (img->packedfile) {
|
||||
name.data[0] = '*';
|
||||
name.length = 1+ ASSIMP_itoa10(name.data+1,MAXLEN-1,conv_data.textures->size());
|
||||
|
||||
conv_data.textures->push_back(new aiTexture());
|
||||
aiTexture* tex = conv_data.textures->back();
|
||||
|
||||
// usually 'img->name' will be the original file name of the embedded textures,
|
||||
// so we can extract the file extension from it.
|
||||
const size_t nlen = strlen( img->name );
|
||||
const char* s = img->name+nlen, *e = s;
|
||||
|
||||
while (s >= img->name && *s != '.')--s;
|
||||
|
||||
tex->achFormatHint[0] = s+1>e ? '\0' : s[1];
|
||||
tex->achFormatHint[1] = s+2>e ? '\0' : s[2];
|
||||
tex->achFormatHint[2] = s+3>e ? '\0' : s[3];
|
||||
tex->achFormatHint[3] = '\0';
|
||||
|
||||
// tex->mHeight = 0;
|
||||
tex->mWidth = img->packedfile->size;
|
||||
uint8_t* ch = new uint8_t[tex->mWidth];
|
||||
|
||||
conv_data.db.reader->SetCurrentPos(img->packedfile->data->val);
|
||||
conv_data.db.reader->CopyAndAdvance(ch,tex->mWidth);
|
||||
|
||||
tex->pcData = reinterpret_cast<aiTexel*>(ch);
|
||||
|
||||
LogInfo("Reading embedded texture, original file was "+std::string(img->name));
|
||||
}
|
||||
else {
|
||||
name = aiString( img->name );
|
||||
}
|
||||
out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
|
||||
conv_data.next_texture[aiTextureType_DIFFUSE]++)
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BlenderImporter::AddSentinelTexture(MaterialHelper* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
|
||||
{
|
||||
mat; tex; conv_data;
|
||||
|
||||
aiString name;
|
||||
name.length = sprintf(name.data, "Procedural,num=%i,type=%s",conv_data.sentinel_cnt++,
|
||||
GetTextureTypeDisplayString(tex->tex->type)
|
||||
);
|
||||
out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
|
||||
conv_data.next_texture[aiTextureType_DIFFUSE]++)
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BlenderImporter::ResolveTexture(MaterialHelper* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
|
||||
{
|
||||
const Tex* rtex = tex->tex.get();
|
||||
if(!rtex || !rtex->type) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We can't support most of the texture types because the're mostly procedural.
|
||||
// These are substituted by a dummy texture.
|
||||
const char* dispnam = "";
|
||||
switch( rtex->type )
|
||||
{
|
||||
// these are listed in blender's UI
|
||||
case Tex::Type_CLOUDS :
|
||||
case Tex::Type_WOOD :
|
||||
case Tex::Type_MARBLE :
|
||||
case Tex::Type_MAGIC :
|
||||
case Tex::Type_BLEND :
|
||||
case Tex::Type_STUCCI :
|
||||
case Tex::Type_NOISE :
|
||||
case Tex::Type_PLUGIN :
|
||||
case Tex::Type_MUSGRAVE :
|
||||
case Tex::Type_VORONOI :
|
||||
case Tex::Type_DISTNOISE :
|
||||
case Tex::Type_ENVMAP :
|
||||
|
||||
// these do no appear in the UI, why?
|
||||
case Tex::Type_POINTDENSITY :
|
||||
case Tex::Type_VOXELDATA :
|
||||
|
||||
LogWarn(std::string("Encountered a texture with an unsupported type: ")+dispnam);
|
||||
AddSentinelTexture(out, mat, tex, conv_data);
|
||||
break;
|
||||
|
||||
case Tex::Type_IMAGE :
|
||||
if (!rtex->ima) {
|
||||
LogError("A texture claims to be an Image, but no image reference is given");
|
||||
break;
|
||||
}
|
||||
ResolveImage(out, mat, tex, rtex->ima.get(),conv_data);
|
||||
break;
|
||||
|
||||
default:
|
||||
ai_assert(false);
|
||||
};
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
||||
{
|
||||
|
@ -386,6 +554,7 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
|||
p->r = p->g = p->b = 0.6f;
|
||||
p->specr = p->specg = p->specb = 0.6f;
|
||||
p->ambir = p->ambig = p->ambib = 0.0f;
|
||||
p->mirr = p->mirg = p->mirb = 0.0f;
|
||||
p->emit = 0.f;
|
||||
p->alpha = 0.f;
|
||||
|
||||
|
@ -401,6 +570,11 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
|||
}
|
||||
|
||||
for_each(boost::shared_ptr<Material> mat, conv_data.materials_raw) {
|
||||
|
||||
// reset per material global counters
|
||||
for (size_t i = 0; i < sizeof(conv_data.next_texture)/sizeof(conv_data.next_texture[0]);++i) {
|
||||
conv_data.next_texture[i] = 0 ;
|
||||
}
|
||||
|
||||
MaterialHelper* mout = new MaterialHelper();
|
||||
conv_data.materials->push_back(mout);
|
||||
|
@ -419,6 +593,17 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
|||
|
||||
col = aiColor3D(mat->ambir,mat->ambig,mat->ambib);
|
||||
mout->AddProperty(&col,1,AI_MATKEY_COLOR_AMBIENT);
|
||||
|
||||
col = aiColor3D(mat->mirr,mat->mirg,mat->mirb);
|
||||
mout->AddProperty(&col,1,AI_MATKEY_COLOR_REFLECTIVE);
|
||||
|
||||
for(size_t i = 0; i < sizeof(mat->mtex) / sizeof(mat->mtex[0]); ++i) {
|
||||
if (!mat->mtex[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ResolveTexture(mout,mat.get(),mat->mtex[i].get(),conv_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,11 +636,11 @@ void BlenderImporter::ConvertMesh(const Scene& in, const Object* obj, const Mesh
|
|||
}
|
||||
|
||||
// some sanity checks
|
||||
if (mesh->totface > mesh->mface.size() ){
|
||||
if (static_cast<size_t> ( mesh->totface ) > mesh->mface.size() ){
|
||||
ThrowException("Number of faces is larger than the corresponding array");
|
||||
}
|
||||
|
||||
if (mesh->totvert > mesh->mvert.size()) {
|
||||
if (static_cast<size_t> ( mesh->totvert ) > mesh->mvert.size()) {
|
||||
ThrowException("Number of vertices is larger than the corresponding array");
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ namespace Assimp {
|
|||
struct Mesh;
|
||||
struct Camera;
|
||||
struct Lamp;
|
||||
struct MTex;
|
||||
struct Image;
|
||||
struct Material;
|
||||
}
|
||||
|
||||
// BlenderLoader.cpp
|
||||
|
@ -157,7 +160,8 @@ protected:
|
|||
|
||||
// --------------------
|
||||
void ConvertBlendFile(aiScene* out,
|
||||
const Blender::Scene& in
|
||||
const Blender::Scene& in,
|
||||
const Blender::FileDatabase& file
|
||||
);
|
||||
|
||||
private:
|
||||
|
@ -191,7 +195,33 @@ private:
|
|||
);
|
||||
|
||||
// --------------------
|
||||
void BuildMaterials(Blender::ConversionData& conv_data) ;
|
||||
void BuildMaterials(
|
||||
Blender::ConversionData& conv_data
|
||||
) ;
|
||||
|
||||
// --------------------
|
||||
void ResolveTexture(
|
||||
MaterialHelper* out,
|
||||
const Blender::Material* mat,
|
||||
const Blender::MTex* tex,
|
||||
Blender::ConversionData& conv_data
|
||||
);
|
||||
|
||||
// --------------------
|
||||
void ResolveImage(
|
||||
MaterialHelper* out,
|
||||
const Blender::Material* mat,
|
||||
const Blender::MTex* tex,
|
||||
const Blender::Image* img,
|
||||
Blender::ConversionData& conv_data
|
||||
);
|
||||
|
||||
void AddSentinelTexture(
|
||||
MaterialHelper* out,
|
||||
const Blender::Material* mat,
|
||||
const Blender::MTex* tex,
|
||||
Blender::ConversionData& conv_data
|
||||
);
|
||||
|
||||
private: // static stuff, mostly logging and error reporting.
|
||||
|
||||
|
|
|
@ -207,6 +207,9 @@ template <> void Structure :: Convert<PackedFile> (
|
|||
) const
|
||||
{
|
||||
|
||||
ReadField<ErrorPolicy_Warn>(dest.size,"size",db);
|
||||
ReadField<ErrorPolicy_Warn>(dest.seek,"seek",db);
|
||||
ReadFieldPtr<ErrorPolicy_Warn>(dest.data,"*data",db);
|
||||
|
||||
db.reader->IncPtr(size);
|
||||
}
|
||||
|
@ -271,6 +274,7 @@ template <> void Structure :: Convert<Material> (
|
|||
ReadFieldPtr<ErrorPolicy_Igno>(dest.group,"*group",db);
|
||||
ReadField<ErrorPolicy_Warn>(dest.diff_shader,"diff_shader",db);
|
||||
ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
|
||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
|
||||
|
||||
db.reader->IncPtr(size);
|
||||
}
|
||||
|
@ -338,7 +342,7 @@ template <> void Structure :: Convert<MVert> (
|
|||
ReadFieldArray<ErrorPolicy_Fail>(dest.no,"no",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||
ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
|
||||
ReadField<ErrorPolicy_Fail>(dest.bweight,"bweight",db);
|
||||
ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
|
||||
|
||||
db.reader->IncPtr(size);
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ namespace Assimp {
|
|||
#define FAIL // fail the import if the field does not exist
|
||||
|
||||
struct Object;
|
||||
struct MTex;
|
||||
|
||||
#define AI_BLEND_MESH_MAX_VERTS 2000000000L
|
||||
|
||||
|
@ -112,9 +113,9 @@ struct ListBase : ElemBase {
|
|||
|
||||
// -------------------------------------------------------------------------------
|
||||
struct PackedFile : ElemBase {
|
||||
// int size;
|
||||
// int seek;
|
||||
// void* data;
|
||||
int size WARN;
|
||||
int seek WARN;
|
||||
boost::shared_ptr< FileOffset > data WARN;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
@ -144,7 +145,7 @@ struct MVert : ElemBase {
|
|||
float no[3] FAIL;
|
||||
char flag;
|
||||
int mat_nr WARN;
|
||||
int bweight FAIL;
|
||||
int bweight;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
@ -222,7 +223,7 @@ struct Material : ElemBase {
|
|||
short diff_shader WARN;
|
||||
short spec_shader WARN;
|
||||
|
||||
//MTex *mtex[18];
|
||||
boost::shared_ptr<MTex> mtex[18];
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue