// Filename: geomTransformer.h // Created by: drose (14Mar02) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // // All use of this software is subject to the terms of the revised BSD // license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// #ifndef GEOMTRANSFORMER_H #define GEOMTRANSFORMER_H #include "pandabase.h" #include "luse.h" #include "geom.h" #include "geomVertexData.h" #include "texMatrixAttrib.h" class GeomNode; class RenderState; class InternalName; class GeomMunger; class Texture; //////////////////////////////////////////////////////////////////// // Class : GeomTransformer // Description : An object specifically designed to transform the // vertices of a Geom without disturbing indexing or // affecting any other Geoms that may share the same // vertex arrays, and without needlessly wasting memory // when different Geoms sharing the same vertex arrays // are transformed by the same amount. // // If you create a single GeomTransformer and use it to // transform a number of different Geoms by various // transformations, then those Geoms which happen to // share the same arrays and are transformed by the same // amounts will still share the same arrays as each // other (but different from the original arrays). //////////////////////////////////////////////////////////////////// class EXPCL_PANDA_PGRAPH GeomTransformer { public: GeomTransformer(); GeomTransformer(const GeomTransformer ©); ~GeomTransformer(); INLINE int get_max_collect_vertices() const; INLINE void set_max_collect_vertices(int max_collect_vertices); void register_vertices(Geom *geom, bool might_have_unused); void register_vertices(GeomNode *node, bool might_have_unused); bool transform_vertices(Geom *geom, const LMatrix4 &mat); bool transform_vertices(GeomNode *node, const LMatrix4 &mat); bool transform_texcoords(Geom *geom, const InternalName *from_name, InternalName *to_name, const LMatrix4 &mat); bool transform_texcoords(GeomNode *node, const InternalName *from_name, InternalName *to_name, const LMatrix4 &mat); bool set_color(Geom *geom, const LColor &color); bool set_color(GeomNode *node, const LColor &color); bool transform_colors(Geom *geom, const LVecBase4 &scale); bool transform_colors(GeomNode *node, const LVecBase4 &scale); bool apply_texture_colors(Geom *geom, TextureStage *ts, Texture *tex, const TexMatrixAttrib *tma, const LColor &base_color, bool keep_vertex_color); bool apply_texture_colors(GeomNode *node, const RenderState *state); bool apply_state(GeomNode *node, const RenderState *state); bool set_format(Geom *geom, const GeomVertexFormat *new_format); bool remove_column(Geom *geom, const InternalName *column); bool remove_column(GeomNode *node, const InternalName *column); bool make_compatible_state(GeomNode *node); bool reverse_normals(Geom *geom); bool doubleside(GeomNode *node); bool reverse(GeomNode *node); void finish_apply(); int collect_vertex_data(Geom *geom, int collect_bits, bool format_only); int collect_vertex_data(GeomNode *node, int collect_bits, bool format_only); int finish_collect(bool format_only); PT(Geom) premunge_geom(const Geom *geom, GeomMunger *munger); private: int _max_collect_vertices; typedef pvector GeomList; // Keeps track of the Geoms that are associated with a particular // GeomVertexData. Also tracks whether the vertex data might have // unused vertices because of our actions. class VertexDataAssoc { public: INLINE VertexDataAssoc(); bool _might_have_unused; GeomList _geoms; void remove_unused_vertices(const GeomVertexData *vdata); }; typedef pmap VertexDataAssocMap; VertexDataAssocMap _vdata_assoc; // Corresponds to a new GeomVertexData created as needed during an // apply operation. class NewVertexData { public: CPT(GeomVertexData) _vdata; }; // The table of GeomVertexData objects that have been transformed by // a particular matrix. class SourceVertices { public: INLINE bool operator < (const SourceVertices &other) const; LMatrix4 _mat; CPT(GeomVertexData) _vertex_data; }; typedef pmap NewVertices; NewVertices _vertices; // The table of GeomVertexData objects whose texture coordinates // have been transformed by a particular matrix. class SourceTexCoords { public: INLINE bool operator < (const SourceTexCoords &other) const; LMatrix4 _mat; CPT(InternalName) _from; CPT(InternalName) _to; CPT(GeomVertexData) _vertex_data; }; typedef pmap NewTexCoords; NewTexCoords _texcoords; // The table of GeomVertexData objects whose colors have been // modified. class SourceColors { public: INLINE bool operator < (const SourceColors &other) const; LVecBase4 _color; CPT(GeomVertexData) _vertex_data; }; typedef pmap NewColors; // We have two concepts of colors: the "fixed" colors, which are // slapped in as a complete replacement of the original colors // (e.g. via a ColorAttrib), and the "transformed" colors, which are // modified from the original colors (e.g. via a ColorScaleAttrib). NewColors _fcolors, _tcolors; // The table of GeomVertexData objects whose texture colors have // been applied. class SourceTextureColors { public: INLINE bool operator < (const SourceTextureColors &other) const; TextureStage *_ts; Texture *_tex; const TexMatrixAttrib *_tma; LColor _base_color; bool _keep_vertex_color; CPT(GeomVertexData) _vertex_data; }; typedef pmap NewTextureColors; NewTextureColors _tex_colors; // The table of GeomVertexData objects whose vertex formats have // been modified. For set_format(): record (format + vertex_data) -> // vertex_data. class SourceFormat { public: INLINE bool operator < (const SourceFormat &other) const; CPT(GeomVertexFormat) _format; CPT(GeomVertexData) _vertex_data; }; typedef pmap NewFormat; NewFormat _format; // The table of GeomVertexData objects whose normals have been // reversed. typedef pmap ReversedNormals; ReversedNormals _reversed_normals; class NewCollectedKey { public: INLINE bool operator < (const NewCollectedKey &other) const; string _name; CPT(GeomVertexFormat) _format; Geom::UsageHint _usage_hint; Geom::AnimationType _animation_type; }; class SourceData { public: const GeomVertexData *_vdata; int _num_vertices; }; typedef pvector SourceDatas; class SourceGeom { public: Geom *_geom; int _vertex_offset; }; typedef pvector SourceGeoms; class NewCollectedData { public: ALLOC_DELETED_CHAIN(NewCollectedData); NewCollectedData(const GeomVertexData *source_data); void add_source_data(const GeomVertexData *source_data); int apply_format_only_changes(); int apply_collect_changes(); CPT(GeomVertexFormat) _new_format; string _vdata_name; GeomEnums::UsageHint _usage_hint; SourceDatas _source_datas; SourceGeoms _source_geoms; int _num_vertices; private: // These are used just during apply_changes(). void append_vdata(const GeomVertexData *vdata, int vertex_offset); void update_geoms(); typedef vector_int IndexMap; PT(GeomVertexData) _new_data; PT(TransformBlendTable) _new_btable; SparseArray _new_btable_rows; // We need a TypeHandle just for ALLOC_DELETED_CHAIN. public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { register_type(_type_handle, "GeomTransformer::NewCollectedData"); } private: static TypeHandle _type_handle; }; typedef pvector NewCollectedList; typedef pmap NewCollectedMap; NewCollectedList _new_collected_list; NewCollectedMap _new_collected_map; class AlreadyCollectedData { public: NewCollectedData *_ncd; int _vertex_offset; }; typedef pmap AlreadyCollectedMap; AlreadyCollectedMap _already_collected_map; static PStatCollector _apply_vertex_collector; static PStatCollector _apply_texcoord_collector; static PStatCollector _apply_set_color_collector; static PStatCollector _apply_scale_color_collector; static PStatCollector _apply_texture_color_collector; static PStatCollector _apply_set_format_collector; public: static void init_type() { NewCollectedData::init_type(); } }; #include "geomTransformer.I" #endif