15 #include "cLwoSurface.h"
16 #include "cLwoSurfaceBlock.h"
18 #include "lwoToEggConverter.h"
20 #include "lwoSurfaceColor.h"
21 #include "lwoSurfaceParameter.h"
22 #include "lwoSurfaceSmoothingAngle.h"
23 #include "lwoSurfaceSidedness.h"
24 #include "lwoSurfaceBlock.h"
25 #include "eggPrimitive.h"
26 #include "string_utils.h"
27 #include "mathNumbers.h"
38 _converter(converter),
42 _rgb.set(1.0, 1.0, 1.0);
43 _checked_material =
false;
44 _checked_texture =
false;
49 int num_chunks = _surface->get_num_chunks();
50 for (
int i = 0; i < num_chunks; i++) {
51 const IffChunk *chunk = _surface->get_chunk(i);
53 if (chunk->
is_of_type(LwoSurfaceColor::get_class_type())) {
58 }
else if (chunk->
is_of_type(LwoSurfaceParameter::get_class_type())) {
62 if (type ==
IffId(
"DIFF")) {
64 _diffuse = param->_value;
66 }
else if (type ==
IffId(
"LUMI")) {
67 _flags |= F_luminosity;
68 _luminosity = param->_value;
70 }
else if (type ==
IffId(
"SPEC")) {
72 _specular = param->_value;
74 }
else if (type ==
IffId(
"REFL")) {
75 _flags |= F_reflection;
76 _reflection = param->_value;
78 }
else if (type ==
IffId(
"TRAN")) {
79 _flags |= F_transparency;
80 _transparency = param->_value;
82 }
else if (type ==
IffId(
"GLOS")) {
84 _gloss = param->_value;
86 }
else if (type ==
IffId(
"TRNL")) {
87 _flags |= F_translucency;
88 _translucency = param->_value;
91 }
else if (chunk->
is_of_type(LwoSurfaceSmoothingAngle::get_class_type())) {
93 _flags |= F_smooth_angle;
94 _smooth_angle = sa->_angle;
96 }
else if (chunk->
is_of_type(LwoSurfaceSidedness::get_class_type())) {
99 _backface = (sn->_sidedness == LwoSurfaceSidedness::S_front_and_back);
101 }
else if (chunk->
is_of_type(LwoSurfaceBlock::get_class_type())) {
109 if (block->_block_type ==
IffId(
"IMAP") &&
110 block->_channel_id ==
IffId(
"COLR") &&
116 }
else if (block->_ordinal < _block->_ordinal) {
132 _color.set(1.0, 1.0, 1.0, 1.0);
134 if ((_flags & F_rgb) != 0) {
140 if ((_flags & F_transparency) != 0) {
141 _color[3] = 1.0 - _transparency;
144 _diffuse_color = _color;
171 PN_stdfloat &smooth_angle) {
172 if (!_surface->_source.empty()) {
176 if (parent != (
CLwoSurface *)NULL && parent !=
this) {
184 egg_prim->set_color(_diffuse_color);
194 generate_uvs(egg_vertices);
197 if ((_flags & F_backface) != 0) {
201 if ((_flags & F_smooth_angle) != 0) {
202 smooth_angle = max(smooth_angle, _smooth_angle);
218 if (_checked_texture) {
221 _checked_texture =
true;
230 int clip_index = _block->_clip_index;
231 if (clip_index < 0) {
238 nout <<
"No clip image with index " << clip_index <<
"\n";
249 _egg_texture =
new EggTexture(
"clip" + format_string(clip_index), pathname);
252 switch (_block->_projection_mode) {
253 case LwoSurfaceBlockProjection::M_planar:
254 _map_uvs = &CLwoSurface::map_planar;
257 case LwoSurfaceBlockProjection::M_cylindrical:
258 _map_uvs = &CLwoSurface::map_cylindrical;
261 case LwoSurfaceBlockProjection::M_spherical:
262 _map_uvs = &CLwoSurface::map_spherical;
265 case LwoSurfaceBlockProjection::M_cubic:
266 _map_uvs = &CLwoSurface::map_cubic;
269 case LwoSurfaceBlockProjection::M_front:
275 case LwoSurfaceBlockProjection::M_uv:
298 if (_checked_material) {
301 _checked_material =
true;
304 if (!_converter->_make_materials) {
311 if ((_flags & F_diffuse) != 0) {
312 _diffuse_color.set(_color[0] * _diffuse,
313 _color[1] * _diffuse,
314 _color[2] * _diffuse,
325 if ((_flags & F_luminosity) != 0) {
326 LColor luminosity(_color[0] * _luminosity,
327 _color[1] * _luminosity,
328 _color[2] * _luminosity,
330 _egg_material->set_emit(luminosity);
333 if ((_flags & F_specular) != 0) {
334 LColor specular(_color[0] * _specular,
335 _color[1] * _specular,
336 _color[2] * _specular,
338 _egg_material->set_spec(specular);
341 if ((_flags & F_gloss) != 0) {
342 _egg_material->set_shininess(_gloss * 128.0);
357 generate_uvs(vector_PT_EggVertex &egg_vertices) {
358 if (_map_uvs == NULL) {
367 vector_PT_EggVertex::const_iterator vi;
368 for (vi = egg_vertices.begin(); vi != egg_vertices.end(); ++vi) {
373 centroid /= (double)egg_vertices.
size();
374 centroid = centroid * _block->_inv_transform;
377 for (vi = egg_vertices.begin(); vi != egg_vertices.end(); ++vi) {
380 LPoint2d uv = (this->*_map_uvs)(pos, centroid);
395 double u = (pos[0] + 0.5);
396 double v = (pos[2] + 0.5);
415 double u_offset = 0.0;
425 xz.set(centroid[0], centroid[2]);
427 }
else if (xz[1] >= 0.0 && ((xz[0] < 0.0) != (centroid[0] < 0.))) {
435 u_offset = (xz[0] < 0.0) ? 1.0 : -1.0;
441 (atan2(xz[0], -xz[1]) / (2.0 * MathNumbers::pi) + 0.5 + u_offset) * _block->_w_repeat;
447 (atan2(yz[0], yz[1]) / MathNumbers::pi + 0.5) * _block->_h_repeat;
464 double u_offset = 0.0;
471 xz.set(centroid[0], centroid[2]);
473 }
else if (xz[1] >= 0.0 && ((xz[0] < 0.0) != (centroid[0] < 0.))) {
475 u_offset = (xz[0] < 0.0) ? 1.0 : -1.0;
479 (atan2(xz[0], -xz[1]) / (2.0 * MathNumbers::pi) + 0.5 + u_offset) * _block->_w_repeat;
483 double v = (pos[1] + 0.5);
500 double x = fabs(centroid[0]);
501 double y = fabs(centroid[1]);
502 double z = fabs(centroid[2]);
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
bool check_material()
Checks whether the surface demands a material or not.
bool is_still_image() const
Returns true if this clip represents a still image, as opposed to an animated image.
This class is a wrapper around LwoSurfaceBlock and stores additional information useful during the co...
const string & get_name() const
Returns the name of the surface.
This is a two-component vector offset.
Describes the shading attributes of a surface.
Defines a texture map that may be applied to geometry.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
void set_texture(EggTexture *texture)
Replaces the current list of textures with the indicated texture.
This is a two-component point in space.
CLwoClip * get_clip(int number) const
Returns a pointer to the clip with the given index number, or NULL if there is no such clip...
A texture layer or shader, part of a LwoSurface chunk.
This class is a wrapper around LwoClip and stores additional information useful during the conversion...
bool check_texture()
Checks whether the surface demands a texture or not.
void set_bface_flag(bool flag)
Sets the backfacing flag of the polygon.
Records the base color of a surface, as an entry within a LwoSurface chunk.
This class is a wrapper around LwoSurface and stores additional information useful during the convers...
The basic kind of record in an EA "IFF" file, which the LightWave object file is based on...
The name of a file, such as a texture file or an Egg file.
void set_material(EggMaterial *material)
Applies the indicated material to the primitive.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
Records whether polygons are frontfacing only or backfacing also.
IffId get_id() const
Returns the ID associated with this chunk.
static const LVector2d & zero()
Returns a zero-length vector.
void apply_properties(EggPrimitive *egg_prim, vector_PT_EggVertex &egg_vertices, PN_stdfloat &smooth_angle)
Applies the color, texture, etc.
double length() const
Returns the length of the vector, by the Pythagorean theorem.
This class supervises the construction of an EggData structure from the data represented by the LwoHe...
Indicates the maximum angle (in radians) between adjacent polygons that should be smooth-shaded...
This is the base class for all three-component vectors and points.
static int size()
Returns 3: the number of components of a LVecBase3.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
CLwoSurface * get_surface(const string &name) const
Returns a pointer to the surface definition with the given name, or NULL if there is no such surface...
A four-byte chunk ID appearing in an "IFF" file.
Records some parameter value of a surface material, as an entry within a LwoSurface chunk...
void set_uv(const LTexCoordd &texCoord)
Replaces the unnamed UV coordinate pair on the vertex with the indicated value.
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.