Panda3D
 All Classes Functions Variables Enumerations
material.cxx
1 // Filename: material.cxx
2 // Created by: mike (09Jan97)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "pandabase.h"
16 #include "material.h"
17 #include "indent.h"
18 #include "datagram.h"
19 #include "datagramIterator.h"
20 #include "bamReader.h"
21 #include "bamWriter.h"
22 
23 TypeHandle Material::_type_handle;
24 PT(Material) Material::_default;
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: Material::Copy Assignment Operator
28 // Access: Published
29 // Description:
30 ////////////////////////////////////////////////////////////////////
31 void Material::
32 operator = (const Material &copy) {
33  Namable::operator = (copy);
34  _ambient = copy._ambient;
35  _diffuse = copy._diffuse;
36  _specular = copy._specular;
37  _emission = copy._emission;
38  _shininess = copy._shininess;
39  _flags = copy._flags & (~F_attrib_lock);
40 }
41 
42 ////////////////////////////////////////////////////////////////////
43 // Function: Material::set_ambient
44 // Access: Published
45 // Description: Specifies the ambient color setting of the material.
46 // This will be the multiplied by any ambient lights in
47 // effect on the material to set its base color.
48 //
49 // This is the color of the object as it appears in the
50 // absence of direct light.
51 //
52 // If this is not set, the object color will be used.
53 ////////////////////////////////////////////////////////////////////
54 void Material::
56  if (enforce_attrib_lock) {
57  if ((_flags & F_ambient)==0) {
58  nassertv(!is_attrib_locked());
59  }
60  }
61  _ambient = color;
62  _flags |= F_ambient;
63 }
64 
65 ////////////////////////////////////////////////////////////////////
66 // Function: Material::set_diffuse
67 // Access: Published
68 // Description: Specifies the diffuse color setting of the material.
69 // This will be multiplied by any lights in effect on
70 // the material to get the color in the parts of the
71 // object illuminated by the lights.
72 //
73 // This is the primary color of an object; the color of
74 // the object as it appears in direct light, in the
75 // absence of highlights.
76 //
77 // If this is not set, the object color will be used.
78 ////////////////////////////////////////////////////////////////////
79 void Material::
81  if (enforce_attrib_lock) {
82  if ((_flags & F_diffuse)==0) {
83  nassertv(!is_attrib_locked());
84  }
85  }
86  _diffuse = color;
87  _flags |= F_diffuse;
88 }
89 
90 ////////////////////////////////////////////////////////////////////
91 // Function: Material::set_specular
92 // Access: Published
93 // Description: Specifies the diffuse color setting of the material.
94 // This will be multiplied by any lights in effect on
95 // the material to compute the color of specular
96 // highlights on the object.
97 //
98 // This is the highlight color of an object: the color
99 // of small highlight reflections.
100 //
101 // If this is not set, highlights will not appear.
102 ////////////////////////////////////////////////////////////////////
103 void Material::
105  if (enforce_attrib_lock) {
106  if ((_flags & F_specular)==0) {
107  nassertv(!is_attrib_locked());
108  }
109  }
110  _specular = color;
111  _flags |= F_specular;
112 }
113 
114 ////////////////////////////////////////////////////////////////////
115 // Function: Material::set_emission
116 // Access: Published
117 // Description: Specifies the emission color setting of the material.
118 // This is the color of the object as it appears in the
119 // absence of any light whatsover, including ambient
120 // light. It is as if the object is glowing by this
121 // color (although of course it will not illuminate
122 // neighboring objects).
123 //
124 // If this is not set, the object will not glow by its
125 // own light and will only appear visible in the
126 // presence of one or more lights.
127 ////////////////////////////////////////////////////////////////////
128 void Material::
130  if (enforce_attrib_lock) {
131  if ((_flags & F_emission)==0) {
132  nassertv(!is_attrib_locked());
133  }
134  }
135  _emission = color;
136  _flags |= F_emission;
137 }
138 
139 ////////////////////////////////////////////////////////////////////
140 // Function: Material::compare_to
141 // Access: Published
142 // Description: Returns a number less than zero if this material
143 // sorts before the other one, greater than zero if it
144 // sorts after, or zero if they are equivalent. The
145 // sorting order is arbitrary and largely meaningless,
146 // except to differentiate different materials.
147 ////////////////////////////////////////////////////////////////////
148 int Material::
149 compare_to(const Material &other) const {
150  if (_flags != other._flags) {
151  return _flags - other._flags;
152  }
153  if (has_ambient() && get_ambient() != other.get_ambient()) {
154  return get_ambient().compare_to(other.get_ambient());
155  }
156  if (has_diffuse() && get_diffuse() != other.get_diffuse()) {
157  return get_diffuse().compare_to(other.get_diffuse());
158  }
159  if (has_specular() && get_specular() != other.get_specular()) {
160  return get_specular().compare_to(other.get_specular());
161  }
162  if (has_emission() && get_emission() != other.get_emission()) {
163  return get_emission().compare_to(other.get_emission());
164  }
165  if (get_shininess() != other.get_shininess()) {
166  return get_shininess() < other.get_shininess() ? -1 : 1;
167  }
168 
169  return strcmp(get_name().c_str(), other.get_name().c_str());
170 }
171 
172 ////////////////////////////////////////////////////////////////////
173 // Function: Material::output
174 // Access: Published
175 // Description:
176 ////////////////////////////////////////////////////////////////////
177 void Material::
178 output(ostream &out) const {
179  out << "Material " << get_name();
180  if (has_ambient()) {
181  out << " a(" << get_ambient() << ")";
182  }
183  if (has_diffuse()) {
184  out << " d(" << get_diffuse() << ")";
185  }
186  if (has_specular()) {
187  out << " s(" << get_specular() << ")";
188  }
189  if (has_emission()) {
190  out << " e(" << get_emission() << ")";
191  }
192  out << " s" << get_shininess()
193  << " l" << get_local()
194  << " t" << get_twoside();
195 }
196 
197 ////////////////////////////////////////////////////////////////////
198 // Function: Material::write
199 // Access: Published
200 // Description:
201 ////////////////////////////////////////////////////////////////////
202 void Material::
203 write(ostream &out, int indent_level) const {
204  indent(out, indent_level) << "Material " << get_name() << "\n";
205  if (has_ambient()) {
206  indent(out, indent_level + 2) << "ambient = " << get_ambient() << "\n";
207  }
208  if (has_diffuse()) {
209  indent(out, indent_level + 2) << "diffuse = " << get_diffuse() << "\n";
210  }
211  if (has_specular()) {
212  indent(out, indent_level + 2) << "specular = " << get_specular() << "\n";
213  }
214  if (has_emission()) {
215  indent(out, indent_level + 2) << "emission = " << get_emission() << "\n";
216  }
217  indent(out, indent_level + 2) << "shininess = " << get_shininess() << "\n";
218  indent(out, indent_level + 2) << "local = " << get_local() << "\n";
219  indent(out, indent_level + 2) << "twoside = " << get_twoside() << "\n";
220 }
221 
222 
223 
224 ////////////////////////////////////////////////////////////////////
225 // Function: Material::register_with_read_factory
226 // Access: Public, Static
227 // Description: Factory method to generate a Material object
228 ////////////////////////////////////////////////////////////////////
229 void Material::
231  BamReader::get_factory()->register_factory(get_class_type(), make_Material);
232 }
233 
234 ////////////////////////////////////////////////////////////////////
235 // Function: Material::write_datagram
236 // Access: Public
237 // Description: Function to write the important information in
238 // the particular object to a Datagram
239 ////////////////////////////////////////////////////////////////////
240 void Material::
242  me.add_string(get_name());
243  _ambient.write_datagram(me);
244  _diffuse.write_datagram(me);
245  _specular.write_datagram(me);
246  _emission.write_datagram(me);
247  me.add_stdfloat(_shininess);
248  me.add_int32(_flags);
249 }
250 
251 ////////////////////////////////////////////////////////////////////
252 // Function: Material::make_Material
253 // Access: Protected
254 // Description: Factory method to generate a Material object
255 ////////////////////////////////////////////////////////////////////
256 TypedWritable *Material::
257 make_Material(const FactoryParams &params) {
258  Material *me = new Material;
259  DatagramIterator scan;
260  BamReader *manager;
261 
262  parse_params(params, scan, manager);
263  me->fillin(scan, manager);
264  return me;
265 }
266 
267 ////////////////////////////////////////////////////////////////////
268 // Function: Material::fillin
269 // Access: Protected
270 // Description: Function that reads out of the datagram (or asks
271 // manager to read) all of the data that is needed to
272 // re-create this object and stores it in the appropiate
273 // place
274 ////////////////////////////////////////////////////////////////////
275 void Material::
276 fillin(DatagramIterator &scan, BamReader *manager) {
277  set_name(scan.get_string());
278  _ambient.read_datagram(scan);
279  _diffuse.read_datagram(scan);
280  _specular.read_datagram(scan);
281  _emission.read_datagram(scan);
282  _shininess = scan.get_stdfloat();
283  _flags = scan.get_int32();
284 }
int compare_to(const LVecBase4f &other) const
This flavor of compare_to uses a default threshold value based on the numeric type.
Definition: lvecBase4.h:971
const LColor & get_ambient() const
Returns the ambient color setting, if it has been set.
Definition: material.I:82
virtual void write_datagram(BamWriter *manager, Datagram &me)
Function to write the important information in the particular object to a Datagram.
Definition: material.cxx:241
void set_diffuse(const LColor &color)
Specifies the diffuse color setting of the material.
Definition: material.cxx:80
void add_string(const string &str)
Adds a variable-length string to the datagram.
Definition: datagram.I:351
PN_stdfloat get_stdfloat()
Extracts either a 32-bit or a 64-bit floating-point number, according to Datagram::set_stdfloat_doubl...
bool has_ambient() const
Returns true if the ambient color has been explicitly set for this material, false otherwise...
Definition: material.I:70
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
bool has_specular() const
Returns true if the specular color has been explicitly set for this material, false otherwise...
Definition: material.I:144
bool get_twoside() const
Returns the state of the two-sided lighting flag.
Definition: material.I:274
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
PN_stdfloat get_shininess() const
Returns the shininess exponent of the material.
Definition: material.I:217
PN_int32 get_int32()
Extracts a signed 32-bit integer.
bool has_emission() const
Returns true if the emission color has been explicitly set for this material, false otherwise...
Definition: material.I:181
const LColor & get_emission() const
Returns the emission color setting, if it has been set.
Definition: material.I:193
string get_string()
Extracts a variable-length string.
void set_emission(const LColor &color)
Specifies the emission color setting of the material.
Definition: material.cxx:129
void set_specular(const LColor &color)
Specifies the diffuse color setting of the material.
Definition: material.cxx:104
void add_stdfloat(PN_stdfloat value)
Adds either a 32-bit or a 64-bit floating-point number, according to set_stdfloat_double().
Definition: datagram.I:240
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void read_datagram(DatagramIterator &source)
Reads the vector from the Datagram using get_stdfloat().
Definition: lvecBase4.h:1442
const LColor & get_specular() const
Returns the specular color setting, if it has been set.
Definition: material.I:156
Defines the way an object appears in the presence of lighting.
Definition: material.h:34
void register_factory(TypeHandle handle, CreateFunc *func)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:90
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
void write_datagram(Datagram &destination) const
Writes the vector to the Datagram using add_stdfloat().
Definition: lvecBase4.h:1422
bool has_diffuse() const
Returns true if the diffuse color has been explicitly set for this material, false otherwise...
Definition: material.I:107
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
void add_int32(PN_int32 value)
Adds a signed 32-bit integer to the datagram.
Definition: datagram.I:159
A class to retrieve the individual data elements previously stored in a Datagram. ...
bool get_local() const
Returns the local viewer flag.
Definition: material.I:242
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
int compare_to(const Material &other) const
Returns a number less than zero if this material sorts before the other one, greater than zero if it ...
Definition: material.cxx:149
void set_ambient(const LColor &color)
Specifies the ambient color setting of the material.
Definition: material.cxx:55
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
const LColor & get_diffuse() const
Returns the diffuse color setting, if it has been set.
Definition: material.I:119
static void register_with_read_factory()
Factory method to generate a Material object.
Definition: material.cxx:230