/** * 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." * * @file geomTransformer.h * @author drose * @date 2002-03-14 */ #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; /** * 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; std::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; std::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