Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
texture.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WW3D *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/texture.h $*
26 * *
27 * $Org Author:: Jani_p $*
28 * *
29 * Author : Kenny Mitchell *
30 * *
31 * $Modtime:: 08/05/02 1:27p $*
32 * *
33 * $Revision:: 46 $*
34 * *
35 * 05/16/02 KM Base texture class to abstract major texture types, e.g. 3d, z, cube, etc.
36 * 06/27/02 KM Texture class abstraction *
37 * 08/05/02 KM Texture class redesign (revisited)
38 *---------------------------------------------------------------------------------------------*
39 * Functions: *
40 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
41
42
43#if defined(_MSC_VER)
44#pragma once
45#endif
46
47#ifndef TEXTURE_H
48#define TEXTURE_H
49
50#include "always.h"
51#include "refcount.h"
52#include "chunkio.h"
53#include "surfaceclass.h"
54#include "ww3dformat.h"
55#include "wwstring.h"
56#include "vector3.h"
57#include "texturefilter.h"
58
59struct IDirect3DBaseTexture8;
60struct IDirect3DTexture8;
61struct IDirect3DCubeTexture8;
62struct IDirect3DVolumeTexture8;
63
64class DX8Wrapper;
65class TextureLoader;
66class LoaderThreadClass;
70
72{
73 friend class TextureLoader;
74 friend class LoaderThreadClass;
75 friend class DX8TextureTrackerClass; //(gth) so it can call Poke_Texture,
77
78public:
79
86
93
94 // base constructor for derived classes
96 (
97 unsigned width,
98 unsigned height,
99 MipCountType mip_level_count=MIP_LEVELS_ALL,
101 bool rendertarget=false,
102 bool reducible=true
103 );
104
105 virtual ~TextureBaseClass();
106
107 virtual TexAssetType Get_Asset_Type() const=0;
108
109 // Names
110 void Set_Texture_Name(const char * name);
111 void Set_Full_Path(const char * path) { FullPath = path; }
112 const StringClass& Get_Texture_Name(void) const { return Name; }
113 const StringClass& Get_Full_Path(void) const { if (FullPath.Is_Empty ()) return Name; return FullPath; }
114
115 unsigned Get_ID() const { return texture_id; } // Each textrure has a unique id
116
117 // The number of Mip levels in the texture
118 unsigned int Get_Mip_Level_Count(void) const
119 {
120 return MipLevelCount;
121 }
122
123 // Note! Width and Height may be zero and may change if texture uses mipmaps
124 int Get_Width() const
125 {
126 return Width;
127 }
128 int Get_Height() const
129 {
130 return Height;
131 }
132
133 // Time, after which the texture is invalidated if not used. Set to zero to indicate infinite.
134 // Time is in milliseconds.
135 void Set_Inactivation_Time(unsigned time) { InactivationTime=time; }
137
138 // Texture priority affects texture management and caching.
139 unsigned int Get_Priority(void);
140 unsigned int Set_Priority(unsigned int priority); // Returns previous priority
141
142 // Debug utility functions for returning the texture memory usage
143 virtual unsigned Get_Texture_Memory_Usage() const=0;
144
145 bool Is_Initialized() const { return Initialized; }
146 bool Is_Lightmap() const { return IsLightmap; }
147 bool Is_Procedural() const { return IsProcedural; }
148 bool Is_Reducible() const { return IsReducible; } //can texture be reduced in resolution for LOD purposes?
149
151 static int _Get_Total_Texture_Size();
155 static int _Get_Total_Texture_Count();
158
159 virtual void Init()=0;
160
161 // This utility function processes the texture reduction (used during rendering)
162 void Invalidate();
163
164 // texture accessors (dx8)
165 IDirect3DBaseTexture8 *Peek_D3D_Base_Texture() const;
166 void Set_D3D_Base_Texture(IDirect3DBaseTexture8* tex);
167
168 PoolType Get_Pool() const { return Pool; }
169
170 bool Is_Missing_Texture();
171
172 // Support for self managed textures
173 bool Is_Dirty() { WWASSERT(Pool==POOL_DEFAULT); return Dirty; };
174 void Set_Dirty() { WWASSERT(Pool==POOL_DEFAULT); Dirty=true; }
175 void Clean() { Dirty=false; };
176
177 void Set_HSV_Shift(const Vector3 &hsv_shift);
178 const Vector3& Get_HSV_Shift() { return HSVShift; }
179
181
182 unsigned Get_Reduction() const;
183
184 // Background texture loader will call this when texture has been loaded
185 virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false)=0; // If the parameter is true, the texture will be flagged as initialised
186
188
189 // Inactivate textures that haven't been used in a while. Pass zero to use textures'
190 // own inactive times (default). In urgent need to free up texture memory, try
191 // calling with relatively small (just few seconds) time override to free up everything
192 // but the currently used textures.
193 static void Invalidate_Old_Unused_Textures(unsigned inactive_time_override);
194
195 // Apply this texture's settings into D3D
196 virtual void Apply(unsigned int stage)=0;
197
198 // Apply a Null texture's settings into D3D
199 static void Apply_Null(unsigned int stage);
200
201 virtual TextureClass* As_TextureClass() { return NULL; }
204
205 IDirect3DTexture8* Peek_D3D_Texture() const { return (IDirect3DTexture8*)Peek_D3D_Base_Texture(); }
206 IDirect3DVolumeTexture8* Peek_D3D_VolumeTexture() const { return (IDirect3DVolumeTexture8*)Peek_D3D_Base_Texture(); }
207 IDirect3DCubeTexture8* Peek_D3D_CubeTexture() const { return (IDirect3DCubeTexture8*)Peek_D3D_Base_Texture(); }
208
209protected:
210
211 void Load_Locked_Surface();
212 void Poke_Texture(IDirect3DBaseTexture8* tex) { D3DTexture = tex; }
213
215
216 // For debug purposes the texture sets this true if it is a lightmap texture
221
222
223 unsigned InactivationTime; // In milliseconds
224 unsigned ExtendedInactivationTime; // This is set by the engine, if needed
226 mutable unsigned LastAccessed;
227
228 // If this is non-zero, the texture will have a hue shift done at the next init (this
229 // value should only be changed by Set_HSV_Shift() function, which also invalidates the
230 // texture).
232
233 int Width;
235
236private:
237
238 // Direct3D texture object
239 IDirect3DBaseTexture8 *D3DTexture;
240
241 // Name
242 StringClass Name;
243 StringClass FullPath;
244
245 // Unique id
246 unsigned texture_id;
247
248 // Support for self-managed textures
249
250 PoolType Pool;
251 bool Dirty;
252
256 TextureLoadTaskClass* TextureLoadTask;
257 TextureLoadTaskClass* ThumbnailLoadTask;
258
259};
260
261
262/*************************************************************************
263** TextureClass
264**
265** This is our regular texture class. For legacy reasons it contains some
266** information beyond the D3D texture itself, such as texture addressing
267** modes.
268**
269*************************************************************************/
271{
273// friend DX8Wrapper;
274
275public:
276
277 // Create texture with desired height, width and format.
279 (
280 unsigned width,
281 unsigned height,
282 WW3DFormat format,
283 MipCountType mip_level_count=MIP_LEVELS_ALL,
285 bool rendertarget=false,
286 bool allow_reduction=true
287 );
288
289 // Create texture from a file. If format is specified the texture is converted to that format.
290 // Note that the format must be supported by the current device and that a texture can't exist
291 // in the system with the same name in multiple formats.
293 (
294 const char *name,
295 const char *full_path=NULL,
296 MipCountType mip_level_count=MIP_LEVELS_ALL,
297 WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN,
298 bool allow_compression=true,
299 bool allow_reduction=true
300 );
301
302 // Create texture from a surface.
304 (
305 SurfaceClass *surface,
306 MipCountType mip_level_count=MIP_LEVELS_ALL
307 );
308
309 TextureClass(IDirect3DBaseTexture8* d3d_texture);
310
311 // defualt constructors for derived classes (cube & vol)
313 (
314 unsigned width,
315 unsigned height,
316 MipCountType mip_level_count=MIP_LEVELS_ALL,
318 bool rendertarget=false,
320 bool allow_reduction=true
321 )
322 : TextureBaseClass(width,height,mip_level_count,pool,rendertarget,allow_reduction), TextureFormat(format), Filter(mip_level_count) { }
323
324 virtual TexAssetType Get_Asset_Type() const { return TEX_REGULAR; }
325
326 virtual void Init();
327
328 // Background texture loader will call this when texture has been loaded
329 virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false); // If the parameter is true, the texture will be flagged as initialised
330
331 // Get the surface of one of the mipmap levels (defaults to highest-resolution one)
332 SurfaceClass *Get_Surface_Level(unsigned int level = 0);
333 IDirect3DSurface8 *Get_D3D_Surface_Level(unsigned int level = 0);
334 void Get_Level_Description( SurfaceClass::SurfaceDescription & desc, unsigned int level = 0 );
335
337
339
340 virtual void Apply(unsigned int stage);
341
342 virtual unsigned Get_Texture_Memory_Usage() const;
343
344 virtual TextureClass* As_TextureClass() { return this; }
345
346protected:
347
349
350 // legacy
352};
353
355{
356public:
357 // Create a z texture with desired height, width and format
359 (
360 unsigned width,
361 unsigned height,
362 WW3DZFormat zformat,
363 MipCountType mip_level_count=MIP_LEVELS_ALL,
365 );
366
367 WW3DZFormat Get_Texture_Format() const { return DepthStencilTextureFormat; }
368
369 virtual TexAssetType Get_Asset_Type() const { return TEX_REGULAR; }
370
371 virtual void Init() {}
372
373 // Background texture loader will call this when texture has been loaded
374 virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false); // If the parameter is true, the texture will be flagged as initialised
375
376 virtual void Apply(unsigned int stage);
377
378 IDirect3DSurface8 *Get_D3D_Surface_Level(unsigned int level = 0);
379 virtual unsigned Get_Texture_Memory_Usage() const;
380
381private:
382
383 WW3DZFormat DepthStencilTextureFormat;
384};
385
387{
388public:
389 // Create texture with desired height, width and format.
391 (
392 unsigned width,
393 unsigned height,
394 WW3DFormat format,
395 MipCountType mip_level_count=MIP_LEVELS_ALL,
397 bool rendertarget=false,
398 bool allow_reduction=true
399 );
400
401 // Create texture from a file. If format is specified the texture is converted to that format.
402 // Note that the format must be supported by the current device and that a texture can't exist
403 // in the system with the same name in multiple formats.
405 (
406 const char *name,
407 const char *full_path=NULL,
408 MipCountType mip_level_count=MIP_LEVELS_ALL,
409 WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN,
410 bool allow_compression=true,
411 bool allow_reduction=true
412 );
413
414 // Create texture from a surface.
416 (
417 SurfaceClass *surface,
418 MipCountType mip_level_count=MIP_LEVELS_ALL
419 );
420
421 CubeTextureClass(IDirect3DBaseTexture8* d3d_texture);
422
423 virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false); // If the parameter is true, the texture will be flagged as initialised
424
425 virtual TexAssetType Get_Asset_Type() const { return TEX_CUBEMAP; }
426
427 virtual CubeTextureClass* As_CubeTextureClass() { return this; }
428
429};
430
432{
433public:
434 // Create texture with desired height, width and format.
436 (
437 unsigned width,
438 unsigned height,
439 unsigned depth,
440 WW3DFormat format,
441 MipCountType mip_level_count=MIP_LEVELS_ALL,
443 bool rendertarget=false,
444 bool allow_reduction=true
445 );
446
447 // Create texture from a file. If format is specified the texture is converted to that format.
448 // Note that the format must be supported by the current device and that a texture can't exist
449 // in the system with the same name in multiple formats.
451 (
452 const char *name,
453 const char *full_path=NULL,
454 MipCountType mip_level_count=MIP_LEVELS_ALL,
455 WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN,
456 bool allow_compression=true,
457 bool allow_reduction=true
458 );
459
460 // Create texture from a surface.
462 (
463 SurfaceClass *surface,
464 MipCountType mip_level_count=MIP_LEVELS_ALL
465 );
466
467 VolumeTextureClass(IDirect3DBaseTexture8* d3d_texture);
468
469 virtual void Apply_New_Surface(IDirect3DBaseTexture8* tex, bool initialized, bool disable_auto_invalidation = false); // If the parameter is true, the texture will be flagged as initialised
470
471 virtual TexAssetType Get_Asset_Type() const { return TEX_VOLUME; }
472
473 virtual VolumeTextureClass* As_VolumeTextureClass() { return this; }
474
475protected:
476
477 int Depth;
478};
479
480// Utility functions for loading and saving texture descriptions from/to W3D files
482void Save_Texture(TextureClass * texture, ChunkSaveClass & csave);
483
484#endif //TEXTURE_H
#define NULL
Definition BaseType.h:92
#define WWASSERT
#define W3DMPO_GLUE(ARGCLASS)
Definition always.h:120
virtual TexAssetType Get_Asset_Type() const
Definition texture.h:425
virtual void Apply_New_Surface(IDirect3DBaseTexture8 *tex, bool initialized, bool disable_auto_invalidation=false)
Apply new surface to texture.
Definition texture.cpp:1595
CubeTextureClass(IDirect3DBaseTexture8 *d3d_texture)
CubeTextureClass(SurfaceClass *surface, MipCountType mip_level_count=MIP_LEVELS_ALL)
virtual CubeTextureClass * As_CubeTextureClass()
Definition texture.h:427
CubeTextureClass(unsigned width, unsigned height, WW3DFormat format, MipCountType mip_level_count=MIP_LEVELS_ALL, PoolType pool=POOL_MANAGED, bool rendertarget=false, bool allow_reduction=true)
Definition texture.cpp:1347
RefCountClass(void)
Definition refcount.h:108
bool Is_Missing_Texture()
Is missing texture.
Definition texture.cpp:302
unsigned Get_Reduction() const
Get reduction mip levels.
Definition texture.cpp:375
static int _Get_Total_Procedural_Texture_Count()
Get total procedural texture count.
Definition texture.cpp:552
IDirect3DTexture8 * Peek_D3D_Texture() const
Definition texture.h:205
friend class DX8TextureTrackerClass
Definition texture.h:75
bool Is_Procedural() const
Definition texture.h:147
static int _Get_Total_Procedural_Texture_Size()
Get total procedural texture size.
Definition texture.cpp:488
friend class VolumeTextureLoadTaskClass
Definition texture.h:255
static int _Get_Total_Texture_Size()
Get total texture size.
Definition texture.cpp:443
MipCountType MipLevelCount
Definition texture.h:187
virtual void Init()=0
unsigned int Get_Priority(void)
Get priority.
Definition texture.cpp:335
IDirect3DVolumeTexture8 * Peek_D3D_VolumeTexture() const
Definition texture.h:206
unsigned int Set_Priority(unsigned int priority)
Set priority.
Definition texture.cpp:355
const StringClass & Get_Texture_Name(void) const
Definition texture.h:112
unsigned Get_ID() const
Definition texture.h:115
virtual CubeTextureClass * As_CubeTextureClass()
Definition texture.h:202
static void Apply_Null(unsigned int stage)
Apply NULL texture state.
Definition texture.cpp:400
IDirect3DBaseTexture8 * Peek_D3D_Base_Texture() const
Returns a pointer to the d3d texture.
Definition texture.cpp:258
unsigned LastAccessed
Definition texture.h:226
void Set_D3D_Base_Texture(IDirect3DBaseTexture8 *tex)
Set the d3d texture pointer. Handles ref counts properly.
Definition texture.cpp:268
virtual void Apply(unsigned int stage)=0
virtual TexAssetType Get_Asset_Type() const =0
static void Invalidate_Old_Unused_Textures(unsigned inactive_time_override)
Invalidate old unused textures.
Definition texture.cpp:142
bool Is_Reducible() const
Definition texture.h:148
const StringClass & Get_Full_Path(void) const
Definition texture.h:113
friend class CubeTextureLoadTaskClass
Definition texture.h:254
void Set_HSV_Shift(const Vector3 &hsv_shift)
Definition texture.cpp:411
int Get_Width() const
Definition texture.h:124
void Invalidate()
Invalidate this texture.
Definition texture.cpp:194
void Set_Full_Path(const char *path)
Definition texture.h:111
static int _Get_Total_Lightmap_Texture_Size()
Get total lightmap texture size.
Definition texture.cpp:465
static int _Get_Total_Texture_Count()
Get total texture count.
Definition texture.cpp:510
virtual ~TextureBaseClass()
Base texture class destructor.
Definition texture.cpp:119
bool Is_Dirty()
Definition texture.h:173
void Set_Texture_Name(const char *name)
Set texture name.
Definition texture.cpp:323
unsigned LastInactivationSyncTime
Definition texture.h:225
Vector3 HSVShift
Definition texture.h:231
bool IsCompressionAllowed
Definition texture.h:218
friend class TextureLoader
Definition texture.h:73
bool Is_Compression_Allowed() const
Definition texture.h:180
void Poke_Texture(IDirect3DBaseTexture8 *tex)
Definition texture.h:212
void Set_Dirty()
Definition texture.h:174
static int _Get_Total_Lightmap_Texture_Count()
Get total light map texture count.
Definition texture.cpp:531
virtual VolumeTextureClass * As_VolumeTextureClass()
Definition texture.h:203
void Set_Inactivation_Time(unsigned time)
Definition texture.h:135
const Vector3 & Get_HSV_Shift()
Definition texture.h:178
int Get_Height() const
Definition texture.h:128
unsigned InactivationTime
Definition texture.h:223
virtual TextureClass * As_TextureClass()
Definition texture.h:201
TextureBaseClass(unsigned width, unsigned height, MipCountType mip_level_count=MIP_LEVELS_ALL, PoolType pool=POOL_MANAGED, bool rendertarget=false, bool reducible=true)
Definition texture.cpp:82
friend class DX8ZTextureTrackerClass
Definition texture.h:76
unsigned int Get_Mip_Level_Count(void) const
Definition texture.h:118
virtual unsigned Get_Texture_Memory_Usage() const =0
void Load_Locked_Surface()
Load locked surface.
Definition texture.cpp:288
bool Is_Initialized() const
Definition texture.h:145
static int _Get_Total_Locked_Surface_Size()
Get total locked surface size.
Definition texture.cpp:421
bool Is_Lightmap() const
Definition texture.h:146
static int _Get_Total_Locked_Surface_Count()
Get total locked surface count.
Definition texture.cpp:574
PoolType Get_Pool() const
Definition texture.h:168
int Get_Inactivation_Time() const
Definition texture.h:136
virtual void Apply_New_Surface(IDirect3DBaseTexture8 *tex, bool initialized, bool disable_auto_invalidation=false)=0
IDirect3DCubeTexture8 * Peek_D3D_CubeTexture() const
Definition texture.h:207
friend class TextureLoadTaskClass
Definition texture.h:253
friend class LoaderThreadClass
Definition texture.h:74
unsigned ExtendedInactivationTime
Definition texture.h:224
TextureFilterClass Filter
Definition texture.h:351
virtual TexAssetType Get_Asset_Type() const
Definition texture.h:324
IDirect3DSurface8 * Get_D3D_Surface_Level(unsigned int level=0)
Get D3D surface from mip level.
Definition texture.cpp:1019
TextureClass(unsigned width, unsigned height, MipCountType mip_level_count=MIP_LEVELS_ALL, PoolType pool=POOL_MANAGED, bool rendertarget=false, WW3DFormat format=WW3D_FORMAT_UNKNOWN, bool allow_reduction=true)
Definition texture.h:313
virtual unsigned Get_Texture_Memory_Usage() const
Get texture memory usage.
Definition texture.cpp:1036
WW3DFormat Get_Texture_Format() const
Definition texture.h:338
void Get_Level_Description(SurfaceClass::SurfaceDescription &desc, unsigned int level=0)
Get surface description for a mip level.
Definition texture.cpp:1006
virtual TextureClass * As_TextureClass()
Definition texture.h:344
SurfaceClass * Get_Surface_Level(unsigned int level=0)
Get surface from mip level.
Definition texture.cpp:986
TextureClass(unsigned width, unsigned height, WW3DFormat format, MipCountType mip_level_count=MIP_LEVELS_ALL, PoolType pool=POOL_MANAGED, bool rendertarget=false, bool allow_reduction=true)
Definition texture.cpp:597
WW3DFormat TextureFormat
Definition texture.h:348
virtual void Init()
Initialise the texture.
Definition texture.cpp:848
TextureFilterClass & Get_Filter()
Definition texture.h:336
virtual void Apply(unsigned int stage)
Apply texture states.
Definition texture.cpp:932
virtual void Apply_New_Surface(IDirect3DBaseTexture8 *tex, bool initialized, bool disable_auto_invalidation=false)
Apply new surface to texture.
Definition texture.cpp:895
VolumeTextureClass(unsigned width, unsigned height, unsigned depth, WW3DFormat format, MipCountType mip_level_count=MIP_LEVELS_ALL, PoolType pool=POOL_MANAGED, bool rendertarget=false, bool allow_reduction=true)
Definition texture.cpp:1629
VolumeTextureClass(SurfaceClass *surface, MipCountType mip_level_count=MIP_LEVELS_ALL)
virtual VolumeTextureClass * As_VolumeTextureClass()
Definition texture.h:473
VolumeTextureClass(IDirect3DBaseTexture8 *d3d_texture)
virtual void Apply_New_Surface(IDirect3DBaseTexture8 *tex, bool initialized, bool disable_auto_invalidation=false)
Apply new surface to texture.
Definition texture.cpp:1883
virtual TexAssetType Get_Asset_Type() const
Definition texture.h:471
virtual void Apply_New_Surface(IDirect3DBaseTexture8 *tex, bool initialized, bool disable_auto_invalidation=false)
Apply new surface to texture.
Definition texture.cpp:1276
virtual unsigned Get_Texture_Memory_Usage() const
Get texture memory usage.
Definition texture.cpp:1328
IDirect3DSurface8 * Get_D3D_Surface_Level(unsigned int level=0)
Get D3D surface from mip level.
Definition texture.cpp:1311
virtual void Init()
Definition texture.h:371
virtual void Apply(unsigned int stage)
Apply depth stencil texture.
Definition texture.cpp:1266
virtual TexAssetType Get_Asset_Type() const
Definition texture.h:369
WW3DZFormat Get_Texture_Format() const
Definition texture.h:367
ZTextureClass(unsigned width, unsigned height, WW3DZFormat zformat, MipCountType mip_level_count=MIP_LEVELS_ALL, PoolType pool=POOL_MANAGED)
Definition texture.cpp:1210
TextureClass * Load_Texture(ChunkLoadClass &cload)
Definition texture.cpp:1051
void Save_Texture(TextureClass *texture, ChunkSaveClass &csave)
Definition texture.cpp:1184
MipCountType
@ MIP_LEVELS_ALL
WW3DFormat
Definition ww3dformat.h:75
@ WW3D_FORMAT_UNKNOWN
Definition ww3dformat.h:76
WW3DZFormat
Definition ww3dformat.h:106