Panda3D
|
00001 // Filename: transformBlendTable.h 00002 // Created by: drose (24Mar05) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef TRANSFORMBLENDTABLE_H 00016 #define TRANSFORMBLENDTABLE_H 00017 00018 #include "pandabase.h" 00019 #include "transformBlend.h" 00020 #include "vertexTransform.h" 00021 #include "copyOnWriteObject.h" 00022 #include "pointerTo.h" 00023 #include "pvector.h" 00024 #include "pmap.h" 00025 #include "indirectLess.h" 00026 #include "cycleData.h" 00027 #include "cycleDataLockedReader.h" 00028 #include "cycleDataReader.h" 00029 #include "cycleDataWriter.h" 00030 #include "pipelineCycler.h" 00031 #include "sparseArray.h" 00032 00033 class FactoryParams; 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Class : TransformBlendTable 00037 // Description : This structure collects together the different 00038 // combinations of transforms and blend amounts used by 00039 // a GeomVertexData, to facilitate computing dynamic 00040 // vertices on the CPU at runtime. Each vertex has a 00041 // pointer to exactly one of the entries in this table, 00042 // and each entry defines a number of transform/blend 00043 // combinations. 00044 // 00045 // This structure is used for a GeomVertexData set up to 00046 // compute its dynamic vertices on the CPU. See 00047 // TransformTable for one set up to compute its 00048 // dynamic vertices on the graphics card. 00049 //////////////////////////////////////////////////////////////////// 00050 class EXPCL_PANDA_GOBJ TransformBlendTable : public CopyOnWriteObject { 00051 protected: 00052 virtual PT(CopyOnWriteObject) make_cow_copy(); 00053 00054 PUBLISHED: 00055 TransformBlendTable(); 00056 TransformBlendTable(const TransformBlendTable ©); 00057 void operator = (const TransformBlendTable ©); 00058 virtual ~TransformBlendTable(); 00059 00060 INLINE int get_num_blends() const; 00061 INLINE const TransformBlend &get_blend(int n) const; 00062 MAKE_SEQ(get_blends, get_num_blends, get_blend); 00063 INLINE UpdateSeq get_modified(Thread *current_thread) const; 00064 00065 void set_blend(int n, const TransformBlend &blend); 00066 void remove_blend(int n); 00067 int add_blend(const TransformBlend &blend); 00068 00069 INLINE int get_num_transforms() const; 00070 INLINE int get_max_simultaneous_transforms() const; 00071 00072 INLINE void set_rows(const SparseArray &rows); 00073 INLINE const SparseArray &get_rows() const; 00074 INLINE SparseArray &modify_rows(); 00075 00076 void write(ostream &out, int indent_level) const; 00077 00078 private: 00079 class CData; 00080 00081 void clear_index(); 00082 INLINE void consider_rebuild_index() const; 00083 void rebuild_index(); 00084 00085 void recompute_modified(CData *cdata, Thread *current_thread); 00086 void clear_modified(Thread *current_thread); 00087 00088 private: 00089 // We don't bother with registering the table, or protecting its 00090 // data in a CycleData structure--the interface on GeomVertexData 00091 // guarantees that the pointer will be copied if we modify the 00092 // table. 00093 typedef pvector<TransformBlend> Blends; 00094 Blends _blends; 00095 00096 SparseArray _rows; 00097 00098 // This map indexes directly into the above vector. That means any 00099 // time we add or remove anything from the vector, we must 00100 // completely rebuild the index (since the vector might reallocate, 00101 // invalidating all the pointers into it). 00102 typedef pmap<const TransformBlend *, int, IndirectLess<TransformBlend> > BlendIndex; 00103 BlendIndex _blend_index; 00104 int _num_transforms; 00105 int _max_simultaneous_transforms; 00106 00107 // Even though we don't store the actual blend table data in a 00108 // CycleData structure, we do need to keep a local cache of the 00109 // relevant modified stamps there, so it can be updated per-thread. 00110 class EXPCL_PANDA_GOBJ CData : public CycleData { 00111 public: 00112 INLINE CData(); 00113 INLINE CData(const CData ©); 00114 virtual CycleData *make_copy() const; 00115 virtual void write_datagram(BamWriter *manager, Datagram &dg) const; 00116 virtual void fillin(DatagramIterator &scan, BamReader *manager); 00117 virtual TypeHandle get_parent_type() const { 00118 return TransformBlendTable::get_class_type(); 00119 } 00120 00121 UpdateSeq _modified; 00122 UpdateSeq _global_modified; 00123 }; 00124 00125 PipelineCycler<CData> _cycler; 00126 typedef CycleDataLockedReader<CData> CDLockedReader; 00127 typedef CycleDataReader<CData> CDReader; 00128 typedef CycleDataWriter<CData> CDWriter; 00129 00130 public: 00131 static void register_with_read_factory(); 00132 virtual void write_datagram(BamWriter *manager, Datagram &dg); 00133 virtual int complete_pointers(TypedWritable **plist, BamReader *manager); 00134 00135 protected: 00136 static TypedWritable *make_from_bam(const FactoryParams ¶ms); 00137 void fillin(DatagramIterator &scan, BamReader *manager); 00138 00139 public: 00140 static TypeHandle get_class_type() { 00141 return _type_handle; 00142 } 00143 static void init_type() { 00144 CopyOnWriteObject::init_type(); 00145 register_type(_type_handle, "TransformBlendTable", 00146 CopyOnWriteObject::get_class_type()); 00147 } 00148 virtual TypeHandle get_type() const { 00149 return get_class_type(); 00150 } 00151 virtual TypeHandle force_init_type() {init_type(); return get_class_type();} 00152 00153 private: 00154 static TypeHandle _type_handle; 00155 00156 friend class VertexTransform; 00157 }; 00158 00159 INLINE ostream &operator << (ostream &out, const TransformBlendTable &obj); 00160 00161 #include "transformBlendTable.I" 00162 00163 #endif