1 #ifndef __VTX_READER_H_ 2 #define __VTX_READER_H_ 3 4 5 #include <osg/Array> 6 #include <osg/Geometry> 7 #include <osg/Matrixd> 8 #include <osg/Node> 9 #include <osg/Object> 10 #include <osg/StateSet> 11 #include <osgDB/Registry> 12 #include <osgDB/FileNameUtils> 13 #include <osg/Referenced> 14 15 #include "MDLLimits.h" 16 #include "MDLRoot.h" 17 #include "VVDReader.h" 18 19 20 namespace mdl 21 { 22 23 struct VTXHeader 24 { 25 int vtx_version; 26 int vertex_cache_size; 27 unsigned short max_bones_per_strip; 28 unsigned short max_bones_per_tri; 29 int max_bones_per_vertex; 30 31 int check_sum; 32 int num_lods; 33 34 int mtl_replace_list_offset; 35 36 int num_body_parts; 37 int body_part_offset; 38 }; 39 40 41 struct VTXMaterialReplacementList 42 { 43 int num_replacements; 44 int replacement_offset; 45 }; 46 47 48 struct VTXMaterialReplacment 49 { 50 short material_id; 51 int replacement_material_name_offset; 52 }; 53 54 55 struct VTXBodyPart 56 { 57 int num_models; 58 int model_offset; 59 }; 60 61 62 struct VTXModel 63 { 64 int num_lods; 65 int lod_offset; 66 }; 67 68 69 struct VTXModelLOD 70 { 71 int num_meshes; 72 int mesh_offset; 73 float switch_point; 74 }; 75 76 77 enum VTXMeshFlags 78 { 79 MESH_IS_TEETH = 0x01, 80 MESH_IS_EYES = 0x02 81 }; 82 83 84 struct VTXMesh 85 { 86 int num_strip_groups; 87 int strip_group_offset; 88 89 unsigned char mesh_flags; 90 }; 91 92 // Can't rely on sizeof() because Valve explicitly packs these structures to 93 // 1-byte alignment in the file, which isn't portable 94 const int VTX_MESH_SIZE = 9; 95 96 97 enum VTXStripGroupFlags 98 { 99 STRIP_GROUP_IS_FLEXED = 0x01, 100 STRIP_GROUP_IS_HW_SKINNED = 0x02, 101 STRIP_GROUP_IS_DELTA_FLEXED = 0x04 102 }; 103 104 105 struct VTXStripGroup 106 { 107 int num_vertices; 108 int vertex_offset; 109 110 int num_indices; 111 int index_offset; 112 113 int num_strips; 114 int strip_offset; 115 116 unsigned char strip_group_flags; 117 }; 118 119 // Can't rely on sizeof() because Valve explicitly packs these structures to 120 // 1-byte alignment in the file, which isn't portable 121 const int VTX_STRIP_GROUP_SIZE = 25; 122 123 124 enum VTXStripFlags 125 { 126 STRIP_IS_TRI_LIST = 0x01, 127 STRIP_IS_TRI_STRIP = 0x02 128 }; 129 130 131 struct VTXStrip 132 { 133 int num_indices; 134 int index_offset; 135 136 int num_vertices; 137 int vertex_offset; 138 139 short num_bones; 140 141 unsigned char strip_flags; 142 143 int num_bone_state_changes; 144 int bone_state_change_offset; 145 }; 146 147 148 // Can't rely on sizeof() because Valve explicitly packs these structures to 149 // 1-byte alignment in the .vtx file, which isn't portable 150 const int VTX_STRIP_SIZE = 27; 151 152 153 struct VTXVertex 154 { 155 unsigned char bone_weight_index[MAX_BONES_PER_VERTEX]; 156 unsigned char num_bones; 157 158 short orig_mesh_vertex_id; 159 160 char bone_id[MAX_BONES_PER_VERTEX]; 161 }; 162 163 164 // Can't rely on sizeof() because Valve explicitly packs these structures to 165 // 1-byte alignment in the .vtx file, which isn't portable 166 const int VTX_VERTEX_SIZE = 9; 167 168 169 struct VTXBoneStateChange 170 { 171 int hardware_id; 172 int new_bone_id; 173 }; 174 175 176 class VTXReader 177 { 178 protected: 179 180 std::string vtx_name; 181 182 VVDReader * vvd_reader; 183 184 MDLRoot * mdl_root; 185 186 osg::ref_ptr<osg::Node> model_root; 187 188 osg::ref_ptr<osg::Group> processBodyPart(std::istream * str, 189 int offset, 190 BodyPart * currentPart); 191 osg::ref_ptr<osg::Group> processModel(std::istream * str, 192 int offset, 193 Model * currentModel); 194 osg::ref_ptr<osg::Group> processLOD(int lodNum, float * distance, 195 std::istream * str, 196 int offset, 197 Model * currentModel); 198 osg::ref_ptr<osg::Geode> processMesh(int lodNum, 199 std::istream * str, 200 int offset, int vertexOffset); 201 osg::ref_ptr<osg::Geometry> processStripGroup(int lodNum, 202 std::istream * str, 203 int offset, 204 int vertexOffset); 205 osg::ref_ptr<osg::PrimitiveSet> processStrip(unsigned short * indexArray, 206 std::istream * str, 207 int offset); 208 209 public: 210 211 VTXReader(VVDReader * vvd, MDLRoot * mdlRoot); 212 virtual ~VTXReader(); 213 214 bool readFile(const std::string & file); 215 216 osg::ref_ptr<osg::Node> getModel(); 217 }; 218 219 220 } 221 222 #endif 223