Panda3D
xFileMaterial.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file xFileMaterial.cxx
10  * @author drose
11  * @date 2001-06-19
12  */
13 
14 #include "xFileMaterial.h"
15 #include "xFileToEggConverter.h"
16 #include "xFileDataNode.h"
17 #include "eggMaterial.h"
18 #include "eggTexture.h"
19 #include "eggPrimitive.h"
20 #include "datagram.h"
21 #include "config_xfile.h"
22 
23 #include <string.h> // for strcmp, strdup
24 
25 /**
26  *
27  */
28 XFileMaterial::
29 XFileMaterial() {
30  _face_color.set(1.0, 1.0, 1.0, 1.0);
31  _specular_color.set(0.0, 0.0, 0.0);
32  _emissive_color.set(0.0, 0.0, 0.0);
33  _power = 64.0;
34 
35  _has_material = false;
36  _has_texture = false;
37 }
38 
39 /**
40  *
41  */
42 XFileMaterial::
43 ~XFileMaterial() {
44 }
45 
46 /**
47  * Sets the structure up from the indicated egg data.
48  */
49 void XFileMaterial::
51  // First, determine the face color.
52  if (egg_prim->has_color()) {
53  _face_color = egg_prim->get_color();
54  _has_material = true;
55  }
56 
57  // Do we have an actual EggMaterial, to control lighting effects?
58  if (egg_prim->has_material()) {
59  _has_material = true;
60  EggMaterial *egg_mat = egg_prim->get_material();
61  if (egg_mat->has_diff()) {
62  _face_color = egg_mat->get_diff();
63  }
64  if (egg_mat->has_spec()) {
65  const LColor &spec = egg_mat->get_spec();
66  _specular_color.set(spec[0], spec[1], spec[2]);
67  }
68  if (egg_mat->has_emit()) {
69  const LColor &emit = egg_mat->get_emit();
70  _emissive_color.set(emit[0], emit[1], emit[2]);
71  }
72  if (egg_mat->has_shininess()) {
73  _power = egg_mat->get_shininess();
74  }
75  }
76 
77  // Finally, if we also have a texture, record that.
78  if (egg_prim->has_texture()) {
79  _has_material = true;
80  _has_texture = true;
81  EggTexture *egg_tex = egg_prim->get_texture();
82  _texture = egg_tex->get_filename();
83  }
84 }
85 
86 /**
87  * Applies the properties in the material to the indicated egg primitive.
88  */
89 void XFileMaterial::
91  // Is there a texture?
92  if (_has_texture) {
93  Filename texture = converter->convert_model_path(_texture);
94  EggTexture temp("", texture);
95  EggTexture *egg_tex = converter->create_unique_texture(temp);
96  egg_prim->set_texture(egg_tex);
97  }
98 
99  // Are there any fancy lighting effects?
100  bool got_spec = (_specular_color != LRGBColor::zero());
101  bool got_emit = (_emissive_color != LRGBColor::zero());
102  if (got_spec || got_emit) {
103  EggMaterial temp("");
104  temp.set_diff(_face_color);
105  if (got_spec) {
106  temp.set_shininess(_power);
107  temp.set_spec(LColor(_specular_color[0], _specular_color[1],
108  _specular_color[2], 1.0));
109  }
110  if (got_emit) {
111  temp.set_emit(LColor(_emissive_color[0], _emissive_color[1],
112  _emissive_color[2], 1.0));
113  }
114  EggMaterial *egg_mat = converter->create_unique_material(temp);
115  egg_prim->set_material(egg_mat);
116  }
117 
118  // Also apply the face color.
119  egg_prim->set_color(_face_color);
120 }
121 
122 /**
123  *
124  */
125 int XFileMaterial::
126 compare_to(const XFileMaterial &other) const {
127  int ct;
128  ct = _face_color.compare_to(other._face_color);
129  if (ct == 0) {
130  ct = (_power == other._power) ? 0 : ((_power < other._power) ? -1 : 1);
131  }
132  if (ct == 0) {
133  ct = _specular_color.compare_to(other._specular_color);
134  }
135  if (ct == 0) {
136  ct = _emissive_color.compare_to(other._emissive_color);
137  }
138  if (ct == 0) {
139  ct = strcmp(_texture.c_str(), other._texture.c_str());
140  }
141  return ct;
142 }
143 
144 /**
145  * Returns true if this material represents something meaningful, or false if
146  * the default material is sufficient.
147  */
148 bool XFileMaterial::
149 has_material() const {
150  return _has_material;
151 }
152 
153 /**
154  * Returns true if this material includes a texture map, false otherwise.
155  */
156 bool XFileMaterial::
157 has_texture() const {
158  return _has_texture;
159 }
160 
161 /**
162  * Creates a Material object for the material list.
163  */
165 make_x_material(XFileNode *x_meshMaterials, const std::string &suffix) {
166  XFileDataNode *x_material =
167  x_meshMaterials->add_Material("material" + suffix,
168  _face_color, _power,
169  _specular_color, _emissive_color);
170 
171  if (has_texture()) {
172  x_material->add_TextureFilename("texture" + suffix, _texture);
173  }
174 
175  return x_material;
176 }
177 
178 /**
179  * Fills the structure based on the raw data from the X file's Material
180  * object.
181  */
182 bool XFileMaterial::
184  _face_color = LCAST(PN_stdfloat, (*obj)["faceColor"].vec4());
185  _power = (*obj)["power"].d();
186  _specular_color = LCAST(PN_stdfloat, (*obj)["specularColor"].vec3());
187  _emissive_color = LCAST(PN_stdfloat, (*obj)["emissiveColor"].vec3());
188  _has_material = true;
189 
190  // Walk through the children of the material. If there are any, there
191  // should be only one, and it should be just a Texture.
192  int num_objects = obj->get_num_objects();
193  for (int i = 0; i < num_objects; i++) {
194  XFileDataNode *child = obj->get_object(i);
195  if (child->is_standard_object("TextureFilename")) {
196  _texture = Filename::from_os_specific((*child)["filename"].s());
197  _has_texture = true;
198 
199  } else {
200  if (xfile_cat.is_debug()) {
201  xfile_cat.debug()
202  << "Ignoring material object of unknown type: "
203  << child->get_template_name() << "\n";
204  }
205  }
206  }
207 
208  return true;
209 }
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
Definition: eggPrimitive.h:47
get_material
Returns a pointer to the applied material, or NULL if there is no material applied.
Definition: eggPrimitive.h:115
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
bool has_texture() const
Returns true if this material includes a texture map, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:30
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileDataNode * make_x_material(XFileNode *x_meshMaterials, const std::string &suffix)
Creates a Material object for the material list.
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
Definition: eggPrimitive.I:116
XFileDataNode * add_Material(const std::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:375
void apply_to_egg(EggPrimitive *egg_prim, XFileToEggConverter *converter)
Applies the properties in the material to the indicated egg primitive.
XFileDataNode * add_TextureFilename(const std::string &name, const Filename &filename)
Creates a new TextureFilename instance, as a child of this node.
Definition: xFileNode.cxx:404
set_material
Applies the indicated material to the primitive.
Definition: eggPrimitive.h:115
LColor get_color() const
Returns the color set on this particular attribute.
Definition: eggAttributes.I:91
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,...
bool has_material() const
Returns true if this material represents something meaningful, or false if the default material is su...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_num_objects() const
Returns the list of child objects of this node.
Definition: xFileNode.I:47
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A single node of an X file.
Definition: xFileNode.h:39
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
Definition: eggPrimitive.I:128
get_spec
It is legal to call this even if has_spec() returns false.
Definition: eggMaterial.h:96
const std::string & get_template_name() const
A convenience function to return the name of the template used to define this data object.
Definition: xFileDataNode.I:43
This represents an X file "material", which consists of a color, lighting, and/or texture specificati...
Definition: xFileMaterial.h:31
This is an abstract base class for an XFileNode which is also an XFileDataObject.
Definition: xFileDataNode.h:33
get_emit
It is legal to call this even if has_emit() returns false.
Definition: eggMaterial.h:95
get_texture
Returns the first texture on the primitive, if any, or NULL if there are no textures on the primitive...
Definition: eggPrimitive.h:100
EggTexture * create_unique_texture(const EggTexture &copy)
Returns an EggTexture pointer whose properties match that of the the given EggTexture,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool fill_material(XFileDataNode *obj)
Fills the structure based on the raw data from the X file's Material object.
XFileDataNode * get_object(int n) const
Returns the nth child object of this node.
Definition: xFileNode.I:57
virtual bool is_standard_object(const std::string &template_name) const
Returns true if this node represents an instance of the standard template with the indicated name,...
get_diff
It is legal to call this even if has_diff() returns false.
Definition: eggMaterial.h:93
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
Definition: filename.cxx:328
Filename convert_model_path(const Filename &orig_filename)
Converts the indicated model filename to a relative or absolute or whatever filename,...
has_material
Returns true if the primitive is materiald (and get_material() will return a real pointer),...
Definition: eggPrimitive.h:115