diff --git a/pandatool/src/lwo/lwoSurfaceBlockHeader.cxx b/pandatool/src/lwo/lwoSurfaceBlockHeader.cxx index b1f71e7c5d..a29d78f264 100644 --- a/pandatool/src/lwo/lwoSurfaceBlockHeader.cxx +++ b/pandatool/src/lwo/lwoSurfaceBlockHeader.cxx @@ -8,6 +8,7 @@ #include "lwoSurfaceBlockChannel.h" #include "lwoSurfaceBlockEnabled.h" #include "lwoSurfaceBlockOpacity.h" +#include "lwoSurfaceBlockAxis.h" #include @@ -74,6 +75,9 @@ make_new_chunk(IffInputFile *in, IffId id) { } else if (id == IffId("OPAC")) { return new LwoSurfaceBlockOpacity; + + } else if (id == IffId("AXIS")) { + return new LwoSurfaceBlockAxis; } else { return IffChunk::make_new_chunk(in, id); diff --git a/pandatool/src/lwoegg/Sources.pp b/pandatool/src/lwoegg/Sources.pp index 34c99b7f9b..38a4bcf8ef 100644 --- a/pandatool/src/lwoegg/Sources.pp +++ b/pandatool/src/lwoegg/Sources.pp @@ -14,6 +14,7 @@ cLwoPolygons.I cLwoPolygons.cxx cLwoPolygons.h \ cLwoSurface.I cLwoSurface.cxx cLwoSurface.h \ cLwoSurfaceBlock.I cLwoSurfaceBlock.cxx cLwoSurfaceBlock.h \ + cLwoSurfaceBlockTMap.I cLwoSurfaceBlockTMap.cxx cLwoSurfaceBlockTMap.h \ lwoToEggConverter.I lwoToEggConverter.cxx lwoToEggConverter.h #define INSTALL_HEADERS \ diff --git a/pandatool/src/lwoegg/cLwoSurface.cxx b/pandatool/src/lwoegg/cLwoSurface.cxx index 5a788babbc..bb190ca34a 100644 --- a/pandatool/src/lwoegg/cLwoSurface.cxx +++ b/pandatool/src/lwoegg/cLwoSurface.cxx @@ -298,11 +298,12 @@ generate_uvs(vector_PT_EggVertex &egg_vertices) { } centroid /= (double)egg_vertices.size(); + centroid = centroid * _block->_inv_transform; // Now go back through and actually compute the UV's. for (vi = egg_vertices.begin(); vi != egg_vertices.end(); ++vi) { EggVertex *egg_vertex = (*vi); - LPoint3d pos = egg_vertex->get_pos3(); + LPoint3d pos = egg_vertex->get_pos3() * _block->_inv_transform; LPoint2d uv = (this->*_map_uvs)(pos, centroid); egg_vertex->set_uv(uv); } diff --git a/pandatool/src/lwoegg/cLwoSurfaceBlock.cxx b/pandatool/src/lwoegg/cLwoSurfaceBlock.cxx index db0f27c0eb..286741fcc3 100644 --- a/pandatool/src/lwoegg/cLwoSurfaceBlock.cxx +++ b/pandatool/src/lwoegg/cLwoSurfaceBlock.cxx @@ -4,6 +4,7 @@ //////////////////////////////////////////////////////////////////// #include "cLwoSurfaceBlock.h" +#include "cLwoSurfaceBlockTMap.h" #include "lwoToEggConverter.h" #include @@ -36,6 +37,7 @@ CLwoSurfaceBlock(LwoToEggConverter *converter, const LwoSurfaceBlock *block) : _h_wrap = LwoSurfaceBlockWrap::M_repeat; _w_repeat = 1.0; _h_repeat = 1.0; + _tmap = (CLwoSurfaceBlockTMap *)NULL; // Scan the chunks in the header. int num_hchunks = _block->_header->get_num_chunks(); @@ -59,7 +61,15 @@ CLwoSurfaceBlock(LwoToEggConverter *converter, const LwoSurfaceBlock *block) : for (int i = 0; i < num_chunks; i++) { const IffChunk *chunk = _block->get_chunk(i); - if (chunk->is_of_type(LwoSurfaceBlockProjection::get_class_type())) { + if (chunk->is_of_type(LwoSurfaceBlockTMap::get_class_type())) { + const LwoSurfaceBlockTMap *lwo_tmap = DCAST(LwoSurfaceBlockTMap, chunk); + if (_tmap != (CLwoSurfaceBlockTMap *)NULL) { + nout << "Two TMAP chunks encountered within surface block.\n"; + delete _tmap; + } + _tmap = new CLwoSurfaceBlockTMap(_converter, lwo_tmap); + + } else if (chunk->is_of_type(LwoSurfaceBlockProjection::get_class_type())) { const LwoSurfaceBlockProjection *proj = DCAST(LwoSurfaceBlockProjection, chunk); _projection_mode = proj->_mode; @@ -90,5 +100,42 @@ CLwoSurfaceBlock(LwoToEggConverter *converter, const LwoSurfaceBlock *block) : } } } + + if (_tmap != (CLwoSurfaceBlockTMap *)NULL) { + _tmap->get_transform(_transform); + } + + // Also rotate the transform if we specify some axis other than Y. + // (All the map_* uv mapping functions are written to assume Y is + // the dominant axis.) + switch (_axis) { + case LwoSurfaceBlockAxis::A_x: + _transform = LMatrix4d::rotate_mat(90.0, + LVecBase3d::unit_z(), + CS_yup_left) * _transform; + break; + + case LwoSurfaceBlockAxis::A_y: + break; + + case LwoSurfaceBlockAxis::A_z: + _transform = LMatrix4d::rotate_mat(-90.0, + LVecBase3d::unit_x(), + CS_yup_left) * _transform; + break; + } + + _inv_transform.invert_from(_transform); } +//////////////////////////////////////////////////////////////////// +// Function: CLwoSurfaceBlock::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +CLwoSurfaceBlock:: +~CLwoSurfaceBlock() { + if (_tmap != (CLwoSurfaceBlockTMap *)NULL) { + delete _tmap; + } +} diff --git a/pandatool/src/lwoegg/cLwoSurfaceBlock.h b/pandatool/src/lwoegg/cLwoSurfaceBlock.h index 1483b60f48..130eda5197 100644 --- a/pandatool/src/lwoegg/cLwoSurfaceBlock.h +++ b/pandatool/src/lwoegg/cLwoSurfaceBlock.h @@ -17,6 +17,7 @@ #include class LwoToEggConverter; +class CLwoSurfaceBlockTMap; //////////////////////////////////////////////////////////////////// // Class : CLwoSurfaceBlock @@ -27,6 +28,7 @@ class LwoToEggConverter; class CLwoSurfaceBlock { public: CLwoSurfaceBlock(LwoToEggConverter *converter, const LwoSurfaceBlock *block); + ~CLwoSurfaceBlock(); IffId _block_type; IffId _channel_id; @@ -50,6 +52,7 @@ public: LwoToEggConverter *_converter; CPT(LwoSurfaceBlock) _block; + CLwoSurfaceBlockTMap *_tmap; }; #include "cLwoSurfaceBlock.I" diff --git a/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.I b/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.I new file mode 100644 index 0000000000..84621a5936 --- /dev/null +++ b/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.I @@ -0,0 +1,4 @@ +// Filename: cLwoSurfaceBlockTMap.I +// Created by: drose (30Apr01) +// +//////////////////////////////////////////////////////////////////// diff --git a/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.cxx b/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.cxx new file mode 100644 index 0000000000..a0824af4cd --- /dev/null +++ b/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.cxx @@ -0,0 +1,69 @@ +// Filename: cLwoSurfaceBlockTMap.cxx +// Created by: drose (30Apr01) +// +//////////////////////////////////////////////////////////////////// + +#include "cLwoSurfaceBlockTMap.h" +#include "lwoToEggConverter.h" + +#include +#include +#include + +//////////////////////////////////////////////////////////////////// +// Function: CLwoSurfaceBlockTMap::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +CLwoSurfaceBlockTMap:: +CLwoSurfaceBlockTMap(LwoToEggConverter *converter, const LwoSurfaceBlockTMap *tmap) : + _converter(converter), + _tmap(tmap) +{ + _center.set(0.0, 0.0, 0.0); + _size.set(1.0, 1.0, 1.0); + _rotation.set(0.0, 0.0, 0.0); + _csys = LwoSurfaceBlockCoordSys::T_object; + _reference_object = "(none)"; + + // Scan the chunks in the body. + int num_chunks = _tmap->get_num_chunks(); + for (int i = 0; i < num_chunks; i++) { + const IffChunk *chunk = _tmap->get_chunk(i); + + if (chunk->is_of_type(LwoSurfaceBlockTransform::get_class_type())) { + const LwoSurfaceBlockTransform *trans = DCAST(LwoSurfaceBlockTransform, chunk); + if (trans->get_id() == IffId("CNTR")) { + _center = trans->_vec; + } else if (trans->get_id() == IffId("SIZE")) { + _size = trans->_vec; + } else if (trans->get_id() == IffId("ROTA")) { + _rotation = trans->_vec; + } + + } else if (chunk->is_of_type(LwoSurfaceBlockRefObj::get_class_type())) { + const LwoSurfaceBlockRefObj *ref = DCAST(LwoSurfaceBlockRefObj, chunk); + _reference_object = ref->_name; + + } else if (chunk->is_of_type(LwoSurfaceBlockCoordSys::get_class_type())) { + const LwoSurfaceBlockCoordSys *csys = DCAST(LwoSurfaceBlockCoordSys, chunk); + _csys = csys->_type; + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: CLwoSurfaceBlockTMap::get_transform +// Access: Public +// Description: Fills up the indicated matrix with the net transform +// indicated by the TMAP chunk, accounting for scale, +// rotate, and translate. +//////////////////////////////////////////////////////////////////// +void CLwoSurfaceBlockTMap:: +get_transform(LMatrix4d &mat) const { + LPoint3d hpr(rad_2_deg(_rotation[0]), + rad_2_deg(-_rotation[1]), + rad_2_deg(-_rotation[2])); + compose_matrix(mat, LCAST(double, _size), hpr, + LCAST(double, _center), CS_yup_left); +} diff --git a/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.h b/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.h new file mode 100644 index 0000000000..242a4c9e5d --- /dev/null +++ b/pandatool/src/lwoegg/cLwoSurfaceBlockTMap.h @@ -0,0 +1,46 @@ +// Filename: cLwoSurfaceBlockTMap.h +// Created by: drose (30Apr01) +// +//////////////////////////////////////////////////////////////////// + +#ifndef CLWOSURFACEBLOCKTMAP_H +#define CLWOSURFACEBLOCKTMAP_H + +#include + +#include +#include + +#include + +class LwoToEggConverter; + +//////////////////////////////////////////////////////////////////// +// Class : CLwoSurfaceBlockTMap +// Description : This class is a wrapper around LwoSurfaceBlockTMap +// and stores additional information useful during the +// conversion-to-egg process. +//////////////////////////////////////////////////////////////////// +class CLwoSurfaceBlockTMap { +public: + CLwoSurfaceBlockTMap(LwoToEggConverter *converter, const LwoSurfaceBlockTMap *tmap); + + void get_transform(LMatrix4d &mat) const; + + LPoint3f _center; + LVecBase3f _size; + LVecBase3f _rotation; + + string _reference_object; + + LwoSurfaceBlockCoordSys::Type _csys; + + LwoToEggConverter *_converter; + CPT(LwoSurfaceBlockTMap) _tmap; +}; + +#include "cLwoSurfaceBlockTMap.I" + +#endif + +