Panda3D
 All Classes Functions Variables Enumerations
xFileMaterial.cxx
1 // Filename: xFileMaterial.cxx
2 // Created by: drose (19Jun01)
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 "xFileMaterial.h"
16 #include "xFileToEggConverter.h"
17 #include "xFileDataNode.h"
18 #include "eggMaterial.h"
19 #include "eggTexture.h"
20 #include "eggPrimitive.h"
21 #include "datagram.h"
22 
23 #include <string.h> // for strcmp, strdup
24 
25 ////////////////////////////////////////////////////////////////////
26 // Function: XFileMaterial::Constructor
27 // Access: Public
28 // Description:
29 ////////////////////////////////////////////////////////////////////
30 XFileMaterial::
31 XFileMaterial() {
32  _face_color.set(1.0, 1.0, 1.0, 1.0);
33  _specular_color.set(0.0, 0.0, 0.0);
34  _emissive_color.set(0.0, 0.0, 0.0);
35  _power = 64.0;
36 
37  _has_material = false;
38  _has_texture = false;
39 }
40 
41 ////////////////////////////////////////////////////////////////////
42 // Function: XFileMaterial::Destructor
43 // Access: Public
44 // Description:
45 ////////////////////////////////////////////////////////////////////
46 XFileMaterial::
47 ~XFileMaterial() {
48 }
49 
50 ////////////////////////////////////////////////////////////////////
51 // Function: XFileMaterial::set_from_egg
52 // Access: Public
53 // Description: Sets the structure up from the indicated egg data.
54 ////////////////////////////////////////////////////////////////////
55 void XFileMaterial::
57  // First, determine the face color.
58  if (egg_prim->has_color()) {
59  _face_color = egg_prim->get_color();
60  _has_material = true;
61  }
62 
63  // Do we have an actual EggMaterial, to control lighting effects?
64  if (egg_prim->has_material()) {
65  _has_material = true;
66  EggMaterial *egg_mat = egg_prim->get_material();
67  if (egg_mat->has_diff()) {
68  _face_color = egg_mat->get_diff();
69  }
70  if (egg_mat->has_spec()) {
71  const LColor &spec = egg_mat->get_spec();
72  _specular_color.set(spec[0], spec[1], spec[2]);
73  }
74  if (egg_mat->has_emit()) {
75  const LColor &emit = egg_mat->get_emit();
76  _emissive_color.set(emit[0], emit[1], emit[2]);
77  }
78  if (egg_mat->has_shininess()) {
79  _power = egg_mat->get_shininess();
80  }
81  }
82 
83  // Finally, if we also have a texture, record that.
84  if (egg_prim->has_texture()) {
85  _has_material = true;
86  _has_texture = true;
87  EggTexture *egg_tex = egg_prim->get_texture();
88  _texture = egg_tex->get_filename();
89  }
90 }
91 
92 ////////////////////////////////////////////////////////////////////
93 // Function: XFileMaterial::apply_to_egg
94 // Access: Public
95 // Description: Applies the properties in the material to the
96 // indicated egg primitive.
97 ////////////////////////////////////////////////////////////////////
98 void XFileMaterial::
100  // Is there a texture?
101  if (_has_texture) {
102  Filename texture = converter->convert_model_path(_texture);
103  EggTexture temp("", texture);
104  EggTexture *egg_tex = converter->create_unique_texture(temp);
105  egg_prim->set_texture(egg_tex);
106  }
107 
108  // Are there any fancy lighting effects?
109  bool got_spec = (_specular_color != LRGBColor::zero());
110  bool got_emit = (_emissive_color != LRGBColor::zero());
111  if (got_spec || got_emit) {
112  EggMaterial temp("");
113  temp.set_diff(_face_color);
114  if (got_spec) {
115  temp.set_shininess(_power);
116  temp.set_spec(LColor(_specular_color[0], _specular_color[1],
117  _specular_color[2], 1.0));
118  }
119  if (got_emit) {
120  temp.set_emit(LColor(_emissive_color[0], _emissive_color[1],
121  _emissive_color[2], 1.0));
122  }
123  EggMaterial *egg_mat = converter->create_unique_material(temp);
124  egg_prim->set_material(egg_mat);
125  }
126 
127  // Also apply the face color.
128  egg_prim->set_color(_face_color);
129 }
130 
131 ////////////////////////////////////////////////////////////////////
132 // Function: XFileMaterial::compare_to
133 // Access: Public
134 // Description:
135 ////////////////////////////////////////////////////////////////////
136 int XFileMaterial::
137 compare_to(const XFileMaterial &other) const {
138  int ct;
139  ct = _face_color.compare_to(other._face_color);
140  if (ct == 0) {
141  ct = (_power == other._power) ? 0 : ((_power < other._power) ? -1 : 1);
142  }
143  if (ct == 0) {
144  ct = _specular_color.compare_to(other._specular_color);
145  }
146  if (ct == 0) {
147  ct = _emissive_color.compare_to(other._emissive_color);
148  }
149  if (ct == 0) {
150  ct = strcmp(_texture.c_str(), other._texture.c_str());
151  }
152  return ct;
153 }
154 
155 ////////////////////////////////////////////////////////////////////
156 // Function: XFileMaterial::has_material
157 // Access: Public
158 // Description: Returns true if this material represents something
159 // meaningful, or false if the default material is
160 // sufficient.
161 ////////////////////////////////////////////////////////////////////
162 bool XFileMaterial::
163 has_material() const {
164  return _has_material;
165 }
166 
167 ////////////////////////////////////////////////////////////////////
168 // Function: XFileMaterial::has_texture
169 // Access: Public
170 // Description: Returns true if this material includes a texture map,
171 // false otherwise.
172 ////////////////////////////////////////////////////////////////////
173 bool XFileMaterial::
174 has_texture() const {
175  return _has_texture;
176 }
177 
178 ////////////////////////////////////////////////////////////////////
179 // Function: XFileMaterial::make_x_material
180 // Access: Public
181 // Description: Creates a Material object for the material list.
182 ////////////////////////////////////////////////////////////////////
184 make_x_material(XFileNode *x_meshMaterials, const string &suffix) {
185  XFileDataNode *x_material =
186  x_meshMaterials->add_Material("material" + suffix,
187  _face_color, _power,
188  _specular_color, _emissive_color);
189 
190  if (has_texture()) {
191  x_material->add_TextureFilename("texture" + suffix, _texture);
192  }
193 
194  return x_material;
195 }
196 
197 ////////////////////////////////////////////////////////////////////
198 // Function: XFileMaterial::fill_material
199 // Access: Public
200 // Description: Fills the structure based on the raw data from the
201 // X file's Material object.
202 ////////////////////////////////////////////////////////////////////
203 bool XFileMaterial::
205  _face_color = LCAST(PN_stdfloat, (*obj)["faceColor"].vec4());
206  _power = (*obj)["power"].d();
207  _specular_color = LCAST(PN_stdfloat, (*obj)["specularColor"].vec3());
208  _emissive_color = LCAST(PN_stdfloat, (*obj)["emissiveColor"].vec3());
209  _has_material = true;
210 
211  // Walk through the children of the material. If there are any,
212  // there should be only one, and it should be just a Texture.
213  int num_objects = obj->get_num_objects();
214  for (int i = 0; i < num_objects; i++) {
215  XFileDataNode *child = obj->get_object(i);
216  if (child->is_standard_object("TextureFilename")) {
217  _texture = Filename::from_os_specific((*child)["filename"].s());
218  _has_texture = true;
219 
220  } else {
221  if (xfile_cat.is_debug()) {
222  xfile_cat.debug()
223  << "Ignoring material object of unknown type: "
224  << child->get_template_name() << "\n";
225  }
226  }
227  }
228 
229  return true;
230 }
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
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
Definition: eggPrimitive.h:51
XFileDataNode * get_object(int n) const
Returns the nth child object of this node.
Definition: xFileNode.I:71
const string & get_template_name() const
A convenience function to return the name of the template used to define this data object...
Definition: xFileDataNode.I:53
LColor get_color() const
Returns the color set on this particular attribute.
virtual bool is_standard_object(const string &template_name) const
Returns true if this node represents an instance of the standard template with the indicated name...
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:33
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
Definition: eggPrimitive.I:139
void apply_to_egg(EggPrimitive *egg_prim, XFileToEggConverter *converter)
Applies the properties in the material to the indicated egg primitive.
EggTexture * get_texture() const
Returns the first texture on the primitive, if any, or NULL if there are no textures on the primitive...
Definition: eggPrimitive.I:182
static const LVecBase3f & zero()
Returns a zero-length vector.
Definition: lvecBase3.h:381
void set_from_egg(EggPrimitive *egg_prim)
Sets the structure up from the indicated egg data.
EggMaterial * create_unique_material(const EggMaterial &copy)
Returns an EggMaterial pointer whose properties match that of the the given EggMaterial, except for the mref name.
int get_num_objects() const
Returns the list of child objects of this node.
Definition: xFileNode.I:58
XFileDataNode * make_x_material(XFileNode *x_meshMaterials, const string &suffix)
Creates a Material object for the material list.
A single node of an X file.
Definition: xFileNode.h:42
XFileDataNode * add_TextureFilename(const string &name, const Filename &filename)
Creates a new TextureFilename instance, as a child of this node.
Definition: xFileNode.cxx:479
LColor get_diff() const
It is legal to call this even if has_diff() returns false.
Definition: eggMaterial.I:55
int compare_to(const LVecBase3f &other) const
This flavor of compare_to uses a default threshold value based on the numeric type.
Definition: lvecBase3.h:923
EggMaterial * get_material() const
Returns a pointer to the applied material, or NULL if there is no material applied.
Definition: eggPrimitive.I:262
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
void set_material(EggMaterial *material)
Applies the indicated material to the primitive.
Definition: eggPrimitive.I:241
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111
bool has_material() const
Returns true if this material represents something meaningful, or false if the default material is su...
bool has_material() const
Returns true if the primitive is materiald (and get_material() will return a real pointer)...
Definition: eggPrimitive.I:275
This represents an X file &quot;material&quot;, which consists of a color, lighting, and/or texture specificati...
Definition: xFileMaterial.h:33
This is an abstract base class for an XFileNode which is also an XFileDataObject. ...
Definition: xFileDataNode.h:36
EggTexture * create_unique_texture(const EggTexture &copy)
Returns an EggTexture pointer whose properties match that of the the given EggTexture, except for the tref name.
bool fill_material(XFileDataNode *obj)
Fills the structure based on the raw data from the X file&#39;s Material object.
LColor get_spec() const
It is legal to call this even if has_spec() returns false.
Definition: eggMaterial.I:196
LColor get_emit() const
It is legal to call this even if has_emit() returns false.
Definition: eggMaterial.I:149
XFileDataNode * add_Material(const string &name, const LColor &face_color, double power, const LRGBColor &specular_color, const LRGBColor &emissive_color)
Creates a new Material instance, as a child of this node.
Definition: xFileNode.cxx:447
Filename convert_model_path(const Filename &orig_filename)
Converts the indicated model filename to a relative or absolute or whatever filename, according to _path_replace.
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
Definition: eggPrimitive.I:155
bool has_texture() const
Returns true if this material includes a texture map, false otherwise.
static Filename from_os_specific(const string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes, and no drive letter) based on the supplied filename string that describes a filename in the local system conventions (for instance, on Windows, it may use backslashes or begin with a drive letter and a colon).
Definition: filename.cxx:332