00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <wx/filename.h>
00013 #include "fhswriter.h"
00014
00015
00016 using namespace VRUT;
00017
00018
00019 FHSWriter::FHSWriter(wxBufferedOutputStream * _outputStream, const Scene * _scene) : scene(_scene), outputStream(_outputStream)
00020 {
00021 textWriter = new TextWriter(outputStream);
00022 }
00023
00024
00025 FHSWriter::~FHSWriter()
00026 {
00028 SAFE_DELETE(textWriter);
00029 }
00030
00031 void FHSWriter::WriteMatrix(const SceneNode *node, std::string tabs)
00032 {
00033 MATRIX transf(*(node->GetLocalTransMatrix()));
00034 if (transf.IsUnit())
00035 return;
00036 textWriter->Write((tabs+"MATRIX (").c_str())->Write(transf._m, 4, ", ");
00037 textWriter->Write((",\n"+tabs+" ").c_str())->Write(&transf._m[4], 4, ", ");
00038 textWriter->Write((",\n"+tabs+" ").c_str())->Write(&transf._m[8], 4, ", ");
00039 textWriter->Write((",\n"+tabs+" ").c_str())->Write(&transf._m[12], 4, ", ")->Write(")\n");
00040 }
00041
00042 void FHSWriter::WriteAssemblyBody(const SceneNode *node, std::string tabs)
00043 {
00044 const SceneNode::NodeIDList *children = node->GetChildren();
00045 for (SceneNode::NodeIDList::const_iterator it = children->begin() ; it != children->end(); it++)
00046 {
00047 const SceneNode * child = scene->GetNode(*it);
00048 switch (child->GetType())
00049 {
00050 case SceneNode::ASSEMBLY:
00051 WriteAssembly(child, tabs);
00052 break;
00053 case SceneNode::CAMERA:
00054 break;
00055 case SceneNode::GEOMETRY:
00056 WriteGeometry((GeometryNode*)child, tabs);
00057 break;
00058 case SceneNode::LIGHT:
00059 WriteLight((LightNode*)child, tabs);
00060 break;
00061 default:
00062 LOGERROR(wxT("not implemented ") + child->GetName());
00063 }
00064 }
00065 }
00066
00067 void FHSWriter::WriteAssembly(const SceneNode *node, std::string tabs)
00068 {
00069 textWriter->Write(tabs.c_str())->Write("ASSEMBLY \"")->Write(node->GetName())->Write("\"\n");
00070 if (!node->GetUid().IsEmpty())
00071 textWriter->Write(tabs.c_str())->Write("DESCX \"UID ")->Write(node->GetUid())->Write("\"\n");
00072 WriteMatrix(node, tabs);
00073 textWriter->Write(tabs.c_str())->Write("{\n");
00074 WriteAssemblyBody(node, tabs+"\t");
00075 textWriter->Write(tabs.c_str())->Write("}\n");
00076 }
00077
00078 void FHSWriter::WriteGeometry(const GeometryNode *node, std::string tabs)
00079 {
00080 textWriter->Write(tabs.c_str())->Write("GEOMETRY \"")->Write(node->GetName())->Write("\"\n");
00081 if (!node->GetUid().IsEmpty())
00082 textWriter->Write(tabs.c_str())->Write("DESCX \"UID ")->Write(node->GetUid())->Write("\"\n");
00083 if (node->GetMaterialID()!=MATERIAL_ID_NONE)
00084 textWriter->Write(tabs.c_str())->Write("USEMAT \"")->Write(scene->GetMaterial(node->GetMaterialID())->name)->Write("\"\n");
00085
00086 WriteMatrix(node, tabs);
00087
00088 const Geometry * geom = scene->GetGeometry(node->GetGeometryID());
00089 if (geom && geom->type == Geometry::GEOMETRY_TRIANGLE)
00090 {
00091 const GeometryTriangles * geometry = (GeometryTriangles *)geom;
00092 size_t indiceIndex = 0;
00093 size_t maxInd = geometry->indices.size();
00094 const std::vector<VECTOR3> * vertices = &geometry->vertices;
00095 const std::vector<VECTOR3> * normals = &geometry->normals;
00096 size_t normalsCount = normals->size();
00097 const std::vector<GeometryTriangles::TexCoord> * texCoords = &geometry->texCoords;
00098 size_t texCoordsCount = texCoords->size();
00099 const std::vector<GeometryTriangles::Indice> * indices = &geometry->indices;
00100
00101
00102 textWriter->Write(tabs.c_str())->Write("POLYPOOL\n")->Write(tabs.c_str())->Write("{\n");
00103 for (size_t i=0; i<vertices->size(); i++)
00104 {
00105 textWriter->Write(tabs.c_str())->Write("\tP=(")->Write(vertices->at(i)._v, 3, ", ");
00106 if (i<normalsCount)
00107 textWriter->Write(") N=(")->Write(normals->at(i)._v, 3, ", ");
00108 if (i<texCoordsCount)
00109 textWriter->Write(") T=(")->Write(texCoords->at(i)._v, 2, ", ");
00110 textWriter->Write(")\n");
00111 }
00112 textWriter->Write(tabs.c_str())->Write("}\n")->Write(tabs.c_str())->Write("{\n");
00113 for (GeometryTriangles::TriDescList::const_iterator indPrimType = geometry->triDescList.begin();
00114 indPrimType != geometry->triDescList.end(); indPrimType++)
00115 {
00116 GeometryTriangles::TriDescList::const_iterator endIndPrimType = indPrimType + 1;
00117 size_t endInd = ( endIndPrimType == geometry->triDescList.end() ? maxInd : endIndPrimType->first );
00118 endInd = __min( endInd, maxInd );
00119 textWriter->Write(tabs.c_str());
00120 switch (indPrimType->second)
00121 {
00122 case GeometryTriangles::TRI_LIST:
00123 textWriter->Write("\tTRIANGLES\n");
00124 break;
00125 case GeometryTriangles::QUADS:
00126 textWriter->Write("\tQUADS\n");
00127 break;
00128 case GeometryTriangles::POLYGON:
00129 textWriter->Write("\tPOLYGON\n");
00130 break;
00131 case GeometryTriangles::TRI_FAN:
00132 textWriter->Write("\tTRIFAN\n");
00133 break;
00134 case GeometryTriangles::TRI_STRIP:
00135 textWriter->Write("\tTRIANGLE_STRIP\n");
00136 break;
00137 case GeometryTriangles::LINES:
00138 textWriter->Write("\tLINES\n");
00139 break;
00140 case GeometryTriangles::LINE_STRIP:
00141 textWriter->Write("\tLINE_STRIP\n");
00142 break;
00143 case GeometryTriangles::POINTS:
00144 textWriter->Write("\tPOINTS\n");
00145 break;
00146 default:
00147 LOGERROR(wxT("<FHSWriter>Unknown primitive type"));
00148 }
00149 textWriter->Write(tabs.c_str())->Write("\t{\n")->Write(tabs.c_str())->Write("\t\t");
00150 for ( ; indiceIndex < endInd; indiceIndex++)
00151 {
00152 GeometryTriangles::Indice indice = indices->at(indiceIndex);
00153 textWriter->Write("I");
00154 if (indice < normalsCount)
00155 textWriter->Write("N");
00156 if (indice < texCoordsCount)
00157 textWriter->Write("T");
00158 textWriter->Write("=")->Write(indice);
00159 if (indiceIndex < endInd-1)
00160 textWriter->Write(" ");
00161 }
00162 textWriter->Write("\n")->Write(tabs.c_str())->Write("\t}\n");
00163 }
00164 textWriter->Write(tabs.c_str())->Write("}\n");
00165 }
00166 }
00167
00168 void FHSWriter::WriteLight(const LightNode *node, std::string tabs)
00169 {
00170 textWriter->Write(tabs.c_str())->Write("LIGHT \"")->Write(node->GetName())->Write("\"\n");
00171 if (!node->GetUid().IsEmpty())
00172 textWriter->Write(tabs.c_str())->Write("DESCX \"UID ")->Write(node->GetUid())->Write("\"\n");
00173 WriteMatrix(node, tabs);
00174 const Light *light = node->GetLight();
00175 textWriter->Write(tabs.c_str())->Write("{\n");
00176 textWriter->Write(tabs.c_str())->Write("\tCOLOR (")->Write(light->diffuse._v, 3, ", ")->Write(")\n");
00177
00178 switch (light->type)
00179 {
00180 case Light::OMNI:
00181 textWriter->Write(tabs.c_str())->Write("\tPOSITION (")->Write(light->position._v, 3, ", ")->Write(")\n");
00182 break;
00183 case Light::DIRECTIONAL:
00184 textWriter->Write(tabs.c_str())->Write("\tDIRECTION (")->Write(light->direction._v, 3, ", ")->Write(")\n");
00185 break;
00186 case Light::SPOTLIGHT:
00187 textWriter->Write(tabs.c_str())->Write("\tPOSITION (")->Write(light->position._v, 3, ", ")->Write(")\n");
00188 textWriter->Write(tabs.c_str())->Write("\tDIRECTION (")->Write(light->direction._v, 3, ", ")->Write(")\n");
00189 textWriter->Write(tabs.c_str())->Write("\tSPOTLIGHT (")->Write(light->angle)->Write(", ")->Write(light->exponent)->Write(")\n");
00190 break;
00191 default:
00192 LOGERROR(wxString::Format(wxT("<FHSWriter>Unknown light type %i"),light->type));
00193 break;
00194 }
00195 textWriter->Write(tabs.c_str())->Write("}\n");
00196 }
00197
00198 void FHSWriter::Write()
00199 {
00200 LOGVERBOSE(wxT("<FHSWriter>Inside FHSWriter::Write."));
00201 textWriter->Write("MODEL \"")->Write(scene->GetName())->Write("\"\nFHSVERSION 1100\nPOINTORDER COUNTERCLOCKWISE\n\n");
00202
00203
00204 const Scene::MaterialList * materials = scene->GetMaterials();
00205
00206 for (Scene::MaterialList::const_iterator it = materials->begin(); it != materials->end(); it++)
00207 {
00208 if (*it==NULL)
00209 continue;
00210 const Material * mat = *it;
00211 textWriter->Write("DEFMAT \"")->Write(mat->name);
00212 textWriter->Write("\"\n{\n\tAMBIENT (")->Write(mat->ambient._v, 3, ", ");
00213 textWriter->Write(")\n\tDIFFUSE (")->Write(mat->diffuse._v, 3, ", ");
00214 textWriter->Write(")\n\tSPECULAR (")->Write(mat->specular._v, 3, ", ");
00215 textWriter->Write(")\n\tSHININESS ")->Write(mat->shininess);
00216 textWriter->Write("\n\tEMISSION (")->Write(mat->emission._v, 3, ", ")->Write(")\n");
00217 if (mat->flags & Material::UNLIT)
00218 textWriter->Write("\tUNLIT\n");
00219 if (mat->flags & Material::BLENDED)
00220 {
00221 if (mat->diffuse.w!=1.0)
00222 {
00223 textWriter->Write("\tTRANSPARENCY ")->Write(1-mat->diffuse.w)->Write("\n");
00224 }
00225 const char *blendKeywords[]={"None", "Zero", "One", "SrcColor", "OneMinusSrcColor", "DstColor", "OneMinusDstColor", "SrcAlpha", "OneMinusSrcAlpha", "DstAlpha", ""};
00226 const GLuint values[]={GL_ZERO, GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA};
00227 int src=0, dst=0;
00228 for (unsigned i=0; i<10; i++)
00229 {
00230 if (values[i]==mat->texBlendSrc)
00231 src=i;
00232 if (values[i]==mat->texBlendDst)
00233 dst=i;
00234 }
00235 if (src>0 || dst>0)
00236 {
00237 textWriter->Write("\tMATX \"BLENDFUNC ")->Write(blendKeywords[src])->Write(" ")->Write(blendKeywords[dst])->Write("\"\n");
00238 }
00239 }
00240 if (!mat->uid.IsEmpty())
00241 textWriter->Write("\tMATX \"UID ")->Write(mat->uid)->Write("\"\n");
00242 textWriter->Write("\tMATX \"DEPTHTEST ")->Write((mat->flags & Material::DEPTH_TEST_DISABLE) ? "0" : "1")->Write("\"\n");
00243 textWriter->Write("\tMATX \"DEPTHMASK ")->Write((mat->flags & Material::DEPTH_MASK_DISABLE) ? "0" : "1")->Write("\"\n");
00244 textWriter->Write("\tMATX \"DEPTHFUNC ")->Write((int)mat->depthFunc)->Write("\"\n");
00245 if (mat->flags & Material::DOUBLE_SIDED)
00246 textWriter->Write("\tMATX \"DSIDED 1\"\n");
00247 if (mat->imageName.size())
00248 {
00249 textWriter->Write("\tTEXTURE \"")->Write(wxFileName(mat->imageName).GetFullName())->Write("\"\n");
00250 textWriter->Write("\tTEXWRAP ");
00251 if (mat->texFlags & Material::TEX_UWRAP_REPEAT)
00252 textWriter->Write("REPEAT ");
00253 else
00254 textWriter->Write("CLAMP ");
00255 if (mat->texFlags & Material::TEX_VWRAP_REPEAT)
00256 textWriter->Write("REPEAT");
00257 else
00258 textWriter->Write("CLAMP");
00259 textWriter->Write("\n\tTEXFILTER ");
00260 if (mat->texFlags & Material::TEX_MIN_FILTER_POINT)
00261 textWriter->Write("POINT ");
00262 else if (mat->texFlags & Material::TEX_MIN_FILTER_LINEAR)
00263 textWriter->Write("LINEAR ");
00264 else
00265 textWriter->Write("MIPMAP ");
00266 if (mat->texFlags & Material::TEX_MAG_FILTER_POINT)
00267 textWriter->Write("POINT");
00268 else
00269 textWriter->Write("LINEAR");
00270 textWriter->Write("\n\tTEXQUALITY HIGH\n");
00271 textWriter->Write("\tTEXBLEND ");
00272 if (mat->texFlags & Material::TEX_ENV_MODULATE)
00273 textWriter->Write("MODULATE");
00274 else if (mat->texFlags & Material::TEX_ENV_REPLACE)
00275 textWriter->Write("REPLACE");
00276 else if (mat->texFlags & Material::TEX_ENV_DECAL)
00277 textWriter->Write("DECAL");
00278 else
00279 textWriter->Write("BLEND");
00280 textWriter->Write("\n");
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 if (mat->texFlags & Material::TEX_GEN_FUNC_U_SPHERE)
00291 textWriter->Write("\tMATX \"GENFUNC s Sphere\" \n");
00292 if (mat->texFlags & Material::TEX_GEN_FUNC_V_SPHERE)
00293 textWriter->Write("\tMATX \"GENFUNC t Sphere\" \n");
00294 if (mat->flags & Material::INVERT_ALPHA)
00295 textWriter->Write("\tMATX \"INVERTALPHA\" \n");
00296 if (mat->texFlags & Material::TEX_IGNORE_COLORS)
00297 textWriter->Write("\tMATX \"IGNORECOLORS\" \n");
00298 if (mat->textureMix!=0)
00299 textWriter->Write("\tMATX \"MIXTEXTURE ")->Write(mat->textureMix)->Write("\"\n");
00300 }
00301 if (mat->shader)
00302 {
00303 textWriter->Write("\tMATX \"SHADERENABLE 1\"\n");
00304 switch (mat->shader->type)
00305 {
00306 case ShaderProgram::LANG_GLSL:
00307 textWriter->Write("\tMATX \"SHADERPROG GLSL VS '")->Write(wxFileName(mat->shader->vsFileName).GetFullName());
00308 textWriter->Write("'\"\n\tMATX \"SHADERPROG GLSL FS '")->Write(wxFileName(mat->shader->fsFileName).GetFullName())->Write("'\"\n");
00309 for (size_t i=0; i<mat->shader->paramList.size(); i++)
00310 {
00311 textWriter->Write("\tMATX \"SHADERPARAM GLSL ")->Write(mat->shader->paramList[i].name);
00312 switch (mat->shader->paramList[i].type)
00313 {
00314 case ShaderParam::FLOAT1:
00315 textWriter->Write(" FLOAT ")->Write(mat->shader->paramList[i].fVals, 3, " ");
00316 break;
00317 case ShaderParam::FLOAT3:
00318 textWriter->Write(" FLOAT3 ")->Write(mat->shader->paramList[i].fVals, 3, " ");
00319 break;
00320 case ShaderParam::FLOAT4:
00321 textWriter->Write(" COLOR ")->Write(mat->shader->paramList[i].fVals, 4, " ");
00322 break;
00323 case ShaderParam::SAMPLER:
00324 textWriter->Write(" SAMPLER2D '")->Write(wxFileName(mat->shader->paramList[i].imageName).GetFullName().c_str())->Write("'");
00325 break;
00326 default:
00327 LOGERROR(wxString::Format(wxT("<FHSWrite>Shader param type %i not supported."), mat->shader->paramList[i].type));
00328 }
00329 textWriter->Write("\"\n");
00330 }
00331 break;
00332 default:
00333 LOGERROR(wxString::Format(wxT("<FHSWrite>Shader type %i not supported."), mat->shader->type));
00334 }
00335 }
00336 textWriter->Write("}\n");
00337 }
00338 textWriter->Write("\n");
00339
00340
00341
00342 WriteAssemblyBody(scene->GetNode(scene->GetRootID()), "");
00343 outputStream->Sync();
00344 }
00345