00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "xFileMaterial.h"
00020 #include "xFileToEggConverter.h"
00021
00022 #include "eggMaterial.h"
00023 #include "eggTexture.h"
00024 #include "eggPrimitive.h"
00025 #include "datagram.h"
00026
00027 #include <string.h>
00028
00029
00030
00031
00032
00033
00034 XFileMaterial::
00035 XFileMaterial() {
00036 _face_color.set(1.0, 1.0, 1.0, 1.0);
00037 _specular_color.set(0.0, 0.0, 0.0);
00038 _emissive_color.set(0.0, 0.0, 0.0);
00039 _power = 64.0;
00040
00041 _has_material = false;
00042 _has_texture = false;
00043 }
00044
00045
00046
00047
00048
00049
00050 XFileMaterial::
00051 ~XFileMaterial() {
00052 }
00053
00054
00055
00056
00057
00058
00059 void XFileMaterial::
00060 set_from_egg(EggPrimitive *egg_prim) {
00061
00062 if (egg_prim->has_color()) {
00063 _face_color = egg_prim->get_color();
00064 _has_material = true;
00065 }
00066
00067
00068 if (egg_prim->has_material()) {
00069 _has_material = true;
00070 EggMaterial *egg_mat = egg_prim->get_material();
00071 if (egg_mat->has_diff()) {
00072 _face_color = egg_mat->get_diff();
00073 }
00074 if (egg_mat->has_spec()) {
00075 const Colorf &spec = egg_mat->get_spec();
00076 _specular_color.set(spec[0], spec[1], spec[2]);
00077 }
00078 if (egg_mat->has_emit()) {
00079 const Colorf &emit = egg_mat->get_emit();
00080 _emissive_color.set(emit[0], emit[1], emit[2]);
00081 }
00082 if (egg_mat->has_shininess()) {
00083 _power = egg_mat->get_shininess();
00084 }
00085 }
00086
00087
00088 if (egg_prim->has_texture()) {
00089 _has_material = true;
00090 _has_texture = true;
00091 EggTexture *egg_tex = egg_prim->get_texture();
00092 _texture = egg_tex->get_filename();
00093 }
00094 }
00095
00096
00097
00098
00099
00100
00101
00102 void XFileMaterial::
00103 apply_to_egg(EggPrimitive *egg_prim, XFileToEggConverter *converter) {
00104
00105 if (_has_texture) {
00106 Filename texture = converter->convert_texture_path(_texture);
00107 EggTexture temp("", texture);
00108 EggTexture *egg_tex = converter->create_unique_texture(temp);
00109 egg_prim->set_texture(egg_tex);
00110 }
00111
00112
00113 bool got_spec = (_specular_color != RGBColorf::zero());
00114 bool got_emit = (_emissive_color != RGBColorf::zero());
00115 if (got_spec || got_emit) {
00116 EggMaterial temp("");
00117 temp.set_diff(_face_color);
00118 if (got_spec) {
00119 temp.set_shininess(_power);
00120 temp.set_spec(Colorf(_specular_color[0], _specular_color[1],
00121 _specular_color[2], 1.0));
00122 }
00123 if (got_emit) {
00124 temp.set_emit(Colorf(_emissive_color[0], _emissive_color[1],
00125 _emissive_color[2], 1.0));
00126 }
00127 EggMaterial *egg_mat = converter->create_unique_material(temp);
00128 egg_prim->set_material(egg_mat);
00129 }
00130
00131
00132 egg_prim->set_color(_face_color);
00133 }
00134
00135
00136
00137
00138
00139
00140 int XFileMaterial::
00141 compare_to(const XFileMaterial &other) const {
00142 int ct;
00143 ct = _face_color.compare_to(other._face_color);
00144 if (ct == 0) {
00145 ct = (_power == other._power) ? 0 : ((_power < other._power) ? -1 : 1);
00146 }
00147 if (ct == 0) {
00148 ct = _specular_color.compare_to(other._specular_color);
00149 }
00150 if (ct == 0) {
00151 ct = _emissive_color.compare_to(other._emissive_color);
00152 }
00153 if (ct == 0) {
00154 ct = strcmp(_texture.c_str(), other._texture.c_str());
00155 }
00156 return ct;
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166 bool XFileMaterial::
00167 has_material() const {
00168 return _has_material;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 bool XFileMaterial::
00178 has_texture() const {
00179 return _has_texture;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 void XFileMaterial::
00189 make_material_data(Datagram &raw_data) {
00190 raw_data.clear();
00191 raw_data.add_float32(_face_color[0]);
00192 raw_data.add_float32(_face_color[1]);
00193 raw_data.add_float32(_face_color[2]);
00194 raw_data.add_float32(_face_color[3]);
00195 raw_data.add_float32(_power);
00196 raw_data.add_float32(_specular_color[0]);
00197 raw_data.add_float32(_specular_color[1]);
00198 raw_data.add_float32(_specular_color[2]);
00199 raw_data.add_float32(_emissive_color[0]);
00200 raw_data.add_float32(_emissive_color[1]);
00201 raw_data.add_float32(_emissive_color[2]);
00202 }
00203
00204
00205
00206
00207
00208
00209
00210 void XFileMaterial::
00211 make_texture_data(Datagram &raw_data) {
00212 raw_data.clear();
00213
00214
00215 string os_filename = _texture.to_os_specific();
00216
00217 string filename;
00218 for (string::const_iterator pi = os_filename.begin();
00219 pi != os_filename.end();
00220 ++pi) {
00221 if ((*pi) == '\\') {
00222 filename += '\\';
00223 filename += '\\';
00224 } else {
00225 filename += (*pi);
00226 }
00227 }
00228
00229
00230
00231
00232
00233
00234
00235 char *filename_str = strdup(filename.c_str());
00236
00237
00238
00239 raw_data.add_int32((int)filename_str);
00240 }
00241
00242
00243
00244
00245
00246
00247
00248 bool XFileMaterial::
00249 read_material_data(const Datagram &raw_data) {
00250 DatagramIterator di(raw_data);
00251
00252 _face_color[0] = di.get_float32();
00253 _face_color[1] = di.get_float32();
00254 _face_color[2] = di.get_float32();
00255 _face_color[3] = di.get_float32();
00256 _power = di.get_float32();
00257 _specular_color[0] = di.get_float32();
00258 _specular_color[1] = di.get_float32();
00259 _specular_color[2] = di.get_float32();
00260 _emissive_color[0] = di.get_float32();
00261 _emissive_color[1] = di.get_float32();
00262 _emissive_color[2] = di.get_float32();
00263 _has_material = true;
00264
00265 if (di.get_remaining_size() != 0) {
00266 nout << "Ignoring " << di.get_remaining_size()
00267 << " trailing MeshMaterial.\n";
00268 }
00269
00270 return true;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 bool XFileMaterial::
00280 read_texture_data(const Datagram &raw_data) {
00281 DatagramIterator di(raw_data);
00282
00283
00284
00285 const char *ptr = (const char *)di.get_int32();
00286 _texture = Filename::from_os_specific(ptr);
00287 _has_texture = true;
00288
00289 if (di.get_remaining_size() != 0) {
00290 nout << "Ignoring " << di.get_remaining_size()
00291 << " trailing MeshMaterial.\n";
00292 }
00293 return true;
00294 }