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

pandatool/src/xfile/xFileMaterial.cxx

Go to the documentation of this file.
00001 // Filename: xFileMaterial.cxx
00002 // Created by:  drose (19Jun01)
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 "xFileMaterial.h"
00020 #include "xFileToEggConverter.h"
00021 
00022 #include "eggMaterial.h"
00023 #include "eggTexture.h"
00024 #include "eggPrimitive.h"
00025 #include "datagram.h"
00026 
00027 #include <string.h>  // for strcmp, strdup
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //     Function: XFileMaterial::Constructor
00031 //       Access: Public
00032 //  Description:
00033 ////////////////////////////////////////////////////////////////////
00034 XFileMaterial::
00035 XFileMaterial() {
00036   _face_color.set(1.0, 1.0, 1.0, 1.0);
00037   _specular_color.set(0.0, 0.0, 0.0);
00038   _emissive_color.set(0.0, 0.0, 0.0);
00039   _power = 64.0;
00040 
00041   _has_material = false;
00042   _has_texture = false;
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: XFileMaterial::Destructor
00047 //       Access: Public
00048 //  Description:
00049 ////////////////////////////////////////////////////////////////////
00050 XFileMaterial::
00051 ~XFileMaterial() {
00052 }
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 //     Function: XFileMaterial::set_from_egg
00056 //       Access: Public
00057 //  Description: Sets the structure up from the indicated egg data.
00058 ////////////////////////////////////////////////////////////////////
00059 void XFileMaterial::
00060 set_from_egg(EggPrimitive *egg_prim) {
00061   // First, determine the face color.
00062   if (egg_prim->has_color()) {
00063     _face_color = egg_prim->get_color();
00064     _has_material = true;
00065   }
00066 
00067   // Do we have an actual EggMaterial, to control lighting effects?
00068   if (egg_prim->has_material()) {
00069     _has_material = true;
00070     EggMaterial *egg_mat = egg_prim->get_material();
00071     if (egg_mat->has_diff()) {
00072       _face_color = egg_mat->get_diff();
00073     }
00074     if (egg_mat->has_spec()) {
00075       const Colorf &spec = egg_mat->get_spec();
00076       _specular_color.set(spec[0], spec[1], spec[2]);
00077     }
00078     if (egg_mat->has_emit()) {
00079       const Colorf &emit = egg_mat->get_emit();
00080       _emissive_color.set(emit[0], emit[1], emit[2]);
00081     }
00082     if (egg_mat->has_shininess()) {
00083       _power = egg_mat->get_shininess();
00084     }
00085   }
00086 
00087   // Finally, if we also have a texture, record that.
00088   if (egg_prim->has_texture()) {
00089     _has_material = true;
00090     _has_texture = true;
00091     EggTexture *egg_tex = egg_prim->get_texture();
00092     _texture = egg_tex->get_filename();
00093   }
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: XFileMaterial::apply_to_egg
00098 //       Access: Public
00099 //  Description: Applies the properties in the material to the
00100 //               indicated egg primitive.
00101 ////////////////////////////////////////////////////////////////////
00102 void XFileMaterial::
00103 apply_to_egg(EggPrimitive *egg_prim, XFileToEggConverter *converter) {
00104   // Is there a texture?
00105   if (_has_texture) {
00106     Filename texture = converter->convert_texture_path(_texture);
00107     EggTexture temp("", texture);
00108     EggTexture *egg_tex = converter->create_unique_texture(temp);
00109     egg_prim->set_texture(egg_tex);
00110   }
00111 
00112   // Are there any fancy lighting effects?
00113   bool got_spec = (_specular_color != RGBColorf::zero());
00114   bool got_emit = (_emissive_color != RGBColorf::zero());
00115   if (got_spec || got_emit) {
00116     EggMaterial temp("");
00117     temp.set_diff(_face_color);
00118     if (got_spec) {
00119       temp.set_shininess(_power);
00120       temp.set_spec(Colorf(_specular_color[0], _specular_color[1],
00121                            _specular_color[2], 1.0));
00122     }
00123     if (got_emit) {
00124       temp.set_emit(Colorf(_emissive_color[0], _emissive_color[1],
00125                            _emissive_color[2], 1.0));
00126     }
00127     EggMaterial *egg_mat = converter->create_unique_material(temp);
00128     egg_prim->set_material(egg_mat);
00129   }
00130 
00131   // Also apply the face color.
00132   egg_prim->set_color(_face_color);
00133 }
00134 
00135 ////////////////////////////////////////////////////////////////////
00136 //     Function: XFileMaterial::compare_to
00137 //       Access: Public
00138 //  Description:
00139 ////////////////////////////////////////////////////////////////////
00140 int XFileMaterial::
00141 compare_to(const XFileMaterial &other) const {
00142   int ct;
00143   ct = _face_color.compare_to(other._face_color);
00144   if (ct == 0) {
00145     ct = (_power == other._power) ? 0 : ((_power < other._power) ? -1 : 1);
00146   }
00147   if (ct == 0) {
00148     ct = _specular_color.compare_to(other._specular_color);
00149   }
00150   if (ct == 0) {
00151     ct = _emissive_color.compare_to(other._emissive_color);
00152   }
00153   if (ct == 0) {
00154     ct = strcmp(_texture.c_str(), other._texture.c_str());
00155   }
00156   return ct;
00157 }
00158 
00159 ////////////////////////////////////////////////////////////////////
00160 //     Function: XFileMaterial::has_material
00161 //       Access: Public
00162 //  Description: Returns true if this material represents something
00163 //               meaningful, or false if the default material is
00164 //               sufficient.
00165 ////////////////////////////////////////////////////////////////////
00166 bool XFileMaterial::
00167 has_material() const {
00168   return _has_material;
00169 }
00170 
00171 ////////////////////////////////////////////////////////////////////
00172 //     Function: XFileMaterial::has_texture
00173 //       Access: Public
00174 //  Description: Returns true if this material includes a texture map,
00175 //               false otherwise.
00176 ////////////////////////////////////////////////////////////////////
00177 bool XFileMaterial::
00178 has_texture() const {
00179   return _has_texture;
00180 }
00181 
00182 ////////////////////////////////////////////////////////////////////
00183 //     Function: XFileMaterial::make_material_data
00184 //       Access: Public
00185 //  Description: Fills the datagram with the raw data for the DX
00186 //               Material template.
00187 ////////////////////////////////////////////////////////////////////
00188 void XFileMaterial::
00189 make_material_data(Datagram &raw_data) {
00190   raw_data.clear();
00191   raw_data.add_float32(_face_color[0]);
00192   raw_data.add_float32(_face_color[1]);
00193   raw_data.add_float32(_face_color[2]);
00194   raw_data.add_float32(_face_color[3]);
00195   raw_data.add_float32(_power);
00196   raw_data.add_float32(_specular_color[0]);
00197   raw_data.add_float32(_specular_color[1]);
00198   raw_data.add_float32(_specular_color[2]);
00199   raw_data.add_float32(_emissive_color[0]);
00200   raw_data.add_float32(_emissive_color[1]);
00201   raw_data.add_float32(_emissive_color[2]);
00202 }
00203 
00204 ////////////////////////////////////////////////////////////////////
00205 //     Function: XFileMaterial::make_texture_data
00206 //       Access: Public
00207 //  Description: Fills the datagram with the raw data for the DX
00208 //               TextureFilename template.
00209 ////////////////////////////////////////////////////////////////////
00210 void XFileMaterial::
00211 make_texture_data(Datagram &raw_data) {
00212   raw_data.clear();
00213 
00214   // Convert the filename to an appropriate form for the X file.
00215   string os_filename = _texture.to_os_specific();
00216   // Now we have to double up the backslashes.
00217   string filename;
00218   for (string::const_iterator pi = os_filename.begin();
00219        pi != os_filename.end();
00220        ++pi) {
00221     if ((*pi) == '\\') {
00222       filename += '\\';
00223       filename += '\\';
00224     } else {
00225       filename += (*pi);
00226     }
00227   }
00228 
00229   // Get a char * pointer to the texture filename, to pass into the
00230   // Microsoft DX file interface.  Unfortunately, we can't delete this
00231   // again, since it needs to live longer than the life of the
00232   // XFileMaterial object itself, so this becomes a memory leak
00233   // (unless the DX file interface frees it, but the documentation is
00234   // far from clear).  Too bad.
00235   char *filename_str = strdup(filename.c_str());
00236 
00237   // The Microsoft convention is to stuff a pointer into a four-byte
00238   // field.  Not terribly portable, but that's the interface.
00239   raw_data.add_int32((int)filename_str);
00240 }
00241 
00242 ////////////////////////////////////////////////////////////////////
00243 //     Function: XFileMaterial::read_material_data
00244 //       Access: Public
00245 //  Description: Fills the structure based on the raw data from the
00246 //               Material template.
00247 ////////////////////////////////////////////////////////////////////
00248 bool XFileMaterial::
00249 read_material_data(const Datagram &raw_data) {
00250   DatagramIterator di(raw_data);
00251 
00252   _face_color[0] = di.get_float32();
00253   _face_color[1] = di.get_float32();
00254   _face_color[2] = di.get_float32();
00255   _face_color[3] = di.get_float32();
00256   _power = di.get_float32();
00257   _specular_color[0] = di.get_float32();
00258   _specular_color[1] = di.get_float32();
00259   _specular_color[2] = di.get_float32();
00260   _emissive_color[0] = di.get_float32();
00261   _emissive_color[1] = di.get_float32();
00262   _emissive_color[2] = di.get_float32();
00263   _has_material = true;
00264 
00265   if (di.get_remaining_size() != 0) {
00266     nout << "Ignoring " << di.get_remaining_size()
00267          << " trailing MeshMaterial.\n";
00268   }
00269 
00270   return true;
00271 }
00272 
00273 ////////////////////////////////////////////////////////////////////
00274 //     Function: XFileMaterial::read_texture_data
00275 //       Access: Public
00276 //  Description: Fills the structure based on the raw data from the
00277 //               TextureFilename template.
00278 ////////////////////////////////////////////////////////////////////
00279 bool XFileMaterial::
00280 read_texture_data(const Datagram &raw_data) {
00281   DatagramIterator di(raw_data);
00282 
00283   // The Microsoft convention is to stuff a pointer into a four-byte
00284   // field.  Not terribly portable, but that's the interface.
00285   const char *ptr = (const char *)di.get_int32();
00286   _texture = Filename::from_os_specific(ptr);
00287   _has_texture = true;
00288 
00289   if (di.get_remaining_size() != 0) {
00290     nout << "Ignoring " << di.get_remaining_size()
00291          << " trailing MeshMaterial.\n";
00292   }
00293   return true;
00294 }

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