Browse Source

Upgraded to newest SDK and improved texture import

bzt 5 years ago
parent
commit
41ae01a6b2
6 changed files with 555 additions and 149 deletions
  1. 31 6
      code/M3D/M3DExporter.cpp
  2. 2 0
      code/M3D/M3DExporter.h
  3. 44 20
      code/M3D/M3DImporter.cpp
  4. 2 2
      code/M3D/M3DMaterials.h
  5. 475 120
      code/M3D/m3d.h
  6. 1 1
      test/unit/utM3DImportExport.cpp

+ 31 - 6
code/M3D/M3DExporter.cpp

@@ -169,6 +169,33 @@ void M3DExporter::doExport (
     outfile.reset();
     outfile.reset();
 }
 }
 
 
+
+// ------------------------------------------------------------------------------------------------
+// helper to add a vertex (private to NodeWalk)
+m3dv_t *M3DExporter::AddVrtx(m3dv_t *vrtx, uint32_t *numvrtx, m3dv_t *v, uint32_t *idx)
+{
+    if(v->x == (M3D_FLOAT)-0.0) v->x = (M3D_FLOAT)0.0;
+    if(v->y == (M3D_FLOAT)-0.0) v->y = (M3D_FLOAT)0.0;
+    if(v->z == (M3D_FLOAT)-0.0) v->z = (M3D_FLOAT)0.0;
+    if(v->w == (M3D_FLOAT)-0.0) v->w = (M3D_FLOAT)0.0;
+    vrtx = (m3dv_t*)M3D_REALLOC(vrtx, ((*numvrtx) + 1) * sizeof(m3dv_t));
+    memcpy(&vrtx[*numvrtx], v, sizeof(m3dv_t));
+    *idx = *numvrtx;
+    (*numvrtx)++;
+    return vrtx;
+}
+
+// ------------------------------------------------------------------------------------------------
+// helper to add a tmap (private to NodeWalk)
+m3dti_t *M3DExporter::AddTmap(m3dti_t *tmap, uint32_t *numtmap, m3dti_t *ti, uint32_t *idx)
+{
+    tmap = (m3dti_t*)M3D_REALLOC(tmap, ((*numtmap) + 1) * sizeof(m3dti_t));
+    memcpy(&tmap[*numtmap], ti, sizeof(m3dti_t));
+    *idx = *numtmap;
+    (*numtmap)++;
+    return tmap;
+}
+
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // recursive node walker
 // recursive node walker
 void M3DExporter::NodeWalk(const aiNode* pNode, aiMatrix4x4 m)
 void M3DExporter::NodeWalk(const aiNode* pNode, aiMatrix4x4 m)
@@ -221,25 +248,23 @@ void M3DExporter::NodeWalk(const aiNode* pNode, aiMatrix4x4 m)
                 if(mesh->HasVertexColors(0))
                 if(mesh->HasVertexColors(0))
                     vertex.color = mkColor(&mesh->mColors[0][l]);
                     vertex.color = mkColor(&mesh->mColors[0][l]);
                 // save the vertex to the output
                 // save the vertex to the output
-                m3d->vertex = _m3d_addvrtx(m3d->vertex, &m3d->numvertex,
+                m3d->vertex = AddVrtx(m3d->vertex, &m3d->numvertex,
                     &vertex, &idx);
                     &vertex, &idx);
                 m3d->face[n].vertex[k] = (M3D_INDEX)idx;
                 m3d->face[n].vertex[k] = (M3D_INDEX)idx;
                 // do we have texture coordinates?
                 // do we have texture coordinates?
                 if(mesh->HasTextureCoords(0)) {
                 if(mesh->HasTextureCoords(0)) {
                     ti.u = mesh->mTextureCoords[0][l].x;
                     ti.u = mesh->mTextureCoords[0][l].x;
                     ti.v = mesh->mTextureCoords[0][l].y;
                     ti.v = mesh->mTextureCoords[0][l].y;
-                    m3d->tmap = _m3d_addtmap(m3d->tmap, &m3d->numtmap, &ti,
-                        &idx);
+                    m3d->tmap = AddTmap(m3d->tmap, &m3d->numtmap, &ti, &idx);
                     m3d->face[n].texcoord[k] = (M3D_INDEX)idx;
                     m3d->face[n].texcoord[k] = (M3D_INDEX)idx;
                 }
                 }
                 // do we have normal vectors?
                 // do we have normal vectors?
                 if(mesh->HasNormals()) {
                 if(mesh->HasNormals()) {
-                    vertex.color = 0;
                     vertex.x = mesh->mNormals[l].x;
                     vertex.x = mesh->mNormals[l].x;
                     vertex.y = mesh->mNormals[l].y;
                     vertex.y = mesh->mNormals[l].y;
                     vertex.z = mesh->mNormals[l].z;
                     vertex.z = mesh->mNormals[l].z;
-                    m3d->vertex = _m3d_addnorm(m3d->vertex, &m3d->numvertex,
-                        &vertex, &idx);
+                    vertex.color = 0;
+                    m3d->vertex = AddVrtx(m3d->vertex, &m3d->numvertex, &vertex, &idx);
                     m3d->face[n].normal[k] = (M3D_INDEX)idx;
                     m3d->face[n].normal[k] = (M3D_INDEX)idx;
                 }
                 }
             }
             }

+ 2 - 0
code/M3D/M3DExporter.h

@@ -87,6 +87,8 @@ namespace Assimp
 
 
         // helper to do the recursive walking
         // helper to do the recursive walking
         void NodeWalk(const aiNode* pNode, aiMatrix4x4 m);
         void NodeWalk(const aiNode* pNode, aiMatrix4x4 m);
+        m3dv_t *AddVrtx(m3dv_t *vrtx, uint32_t *numvrtx, m3dv_t *v, uint32_t *idx);
+        m3dti_t *AddTmap(m3dti_t *tmap, uint32_t *numtmap, m3dti_t *ti, uint32_t *idx);
         uint32_t mkColor(aiColor4D* c);
         uint32_t mkColor(aiColor4D* c);
         M3D_INDEX addMaterial(const aiMaterial *mat);
         M3D_INDEX addMaterial(const aiMaterial *mat);
         void addProp(m3dm_t *m, uint8_t type, uint32_t value);
         void addProp(m3dm_t *m, uint8_t type, uint32_t value);

+ 44 - 20
code/M3D/M3DImporter.cpp

@@ -44,6 +44,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #define M3D_IMPLEMENTATION
 #define M3D_IMPLEMENTATION
 #define M3D_ASCII
 #define M3D_ASCII
+#define M3D_NONORMALS       /* leave the post-processing to Assimp */
+#define M3D_NOWEIGHTS
+#define M3D_NOANIMATION
 
 
 #include <assimp/IOStreamBuffer.h>
 #include <assimp/IOStreamBuffer.h>
 #include <memory>
 #include <memory>
@@ -104,16 +107,21 @@ extern "C" {
         std::string file(fn);
         std::string file(fn);
         std::unique_ptr<Assimp::IOStream> pStream(
         std::unique_ptr<Assimp::IOStream> pStream(
             (reinterpret_cast<Assimp::IOSystem*>(m3dimporter_pIOHandler))->Open( file, "rb"));
             (reinterpret_cast<Assimp::IOSystem*>(m3dimporter_pIOHandler))->Open( file, "rb"));
-        size_t fileSize = pStream->FileSize();
-        // should be allocated with malloc(), because the library will call free() to deallocate
-        unsigned char *data = (unsigned char*)malloc(fileSize);
-        if( !data || !pStream.get() || !fileSize || fileSize != pStream->Read(data,1,fileSize)) {
+        size_t fileSize = 0;
+        unsigned char *data = NULL;
+        // sometimes pStream is nullptr for some reason (should be an empty object returning nothing I guess)
+        if(pStream) {
+            fileSize = pStream->FileSize();
+            // should be allocated with malloc(), because the library will call free() to deallocate
+            data = (unsigned char*)malloc(fileSize);
+            if( !data || !pStream.get() || !fileSize || fileSize != pStream->Read(data,1,fileSize)) {
+                pStream.reset();
+                *size = 0;
+                // don't throw a deadly exception, it's not fatal if we can't read an external asset
+                return nullptr;
+            }
             pStream.reset();
             pStream.reset();
-            *size = 0;
-            // don't throw a deadly exception, it's not fatal if we can't read an external asset
-            return nullptr;
         }
         }
-        pStream.reset();
         *size = (int)fileSize;
         *size = (int)fileSize;
         return data;
         return data;
     }
     }
@@ -307,7 +315,7 @@ void M3DImporter::importMaterials()
                 m->prop[j].value.textureid < m3d->numtexture &&
                 m->prop[j].value.textureid < m3d->numtexture &&
                 m3d->texture[m->prop[j].value.textureid].name) {
                 m3d->texture[m->prop[j].value.textureid].name) {
                     name.Set(std::string(std::string(m3d->texture[m->prop[j].value.textureid].name) + ".png"));
                     name.Set(std::string(std::string(m3d->texture[m->prop[j].value.textureid].name) + ".png"));
-                    mat->AddProperty(&name, aiProps[k].pKey, aiProps[k].type, aiProps[k].index);
+                    mat->AddProperty(&name, aiTxProps[k].pKey, aiTxProps[k].type, aiTxProps[k].index);
                     n = 0;
                     n = 0;
                     mat->AddProperty(&n, 1, _AI_MATKEY_UVWSRC_BASE, aiProps[k].type, aiProps[k].index);
                     mat->AddProperty(&n, 1, _AI_MATKEY_UVWSRC_BASE, aiProps[k].type, aiProps[k].index);
             }
             }
@@ -321,6 +329,7 @@ void M3DImporter::importMaterials()
 void M3DImporter::importTextures()
 void M3DImporter::importTextures()
 {
 {
     unsigned int i;
     unsigned int i;
+    const char *formatHint[] = { "rgba0800", "rgba0808", "rgba8880", "rgba8888" };
     m3dtx_t *t;
     m3dtx_t *t;
 
 
     ai_assert(mScene != nullptr);
     ai_assert(mScene != nullptr);
@@ -334,14 +343,29 @@ void M3DImporter::importTextures()
 
 
     mScene->mTextures = new aiTexture*[m3d->numtexture];
     mScene->mTextures = new aiTexture*[m3d->numtexture];
     for(i = 0; i < m3d->numtexture; i++) {
     for(i = 0; i < m3d->numtexture; i++) {
+        unsigned int j, k;
         t = &m3d->texture[i];
         t = &m3d->texture[i];
+        if(!t->w || !t->h || !t->f || !t->d) continue;
         aiTexture *tx = new aiTexture;
         aiTexture *tx = new aiTexture;
-        strcpy(tx->achFormatHint, "rgba8888");
+        strcpy(tx->achFormatHint, formatHint[t->f - 1]);
         tx->mFilename = aiString(std::string(t->name) + ".png");
         tx->mFilename = aiString(std::string(t->name) + ".png");
         tx->mWidth = t->w;
         tx->mWidth = t->w;
         tx->mHeight = t->h;
         tx->mHeight = t->h;
         tx->pcData = new aiTexel[ tx->mWidth*tx->mHeight ];
         tx->pcData = new aiTexel[ tx->mWidth*tx->mHeight ];
-        memcpy(tx->pcData, t->d, tx->mWidth*tx->mHeight*4);
+        for(j = k = 0; j < tx->mWidth*tx->mHeight; j++) {
+            switch(t->f) {
+                case 1: tx->pcData[j].g = t->d[k++]; break;
+                case 2: tx->pcData[j].g = t->d[k++]; tx->pcData[j].a = t->d[k++]; break;
+                case 3:
+                    tx->pcData[j].r = t->d[k++]; tx->pcData[j].g = t->d[k++];
+                    tx->pcData[j].b = t->d[k++]; tx->pcData[j].a = 255;
+                break;
+                case 4:
+                    tx->pcData[j].r = t->d[k++]; tx->pcData[j].g = t->d[k++];
+                    tx->pcData[j].b = t->d[k++]; tx->pcData[j].a = t->d[k++];
+                break;
+            }
+        }
         mScene->mTextures[i] = tx;
         mScene->mTextures[i] = tx;
     }
     }
 }
 }
@@ -574,15 +598,15 @@ void M3DImporter::convertPose(aiMatrix4x4 *m, unsigned int posid, unsigned int o
         m->a2 = m->a3 = m->b1 = m->b3 = m->c1 = m->c2 = 0.0;
         m->a2 = m->a3 = m->b1 = m->b3 = m->c1 = m->c2 = 0.0;
         m->a1 = m->b2 = m->c3 = -1.0;
         m->a1 = m->b2 = m->c3 = -1.0;
     } else {
     } else {
-        m->a1 = 1 - 2 * (q->y * q->y + q->z * q->z); if(m->a1 > -1e-7 && m->a1 < 1e-7) m->a1 = 0.0;
-        m->a2 = 2 * (q->x * q->y - q->z * q->w);     if(m->a2 > -1e-7 && m->a2 < 1e-7) m->a2 = 0.0;
-        m->a3 = 2 * (q->x * q->z + q->y * q->w);     if(m->a3 > -1e-7 && m->a3 < 1e-7) m->a3 = 0.0;
-        m->b1 = 2 * (q->x * q->y + q->z * q->w);     if(m->b1 > -1e-7 && m->b1 < 1e-7) m->b1 = 0.0;
-        m->b2 = 1 - 2 * (q->x * q->x + q->z * q->z); if(m->b2 > -1e-7 && m->b2 < 1e-7) m->b2 = 0.0;
-        m->b3 = 2 * (q->y * q->z - q->x * q->w);     if(m->b3 > -1e-7 && m->b3 < 1e-7) m->b3 = 0.0;
-        m->c1 = 2 * (q->x * q->z - q->y * q->w);     if(m->c1 > -1e-7 && m->c1 < 1e-7) m->c1 = 0.0;
-        m->c2 = 2 * (q->y * q->z + q->x * q->w);     if(m->c2 > -1e-7 && m->c2 < 1e-7) m->c2 = 0.0;
-        m->c3 = 1 - 2 * (q->x * q->x + q->y * q->y); if(m->c3 > -1e-7 && m->c3 < 1e-7) m->c3 = 0.0;
+        m->a1 = 1 - 2 * (q->y * q->y + q->z * q->z); if(m->a1 > -M3D_EPSILON && m->a1 < M3D_EPSILON) m->a1 = 0.0;
+        m->a2 = 2 * (q->x * q->y - q->z * q->w);     if(m->a2 > -M3D_EPSILON && m->a2 < M3D_EPSILON) m->a2 = 0.0;
+        m->a3 = 2 * (q->x * q->z + q->y * q->w);     if(m->a3 > -M3D_EPSILON && m->a3 < M3D_EPSILON) m->a3 = 0.0;
+        m->b1 = 2 * (q->x * q->y + q->z * q->w);     if(m->b1 > -M3D_EPSILON && m->b1 < M3D_EPSILON) m->b1 = 0.0;
+        m->b2 = 1 - 2 * (q->x * q->x + q->z * q->z); if(m->b2 > -M3D_EPSILON && m->b2 < M3D_EPSILON) m->b2 = 0.0;
+        m->b3 = 2 * (q->y * q->z - q->x * q->w);     if(m->b3 > -M3D_EPSILON && m->b3 < M3D_EPSILON) m->b3 = 0.0;
+        m->c1 = 2 * (q->x * q->z - q->y * q->w);     if(m->c1 > -M3D_EPSILON && m->c1 < M3D_EPSILON) m->c1 = 0.0;
+        m->c2 = 2 * (q->y * q->z + q->x * q->w);     if(m->c2 > -M3D_EPSILON && m->c2 < M3D_EPSILON) m->c2 = 0.0;
+        m->c3 = 1 - 2 * (q->x * q->x + q->y * q->y); if(m->c3 > -M3D_EPSILON && m->c3 < M3D_EPSILON) m->c3 = 0.0;
     }
     }
 
 
     /* set translation */
     /* set translation */

+ 2 - 2
code/M3D/M3DMaterials.h

@@ -75,7 +75,7 @@ static const aiMatProp aiProps[] = {
     { AI_MATKEY_REFLECTIVITY },                                 /* m3dp_Pm */
     { AI_MATKEY_REFLECTIVITY },                                 /* m3dp_Pm */
     { NULL, 0, 0 },                                             /* m3dp_Ps */
     { NULL, 0, 0 },                                             /* m3dp_Ps */
     { AI_MATKEY_REFRACTI },                                     /* m3dp_Ni */
     { AI_MATKEY_REFRACTI },                                     /* m3dp_Ni */
-    { NULL, 0, 0 },
+    { NULL, 0, 0 },                                             /* m3dp_Nt */
     { NULL, 0, 0 },
     { NULL, 0, 0 },
     { NULL, 0, 0 },
     { NULL, 0, 0 },
     { NULL, 0, 0 }
     { NULL, 0, 0 }
@@ -97,7 +97,7 @@ static const aiMatProp aiTxProps[] = {
     { AI_MATKEY_TEXTURE(aiTextureType_METALNESS,0) },        /* m3dp_map_Pm */
     { AI_MATKEY_TEXTURE(aiTextureType_METALNESS,0) },        /* m3dp_map_Pm */
     { NULL, 0, 0 },                                          /* m3dp_map_Ps */
     { NULL, 0, 0 },                                          /* m3dp_map_Ps */
     { AI_MATKEY_TEXTURE(aiTextureType_AMBIENT_OCCLUSION,0) },/* m3dp_map_Ni */
     { AI_MATKEY_TEXTURE(aiTextureType_AMBIENT_OCCLUSION,0) },/* m3dp_map_Ni */
-    { NULL, 0, 0 },
+    { NULL, 0, 0 },                                          /* m3dp_map_Nt */
     { NULL, 0, 0 },
     { NULL, 0, 0 },
     { NULL, 0, 0 },
     { NULL, 0, 0 },
     { NULL, 0, 0 }
     { NULL, 0, 0 }

File diff suppressed because it is too large
+ 475 - 120
code/M3D/m3d.h


+ 1 - 1
test/unit/utM3DImportExport.cpp

@@ -54,7 +54,7 @@ class utM3DImportExport : public AbstractImportExportBase {
 public:
 public:
     virtual bool importerTest() {
     virtual bool importerTest() {
         Assimp::Importer importer;
         Assimp::Importer importer;
-        const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/M3D/WusonBlitz0.m3d", aiProcess_ValidateDataStructure );
+        const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/M3D/cube_usemtl.m3d", aiProcess_ValidateDataStructure );
 #ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
 #ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
         return nullptr != scene;
         return nullptr != scene;
 #else
 #else

Some files were not shown because too many files changed in this diff