Panda3D

material.cxx

00001 // Filename: material.cxx
00002 // Created by:  mike (09Jan97)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "pandabase.h"
00016 #include "material.h"
00017 #include "indent.h"
00018 #include "datagram.h"
00019 #include "datagramIterator.h"
00020 #include "bamReader.h"
00021 #include "bamWriter.h"
00022 
00023 TypeHandle Material::_type_handle;
00024 PT(Material) Material::_default;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: Material::Copy Assignment Operator
00028 //       Access: Published
00029 //  Description:
00030 ////////////////////////////////////////////////////////////////////
00031 void Material::
00032 operator = (const Material &copy) {
00033   Namable::operator = (copy);
00034   _ambient = copy._ambient;
00035   _diffuse = copy._diffuse;
00036   _specular = copy._specular;
00037   _emission = copy._emission;
00038   _shininess = copy._shininess;
00039   _flags = copy._flags & (~F_attrib_lock);
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: Material::set_ambient
00044 //       Access: Published
00045 //  Description: Specifies the ambient color setting of the material.
00046 //               This will be the multiplied by any ambient lights in
00047 //               effect on the material to set its base color.
00048 //
00049 //               This is the color of the object as it appears in the
00050 //               absence of direct light.
00051 //
00052 //               If this is not set, the object color will be used.
00053 ////////////////////////////////////////////////////////////////////
00054 void Material::
00055 set_ambient(const LColor &color) {
00056   if (enforce_attrib_lock) {
00057     if ((_flags & F_ambient)==0) {
00058       nassertv(!is_attrib_locked());
00059     }
00060   }
00061   _ambient = color;
00062   _flags |= F_ambient;
00063 }
00064 
00065 ////////////////////////////////////////////////////////////////////
00066 //     Function: Material::set_diffuse
00067 //       Access: Published
00068 //  Description: Specifies the diffuse color setting of the material.
00069 //               This will be multiplied by any lights in effect on
00070 //               the material to get the color in the parts of the
00071 //               object illuminated by the lights.
00072 //
00073 //               This is the primary color of an object; the color of
00074 //               the object as it appears in direct light, in the
00075 //               absence of highlights.
00076 //
00077 //               If this is not set, the object color will be used.
00078 ////////////////////////////////////////////////////////////////////
00079 void Material::
00080 set_diffuse(const LColor &color) {
00081   if (enforce_attrib_lock) {
00082     if ((_flags & F_diffuse)==0) {
00083       nassertv(!is_attrib_locked());
00084     }
00085   }
00086   _diffuse = color;
00087   _flags |= F_diffuse;
00088 }
00089 
00090 ////////////////////////////////////////////////////////////////////
00091 //     Function: Material::set_specular
00092 //       Access: Published
00093 //  Description: Specifies the diffuse color setting of the material.
00094 //               This will be multiplied by any lights in effect on
00095 //               the material to compute the color of specular
00096 //               highlights on the object.
00097 //
00098 //               This is the highlight color of an object: the color
00099 //               of small highlight reflections.
00100 //
00101 //               If this is not set, highlights will not appear.
00102 ////////////////////////////////////////////////////////////////////
00103 void Material::
00104 set_specular(const LColor &color) {
00105   if (enforce_attrib_lock) {
00106     if ((_flags & F_specular)==0) {
00107       nassertv(!is_attrib_locked());
00108     }
00109   }
00110   _specular = color;
00111   _flags |= F_specular;
00112 }
00113 
00114 ////////////////////////////////////////////////////////////////////
00115 //     Function: Material::set_emission
00116 //       Access: Published
00117 //  Description: Specifies the emission color setting of the material.
00118 //               This is the color of the object as it appears in the
00119 //               absence of any light whatsover, including ambient
00120 //               light.  It is as if the object is glowing by this
00121 //               color (although of course it will not illuminate
00122 //               neighboring objects).
00123 //
00124 //               If this is not set, the object will not glow by its
00125 //               own light and will only appear visible in the
00126 //               presence of one or more lights.
00127 ////////////////////////////////////////////////////////////////////
00128 void Material::
00129 set_emission(const LColor &color) {
00130   if (enforce_attrib_lock) {
00131     if ((_flags & F_emission)==0) {
00132       nassertv(!is_attrib_locked());
00133     }
00134   }
00135   _emission = color;
00136   _flags |= F_emission;
00137 }
00138 
00139 ////////////////////////////////////////////////////////////////////
00140 //     Function: Material::compare_to
00141 //       Access: Published
00142 //  Description: Returns a number less than zero if this material
00143 //               sorts before the other one, greater than zero if it
00144 //               sorts after, or zero if they are equivalent.  The
00145 //               sorting order is arbitrary and largely meaningless,
00146 //               except to differentiate different materials.
00147 ////////////////////////////////////////////////////////////////////
00148 int Material::
00149 compare_to(const Material &other) const {
00150   if (_flags != other._flags) {
00151     return _flags - other._flags;
00152   }
00153   if (has_ambient() && get_ambient() != other.get_ambient()) {
00154     return get_ambient().compare_to(other.get_ambient());
00155   }
00156   if (has_diffuse() && get_diffuse() != other.get_diffuse()) {
00157     return get_diffuse().compare_to(other.get_diffuse());
00158   }
00159   if (has_specular() && get_specular() != other.get_specular()) {
00160     return get_specular().compare_to(other.get_specular());
00161   }
00162   if (has_emission() && get_emission() != other.get_emission()) {
00163     return get_emission().compare_to(other.get_emission());
00164   }
00165   if (get_shininess() != other.get_shininess()) {
00166     return get_shininess() < other.get_shininess() ? -1 : 1;
00167   }
00168 
00169   return strcmp(get_name().c_str(), other.get_name().c_str());
00170 }
00171 
00172 ////////////////////////////////////////////////////////////////////
00173 //     Function: Material::output
00174 //       Access: Published
00175 //  Description:
00176 ////////////////////////////////////////////////////////////////////
00177 void Material::
00178 output(ostream &out) const {
00179   out << "Material " << get_name();
00180   if (has_ambient()) {
00181     out << " a(" << get_ambient() << ")";
00182   }
00183   if (has_diffuse()) {
00184     out << " d(" << get_diffuse() << ")";
00185   }
00186   if (has_specular()) {
00187     out << " s(" << get_specular() << ")";
00188   }
00189   if (has_emission()) {
00190     out << " e(" << get_emission() << ")";
00191   }
00192   out << " s" << get_shininess()
00193       << " l" << get_local()
00194       << " t" << get_twoside();
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: Material::write
00199 //       Access: Published
00200 //  Description:
00201 ////////////////////////////////////////////////////////////////////
00202 void Material::
00203 write(ostream &out, int indent_level) const {
00204   indent(out, indent_level) << "Material " << get_name() << "\n";
00205   if (has_ambient()) {
00206     indent(out, indent_level + 2) << "ambient = " << get_ambient() << "\n";
00207   }
00208   if (has_diffuse()) {
00209     indent(out, indent_level + 2) << "diffuse = " << get_diffuse() << "\n";
00210   }
00211   if (has_specular()) {
00212     indent(out, indent_level + 2) << "specular = " << get_specular() << "\n";
00213   }
00214   if (has_emission()) {
00215     indent(out, indent_level + 2) << "emission = " << get_emission() << "\n";
00216   }
00217   indent(out, indent_level + 2) << "shininess = " << get_shininess() << "\n";
00218   indent(out, indent_level + 2) << "local = " << get_local() << "\n";
00219   indent(out, indent_level + 2) << "twoside = " << get_twoside() << "\n";
00220 }
00221 
00222 
00223 
00224 ////////////////////////////////////////////////////////////////////
00225 //     Function: Material::register_with_read_factory
00226 //       Access: Public, Static
00227 //  Description: Factory method to generate a Material object
00228 ////////////////////////////////////////////////////////////////////
00229 void Material::
00230 register_with_read_factory() {
00231   BamReader::get_factory()->register_factory(get_class_type(), make_Material);
00232 }
00233 
00234 ////////////////////////////////////////////////////////////////////
00235 //     Function: Material::write_datagram
00236 //       Access: Public
00237 //  Description: Function to write the important information in
00238 //               the particular object to a Datagram
00239 ////////////////////////////////////////////////////////////////////
00240 void Material::
00241 write_datagram(BamWriter *manager, Datagram &me) {
00242   me.add_string(get_name());
00243   _ambient.write_datagram(me);
00244   _diffuse.write_datagram(me);
00245   _specular.write_datagram(me);
00246   _emission.write_datagram(me);
00247   me.add_stdfloat(_shininess);
00248   me.add_int32(_flags);
00249 }
00250 
00251 ////////////////////////////////////////////////////////////////////
00252 //     Function: Material::make_Material
00253 //       Access: Protected
00254 //  Description: Factory method to generate a Material object
00255 ////////////////////////////////////////////////////////////////////
00256 TypedWritable *Material::
00257 make_Material(const FactoryParams &params) {
00258   Material *me = new Material;
00259   DatagramIterator scan;
00260   BamReader *manager;
00261 
00262   parse_params(params, scan, manager);
00263   me->fillin(scan, manager);
00264   return me;
00265 }
00266 
00267 ////////////////////////////////////////////////////////////////////
00268 //     Function: Material::fillin
00269 //       Access: Protected
00270 //  Description: Function that reads out of the datagram (or asks
00271 //               manager to read) all of the data that is needed to
00272 //               re-create this object and stores it in the appropiate
00273 //               place
00274 ////////////////////////////////////////////////////////////////////
00275 void Material::
00276 fillin(DatagramIterator &scan, BamReader *manager) {
00277   set_name(scan.get_string());
00278   _ambient.read_datagram(scan);
00279   _diffuse.read_datagram(scan);
00280   _specular.read_datagram(scan);
00281   _emission.read_datagram(scan);
00282   _shininess = scan.get_stdfloat();
00283   _flags = scan.get_int32();
00284 }
 All Classes Functions Variables Enumerations