summaryrefslogtreecommitdiff
path: root/opengl/generate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'opengl/generate.cpp')
-rw-r--r--opengl/generate.cpp392
1 files changed, 392 insertions, 0 deletions
diff --git a/opengl/generate.cpp b/opengl/generate.cpp
new file mode 100644
index 0000000..cdce010
--- /dev/null
+++ b/opengl/generate.cpp
@@ -0,0 +1,392 @@
+// Generate.cpp: implementation of the Generate class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include <sstream>
+#include <algorithm>
+#include <cctype>
+#include <cstdio>
+#include <w32dlib/w32dlib.h>
+#include "generate.h"
+#include "msLib.h"
+
+#define INDENT " "
+#define EOL "\r\n"
+
+#define FLT_MAX 10e35
+#define FLT_MIN -10e35
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+Generate::Generate(msModel *model) : m_model(model),
+
+ m_cogx(0),
+ m_cogy(0),
+ m_cogz(0),
+
+ m_appcogx(0),
+ m_appcogy(0),
+ m_appcogz(0),
+
+ m_max_x(FLT_MIN),
+ m_min_x(FLT_MAX),
+ m_max_y(FLT_MIN),
+ m_min_y(FLT_MAX),
+ m_max_z(FLT_MIN),
+ m_min_z(FLT_MAX)
+{
+ CalcModelBounds();
+}
+
+Generate::~Generate()
+{
+}
+
+//////////////////////////////////////////////////////////////////////
+// Public members
+//////////////////////////////////////////////////////////////////////
+
+std::string Generate::Info()
+{
+ std::ostringstream str;
+
+ str << "Create files : " << EOL
+ << "\t" << m_dir << "\\" << m_funcName << ".c" << EOL
+ << "\t" << m_dir << "\\" << m_funcName << ".h" << EOL << EOL
+ << "Centre of gravity : "
+ << (m_cogx-m_appcogx) << ","
+ << (m_cogy-m_appcogy) << ","
+ << (m_cogz-m_appcogz) << EOL
+ << "Lowest X co-ord : " << m_min_x-m_appcogx << EOL
+ << "Highest X co-ord : " << m_max_x-m_appcogx << EOL
+ << "Lowest Y co-ord : " << m_min_y-m_appcogx << EOL
+ << "Highest Y co-ord : " << m_max_y-m_appcogx << EOL
+ << "Lowest Z co-ord : " << m_min_z-m_appcogx << EOL
+ << "Highest Z co-ord : " << m_max_z-m_appcogx << EOL;
+
+ return str.str();
+}
+
+void Generate::MakeFiles()
+{
+ std::FILE *fp;
+ int len;
+ std::string fname_c;
+ std::string fname_h;
+ std::string def;
+ std::string missing;
+
+ len=m_funcName.length()+6;
+
+ fname_c=m_dir+"\\"+m_funcName;
+ fname_h=fname_c+".h";
+ fname_c+=".c";
+
+ for(std::string::const_iterator i=m_funcName.begin();
+ i!=m_funcName.end();++i)
+ {
+ def+=std::toupper(*i);
+ }
+
+ // Generate header
+ //
+ if (!(fp=fopen(fname_h.c_str(),"w")))
+ {
+ W32DLib::Common::Error(0,"Couldn't create header file");
+ return;
+ }
+
+ std::fprintf(fp,"%s","/* Code generated with Milkshape "
+ "Export OpenGL plugin\n*/\n");
+ std::fprintf(fp,"\n");
+
+ std::fprintf(fp,"#ifndef %s_H\n#define %s_H\n\n",
+ def.c_str(),def.c_str());
+
+ std::fprintf(fp,"%s","#ifdef _cplusplus\nextern \"C\" {\n#endif\n\n");
+
+
+ std::fprintf(fp,"void %s(GLfloat x, GLfloat y, GLfloat z,\n",
+ m_funcName.c_str());
+ std::fprintf(fp,"%sGLfloat rot_x, GLfloat rot_y, GLfloat rot_z",
+ Space(len));
+
+ if (m_useTexture)
+ {
+ std::fprintf(fp,",\n%sGLint tid);\n\n", Space(len));
+ }
+ else
+ {
+ std::fprintf(fp,");\n\n");
+ }
+
+ if (m_useInfo)
+ {
+ std::fprintf(fp,"#define %s_COG_X %f\n",def.c_str(),m_cogx-m_appcogx);
+ std::fprintf(fp,"#define %s_COG_Y %f\n",def.c_str(),m_cogy-m_appcogy);
+ std::fprintf(fp,"#define %s_COG_Z %f\n\n",def.c_str(),m_cogz-m_appcogz);
+
+ std::fprintf(fp,"#define %s_MIN_X %f\n",def.c_str(),m_min_x-m_appcogx);
+ std::fprintf(fp,"#define %s_MAX_X %f\n",def.c_str(),m_max_x-m_appcogx);
+ std::fprintf(fp,"#define %s_MIN_Y %f\n",def.c_str(),m_min_y-m_appcogy);
+ std::fprintf(fp,"#define %s_MAX_Y %f\n",def.c_str(),m_max_y-m_appcogy);
+ std::fprintf(fp,"#define %s_MIN_Z %f\n",def.c_str(),m_min_z-m_appcogz);
+ std::fprintf(fp,"#define %s_MAX_Z %f\n\n",def.c_str(),
+ m_max_z-m_appcogz);
+
+ float sx=m_max_x-m_min_x;
+ float sy=m_max_y-m_min_y;
+ float sz=m_max_z-m_min_z;
+
+ std::fprintf(fp,"#define %s_SIZE_X %f\n",def.c_str(),sx);
+ std::fprintf(fp,"#define %s_SIZE_Y %f\n",def.c_str(),sy);
+ std::fprintf(fp,"#define %s_SIZE_Z %f\n\n",def.c_str(),sz);
+ }
+
+ std::fprintf(fp,"#define %s_TEXTURED %d\n\n",def.c_str(),m_useTexture?1:0);
+
+ std::fprintf(fp,"%s","#ifdef _cplusplus\n}\n#endif\n\n");
+
+ std::fprintf(fp,"#endif /* %s_H */\n\n",def.c_str());
+
+ std::fprintf(fp,"%s","/* END OF FILE */\n");
+
+ std::fclose(fp);
+
+ // Generate C source
+ //
+ if (!(fp=fopen(fname_c.c_str(),"w")))
+ {
+ W32DLib::Common::Error(0,"Couldn't create source file");
+ return;
+ }
+
+ std::fprintf(fp,"%s","/* Code generated with Milkshape "
+ "Export OpenGL plugin\n*/\n");
+
+ std::fprintf(fp,"%s","#include <GL/gl.h>\n\n");
+
+ std::fprintf(fp,"void %s(GLfloat x, GLfloat y, GLfloat z,\n",
+ m_funcName.c_str());
+ std::fprintf(fp,"%sGLfloat rot_x, GLfloat rot_y, GLfloat rot_z",
+ Space(len));
+
+ if (m_useTexture)
+ {
+ std::fprintf(fp,",\n%sGLint tid)\n", Space(len));
+ }
+ else
+ {
+ std::fprintf(fp,")\n");
+ }
+
+ std::fprintf(fp,"{\n");
+
+ std::fprintf(fp,INDENT "glPushMatrix();\n");
+ std::fprintf(fp,INDENT "glLoadIdentity();\n");
+ std::fprintf(fp,INDENT "glTranslatef(x,y,z);\n");
+ std::fprintf(fp,INDENT "glRotatef(rot_x,1.0f,0.0f,0.0f);\n"),
+ std::fprintf(fp,INDENT "glRotatef(rot_y,0.0f,1.0f,0.0f);\n"),
+ std::fprintf(fp,INDENT "glRotatef(rot_z,0.0f,0.0f,1.0f);\n"),
+ std::fprintf(fp,"\n");
+
+ std::fprintf(fp,INDENT "glBegin(GL_TRIANGLES);\n");
+
+ if (m_useTexture)
+ {
+ std::fprintf(fp,INDENT "glBindTexture(GL_TEXTURE_2D,tid);\n");
+ }
+
+ std::fprintf(fp,"\n");
+
+ for(int m=0;m<m_model->nNumMeshes;m++)
+ {
+ msMesh *mesh=m_model->pMeshes+m;
+
+ std::fprintf(fp,INDENT "/* Mesh %d - %s\n",m+1,mesh->szName);
+ std::fprintf(fp,INDENT "*/\n");
+
+ if (mesh->nMaterialIndex<0)
+ {
+ missing+=mesh->szName;
+ missing+="\n";
+
+ std::fprintf(fp,INDENT "glColor3f(1.0f,1.0f,1.0f);\n");
+ }
+ else
+ {
+ msMaterial *mat=m_model->pMaterials+mesh->nMaterialIndex;
+
+ std::fprintf(fp,INDENT "glColor3f(%f,%f,%f);\n",
+ mat->Diffuse[0],
+ mat->Diffuse[1],
+ mat->Diffuse[2]);
+ }
+
+ for(int t=0;t<mesh->nNumTriangles;t++)
+ {
+ msTriangle *tri;
+
+ tri=mesh->pTriangles+t;
+
+ if (!(tri->nFlags&eHidden))
+ {
+ // To allow vertex order to be tweaked...
+ //
+ static int order[3]={0,1,2};
+
+ for(int i=0;i<3;i++)
+ {
+ msVertex *v=mesh->pVertices+tri->nVertexIndices[order[i]];
+
+ std::fprintf(fp,INDENT "glVertex3f(%f,%f,%f);\n",
+ v->Vertex[0]-m_appcogx,
+ v->Vertex[1]-m_appcogy,
+ v->Vertex[2]-m_appcogz);
+
+ if (m_useTexture)
+ {
+ std::fprintf(fp,INDENT "glTexCoord2f(%f,%f);\n",
+ v->u,
+ v->v);
+ }
+ }
+ }
+ }
+
+ std::fprintf(fp,"\n");
+ }
+
+ std::fprintf(fp,INDENT "glEnd();\n");
+ std::fprintf(fp,INDENT "glPopMatrix();\n");
+
+ std::fprintf(fp,"}\n");
+
+ std::fclose(fp);
+
+ if (missing.length()>0)
+ {
+ missing="The following meshes had no material:\n\n"+missing;
+ missing+="\n\nThey were given the colour white.";
+
+ W32DLib::Common::Message(0,missing);
+ }
+}
+
+
+void Generate::Setup(const std::string& dir,
+ const std::string& funcname,
+ bool texture,
+ bool info,
+ bool forceCOG)
+{
+ m_dir=dir;
+ m_funcName=funcname;
+ m_useTexture=texture;
+ m_useInfo=info;
+ m_forceCOG=forceCOG;
+
+ if (m_forceCOG)
+ {
+ m_appcogx=m_cogx;
+ m_appcogy=m_cogy;
+ m_appcogz=m_cogz;
+ }
+ else
+ {
+ m_appcogx=0;
+ m_appcogy=0;
+ m_appcogz=0;
+ }
+}
+
+
+std::string Generate::GenerateFuncname()
+{
+ std::string fn;
+ char *name;
+
+ msMesh *mesh=msModel_GetMeshAt(m_model,0);
+
+ name=mesh->szName;
+
+ for(int f=0;name[f];f++)
+ {
+ if (std::isalpha(name[f]) || (f && name[f]=='_'))
+ {
+ fn+=name[f];
+ }
+ }
+
+ if (fn=="")
+ {
+ fn="object";
+ }
+
+ return fn;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Private members
+//////////////////////////////////////////////////////////////////////
+
+const char *Generate::Space(int len)
+{
+ static int cyc=0;
+ static char buff[10][128];
+ int f;
+
+ cyc=(cyc+1)%10;
+
+ for(f=0;f<len && f < 126;f++)
+ {
+ buff[cyc][f]=' ';
+ }
+
+ buff[cyc][f]=0;
+
+ return &buff[cyc][0];
+}
+
+
+void Generate::CalcModelBounds()
+{
+ for(int m=0;m<m_model->nNumMeshes;m++)
+ {
+ msMesh *mesh;
+
+ mesh=m_model->pMeshes+m;
+
+ for(int t=0;t<mesh->nNumTriangles;t++)
+ {
+ msTriangle *tri;
+
+ tri=mesh->pTriangles+t;
+
+ if (!(tri->nFlags&eHidden))
+ {
+ for(int i=0;i<3;i++)
+ {
+ msVertex *v=mesh->pVertices+tri->nVertexIndices[i];
+
+ m_min_x=std::min(m_min_x,v->Vertex[0]);
+ m_max_x=std::max(m_max_x,v->Vertex[0]);
+
+ m_min_y=std::min(m_min_y,v->Vertex[1]);
+ m_max_y=std::max(m_max_y,v->Vertex[1]);
+
+ m_min_z=std::min(m_min_z,v->Vertex[2]);
+ m_max_z=std::max(m_max_z,v->Vertex[2]);
+ }
+ }
+ }
+ }
+
+ m_cogx=m_min_x+(m_max_x-m_min_x)/2;
+ m_cogy=m_min_y+(m_max_y-m_min_y)/2;
+ m_cogz=m_min_z+(m_max_z-m_min_z)/2;
+}