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  */
50 set_from_egg(EggPrimitive *egg_prim) {
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  */
90 apply_to_egg(EggPrimitive *egg_prim, XFileToEggConverter *converter) {
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  */
149 has_material() const {
150  return _has_material;
151 }
152 
153 /**
154  * Returns true if this material includes a texture map, false otherwise.
155  */
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  */
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 }
LColor get_color() const
Returns the color set on this particular attribute.
Definition: eggAttributes.I:91
const Filename & get_filename() const
Returns a nonmodifiable reference to the filename.
get_emit
It is legal to call this even if has_emit() returns false.
Definition: eggMaterial.h:95
get_spec
It is legal to call this even if has_spec() returns false.
Definition: eggMaterial.h:96
get_diff
It is legal to call this even if has_diff() returns false.
Definition: eggMaterial.h:93
A base class for any of a number of kinds of geometry primitives: polygons, point lights,...
Definition: eggPrimitive.h:49
get_material
Returns a pointer to the applied material, or NULL if there is no material applied.
Definition: eggPrimitive.h:115
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
Definition: eggPrimitive.I:116
set_material
Applies the indicated material to the primitive.
Definition: eggPrimitive.h:115
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
Definition: eggPrimitive.I:128
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
has_material
Returns true if the primitive is materiald (and get_material() will return a real pointer),...
Definition: eggPrimitive.h:115
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:30
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
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,...
This is an abstract base class for an XFileNode which is also an XFileDataObject.
Definition: xFileDataNode.h:33
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
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,...
This represents an X file "material", which consists of a color, lighting, and/or texture specificati...
Definition: xFileMaterial.h:31
bool has_texture() const
Returns true if this material includes a texture map, false otherwise.
XFileDataNode * make_x_material(XFileNode *x_meshMaterials, const std::string &suffix)
Creates a Material object for the material list.
void apply_to_egg(EggPrimitive *egg_prim, XFileToEggConverter *converter)
Applies the properties in the material to the indicated egg primitive.
bool fill_material(XFileDataNode *obj)
Fills the structure based on the raw data from the X file's Material object.
bool has_material() const
Returns true if this material represents something meaningful, or false if the default material is su...
void set_from_egg(EggPrimitive *egg_prim)
Sets the structure up from the indicated egg data.
A single node of an X file.
Definition: xFileNode.h:40
int get_num_objects() const
Returns the list of child objects of this node.
Definition: xFileNode.I:57
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
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
XFileDataNode * get_object(int n) const
Returns the nth child object of this node.
Definition: xFileNode.I:67
EggTexture * create_unique_texture(const EggTexture &copy)
Returns an EggTexture pointer whose properties match that of the the given EggTexture,...
EggMaterial * create_unique_material(const EggMaterial &copy)
Returns an EggMaterial pointer whose properties match that of the the given EggMaterial,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.