Requested modifications
parent
512e6dff4f
commit
a10b0d4de3
|
@ -45,7 +45,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#define M3D_IMPLEMENTATION
|
||||
#define M3D_NOIMPORTER
|
||||
#define M3D_EXPORTER
|
||||
#define M3D_ASCII
|
||||
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
|
||||
#define M3D_NODUP
|
||||
#endif
|
||||
|
@ -65,9 +64,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
|
||||
#include "M3DWrapper.h"
|
||||
#include "M3DExporter.h"
|
||||
#include "M3DMaterials.h"
|
||||
#include "M3DWrapper.h"
|
||||
|
||||
// RESOURCES:
|
||||
// https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md
|
||||
|
@ -131,6 +130,28 @@ void addProp(m3dm_t *m, uint8_t type, uint32_t value) {
|
|||
m->prop[i].value.num = value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// convert aiString to identifier safe C string. This is a duplication of _m3d_safestr
|
||||
char *SafeStr(aiString str, bool isStrict)
|
||||
{
|
||||
char *s = (char *)&str.data;
|
||||
char *d, *ret;
|
||||
int i, len;
|
||||
|
||||
for(len = str.length + 1; *s && (*s == ' ' || *s == '\t'); s++, len--);
|
||||
if(len > 255) len = 255;
|
||||
ret = (char *)M3D_MALLOC(len + 1);
|
||||
if (!ret) {
|
||||
throw DeadlyExportError("memory allocation error");
|
||||
}
|
||||
for(i = 0, d = ret; i < len && *s && *s != '\r' && *s != '\n'; s++, d++, i++) {
|
||||
*d = isStrict && (*s == ' ' || *s == '\t' || *s == '/' || *s == '\\') ? '_' : (*s == '\t' ? ' ' : *s);
|
||||
}
|
||||
for(; d > ret && (*(d-1) == ' ' || *(d-1) == '\t'); d--);
|
||||
*d = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// add a material to the output
|
||||
M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
|
||||
|
@ -157,7 +178,7 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
|
|||
if (!m3d->material) {
|
||||
throw DeadlyExportError("memory allocation error");
|
||||
}
|
||||
m3d->material[mi].name = _m3d_safestr((char *)&name.data, 0);
|
||||
m3d->material[mi].name = SafeStr(name, true);
|
||||
m3d->material[mi].numprop = 0;
|
||||
m3d->material[mi].prop = NULL;
|
||||
// iterate through the material property table and see what we got
|
||||
|
@ -218,7 +239,7 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
|
|||
(name.data[j + 1] == 'g' || name.data[j + 1] == 'G'))
|
||||
name.data[j] = 0;
|
||||
// do we have this texture saved already?
|
||||
fn = _m3d_safestr((char *)&name.data, 0);
|
||||
fn = SafeStr(name, true);
|
||||
for (j = 0, i = M3D_NOTDEFINED; j < m3d->numtexture; j++)
|
||||
if (!strcmp(fn, m3d->texture[j].name)) {
|
||||
i = j;
|
||||
|
@ -275,11 +296,15 @@ void ExportSceneA3D(
|
|||
const ExportProperties *pProperties
|
||||
|
||||
) {
|
||||
#ifdef M3D_ASCII
|
||||
// initialize the exporter
|
||||
M3DExporter exporter(pScene, pProperties);
|
||||
|
||||
// perform ascii export
|
||||
exporter.doExport(pFile, pIOSystem, true);
|
||||
#else
|
||||
throw DeadlyExportError("Assimp configured without M3D_ASCII support");
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -306,7 +331,7 @@ void M3DExporter::doExport(
|
|||
if (!m3d) {
|
||||
throw DeadlyExportError("memory allocation error");
|
||||
}
|
||||
m3d->name = _m3d_safestr((char *)&mScene->mRootNode->mName.data, 2);
|
||||
m3d->name = SafeStr(mScene->mRootNode->mName, false);
|
||||
|
||||
// Create a model from assimp structures
|
||||
aiMatrix4x4 m;
|
||||
|
|
|
@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
|
||||
|
||||
#define M3D_IMPLEMENTATION
|
||||
#define M3D_ASCII
|
||||
#define M3D_NONORMALS /* leave the post-processing to Assimp */
|
||||
#define M3D_NOWEIGHTS
|
||||
#define M3D_NOANIMATION
|
||||
|
@ -57,9 +56,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/Importer.hpp>
|
||||
#include <memory>
|
||||
|
||||
#include "M3DWrapper.h"
|
||||
#include "M3DImporter.h"
|
||||
#include "M3DMaterials.h"
|
||||
#include "M3DWrapper.h"
|
||||
|
||||
// RESOURCES:
|
||||
// https://gitlab.com/bztsrc/model3d/blob/master/docs/m3d_format.md
|
||||
|
@ -96,7 +95,11 @@ static const aiImporterDesc desc = {
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
#ifdef M3D_ASCII
|
||||
"m3d a3d"
|
||||
#else
|
||||
"m3d"
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace Assimp {
|
||||
|
@ -113,7 +116,11 @@ M3DImporter::M3DImporter() :
|
|||
bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
|
||||
const std::string extension = GetExtension(pFile);
|
||||
|
||||
if (extension == "m3d" || extension == "a3d")
|
||||
if (extension == "m3d"
|
||||
#ifdef M3D_ASCII
|
||||
|| extension == "a3d"
|
||||
#endif
|
||||
)
|
||||
return true;
|
||||
else if (!extension.length() || checkSig) {
|
||||
if (!pIOHandler) {
|
||||
|
@ -131,7 +138,11 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
|
|||
if (4 != pStream->Read(data, 1, 4)) {
|
||||
return false;
|
||||
}
|
||||
return !memcmp(data, "3DMO", 4) /* bin */ || !memcmp(data, "3dmo", 4) /* ASCII */;
|
||||
return !memcmp(data, "3DMO", 4) /* bin */
|
||||
#ifdef M3D_ASCII
|
||||
|| !memcmp(data, "3dmo", 4) /* ASCII */
|
||||
#endif
|
||||
;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -163,6 +174,12 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
|
|||
if(!memcmp(buffer.data(), "3DMO", 4) && memcmp(buffer.data() + 4, &fileSize, 4)) {
|
||||
throw DeadlyImportError("Bad binary header in file " + file + ".");
|
||||
}
|
||||
#ifdef M3D_ASCII
|
||||
// make sure there's a terminator zero character, as input must be ASCIIZ
|
||||
if(!memcmp(buffer.data(), "3dmo", 4)) {
|
||||
buffer.push_back(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get the path for external assets
|
||||
std::string folderName("./");
|
||||
|
@ -180,7 +197,6 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
|
|||
// let the C SDK do the hard work for us
|
||||
M3DWrapper m3d(pIOHandler, buffer);
|
||||
|
||||
|
||||
if (!m3d) {
|
||||
throw DeadlyImportError("Unable to parse " + file + " as M3D.");
|
||||
}
|
||||
|
@ -310,32 +326,40 @@ void M3DImporter::importTextures(const M3DWrapper &m3d) {
|
|||
for (i = 0; i < m3d->numtexture; i++) {
|
||||
unsigned int j, k;
|
||||
t = &m3d->texture[i];
|
||||
if (!t->w || !t->h || !t->f || !t->d) continue;
|
||||
aiTexture *tx = new aiTexture;
|
||||
strcpy(tx->achFormatHint, formatHint[t->f - 1]);
|
||||
tx->mFilename = aiString(std::string(t->name) + ".png");
|
||||
tx->mWidth = t->w;
|
||||
tx->mHeight = t->h;
|
||||
tx->pcData = new aiTexel[tx->mWidth * tx->mHeight];
|
||||
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;
|
||||
if (!t->w || !t->h || !t->f || !t->d) {
|
||||
/* without ASSIMP_USE_M3D_READFILECB, we only have the filename, but no texture data ever */
|
||||
tx->mWidth = 0;
|
||||
tx->mHeight = 0;
|
||||
memcpy(tx->achFormatHint, "png\000", 4);
|
||||
tx->pcData = nullptr;
|
||||
} else {
|
||||
/* if we have the texture loaded, set format hint and pcData too */
|
||||
tx->mWidth = t->w;
|
||||
tx->mHeight = t->h;
|
||||
strcpy(tx->achFormatHint, formatHint[t->f - 1]);
|
||||
tx->pcData = new aiTexel[tx->mWidth * tx->mHeight];
|
||||
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;
|
||||
|
|
|
@ -48,15 +48,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/IOStreamBuffer.h>
|
||||
#include <assimp/ai_assert.h>
|
||||
|
||||
#if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
|
||||
# define threadlocal thread_local
|
||||
#else
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
|
||||
# define threadlocal __declspec(thread)
|
||||
#ifdef ASSIMP_USE_M3D_READFILECB
|
||||
|
||||
# if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
|
||||
# define threadlocal thread_local
|
||||
# else
|
||||
# define threadlocal
|
||||
# if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
|
||||
# define threadlocal __declspec(thread)
|
||||
# else
|
||||
# define threadlocal
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
@ -89,6 +91,7 @@ unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
|
|||
return data;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace Assimp {
|
||||
M3DWrapper::M3DWrapper() {
|
||||
|
@ -97,11 +100,15 @@ M3DWrapper::M3DWrapper() {
|
|||
}
|
||||
|
||||
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
|
||||
#ifdef ASSIMP_USE_M3D_READFILECB
|
||||
// pass this IOHandler to the C callback in a thread-local pointer
|
||||
m3dimporter_pIOHandler = pIOHandler;
|
||||
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
|
||||
// Clear the C callback
|
||||
m3dimporter_pIOHandler = nullptr;
|
||||
#else
|
||||
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
M3DWrapper::~M3DWrapper() {
|
||||
|
|
|
@ -52,6 +52,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
// Assimp specific M3D configuration. Comment out these defines to remove functionality
|
||||
#define ASSIMP_USE_M3D_READFILECB
|
||||
#define M3D_ASCII
|
||||
|
||||
#include "m3d.h"
|
||||
|
||||
namespace Assimp {
|
||||
|
|
|
@ -91,11 +91,7 @@ typedef uint16_t M3D_INDEX;
|
|||
#else
|
||||
#define _inline
|
||||
#define _pack
|
||||
# ifdef __cplusplus /* only for c++ code */
|
||||
# define _unused __pragma(warning(suppress:4100))
|
||||
# else
|
||||
# define _unused (void)
|
||||
# endif
|
||||
#define _unused __pragma(warning(suppress:4100))
|
||||
#endif
|
||||
#ifndef __cplusplus
|
||||
#define _register register
|
||||
|
@ -2064,7 +2060,7 @@ static char *_m3d_getfloat(char *s, M3D_FLOAT *ret)
|
|||
return _m3d_findarg(e);
|
||||
}
|
||||
#endif
|
||||
#if !defined(M3D_NODUP) && (defined(M3D_ASCII) || defined(M3D_EXPORTER))
|
||||
#if !defined(M3D_NODUP) && (!defined(M3D_NOIMPORTER) || defined(M3D_ASCII) || defined(M3D_EXPORTER))
|
||||
/* helper function to create safe strings */
|
||||
char *_m3d_safestr(char *in, int morelines)
|
||||
{
|
||||
|
@ -2139,45 +2135,48 @@ M3D_INDEX _m3d_gettx(m3d_t *model, m3dread_t readfilecb, m3dfree_t freecb, char
|
|||
buff = (*readfilecb)(fn2, &len);
|
||||
M3D_FREE(fn2);
|
||||
}
|
||||
if(!buff)
|
||||
if(!buff) {
|
||||
buff = (*readfilecb)(fn, &len);
|
||||
if(!buff) return M3D_UNDEF;
|
||||
}
|
||||
}
|
||||
if(!buff) return M3D_UNDEF;
|
||||
/* add to textures array */
|
||||
i = model->numtexture++;
|
||||
model->texture = (m3dtx_t*)M3D_REALLOC(model->texture, model->numtexture * sizeof(m3dtx_t));
|
||||
if(!model->texture) {
|
||||
if(freecb) (*freecb)(buff);
|
||||
if(buff && freecb) (*freecb)(buff);
|
||||
model->errcode = M3D_ERR_ALLOC;
|
||||
return M3D_UNDEF;
|
||||
}
|
||||
model->texture[i].name = fn;
|
||||
model->texture[i].w = model->texture[i].h = 0; model->texture[i].d = NULL;
|
||||
if(buff[0] == 0x89 && buff[1] == 'P' && buff[2] == 'N' && buff[3] == 'G') {
|
||||
if(buff) {
|
||||
if(buff[0] == 0x89 && buff[1] == 'P' && buff[2] == 'N' && buff[3] == 'G') {
|
||||
#ifdef STBI__PNG_TYPE
|
||||
s.read_from_callbacks = 0;
|
||||
s.img_buffer = s.img_buffer_original = (unsigned char *) buff;
|
||||
s.img_buffer_end = s.img_buffer_original_end = (unsigned char *) buff+len;
|
||||
/* don't use model->texture[i].w directly, it's a uint16_t */
|
||||
w = h = len = 0;
|
||||
ri.bits_per_channel = 8;
|
||||
model->texture[i].d = (uint8_t*)stbi__png_load(&s, (int*)&w, (int*)&h, (int*)&len, 0, &ri);
|
||||
model->texture[i].w = w;
|
||||
model->texture[i].h = h;
|
||||
model->texture[i].f = (uint8_t)len;
|
||||
s.read_from_callbacks = 0;
|
||||
s.img_buffer = s.img_buffer_original = (unsigned char *) buff;
|
||||
s.img_buffer_end = s.img_buffer_original_end = (unsigned char *) buff+len;
|
||||
/* don't use model->texture[i].w directly, it's a uint16_t */
|
||||
w = h = len = 0;
|
||||
ri.bits_per_channel = 8;
|
||||
model->texture[i].d = (uint8_t*)stbi__png_load(&s, (int*)&w, (int*)&h, (int*)&len, 0, &ri);
|
||||
model->texture[i].w = w;
|
||||
model->texture[i].h = h;
|
||||
model->texture[i].f = (uint8_t)len;
|
||||
#endif
|
||||
} else {
|
||||
} else {
|
||||
#ifdef M3D_TX_INTERP
|
||||
if((model->errcode = M3D_TX_INTERP(fn, buff, len, &model->texture[i])) != M3D_SUCCESS) {
|
||||
M3D_LOG("Unable to generate texture");
|
||||
M3D_LOG(fn);
|
||||
}
|
||||
if((model->errcode = M3D_TX_INTERP(fn, buff, len, &model->texture[i])) != M3D_SUCCESS) {
|
||||
M3D_LOG("Unable to generate texture");
|
||||
M3D_LOG(fn);
|
||||
}
|
||||
#else
|
||||
M3D_LOG("Unimplemented interpreter");
|
||||
M3D_LOG(fn);
|
||||
M3D_LOG("Unimplemented interpreter");
|
||||
M3D_LOG(fn);
|
||||
#endif
|
||||
}
|
||||
if(freecb) (*freecb)(buff);
|
||||
}
|
||||
if(freecb) (*freecb)(buff);
|
||||
if(!model->texture[i].d)
|
||||
model->errcode = M3D_ERR_UNKIMG;
|
||||
return i;
|
||||
|
@ -2589,6 +2588,7 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d
|
|||
if(!pe || !*pe) goto asciiend;
|
||||
m->prop[j].value.textureid = _m3d_gettx(model, readfilecb, freecb, pe);
|
||||
if(model->errcode == M3D_ERR_ALLOC) { M3D_FREE(pe); goto memerr; }
|
||||
/* this error code only returned if readfilecb was specified */
|
||||
if(m->prop[j].value.textureid == M3D_UNDEF) {
|
||||
M3D_LOG("Texture not found");
|
||||
M3D_LOG(pe);
|
||||
|
@ -3254,6 +3254,7 @@ memerr: M3D_LOG("Out of memory");
|
|||
M3D_GETSTR(name);
|
||||
m->prop[i].value.textureid = _m3d_gettx(model, readfilecb, freecb, name);
|
||||
if(model->errcode == M3D_ERR_ALLOC) goto memerr;
|
||||
/* this error code only returned if readfilecb was specified */
|
||||
if(m->prop[i].value.textureid == M3D_UNDEF) {
|
||||
M3D_LOG("Texture not found");
|
||||
M3D_LOG(m->name);
|
||||
|
|
Loading…
Reference in New Issue