1 /** 2 * \file sg_binobj.hxx 3 * Routines to read and write the low level (binary) simgear 3d object format. 4 */ 5 6 // Written by Curtis Olson, started January 2000. 7 // 8 // Copyright (C) 2000 Curtis L. Olson - http://www.flightgear.org/~curt 9 // 10 // This program is free software; you can redistribute it and/or modify 11 // it under the terms of the GNU General Public License as published by 12 // the Free Software Foundation; either version 2 of the License, or 13 // (at your option) any later version. 14 // 15 // This program is distributed in the hope that it will be useful, 16 // but WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with this program; if not, write to the Free Software 22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 23 // 24 // $Id$ 25 26 27 #ifndef _SG_BINOBJ_HXX 28 #define _SG_BINOBJ_HXX 29 30 #include <zlib.h> // for gzFile 31 32 #include <simgear/compiler.h> 33 #include <simgear/constants.h> 34 #include <simgear/math/sg_types.hxx> 35 #include <simgear/math/SGMath.hxx> 36 37 #include <array> 38 #include <string> 39 #include <vector> 40 41 #define MAX_TC_SETS (4) 42 #define MAX_VAS (8) 43 44 typedef std::array<int_list, MAX_TC_SETS> tci_list; 45 typedef std::array<int_list, MAX_VAS> vai_list; 46 47 /** STL Structure used to store (integer index) object information */ 48 typedef std::vector < int_list > group_list; 49 typedef group_list::iterator group_list_iterator; 50 typedef group_list::const_iterator const_group_list_iterator; 51 52 /** STL Structure used to store (tc index) object information */ 53 typedef std::vector < tci_list > group_tci_list; 54 typedef group_tci_list::iterator group_tci_list_iterator; 55 typedef group_tci_list::const_iterator const_group_tci_list_iterator; 56 57 /** STL Structure used to store (va index) object information */ 58 typedef std::vector < vai_list > group_vai_list; 59 typedef group_vai_list::iterator group_vai_list_iterator; 60 typedef group_vai_list::const_iterator const_group_vai_list_iterator; 61 62 63 // forward decls 64 class SGBucket; 65 class SGPath; 66 67 class SGBinObjectPoint { 68 public: 69 std::string material; 70 int_list v_list; 71 int_list n_list; 72 int_list c_list; 73 clear(void)74 void clear( void ) { 75 material = ""; 76 v_list.clear(); 77 n_list.clear(); 78 c_list.clear(); 79 }; 80 }; 81 82 class SGBinObjectTriangle { 83 public: 84 std::string material; 85 int_list v_list; 86 int_list n_list; 87 int_list c_list; 88 89 tci_list tc_list; 90 vai_list va_list; 91 clear(void)92 void clear( void ) { 93 material = ""; 94 v_list.clear(); 95 n_list.clear(); 96 c_list.clear(); 97 for ( unsigned int i=0; i<MAX_TC_SETS; i++ ) { 98 tc_list[i].clear(); 99 } 100 for ( unsigned int i=0; i<MAX_VAS; i++ ) { 101 va_list[i].clear(); 102 } 103 }; 104 105 }; 106 107 108 109 /** 110 * A class to manipulate the simgear 3d object format. 111 * This class provides functionality to both read and write the binary format. 112 * 113 * Here is a really quick overview of the file syntax: 114 * 115 * - scenery-file: magic, nobjects, object+ 116 * 117 * - magic: "TG" + version 118 * 119 * - object: obj_typecode, nproperties, nelements, property+, element+ 120 * 121 * - element: nbytes, BYTE+ 122 * 123 * - property: prop_typecode, nbytes, BYTE+ 124 * 125 * - obj_typecode: bounding sphere | vertices | normals | texcoords | 126 * points | triangles | fans | strips 127 * 128 * - prop_typecode: material_name | ??? 129 * 130 * - nelements: USHORT (Gives us 65536 which ought to be enough, right?) 131 * 132 * - nproperties: USHORT 133 * 134 * - *_typecode: CHAR 135 * 136 * - nbytes: INTEGER (If we used short here that would mean 65536 bytes = 16384 137 * floats = 5461 vertices which is not enough for future 138 * growth) 139 * 140 * - vertex: FLOAT, FLOAT, FLOAT 141 */ 142 class SGBinObject { 143 private: 144 unsigned short version; 145 146 SGVec3d gbs_center; 147 float gbs_radius; 148 149 std::vector<SGVec3d> wgs84_nodes; // vertex list 150 std::vector<SGVec4f> colors; // color list 151 std::vector<SGVec3f> normals; // normal list 152 std::vector<SGVec2f> texcoords; // texture coordinate list 153 std::vector<float> va_flt; // vertex attribute list (floats) 154 std::vector<int> va_int; // vertex attribute list (ints) 155 156 group_list pts_v; // points vertex index 157 group_list pts_n; // points normal index 158 group_list pts_c; // points color index 159 group_tci_list pts_tcs; // points texture coordinates ( up to 4 sets ) 160 group_vai_list pts_vas; // points vertex attributes ( up to 8 sets ) 161 string_list pt_materials; // points materials 162 163 group_list tris_v; // triangles vertex index 164 group_list tris_n; // triangles normal index 165 group_list tris_c; // triangles color index 166 group_tci_list tris_tcs; // triangles texture coordinates ( up to 4 sets ) 167 group_vai_list tris_vas; // triangles vertex attributes ( up to 8 sets ) 168 string_list tri_materials; // triangles materials 169 170 group_list strips_v; // tristrips vertex index 171 group_list strips_n; // tristrips normal index 172 group_list strips_c; // tristrips color index 173 group_tci_list strips_tcs; // tristrips texture coordinates ( up to 4 sets ) 174 group_vai_list strips_vas; // tristrips vertex attributes ( up to 8 sets ) 175 string_list strip_materials; // tristrips materials 176 177 group_list fans_v; // fans vertex index 178 group_list fans_n; // fans normal index 179 group_list fans_c; // fans color index 180 group_tci_list fans_tcs; // fanss texture coordinates ( up to 4 sets ) 181 group_vai_list fans_vas; // fans vertex attributes ( up to 8 sets ) 182 string_list fan_materials; // fans materials 183 184 void read_properties(gzFile fp, int nproperties); 185 186 void read_object( gzFile fp, 187 int obj_type, 188 int nproperties, 189 int nelements, 190 group_list& vertices, 191 group_list& normals, 192 group_list& colors, 193 group_tci_list& texCoords, 194 group_vai_list& vertexAttribs, 195 string_list& materials); 196 197 void write_header(gzFile fp, int type, int nProps, int nElements); 198 void write_objects(gzFile fp, 199 int type, 200 const group_list& verts, 201 const group_list& normals, 202 const group_list& colors, 203 const group_tci_list& texCoords, 204 const group_vai_list& vertexAttribs, 205 const string_list& materials); 206 207 unsigned int count_objects(const string_list& materials); 208 209 public: get_version() const210 inline unsigned short get_version() const { return version; } 211 get_gbs_center() const212 inline const SGVec3d& get_gbs_center() const { return gbs_center; } set_gbs_center(const SGVec3d & p)213 inline void set_gbs_center( const SGVec3d& p ) { gbs_center = p; } 214 get_gbs_radius() const215 inline float get_gbs_radius() const { return gbs_radius; } set_gbs_radius(float r)216 inline void set_gbs_radius( float r ) { gbs_radius = r; } 217 get_wgs84_nodes() const218 inline const std::vector<SGVec3d>& get_wgs84_nodes() const { return wgs84_nodes; } set_wgs84_nodes(const std::vector<SGVec3d> & n)219 inline void set_wgs84_nodes( const std::vector<SGVec3d>& n ) { wgs84_nodes = n; } 220 get_colors() const221 inline const std::vector<SGVec4f>& get_colors() const { return colors; } set_colors(const std::vector<SGVec4f> & c)222 inline void set_colors( const std::vector<SGVec4f>& c ) { colors = c; } 223 get_normals() const224 inline const std::vector<SGVec3f>& get_normals() const { return normals; } set_normals(const std::vector<SGVec3f> & n)225 inline void set_normals( const std::vector<SGVec3f>& n ) { normals = n; } 226 get_texcoords() const227 inline const std::vector<SGVec2f>& get_texcoords() const { return texcoords; } set_texcoords(const std::vector<SGVec2f> & t)228 inline void set_texcoords( const std::vector<SGVec2f>& t ) { texcoords = t; } 229 230 // Points API 231 bool add_point( const SGBinObjectPoint& pt ); get_pts_v() const232 inline const group_list& get_pts_v() const { return pts_v; } get_pts_n() const233 inline const group_list& get_pts_n() const { return pts_n; } get_pts_tcs() const234 inline const group_tci_list& get_pts_tcs() const { return pts_tcs; } get_pts_vas() const235 inline const group_vai_list& get_pts_vas() const { return pts_vas; } get_pt_materials() const236 inline const string_list& get_pt_materials() const { return pt_materials; } 237 238 // Triangles API 239 bool add_triangle( const SGBinObjectTriangle& tri ); get_tris_v() const240 inline const group_list& get_tris_v() const { return tris_v; } get_tris_n() const241 inline const group_list& get_tris_n() const { return tris_n; } get_tris_c() const242 inline const group_list& get_tris_c() const { return tris_c; } get_tris_tcs() const243 inline const group_tci_list& get_tris_tcs() const { return tris_tcs; } get_tris_vas() const244 inline const group_vai_list& get_tris_vas() const { return tris_vas; } get_tri_materials() const245 inline const string_list& get_tri_materials() const { return tri_materials; } 246 247 // Strips API (deprecated - read only) get_strips_v() const248 inline const group_list& get_strips_v() const { return strips_v; } get_strips_n() const249 inline const group_list& get_strips_n() const { return strips_n; } get_strips_c() const250 inline const group_list& get_strips_c() const { return strips_c; } get_strips_tcs() const251 inline const group_tci_list& get_strips_tcs() const { return strips_tcs; } get_strips_vas() const252 inline const group_vai_list& get_strips_vas() const { return strips_vas; } get_strip_materials() const253 inline const string_list& get_strip_materials() const { return strip_materials; } 254 255 // Fans API (deprecated - read only ) get_fans_v() const256 inline const group_list& get_fans_v() const { return fans_v; } get_fans_n() const257 inline const group_list& get_fans_n() const { return fans_n; } get_fans_c() const258 inline const group_list& get_fans_c() const { return fans_c; } get_fans_tcs() const259 inline const group_tci_list& get_fans_tcs() const { return fans_tcs; } get_fans_vas() const260 inline const group_vai_list& get_fans_vas() const { return fans_vas; } get_fan_materials() const261 inline const string_list& get_fan_materials() const { return fan_materials; } 262 263 /** 264 * Read a binary file object and populate the provided structures. 265 * @param file input file name 266 * @return result of read 267 */ 268 bool read_bin( const SGPath& file ); 269 270 /** 271 * Write out the structures to a binary file. We assume that the 272 * groups come to us sorted by material property. If not, things 273 * don't break, but the result won't be as optimal. 274 * @param base name of output path 275 * @param name name of output file 276 * @param b bucket for object location 277 * @return result of write 278 */ 279 bool write_bin( const std::string& base, const std::string& name, const SGBucket& b ); 280 281 282 bool write_bin_file(const SGPath& file); 283 284 /** 285 * Write out the structures to an ASCII file. We assume that the 286 * groups come to us sorted by material property. If not, things 287 * don't break, but the result won't be as optimal. 288 * @param base name of output path 289 * @param name name of output file 290 * @param b bucket for object location 291 * @return result of write 292 */ 293 bool write_ascii( const std::string& base, const std::string& name, 294 const SGBucket& b ); 295 }; 296 297 #endif // _SG_BINOBJ_HXX 298