/
models.h
294 lines (248 loc) · 7.71 KB
/
models.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/**
* @file models.h
*
* 3D Model Resources.
*
* @ingroup resource
*
* @author Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @author Copyright © 2006-2013 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/
#ifndef LIBDENG_RESOURCE_MODELS_H
#define LIBDENG_RESOURCE_MODELS_H
#include <vector>
#include <de/Vector>
#include "def_data.h"
#include "gl/gl_model.h"
/// Unique identifier associated with each model in the collection.
typedef uint modelid_t;
/// Special value used to signify an invalid model id.
#define NOMODELID 0
/**
* @defgroup modelFrameFlags Model frame flags
* @ingroup flags
*/
///@{
#define MFF_FULLBRIGHT 0x00000001
#define MFF_SHADOW1 0x00000002
#define MFF_SHADOW2 0x00000004
#define MFF_BRIGHTSHADOW 0x00000008
#define MFF_MOVEMENT_PITCH 0x00000010 ///< Pitch aligned to movement.
#define MFF_SPIN 0x00000020 ///< Spin around (for bonus items).
#define MFF_SKINTRANS 0x00000040 ///< Color translation -> skins.
#define MFF_AUTOSCALE 0x00000080 ///< Scale to match sprite height.
#define MFF_MOVEMENT_YAW 0x00000100
#define MFF_DONT_INTERPOLATE 0x00000200 ///< Don't interpolate from the frame.
#define MFF_BRIGHTSHADOW2 0x00000400
#define MFF_ALIGN_YAW 0x00000800
#define MFF_ALIGN_PITCH 0x00001000
#define MFF_DARKSHADOW 0x00002000
#define MFF_IDSKIN 0x00004000 ///< Mobj id -> skin in skin range
#define MFF_DISABLE_Z_WRITE 0x00008000
#define MFF_NO_DISTANCE_CHECK 0x00010000
#define MFF_SELSKIN 0x00020000
#define MFF_PARTICLE_SUB1 0x00040000 ///< Sub1 center is particle origin.
#define MFF_NO_PARTICLES 0x00080000 ///< No particles for this object.
#define MFF_SHINY_SPECULAR 0x00100000 ///< Shiny skin rendered as additive.
#define MFF_SHINY_LIT 0x00200000 ///< Shiny skin is not fullbright.
#define MFF_IDFRAME 0x00400000 ///< Mobj id -> frame in frame range
#define MFF_IDANGLE 0x00800000 ///< Mobj id -> static angle offset
#define MFF_DIM 0x01000000 ///< Never fullbright.
#define MFF_SUBTRACT 0x02000000 ///< Subtract blending.
#define MFF_REVERSE_SUBTRACT 0x04000000 ///< Reverse subtract blending.
#define MFF_TWO_SIDED 0x08000000 ///< Disable culling.
#define MFF_NO_TEXCOMP 0x10000000 ///< Never compress skins.
#define MFF_WORLD_TIME_ANIM 0x20000000
///@}
struct SubmodelDef
{
modelid_t modelId;
short frame;
char frameRange;
int _flags;
short skin;
char skinRange;
float offset[3];
byte alpha;
struct texture_s* shinySkin;
blendmode_t blendMode;
SubmodelDef()
: modelId(0),
frame(0),
frameRange(0),
_flags(0),
skin(0),
skinRange(0),
alpha(0),
shinySkin(0),
blendMode(BM_NORMAL)
{
de::zap(offset);
}
void setFlags(int newFlags)
{
_flags = newFlags;
}
/**
* Tests if the flags in @a flag are all set for the submodel.
*
* @param flag One or more flags.
*
* @return @c true, if all the flags were set; otherwise @c false.
*/
bool testFlag(int flag) const
{
return (_flags & flag) == flag;
}
};
typedef SubmodelDef submodeldef_t;
#define MODELDEF_ID_MAXLEN 32
struct ModelDef
{
char id[MODELDEF_ID_MAXLEN + 1];
/// Pointer to the states list.
state_t* state;
int flags;
unsigned int group;
int select;
short skinTics;
/// [0,1) When is this frame in effect?
float interMark;
float interRange[2];
float offset[3];
float resize;
float scale[3];
typedef std::vector<de::Vector3f> PtcOffsets;
PtcOffsets _ptcOffset;
float visualRadius;
ded_model_t* def;
/// Points to next inter-frame, or NULL.
ModelDef *interNext;
/// Points to next selector, or NULL (only for "base" modeldefs).
ModelDef *selectNext;
/// Submodels.
typedef std::vector<SubmodelDef> Subs;
Subs _sub;
ModelDef(char const *modelDefId = "")
: state(0),
flags(0),
group(0),
select(0),
skinTics(0),
interMark(0),
resize(0),
visualRadius(0),
def(0),
interNext(0),
selectNext(0)
{
de::zap(id);
strncpy(id, modelDefId, MODELDEF_ID_MAXLEN);
de::zap(interRange);
de::zap(offset);
de::zap(scale);
}
SubmodelDef *addSub()
{
_sub.push_back(SubmodelDef());
_ptcOffset.push_back(de::Vector3f());
return &_sub.back();
}
void clearSubs()
{
_sub.clear();
_ptcOffset.clear();
}
uint subCount() const
{
return _sub.size();
}
bool testSubFlag(unsigned int subnum, int flag) const
{
if(!hasSub(subnum)) return false;
return _sub[subnum].testFlag(flag);
}
modelid_t subModelId(unsigned int subnum) const
{
if(!hasSub(subnum)) return NOMODELID;
return _sub[subnum].modelId;
}
SubmodelDef &subModelDef(unsigned int subnum)
{
DENG_ASSERT(hasSub(subnum));
return _sub[subnum];
}
SubmodelDef const &subModelDef(unsigned int subnum) const
{
DENG_ASSERT(hasSub(subnum));
return _sub[subnum];
}
bool hasSub(unsigned int subnum) const
{
return subnum < _sub.size();
}
de::Vector3f particleOffset(unsigned int subnum) const
{
if(hasSub(subnum))
{
DENG_ASSERT(subnum < _ptcOffset.size());
return _ptcOffset[subnum];
}
return de::Vector3f();
}
void setParticleOffset(unsigned int subnum, de::Vector3f const &off)
{
DENG_ASSERT(hasSub(subnum));
_ptcOffset[subnum] = off;
}
};
typedef ModelDef modeldef_t;
typedef std::vector<ModelDef> ModelDefs;
#ifdef __CLIENT__
extern ModelDefs modefs;
extern byte useModels;
extern float rModelAspectMod;
/**
* @pre States must be initialized before this.
*/
void Models_Init(void);
/**
* Frees all memory allocated for models.
*/
void Models_Shutdown(void);
model_t* Models_ToModel(modelid_t id);
/**
* Is there a model for this mobj? The decision is made based on the state and tics
* of the mobj. Returns the modeldefs that are in effect at the moment (interlinks
* checked appropriately).
*/
float Models_ModelForMobj(struct mobj_s* mo, modeldef_t** mdef, modeldef_t** nextmdef);
/**
* Lookup a model definition by id.
*
* @param id Unique id of the definition to lookup.
* @return Found model definition; otherwise @c 0.
*/
modeldef_t* Models_Definition(char const* id);
void Models_Cache(modeldef_t* modef);
/**
* @note The skins are also bound here once so they should be ready for use
* the next time they are needed.
*/
int Models_CacheForMobj(thinker_t* th, void* context);
#endif // __CLIENT__
#endif // LIBDENG_RESOURCE_MODELS_H