#include "ldae_exporter.h" #include "scene/main/node.h" #include "scene/3d/light.h" #include "ldebug.h" #include "lportal.h" #define FSL(a) m_File.store_line(a) #define FSS(a) m_File.store_string(a) #define FSL_T(a, b) {for (int n=0; n"); for (int n=0; n"); // mesh instances FSL("\t"); // merged mesh? if (m_pMergedMI) SaveData_MeshInstance(*m_pMergedMI); for (int n=0; n"); m_Stage = ST_SCENE_GRAPH; Save_Mid(); // now save the scene graph SaveScene_Recursive(pNode, 0); Save_Final(); m_File.close(); return true; } bool LDAEExporter::Save_Preamble() { FSL(""); FSL(""); return true; } bool LDAEExporter::Save_Mid() { FSL("\t"); FSL("\t\t"); if (m_bAddRootNode) { FSL_T(3, ""); // rotate x by 90 degrees FSL_T(3, "1 0 0 0 0 0 -1 0 0 1 0 0 0 0 0 1"); } if (m_pMergedMI) { String sz = SaveScene_MeshInstance(*m_pMergedMI, 3); FSL(sz); // merged node close FSL_T(3, ""); } return true; } void LDAEExporter::TransformToMatrix(const Transform &tr, float * m) { const Basis &b = tr.basis; m[0] = b.elements[0][0]; m[1] = b.elements[0][1]; m[2] = b.elements[0][2]; m[3] = tr.origin.x; m[4] = b.elements[1][0]; m[5] = b.elements[1][1]; m[6] = b.elements[1][2]; m[7] = tr.origin.y; m[8] = b.elements[2][0]; m[9] = b.elements[2][1]; m[10] = b.elements[2][2]; m[11] = tr.origin.z; m[12] = 0.0f; m[13] = 0.0f; m[14] = 0.0f; m[15] = 1.0f; } String LDAEExporter::SaveScene_Light(const Light &l, int depth) { int tab_depth = 3 + depth; String name = l.get_name(); String long_name = name + "-light"; FSL_T(tab_depth, ""); WriteMatrix(l.get_transform(), tab_depth+1); FSL_T(tab_depth+1, ""); String sz = ""; for (int n=0; n"); for (int n=0; n<16; n++) { FSS(ftos(mat[n]) + " "); } FSS("\n"); } String LDAEExporter::SaveScene_MeshInstance(const MeshInstance &mi, int depth) { int tab_depth = 3 + depth; String name = mi.get_name(); String long_name = name + "-mesh"; FSL_T(tab_depth, ""); WriteMatrix(mi.get_transform(), tab_depth+1); FSL_T(tab_depth+1, ""); FSL_T(tab_depth+1, ""); String sz = ""; for (int n=0; n"); return sz; } String LDAEExporter::SaveScene_Spatial(const Spatial &sp, int depth) { int tab_depth = 3 + depth; String name = sp.get_name(); FSL_T(tab_depth, ""); WriteMatrix(sp.get_transform(), tab_depth+1); String sz = ""; for (int n=0; n"); // level } if (m_bAddRootNode) { FSL_T(3, ""); // root } FSL("\t\t"); FSL("\t"); FSL("\t"); FSL("\t\t"); FSL("\t"); FSL(""); return true; } bool LDAEExporter::IsPortal(const MeshInstance &mi) { if (LPortal::NameStartsWith(&mi, "portal_")) return true; return false; } bool LDAEExporter::SaveScene_Recursive(Node * pNode, int depth) { String szClose = ""; // mesh instance? MeshInstance * pMI = Object::cast_to(pNode); if (pMI) { if (m_bRemovePortals && (IsPortal(*pMI))) { // portal .. not exporting } else { if (m_Stage == ST_DATA) m_MeshInstances.push_back(pMI); else szClose = SaveScene_MeshInstance(*pMI, depth); } } // light? Light * pLight = Object::cast_to(pNode); if (pLight) { if (m_Stage == ST_DATA) m_Lights.push_back(pLight); else szClose = SaveScene_Light(*pLight, depth); } // spatial? (and only a spatial) if (pNode->get_class() == "Spatial") { if (m_Stage == ST_SCENE_GRAPH) { szClose = SaveScene_Spatial(*Object::cast_to(pNode), depth); } } // go through the children for (int n=0; nget_child_count(); n++) { SaveScene_Recursive(pNode->get_child(n), depth+1); } // a closing xml expression if (szClose != "") { FSL(szClose); } return true; } bool LDAEExporter::SaveData_Light(const Light &light) { String name = light.get_name(); String long_name = name + "-light"; int t = 1; String szLightType = "point"; //if (light.is_class("OmniLight") if (light.is_class("SpotLight")) szLightType = "spot"; if (light.is_class("DirectionalLight")) szLightType = "directional"; FSL_T(t, ""); FSL_T(t+1, ""); FSL_T(t+2, "<" + szLightType + ">"); FSL_T(t+2, ""); FSL_T(t+1, ""); FSL_T(t, ""); return true; } //static bool g_SingleDAETest = false; bool LDAEExporter::SaveData_MeshInstance(const MeshInstance &mi) { // if (g_SingleDAETest) // return true; // g_SingleDAETest = true; Ref rmesh = mi.get_mesh(); Array arrays = rmesh->surface_get_arrays(0); PoolVector verts = arrays[VS::ARRAY_VERTEX]; PoolVector norms = arrays[VS::ARRAY_NORMAL]; PoolVector uv1s = arrays[VS::ARRAY_TEX_UV]; PoolVector inds = arrays[VS::ARRAY_INDEX]; int nVerts = verts.size(); int nInds = inds.size(); int nFaces = nInds / 3; String name = mi.get_name(); String long_name = name + "-mesh"; FSL("\t"); FSL("\t\t"); // positions FSL("\t\t\t"); FSS("\t\t\t\t"); for (int n=0; n\n"); FSL("\t\t\t\t"); FSL("\t\t\t\t\t"); FSL("\t\t\t\t\t\t"); FSL("\t\t\t\t\t\t"); FSL("\t\t\t\t\t\t"); FSL("\t\t\t\t\t"); FSL("\t\t\t\t"); FSL("\t\t\t"); // normals if (norms.size()) { FSL("\t\t\t"); FSS("\t\t\t\t"); for (int n=0; n\n"); FSL("\t\t\t\t"); FSL("\t\t\t\t\t"); FSL("\t\t\t\t\t\t"); FSL("\t\t\t\t\t\t"); FSL("\t\t\t\t\t\t"); FSL("\t\t\t\t\t"); FSL("\t\t\t\t"); FSL("\t\t\t"); } FSL("\t\t\t"); FSL("\t\t\t\t"); FSL("\t\t\t"); FSL("\t\t\t"); FSL("\t\t\t\t"); if (norms.size()) { FSL("\t\t\t\t"); } FSS("\t\t\t\t

"); // DAE has face winding reversed compared to godot for (int f=0; f\n"); FSL("\t\t\t"); FSL("\t\t"); FSL("\t"); return true; } #undef FSL #undef FSS