Panda3D
|
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 ©) { 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 ¶ms) { 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 }