Panda3D
Loading...
Searching...
No Matches
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 */
28XFileMaterial::
29XFileMaterial() {
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 */
42XFileMaterial::
43~XFileMaterial() {
44}
45
46/**
47 * Sets the structure up from the indicated egg data.
48 */
50set_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 */
90apply_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 */
125int XFileMaterial::
126compare_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 */
149has_material() const {
150 return _has_material;
151}
152
153/**
154 * Returns true if this material includes a texture map, false otherwise.
155 */
157has_texture() const {
158 return _has_texture;
159}
160
161/**
162 * Creates a Material object for the material list.
163 */
165make_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.
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,...
get_material
Returns a pointer to the applied material, or NULL if there is no material applied.
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
set_material
Applies the indicated material to the primitive.
bool has_texture() const
Returns true if the primitive has any textures specified, false otherwise.
get_texture
Returns the first texture on the primitive, if any, or NULL if there are no textures on the primitive...
has_material
Returns true if the primitive is materiald (and get_material() will return a real pointer),...
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:44
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.
const std::string & get_template_name() const
A convenience function to return the name of the template used to define this data object.
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...
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.
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.
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.