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