Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pandatool/src/egg-palettize/txaFile.cxx

Go to the documentation of this file.
00001 // Filename: txaFile.cxx
00002 // Created by:  drose (30Nov00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "txaFile.h"
00020 #include "pal_string_utils.h"
00021 #include "palettizer.h"
00022 #include "paletteGroup.h"
00023 #include "textureImage.h"
00024 
00025 #include <notify.h>
00026 #include <pnmFileTypeRegistry.h>
00027 
00028 ////////////////////////////////////////////////////////////////////
00029 //     Function: TxaFile::Constructor
00030 //       Access: Public
00031 //  Description:
00032 ////////////////////////////////////////////////////////////////////
00033 TxaFile::
00034 TxaFile() {
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: TxaFile::read
00039 //       Access: Public
00040 //  Description: Reads the indicated .txa filename, and returns true
00041 //               if successful, or false if there is an error.
00042 ////////////////////////////////////////////////////////////////////
00043 bool TxaFile::
00044 read(Filename filename) {
00045   filename.set_text();
00046   ifstream in;
00047   if (!filename.open_read(in)) {
00048     nout << "Unable to open " << filename << "\n";
00049     return false;
00050   }
00051 
00052   string line;
00053   getline(in, line);
00054   int line_number = 1;
00055 
00056   while (!in.eof() && !in.fail()) {
00057     bool okflag = true;
00058 
00059     // Strip off the comment.
00060     size_t hash = line.find('#');
00061     if (hash != string::npos) {
00062       line = line.substr(0, hash);
00063     }
00064     line = trim_left(line);
00065     if (line.empty()) {
00066       // Empty lines are ignored.
00067 
00068     } else if (line[0] == ':') {
00069       // This is a keyword line.
00070       vector_string words;
00071       extract_words(line, words);
00072       if (words[0] == ":group") {
00073         okflag = parse_group_line(words);
00074 
00075       } else if (words[0] == ":palette") {
00076         okflag = parse_palette_line(words);
00077 
00078       } else if (words[0] == ":margin") {
00079         okflag = parse_margin_line(words);
00080 
00081       } else if (words[0] == ":coverage") {
00082         okflag = parse_coverage_line(words);
00083 
00084       } else if (words[0] == ":imagetype") {
00085         okflag = parse_imagetype_line(words);
00086 
00087       } else if (words[0] == ":shadowtype") {
00088         okflag = parse_shadowtype_line(words);
00089 
00090       } else if (words[0] == ":round") {
00091         okflag = parse_round_line(words);
00092 
00093       } else if (words[0] == ":remap") {
00094         okflag = parse_remap_line(words);
00095 
00096       } else {
00097         nout << "Invalid keyword " << words[0] << "\n";
00098         okflag = false;
00099       }
00100 
00101     } else {
00102       _lines.push_back(TxaLine());
00103       TxaLine &txa_line = _lines.back();
00104 
00105       okflag = txa_line.parse(line);
00106     }
00107 
00108     if (!okflag) {
00109       nout << "Error on line " << line_number << " of " << filename << "\n";
00110       return false;
00111     }
00112 
00113     getline(in, line);
00114     line_number++;
00115   }
00116 
00117   if (!in.eof()) {
00118     nout << "I/O error reading " << filename << "\n";
00119     return false;
00120   }
00121 
00122   return true;
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: TxaFile::match_egg
00127 //       Access: Public
00128 //  Description: Searches for a matching line in the .txa file for the
00129 //               given egg file and applies its specifications.  If a
00130 //               match is found, returns true; otherwise, returns
00131 //               false.  Also returns false if all the matching lines
00132 //               for the egg file include the keyword "cont".
00133 ////////////////////////////////////////////////////////////////////
00134 bool TxaFile::
00135 match_egg(EggFile *egg_file) const {
00136   Lines::const_iterator li;
00137   for (li = _lines.begin(); li != _lines.end(); ++li) {
00138     if ((*li).match_egg(egg_file)) {
00139       return true;
00140     }
00141   }
00142 
00143   return false;
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: TxaFile::match_texture
00148 //       Access: Public
00149 //  Description: Searches for a matching line in the .txa file for the
00150 //               given texture and applies its specifications.  If a
00151 //               match is found, returns true; otherwise, returns
00152 //               false.  Also returns false if all the matching lines
00153 //               for the texture include the keyword "cont".
00154 ////////////////////////////////////////////////////////////////////
00155 bool TxaFile::
00156 match_texture(TextureImage *texture) const {
00157   Lines::const_iterator li;
00158   for (li = _lines.begin(); li != _lines.end(); ++li) {
00159     if ((*li).match_texture(texture)) {
00160       return true;
00161     }
00162   }
00163 
00164   return false;
00165 }
00166 
00167 ////////////////////////////////////////////////////////////////////
00168 //     Function: TxaFile::write
00169 //       Access: Public
00170 //  Description: Outputs a representation of the lines that were read
00171 //               in to the indicated output stream.  This is primarily
00172 //               useful for debugging.
00173 ////////////////////////////////////////////////////////////////////
00174 void TxaFile::
00175 write(ostream &out) const {
00176   Lines::const_iterator li;
00177   for (li = _lines.begin(); li != _lines.end(); ++li) {
00178     out << (*li) << "\n";
00179   }
00180 }
00181 
00182 
00183 ////////////////////////////////////////////////////////////////////
00184 //     Function: TxaFile::parse_group_line
00185 //       Access: Private
00186 //  Description: Handles the line in a .txa file that begins with the
00187 //               keyword ":group" and indicates the relationships
00188 //               between one or more groups.
00189 ////////////////////////////////////////////////////////////////////
00190 bool TxaFile::
00191 parse_group_line(const vector_string &words) {
00192   vector_string::const_iterator wi;
00193   wi = words.begin();
00194   assert (wi != words.end());
00195   ++wi;
00196 
00197   const string &group_name = (*wi);
00198   PaletteGroup *group = pal->get_palette_group(group_name);
00199   ++wi;
00200 
00201   enum State {
00202     S_none,
00203     S_with,
00204     S_dir,
00205   };
00206   State state = S_none;
00207 
00208   while (wi != words.end()) {
00209     const string &word = (*wi);
00210     if (word == "with") {
00211       state = S_with;
00212 
00213     } else if (word == "dir") {
00214       state = S_dir;
00215 
00216     } else {
00217       switch (state) {
00218       case S_none:
00219         nout << "Invalid keyword: " << word << "\n";
00220         return false;
00221 
00222       case S_with:
00223         group->group_with(pal->get_palette_group(word));
00224         break;
00225 
00226       case S_dir:
00227         group->set_dirname(word);
00228         state = S_none;
00229         break;
00230       }
00231     }
00232 
00233     ++wi;
00234   }
00235 
00236   return true;
00237 }
00238 
00239 ////////////////////////////////////////////////////////////////////
00240 //     Function: TxaFile::parse_palette_line
00241 //       Access: Private
00242 //  Description: Handles the line in a .txa file that begins with the
00243 //               keyword ":palette" and indicates the appropriate size
00244 //               for the palette images.
00245 ////////////////////////////////////////////////////////////////////
00246 bool TxaFile::
00247 parse_palette_line(const vector_string &words) {
00248   if (words.size() != 3) {
00249     nout << "Exactly two parameters required for :palette, the x and y "
00250          << "size of the palette images to generate.\n";
00251     return false;
00252   }
00253 
00254   if (!string_to_int(words[1], pal->_pal_x_size) ||
00255       !string_to_int(words[2], pal->_pal_y_size)) {
00256     nout << "Invalid palette size: " << words[1] << " " << words[2] << "\n";
00257     return false;
00258   }
00259 
00260   if (pal->_pal_x_size <= 0 || pal->_pal_y_size <= 0) {
00261     nout << "Invalid palette size: " << pal->_pal_x_size
00262          << " " << pal->_pal_y_size << "\n";
00263     return false;
00264   }
00265 
00266   return true;
00267 }
00268 
00269 ////////////////////////////////////////////////////////////////////
00270 //     Function: TxaFile::parse_margin_line
00271 //       Access: Private
00272 //  Description: Handles the line in a .txa file that begins with the
00273 //               keyword ":margin" and indicates the default margin
00274 //               size.
00275 ////////////////////////////////////////////////////////////////////
00276 bool TxaFile::
00277 parse_margin_line(const vector_string &words) {
00278   if (words.size() != 2) {
00279     nout << "Exactly one parameter required for :margin, the "
00280          << "size of the default margin to apply.\n";
00281     return false;
00282   }
00283 
00284   if (!string_to_int(words[1], pal->_margin)) {
00285     nout << "Invalid margin: " << words[1] << "\n";
00286     return false;
00287   }
00288 
00289   if (pal->_margin < 0) {
00290     nout << "Invalid margin: " << pal->_margin << "\n";
00291     return false;
00292   }
00293 
00294   return true;
00295 }
00296 
00297 ////////////////////////////////////////////////////////////////////
00298 //     Function: TxaFile::parse_coverage_line
00299 //       Access: Private
00300 //  Description: Handles the line in a .txa file that begins with the
00301 //               keyword ":coverage" and indicates the default
00302 //               coverage threshold.
00303 ////////////////////////////////////////////////////////////////////
00304 bool TxaFile::
00305 parse_coverage_line(const vector_string &words) {
00306   if (words.size() != 2) {
00307     nout << "Exactly one parameter required for :coverage, the "
00308          << "value for the default coverage threshold.\n";
00309     return false;
00310   }
00311 
00312 
00313   if (!string_to_double(words[1], pal->_coverage_threshold)) {
00314     nout << "Invalid coverage threshold: " << words[1] << "\n";
00315     return false;
00316   }
00317 
00318   if (pal->_coverage_threshold <= 0.0) {
00319     nout << "Invalid coverage threshold: " << pal->_coverage_threshold << "\n";
00320     return false;
00321   }
00322 
00323   return true;
00324 }
00325 
00326 ////////////////////////////////////////////////////////////////////
00327 //     Function: TxaFile::parse_imagetype_line
00328 //       Access: Private
00329 //  Description: Handles the line in a .txa file that begins with the
00330 //               keyword ":imagetype" and indicates the default image
00331 //               file type to convert palettes and textures to.
00332 ////////////////////////////////////////////////////////////////////
00333 bool TxaFile::
00334 parse_imagetype_line(const vector_string &words) {
00335   if (words.size() != 2) {
00336     nout << "Exactly one parameter required for :imagetype.\n";
00337     return false;
00338   }
00339   const string &imagetype = words[1];
00340   if (!parse_image_type_request(imagetype, pal->_color_type, pal->_alpha_type)) {
00341     nout << "\nKnown image types are:\n";
00342     PNMFileTypeRegistry::get_ptr()->write_types(nout, 2);
00343     nout << "\n";
00344     return false;
00345   }
00346 
00347   return true;
00348 }
00349 
00350 ////////////////////////////////////////////////////////////////////
00351 //     Function: TxaFile::parse_shadowtype_line
00352 //       Access: Private
00353 //  Description: Handles the line in a .txa file that begins with the
00354 //               keyword ":shadowtype" and indicates the image file
00355 //               type to convert working copies of the palette images
00356 //               to.
00357 ////////////////////////////////////////////////////////////////////
00358 bool TxaFile::
00359 parse_shadowtype_line(const vector_string &words) {
00360   if (words.size() != 2) {
00361     nout << "Exactly one parameter required for :shadowtype.\n";
00362     return false;
00363   }
00364   const string &shadowtype = words[1];
00365   if (!parse_image_type_request(shadowtype, pal->_shadow_color_type,
00366                                 pal->_shadow_alpha_type)) {
00367     nout << "\nKnown image types are:\n";
00368     PNMFileTypeRegistry::get_ptr()->write_types(nout, 2);
00369     nout << "\n";
00370     return false;
00371   }
00372 
00373   return true;
00374 }
00375 
00376 ////////////////////////////////////////////////////////////////////
00377 //     Function: TxaFile::parse_round_line
00378 //       Access: Private
00379 //  Description: Handles the line in a .txa file that begins with the
00380 //               keyword ":round" and indicates how or whether to
00381 //               round up UV minmax boxes.
00382 ////////////////////////////////////////////////////////////////////
00383 bool TxaFile::
00384 parse_round_line(const vector_string &words) {
00385   if (words.size() == 2) {
00386     if (words[1] == "no") {
00387       pal->_round_uvs = false;
00388       return true;
00389     } else {
00390       nout << "Invalid round keyword: " << words[1] << ".\n"
00391            << "Expected 'no', or a round fraction and fuzz factor.\n";
00392       return false;
00393     }
00394   }
00395 
00396   if (words.size() != 3) {
00397     nout << "Exactly two parameters required for :round, the fraction "
00398          << "to round to, and the fuzz factor.\n";
00399     return false;
00400   }
00401 
00402   if (!string_to_double(words[1], pal->_round_unit) ||
00403       !string_to_double(words[2], pal->_round_fuzz)) {
00404     nout << "Invalid rounding: " << words[1] << " " << words[2] << "\n";
00405     return false;
00406   }
00407 
00408   if (pal->_round_unit <= 0.0 || pal->_round_fuzz < 0.0) {
00409     nout << "Invalid rounding: " << pal->_round_unit
00410          << " " << pal->_round_fuzz << "\n";
00411     return false;
00412   }
00413 
00414   pal->_round_uvs = true;
00415   return true;
00416 }
00417 
00418 ////////////////////////////////////////////////////////////////////
00419 //     Function: TxaFile::parse_remap_line
00420 //       Access: Private
00421 //  Description: Handles the line in a .txa file that begins with the
00422 //               keyword ":remap" and indicates how or whether to
00423 //               remap UV coordinates in egg files to the unit box.
00424 ////////////////////////////////////////////////////////////////////
00425 bool TxaFile::
00426 parse_remap_line(const vector_string &words) {
00427   int i = 1;
00428   while (i < (int)words.size()) {
00429     const string &keyword = words[i];
00430     if (keyword == "char") {
00431       // Defining how to remap UV's for characters.
00432       i++;
00433       if (i == (int)words.size()) {
00434         nout << "Keyword expected following 'char'\n";
00435         return false;
00436       }
00437       pal->_remap_char_uv = Palettizer::string_remap(words[i]);
00438       if (pal->_remap_char_uv == Palettizer::RU_invalid) {
00439         nout << "Invalid remap keyword: " << words[i] << "\n";
00440         return false;
00441       }
00442 
00443     } else {
00444       // Defining how to remap UV's in general.
00445       pal->_remap_uv = Palettizer::string_remap(words[i]);
00446       if (pal->_remap_uv == Palettizer::RU_invalid) {
00447         nout << "Invalid remap keyword: " << words[i] << "\n";
00448         return false;
00449       }
00450 
00451       pal->_remap_char_uv = pal->_remap_uv;
00452     }
00453 
00454     i++;
00455   }
00456 
00457   return true;
00458 }

Generated on Fri May 2 03:18:32 2003 for Panda-Tool by doxygen1.3