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