283 lines
8.6 KiB
C
283 lines
8.6 KiB
C
|
/**
|
||
|
* 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<PT(Geom) > 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<CPT(GeomVertexData), VertexDataAssoc> 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<SourceVertices, NewVertexData> 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<SourceTexCoords, NewVertexData> 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<SourceColors, NewVertexData> 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<SourceTextureColors, NewVertexData> 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<SourceFormat, NewVertexData> NewFormat;
|
||
|
NewFormat _format;
|
||
|
|
||
|
// The table of GeomVertexData objects whose normals have been reversed.
|
||
|
typedef pmap<CPT(GeomVertexData), NewVertexData> 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<SourceData> SourceDatas;
|
||
|
class SourceGeom {
|
||
|
public:
|
||
|
Geom *_geom;
|
||
|
int _vertex_offset;
|
||
|
};
|
||
|
typedef pvector<SourceGeom> 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<NewCollectedData *> NewCollectedList;
|
||
|
typedef pmap<NewCollectedKey, NewCollectedData *> NewCollectedMap;
|
||
|
NewCollectedList _new_collected_list;
|
||
|
NewCollectedMap _new_collected_map;
|
||
|
|
||
|
class AlreadyCollectedData {
|
||
|
public:
|
||
|
NewCollectedData *_ncd;
|
||
|
int _vertex_offset;
|
||
|
};
|
||
|
typedef pmap<CPT(GeomVertexData), AlreadyCollectedData> 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
|