// Filename: transformBlendTable.h // Created by: drose (24Mar05) // //////////////////////////////////////////////////////////////////// // // 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 TRANSFORMBLENDTABLE_H #define TRANSFORMBLENDTABLE_H #include "pandabase.h" #include "transformBlend.h" #include "vertexTransform.h" #include "copyOnWriteObject.h" #include "pointerTo.h" #include "pvector.h" #include "pmap.h" #include "indirectLess.h" #include "cycleData.h" #include "cycleDataLockedReader.h" #include "cycleDataReader.h" #include "cycleDataWriter.h" #include "pipelineCycler.h" #include "sparseArray.h" class FactoryParams; //////////////////////////////////////////////////////////////////// // Class : TransformBlendTable // Description : This structure collects together the different // combinations of transforms and blend amounts used by // a GeomVertexData, to facilitate computing dynamic // vertices on the CPU at runtime. Each vertex has a // pointer to exactly one of the entries in this table, // and each entry defines a number of transform/blend // combinations. // // This structure is used for a GeomVertexData set up to // compute its dynamic vertices on the CPU. See // TransformTable for one set up to compute its // dynamic vertices on the graphics card. //////////////////////////////////////////////////////////////////// class EXPCL_PANDA_GOBJ TransformBlendTable : public CopyOnWriteObject { protected: virtual PT(CopyOnWriteObject) make_cow_copy(); PUBLISHED: TransformBlendTable(); TransformBlendTable(const TransformBlendTable ©); void operator = (const TransformBlendTable ©); virtual ~TransformBlendTable(); INLINE int get_num_blends() const; INLINE const TransformBlend &get_blend(int n) const; MAKE_SEQ(get_blends, get_num_blends, get_blend); INLINE UpdateSeq get_modified(Thread *current_thread) const; void set_blend(int n, const TransformBlend &blend); void remove_blend(int n); int add_blend(const TransformBlend &blend); INLINE int get_num_transforms() const; INLINE int get_max_simultaneous_transforms() const; INLINE void set_rows(const SparseArray &rows); INLINE const SparseArray &get_rows() const; INLINE SparseArray &modify_rows(); void write(ostream &out, int indent_level) const; private: class CData; void clear_index(); INLINE void consider_rebuild_index() const; void rebuild_index(); void recompute_modified(CData *cdata, Thread *current_thread); void clear_modified(Thread *current_thread); private: // We don't bother with registering the table, or protecting its // data in a CycleData structure--the interface on GeomVertexData // guarantees that the pointer will be copied if we modify the // table. typedef pvector Blends; Blends _blends; SparseArray _rows; // This map indexes directly into the above vector. That means any // time we add or remove anything from the vector, we must // completely rebuild the index (since the vector might reallocate, // invalidating all the pointers into it). typedef pmap > BlendIndex; BlendIndex _blend_index; int _num_transforms; int _max_simultaneous_transforms; // Even though we don't store the actual blend table data in a // CycleData structure, we do need to keep a local cache of the // relevant modified stamps there, so it can be updated per-thread. class EXPCL_PANDA_GOBJ CData : public CycleData { public: INLINE CData(); INLINE CData(const CData ©); virtual CycleData *make_copy() const; virtual void write_datagram(BamWriter *manager, Datagram &dg) const; virtual void fillin(DatagramIterator &scan, BamReader *manager); virtual TypeHandle get_parent_type() const { return TransformBlendTable::get_class_type(); } UpdateSeq _modified; UpdateSeq _global_modified; }; PipelineCycler _cycler; typedef CycleDataLockedReader CDLockedReader; typedef CycleDataReader CDReader; typedef CycleDataWriter CDWriter; public: static void register_with_read_factory(); virtual void write_datagram(BamWriter *manager, Datagram &dg); virtual int complete_pointers(TypedWritable **plist, BamReader *manager); protected: static TypedWritable *make_from_bam(const FactoryParams ¶ms); void fillin(DatagramIterator &scan, BamReader *manager); public: static TypeHandle get_class_type() { return _type_handle; } static void init_type() { CopyOnWriteObject::init_type(); register_type(_type_handle, "TransformBlendTable", CopyOnWriteObject::get_class_type()); } virtual TypeHandle get_type() const { return get_class_type(); } virtual TypeHandle force_init_type() {init_type(); return get_class_type();} private: static TypeHandle _type_handle; friend class VertexTransform; }; INLINE ostream &operator << (ostream &out, const TransformBlendTable &obj); #include "transformBlendTable.I" #endif