kick
|
00001 // 00002 // ObjSave.cpp 00003 // KickObjLoader 00004 // 00005 // Created by morten on 9/1/13. 00006 // Copyright (c) 2013 morten. All rights reserved. 00007 // 00008 00009 #include "obj_save.h" 00010 #include "obj_load.h" 00011 #include <fstream> 00012 #include <sstream> 00013 #include <cstring> 00014 00015 using namespace std; 00016 using namespace glm; 00017 00018 namespace kick { 00019 00020 ostream& operator<<(ostream& cout,vec3 obj) 00021 { 00022 cout << obj[0]<<" "<<obj[1] << " "<<obj[2]; 00023 return cout; 00024 } 00025 00026 ostream& operator<<(ostream& cout,vec4 obj) 00027 { 00028 cout << obj[0]<<" "<<obj[1] << " "<<obj[2] << " "<<obj[3]; 00029 return cout; 00030 } 00031 00032 ostream& operator<<(ostream& cout,ObjVertex obj) 00033 { 00034 cout << " " << obj.vertexPositionIdx; 00035 if (obj.textureIdx>0){ 00036 cout << "/"<<obj.textureIdx; 00037 if (obj.normalIdx>0){ 00038 cout << "/"<<obj.normalIdx; 00039 } 00040 } else if (obj.normalIdx>0){ 00041 cout << "//"<<obj.normalIdx; 00042 } 00043 return cout; 00044 } 00045 00046 00047 string saveMaterialLib(ObjData & data, std::string path, std::string filename){ 00048 size_t pos = filename.find_last_of('.'); 00049 if (pos != string::npos){ 00050 filename = filename.substr(0, pos); 00051 } 00052 filename += ".mtl"; 00053 00054 ofstream file; 00055 file.open ((path + filename).c_str()); 00056 for (auto & material : data.materials){ 00057 file << "newmtl "<<material.name<<endl; 00058 file << "Ns "<<material.specularCoefficient<<endl; 00059 file << "Ka "<<material.ambientColor<<endl; 00060 file << "Kd "<<material.diffuseColor<<endl; 00061 file << "Ks "<<material.specularColor<<endl; 00062 file << "d "<<material.transparent<<endl; 00063 for (auto & i : material.illuminationModes) { 00064 file << "illum "<<static_cast<int>(i)<<endl; 00065 } 00066 } 00067 file.close(); 00068 00069 return filename; 00070 } 00071 00072 void saveObjData(ObjData & data, std::string path, std::string filename){ 00073 path = fixPathEnd(path); 00074 ofstream file; 00075 file.open ((path + filename).c_str()); 00076 // save initial comment 00077 stringstream ss{data.initialComment}; 00078 while (ss.good()){ 00079 const int bufferSize = 256; 00080 char buffer[bufferSize]; 00081 ss.getline(buffer, bufferSize); 00082 if (strlen(buffer)>0){ 00083 file << "# "<< buffer << endl; 00084 } 00085 } 00086 if (!data.materials.empty()){ 00087 string name = saveMaterialLib(data, path, filename); 00088 file << "mtllib "<< name << endl; 00089 } 00090 for (auto & vertexPos: data.vertexPositions) { 00091 file << "v "; 00092 if (vertexPos[3] == 1){ // remove optional 4th value if possible 00093 vec3 v{vertexPos[0],vertexPos[1],vertexPos[2]}; 00094 file << v << endl; 00095 } else { 00096 file << vertexPos<<endl; 00097 } 00098 } 00099 for (auto & texCoord: data.textureCoords) { 00100 file << "vt "; 00101 if (texCoord[2] == 0){ // remove optional 3 coord if possible 00102 file << texCoord[0] << " "<< texCoord[1]<<endl; 00103 } else { 00104 file << texCoord << endl; 00105 } 00106 } 00107 for (auto & normal: data.normals) { 00108 file << "vn " << normal << endl; 00109 } 00110 int faceIndex = 1; 00111 auto materialIter = data.materialChanges.begin(); 00112 auto materialIterEnd = data.materialChanges.end(); 00113 auto smoothingGroupIter = data.smoothGroups.begin(); 00114 auto smoothingGroupIterEnd = data.smoothGroups.end(); 00115 for (auto & face : data.faces) { 00116 while (materialIter != materialIterEnd && materialIter->faceIndex==faceIndex){ 00117 file << "usemtl "<<materialIter->name<<endl;; 00118 materialIter++; 00119 } 00120 while (smoothingGroupIter != smoothingGroupIterEnd && smoothingGroupIter->faceIndex==faceIndex){ 00121 int group = smoothingGroupIter->smoothGroupIdx; 00122 file << "s "; 00123 if (group == 0){ 00124 file << "off"; 00125 } else { 00126 file << group; 00127 } 00128 file<<endl;; 00129 smoothingGroupIter++; 00130 } 00131 file << "f"; 00132 for (auto & vertexIndex : face) { 00133 file << vertexIndex; 00134 } 00135 file << endl; 00136 faceIndex++; 00137 } 00138 00139 file.close(); 00140 } 00141 }