Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
hlodsave.cpp
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 : Renegade / G *
24 * *
25 * $Archive:: /Commando/Code/Tools/max2w3d/hlodsave.cpp $*
26 * *
27 * $Author:: Greg_h $*
28 * *
29 * $Modtime:: 11/07/00 5:24p $*
30 * *
31 * $Revision:: 9 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * -- The constructor builds the whole HLOD tree in a *
36 * -- Destructor blows away the dynamic memory we used. *
37 * -- Method called when saving to a W3D file. Saves the chunks *
38 * -- Write the header *
39 * -- Writes each LOD *
40 * -- Writes the mesh to bone connectivity info for each mesh in an LOD. *
41 * HLodSaveClass::save_aggregate_array -- save the aggregates (if any) *
42 * HLodSaveClass::save_proxy_array -- save the array of proxies (if any) *
43 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44
45
46#include "hlodsave.h"
47#include "meshcon.h"
48#include "errclass.h"
49#include "util.h"
50#include "w3dappdata.h"
51#include "wwmath.h" // NO_MAX_SCREEN_SIZE
52#include "exportlog.h"
53
54
55
56/* Behold, the applicable snippets of code from w3d_file.h that are applicable to this module!
57
58 W3D_CHUNK_HLOD =0x00000700, // description of an HLod object (see HLodClass)
59 W3D_CHUNK_HLOD_HEADER, // general information such as name and version
60 W3D_CHUNK_HLOD_LOD_ARRAY, // wrapper around the array of objects for each level of detail
61 W3D_CHUNK_HLOD_LOD_ARRAY_HEADER, // info on the objects in this level of detail array
62 W3D_CHUNK_HLOD_SUB_OBJECT, // an object in this level of detail array
63
64struct W3dHLodHeaderStruct
65{
66 uint32 Version;
67 uint32 LodCount;
68 char Name[W3D_NAME_LEN];
69 char HierarchyName[W3D_NAME_LEN]; // name of the hierarchy tree to use (\0 if none)
70};
71
72struct W3dHLodArrayHeaderStruct
73{
74 uint32 ModelCount;
75 float32 MaxScreenSize; // if model is bigger than this, switch to higher lod.
76};
77
78struct W3dHLodSubObjectStruct
79{
80 uint32 BoneIndex;
81 char Name[W3D_NAME_LEN*2];
82};
83*/
84
85
86/***********************************************************************************************
87 * HLodSaveClass -- The constructor builds the whole HLOD tree in a form suitable for saving *
88 * to a W3D file. *
89 * *
90 * INPUT: *
91 * *
92 * OUTPUT: *
93 * *
94 * WARNINGS: *
95 * *
96 * HISTORY: *
97 * 9/14/1999 AJA : Created. *
98 *=============================================================================================*/
99HLodSaveClass::HLodSaveClass (MeshConnectionsClass **connections, int lod_count, TimeValue CurTime,
100 char *name, const char *htree_name, Progress_Meter_Class &meter,
101 INodeListClass *origin_list)
103{
104 /*
105 ** Fill in the W3dHLodHeaderStruct
106 */
108 header.LodCount = lod_count;
109 Set_W3D_Name(header.Name, name);
110 Set_W3D_Name(header.HierarchyName, htree_name);
111 ExportLog::printf("\nExporting HLOD object: %s\n",header.Name);
112 ExportLog::printf(" lod count: %d\n",header.LodCount);
113
114 /*
115 ** Create the array of stuff for each LOD.
116 */
117 lod_array = new HLodArrayEntry[lod_count];
118 if (!lod_array)
119 throw ErrorClass("Out Of Memory!");
120
121 int i;
122 for (i = 0; i < lod_count; i++)
123 {
124
125 ExportLog::printf(" Exporting LOD Array %d\n",i);
126
127 INode *origin = connections[i]->Get_Origin();
128 int sub_obj_count = connections[i]->Get_Sub_Object_Count();
129 lod_array[i].Allocate_Sub_Objects(sub_obj_count);
130 lod_array[i].header.ModelCount = sub_obj_count;
131
132 float screen_size = NO_MAX_SCREEN_SIZE;
133 if (origin)
134 origin->GetUserPropFloat("MaxScreenSize", screen_size);
135 lod_array[i].header.MaxScreenSize = screen_size;
136
137 /*
138 ** Create the info per mesh in this LOD.
139 */
140 int j;
141 W3dHLodSubObjectStruct *sub_obj = lod_array[i].sub_obj;
142 ExportLog::printf(" sub-object count: %d\n",sub_obj_count);
143 for (j = 0; j < sub_obj_count; j++)
144 {
145 char *mesh_name;
146 int bone_index;
147 INode *mesh_node;
148 if (!connections[i]->Get_Sub_Object_Data(j, &mesh_name, &bone_index, &mesh_node))
149 throw ErrorClass("Model %s is missing connection data!", name);
150
151 strcpy(sub_obj[j].Name, mesh_name);
152 sub_obj[j].BoneIndex = bone_index;
153
154 ExportLog::printf(" Sub Object: %s Bone: %d\n",mesh_name,bone_index);
155 }
156 }
157
158 /*
159 ** Copy aggregates from the Top-Level LOD
160 */
161 int agg_count = connections[lod_count-1]->Get_Aggregate_Count();
162 aggregate_array.Allocate_Sub_Objects(agg_count);
163 aggregate_array.header.ModelCount = agg_count;
164 aggregate_array.header.MaxScreenSize = 0.0f;
165
166 ExportLog::printf(" Exporting Aggregates:\n");
167 ExportLog::printf(" aggregate count: %d\n",agg_count);
168
169 for (i=0; i<agg_count; i++) {
170
171 char *mesh_name;
172 int bone_index;
173 INode *mesh_node;
174 connections[lod_count-1]->Get_Aggregate_Data(i, &mesh_name, &bone_index, &mesh_node);
175
176 W3dHLodSubObjectStruct & sub_obj = aggregate_array.sub_obj[i];
177 strcpy(sub_obj.Name, mesh_name);
178 sub_obj.BoneIndex = bone_index;
179
180 ExportLog::printf(" Aggregate object: %s Bone: %d\n",mesh_name,bone_index);
181
182 }
183
184 /*
185 ** Copy the proxy objects from the Top-Level LOD
186 */
187 int proxy_count = connections[lod_count-1]->Get_Proxy_Count();
188 proxy_array.Allocate_Sub_Objects(proxy_count);
189 proxy_array.header.ModelCount = proxy_count;
190 proxy_array.header.MaxScreenSize = 0.0f;
191
192 ExportLog::printf(" Exporting Proxies\n");
193 ExportLog::printf(" proxy count: %d\n",proxy_count);
194 for (i=0; i<proxy_count; i++) {
195
196 char *mesh_name;
197 int bone_index;
198 INode *mesh_node;
199 connections[lod_count-1]->Get_Proxy_Data(i, &mesh_name, &bone_index, &mesh_node);
200
201 W3dHLodSubObjectStruct & sub_obj = proxy_array.sub_obj[i];
202 strcpy(sub_obj.Name, mesh_name);
203 sub_obj.BoneIndex = bone_index;
204
205 ExportLog::printf(" Proxy object: %s Bone: %d\n",mesh_name,bone_index);
206 }
207
208}
209
210
211/***********************************************************************************************
212 * ~HLodSaveClass -- Destructor blows away the dynamic memory we used. *
213 * *
214 * INPUT: *
215 * *
216 * OUTPUT: *
217 * *
218 * WARNINGS: *
219 * *
220 * HISTORY: *
221 * 9/14/1999 AJA : Created. *
222 *=============================================================================================*/
224{
225 if (lod_array)
226 {
227 delete []lod_array;
228 lod_array = NULL;
229 }
230}
231
232
233/***********************************************************************************************
234 * HLodSaveClass::Save -- Method called when saving to a W3D file. Saves the chunks that *
235 * define a HLOD. *
236 * *
237 * INPUT: *
238 * *
239 * OUTPUT: *
240 * *
241 * WARNINGS: *
242 * *
243 * HISTORY: *
244 * 9/14/1999 AJA : Created. *
245 *=============================================================================================*/
247{
248 if (!lod_array)
249 return false;
250
251 if (!csave.Begin_Chunk(W3D_CHUNK_HLOD))
252 return false;
253
254 if (!save_header(csave))
255 return false;
256
257 if (!save_lod_arrays(csave))
258 return false;
259
260 if (!save_aggregate_array(csave))
261 return false;
262
263 if (!save_proxy_array(csave))
264 return false;
265
266 if (!csave.End_Chunk())
267 return false;
268
269 return true;
270}
271
272
273/***********************************************************************************************
274 * HLodSaveClass::save_header -- Write the header *
275 * *
276 * INPUT: *
277 * *
278 * OUTPUT: *
279 * *
280 * WARNINGS: *
281 * *
282 * HISTORY: *
283 * 9/14/1999 AJA : Created. *
284 *=============================================================================================*/
286{
288 return false;
289
290 if (csave.Write(&header, sizeof(header)) != sizeof(header))
291 return false;
292
293 if (!csave.End_Chunk())
294 return false;
295
296 return true;
297}
298
299
300/***********************************************************************************************
301 * HLodSaveClass::save_lod_arrays -- Writes each LOD *
302 * *
303 * INPUT: *
304 * *
305 * OUTPUT: *
306 * *
307 * WARNINGS: *
308 * *
309 * HISTORY: *
310 * 9/14/1999 AJA : Created. *
311 *=============================================================================================*/
313{
314 for (int i = 0; i < header.LodCount; i++)
315 {
317 return false;
318
319 if (!save_sub_object_array(csave, lod_array[i]))
320 return false;
321
322 if (!csave.End_Chunk())
323 return false;
324 }
325
326 return true;
327}
328
329
330
331/***********************************************************************************************
332 * HLodSaveClass::save_aggregate_array -- save the aggregates (if any) *
333 * *
334 * INPUT: *
335 * *
336 * OUTPUT: *
337 * *
338 * WARNINGS: *
339 * *
340 * HISTORY: *
341 * 10/25/2000 gth : Created. *
342 *=============================================================================================*/
344{
345 if (aggregate_array.num_sub_objects > 0) {
347 return false;
348
350 return false;
351
352 if (!csave.End_Chunk())
353 return false;
354 }
355 return true;
356}
357
358
359/***********************************************************************************************
360 * HLodSaveClass::save_proxy_array -- save the array of proxies (if any) *
361 * *
362 * INPUT: *
363 * *
364 * OUTPUT: *
365 * *
366 * WARNINGS: *
367 * *
368 * HISTORY: *
369 * 10/27/2000 gth : Created. *
370 *=============================================================================================*/
372{
373 if (proxy_array.num_sub_objects > 0) {
375 return false;
376
378 return false;
379
380 if (!csave.End_Chunk())
381 return false;
382 }
383 return true;
384}
385
386
387/***********************************************************************************************
388 * HLodSaveClass::save_sub_object_array -- Writes the mesh to bone connectivity info for each *
389 * mesh in an LOD. *
390 * *
391 * INPUT: *
392 * *
393 * OUTPUT: *
394 * *
395 * WARNINGS: *
396 * *
397 * HISTORY: *
398 * 9/14/1999 AJA : Created. *
399 *=============================================================================================*/
401{
403 return false;
404
405 if (csave.Write(&(array.header), sizeof(array.header)) != sizeof(array.header))
406 return false;
407
408 if (!csave.End_Chunk())
409 return false;
410
411 for (int j = 0; j < array.num_sub_objects; j++)
412 {
414 return false;
415
416 if (csave.Write(&(array.sub_obj[j]), sizeof(array.sub_obj[j])) != sizeof(array.sub_obj[j]))
417 return false;
418
419 if (!csave.End_Chunk())
420 return false;
421 }
422
423 return true;
424}
425
426
#define NULL
Definition BaseType.h:92
@ W3D_CHUNK_HLOD_AGGREGATE_ARRAY
Definition w3d_file.h:470
@ W3D_CHUNK_HLOD_PROXY_ARRAY
Definition w3d_file.h:471
@ W3D_CHUNK_HLOD
Definition w3d_file.h:465
@ W3D_CHUNK_HLOD_LOD_ARRAY
Definition w3d_file.h:467
@ W3D_CHUNK_HLOD_SUB_OBJECT
Definition w3d_file.h:469
@ W3D_CHUNK_HLOD_HEADER
Definition w3d_file.h:466
@ W3D_CHUNK_HLOD_SUB_OBJECT_ARRAY_HEADER
Definition w3d_file.h:468
#define W3D_CURRENT_HLOD_VERSION
Definition w3d_file.h:2044
#define NO_MAX_SCREEN_SIZE
Definition w3d_file.h:2045
uint32 Write(const void *buf, uint32 nbytes)
Definition chunkio.cpp:264
bool Begin_Chunk(uint32 id)
Definition chunkio.cpp:108
bool End_Chunk()
Definition chunkio.cpp:148
static void printf(char *,...)
Definition hlodsave.h:78
W3dHLodSubObjectStruct * sub_obj
Definition hlodsave.h:81
int num_sub_objects
Definition hlodsave.h:82
W3dHLodArrayHeaderStruct header
Definition hlodsave.h:80
bool Save(ChunkSaveClass &csave)
Definition hlodsave.cpp:246
bool save_sub_object_array(ChunkSaveClass &csave, const HLodArrayEntry &array)
Definition hlodsave.cpp:400
bool save_lod_arrays(ChunkSaveClass &csave)
Definition hlodsave.cpp:312
W3dHLodHeaderStruct header
Definition hlodsave.h:121
HLodArrayEntry * lod_array
Definition hlodsave.h:122
bool save_header(ChunkSaveClass &csave)
Definition hlodsave.cpp:285
~HLodSaveClass(void)
Definition hlodsave.cpp:223
HLodArrayEntry aggregate_array
Definition hlodsave.h:123
bool save_aggregate_array(ChunkSaveClass &csave)
Definition hlodsave.cpp:343
HLodArrayEntry proxy_array
Definition hlodsave.h:124
bool save_proxy_array(ChunkSaveClass &csave)
Definition hlodsave.cpp:371
HLodSaveClass(MeshConnectionsClass **connections, int lod_count, TimeValue CurTime, char *name, const char *htree_name, Progress_Meter_Class &meter, INodeListClass *origin_list)
Definition hlodsave.cpp:99
INode * Get_Origin(void) const
Definition meshcon.h:131
bool Get_Proxy_Data(int index, char **out_name, int *out_boneindex, INode **out_inode=NULL)
Definition meshcon.cpp:186
int Get_Proxy_Count(void) const
Definition meshcon.h:115
bool Get_Aggregate_Data(int index, char **out_name, int *out_boneindex, INode **out_inode=NULL)
Definition meshcon.cpp:158
int Get_Aggregate_Count(void) const
Definition meshcon.h:114
int Get_Sub_Object_Count(void) const
Definition meshcon.h:113
char Name[W3D_NAME_LEN *2]
Definition w3d_file.h:2064
void Set_W3D_Name(char *set_name, const char *src)
Definition util.cpp:112