Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
meshmdlio.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 : WW3D *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/meshmdlio.cpp $*
26 * *
27 * Author:: Greg Hjelstrom *
28 * *
29 * $Modtime:: 1/18/02 3:09p $*
30 * *
31 * $Revision:: 27 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * MeshModelClass::Load_W3D -- Load a mesh from a W3D file *
36 * MeshModelClass::read_chunks -- read all of the chunks for a mesh *
37 * MeshModelClass::read_vertices -- reads the vertex chunk *
38 * MeshModelClass::read_texcoords -- read in the texture coordinates chunk *
39 * MeshModelClass::read_vertex_normals -- reads a vertex normal chunk from the w3d file *
40 * MeshModelClass::read_v3_materials -- Reads in version 3 materials. *
41 * MeshModelClass::read_triangles -- read the triangles chunk *
42 * MeshModelClass::read_per_tri_materials -- read the material indices for each triangle *
43 * MeshModelClass::read_user_text -- read in the user text chunk *
44 * MeshModelClass::read_vertex_colors -- read in the vertex colors chunk *
45 * MeshModelClass::read_vertex_influences -- read in the vertex influences chunk *
46 * MeshModelClass::read_vertex_shade_indices -- read the shade index chunk *
47 * MeshModelClass::read_material_info -- read the material info chunk *
48 * MeshModelClass::read_shaders -- read the shaders chunk *
49 * MeshModelClass::read_vertex_materials -- read the vertex materials chunk *
50 * MeshModelClass::read_textures -- read the textures chunk *
51 * MeshModelClass::read_material_pass -- read a material pass chunk *
52 * MeshModelClass::read_vertex_material_ids -- read the vmat ids for a pass *
53 * MeshModelClass::read_shader_ids -- read the shader indexes for a pass *
54 * MeshModelClass::read_dcg -- read the per-vertex diffuse color for a pass *
55 * MeshModelClass::read_dig -- read the per-vertex diffuse illumination for a pass *
56 * MeshModelClass::read_scg -- read the specular color for a pass *
57 * MeshModelClass::read_texture_stage -- read texture stage chunks *
58 * MeshModelClass::read_texture_ids -- read the texture ids for a pass,stage *
59 * MeshModelClass::read_stage_texcoords -- read the texcoords for a pass,stage *
60 * MeshModelClass::read_per_face_texcoord_ids -- read uv indices for given (pass,stage). *
61 * MeshModelClass::read_prelit_material -- read prelit material chunks. *
62 * MeshModelClass::read_aabtree -- loads the aabtree chunk *
63 * MeshModelClass::Save -- Save this mesh model! *
64 * MeshLoadContextClass::MeshLoadContextClass -- constructor for MeshLoadContextClass *
65 * MeshLoadContextClass::~MeshLoadContextClass -- destructor *
66 * MeshLoadContextClass::Get_Texcoord_Array -- returns the texture coordinates array *
67 * MeshLoadContextClass::Add_Shader -- adds a shader to the array *
68 * MeshLoadContextClass::Add_Vertex_Materail -- adds a vertex material *
69 * MeshLoadContextClass::Add_Texture -- adds a texture *
70 * MeshLoadContextClass::Add_Legacy_Material -- adds a legacy material *
71 * MeshLoadContextClass::Peek_Legacy_Shader -- returns a legacy shader *
72 * MeshLoadContextClass::Peek_Legacy_Vertex_Material -- returns a pointer to a legacy vmat *
73 * MeshLoadContextClass::Peek_Legacy_Texture -- returns a pointer to a texture *
74 * MeshSaveContextClass::MeshSaveContextClass -- constructor *
75 * MeshSaveContextClass::~MeshSaveContextClass -- destructor *
76 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
77
78#include "meshmdl.h"
79#include "aabtree.h"
80#include "matinfo.h"
81#include "vertmaterial.h"
82#include "shader.h"
83#include "texture.h"
84#include "chunkio.h"
85#include "w3derr.h"
86#include "w3d_file.h"
87#include "w3d_util.h"
88#include "assetmgr.h"
89#include "simplevec.h"
90#include "realcrc.h"
91#include "dx8wrapper.h"
92
93#include <stdio.h>
94
95#ifdef _UNIX
96#include "osdep/osdep.h"
97#endif
98
99#define MESH_SINGLE_MATERIAL_HACK 0 // (gth) forces all multi-material meshes to use their first material only. (NOT RECOMMENDED, TESTING ONLY!)
100#define MESH_FORCE_STATIC_SORT_HACK 0 // (gth) forces all sorting meshes to use static sort level 1 instead.
114class MeshLoadContextClass : public W3DMPO
115{
116 W3DMPO_GLUE(MeshLoadContextClass)
117private:
118 MeshLoadContextClass(void);
119 ~MeshLoadContextClass(void);
120
121 W3dTexCoordStruct * Get_Texcoord_Array(void);
122
123 int Add_Shader(ShaderClass shader);
124 int Add_Vertex_Material(VertexMaterialClass * vmat);
125 int Add_Texture(TextureClass* tex);
126
127 ShaderClass Peek_Shader(int index) { return Shaders[index]; }
128 VertexMaterialClass * Peek_Vertex_Material(int index) { return VertexMaterials[index]; }
129 TextureClass * Peek_Texture(int index) { return Textures[index]; }
130
131 int Shader_Count(void) { return Shaders.Count(); }
132 int Vertex_Material_Count(void) { return VertexMaterials.Count(); }
133 int Texture_Count(void) { return Textures.Count(); }
134
135 /*
136 ** Legacy material support.
137 */
138 void Add_Legacy_Material(ShaderClass shader,VertexMaterialClass * vmat,TextureClass * tex);
139 ShaderClass Peek_Legacy_Shader(int legacy_material_index);
140 VertexMaterialClass * Peek_Legacy_Vertex_Material(int legacy_material_index);
141 TextureClass * Peek_Legacy_Texture(int legacy_material_index);
142
143 /*
144 ** Redundant UV detection support. The context provides a temporary buffer to
145 ** load the uv coordinates into.
146 */
147 Vector2 * Get_Temporary_UV_Array(int elementcount);
148
149
150 /*
151 ** Currently, the only tool that creates DIG chunks is the lightmap tool. Since DX8 support
152 ** for linking the emissive material color to an array seems poor, We're just going to multiply
153 ** the DIG array into the DCG array (or make it the DCG array). Now, to properly support the
154 ** "alternate material set", we have to know whether we've already encountered a DIG chunk so
155 ** these flags provide that functionality.
156 */
157 void Notify_Loaded_DIG_Chunk(bool onoff = true) { LoadedDIG = onoff; }
158 bool Already_Loaded_DIG(void) { return LoadedDIG; }
159
160private:
161
162 struct LegacyMaterialClass
163 {
164 LegacyMaterialClass(void) : VertexMaterialIdx(0),ShaderIdx(0),TextureIdx(0) { }
165 ~LegacyMaterialClass(void) { }
166 void Set_Name(const char * name) { Name=name; }
167
168 StringClass Name;
169 int VertexMaterialIdx;
170 int ShaderIdx;
171 int TextureIdx;
172 };
173
174
176 W3dTexCoordStruct * TexCoords;
177 W3dMaterialInfoStruct MatInfo;
178
179 uint32 PrelitChunkID;
180
181 int CurPass;
182 int CurTexStage;
183
184 DynamicVectorClass < LegacyMaterialClass * > LegacyMaterials;
185 DynamicVectorClass < ShaderClass > Shaders;
186 DynamicVectorClass < VertexMaterialClass * > VertexMaterials;
187 DynamicVectorClass < unsigned long > VertexMaterialCrcs;
188 DynamicVectorClass < TextureClass * > Textures;
189
190 /*
191 ** Alternate material data. Any alternate material data will be loaded into
192 ** this MeshMatDescClass object. When loading is finished, an alternate MeshMatDescClass
193 ** will be allocated in the mesh model. This MeshMatDescClass will be initialized to be
194 ** identical to the default MeshMatDescClass and then any data contained in this
195 ** MeshMatDescClass will replace the relevant arrays.
196 */
197 MeshMatDescClass AlternateMatDesc;
198
199 SimpleVecClass<Vector2> TempUVArray;
200
201 /*
202 ** Record when we load the DIG chunk
203 */
204 bool LoadedDIG;
205
206 friend class MeshClass;
207 friend class MeshModelClass;
208};
209
210
211/*
212** MeshSaveContextClass
213** This class is used to pass information between the saving code in a mesh
214*/
225
226
227/***********************************************************************************************
228 * MeshModelClass::Load_W3D -- Load a mesh from a W3D file *
229 * *
230 * INPUT: *
231 * *
232 * OUTPUT: *
233 * *
234 * WARNINGS: *
235 * *
236 * HISTORY: *
237 * 2/16/99 GTH : Created. *
238 *=============================================================================================*/
240{
241 MeshLoadContextClass * context = NULL;
242
243 /*
244 ** Open the first chunk, it should be the mesh header
245 */
246 cload.Open_Chunk();
247
248 if (cload.Cur_Chunk_ID() != W3D_CHUNK_MESH_HEADER3) {
249 WWDEBUG_SAY(("Old format mesh mesh, no longer supported.\n"));
250 goto Error;
251 }
252
254
255 if (cload.Read(&(context->Header),sizeof(W3dMeshHeader3Struct)) != sizeof(W3dMeshHeader3Struct)) {
256 goto Error;
257 }
258 cload.Close_Chunk();
259
260 /*
261 ** Process the header
262 */
263 char * tmpname;
264 int namelen;
265
266 Reset(context->Header.NumTris,context->Header.NumVertices,1);
267
268 namelen = strlen(context->Header.ContainerName);
269 namelen += strlen(context->Header.MeshName);
270 namelen += 2;
271 W3dAttributes = context->Header.Attributes;
272 SortLevel = context->Header.SortLevel;
273 tmpname = W3DNEWARRAY char[namelen];
274 memset(tmpname,0,namelen);
275
276 if (strlen(context->Header.ContainerName) > 0) {
277 strcpy(tmpname,context->Header.ContainerName);
278 strcat(tmpname,".");
279 }
280 strcat(tmpname,context->Header.MeshName);
281
282 Set_Name(tmpname);
283
284 delete[] tmpname;
285 tmpname = NULL;
286
287 context->AlternateMatDesc.Set_Vertex_Count(VertexCount);
288 context->AlternateMatDesc.Set_Polygon_Count(PolyCount);
289
290 /*
291 ** Set Bounding Info
292 */
293 BoundBoxMin.Set(context->Header.Min.X,context->Header.Min.Y,context->Header.Min.Z);
294 BoundBoxMax.Set(context->Header.Max.X,context->Header.Max.Y,context->Header.Max.Z);
295
296 BoundSphereCenter.Set(context->Header.SphCenter.X,context->Header.SphCenter.Y,context->Header.SphCenter.Z);
297 BoundSphereRadius = context->Header.SphRadius;
298
299 /*
300 ** Flags
301 */
302 if (context->Header.Version >= W3D_MAKE_VERSION(4,1)) {
303 int geometry_type = context->Header.Attributes & W3D_MESH_FLAG_GEOMETRY_TYPE_MASK;
304 switch (geometry_type)
305 {
307 break;
309 Set_Flag(ALIGNED,true);
310 break;
312 Set_Flag(ORIENTED,true);
313 break;
315 Set_Flag(SKIN,true);
317 break;
318 }
319 }
320
321 if (context->Header.Attributes & W3D_MESH_FLAG_TWO_SIDED) {
322 Set_Flag(TWO_SIDED,true);
323 }
324
325 if (context->Header.Attributes & W3D_MESH_FLAG_CAST_SHADOW) {
326 Set_Flag(CAST_SHADOW,true);
327 }
328
329 if (context->Header.Attributes & W3D_MESH_FLAG_NPATCHABLE) {
331 }
332
333 // Configure the load sequence for prelighting.
334 if (context->Header.Attributes & W3D_MESH_FLAG_PRELIT_MASK) {
335
336 // Select from the available prelit materials based on current prelit lighting mode.
337 // If the model does not have the current prelit mode, select the next highest quality
338 // prelit material that is available.
339 switch (WW3D::Get_Prelit_Mode()) {
340
343 context->PrelitChunkID = W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_TEXTURE;
345 break;
346 }
347 // Else fall thru...
348
351 context->PrelitChunkID = W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_PASS;
353 break;
354 }
355 // Else fall thru...
356
358 if (context->Header.Attributes & W3D_MESH_FLAG_PRELIT_VERTEX) {
359 context->PrelitChunkID = W3D_CHUNK_PRELIT_VERTEX;
360 Set_Flag (PRELIT_VERTEX, true);
361 break;
362 }
363 // Else fall thru...
364
365 default:
366
367 // This prelighting option MUST be available if none of the others are available.
369 context->PrelitChunkID = W3D_CHUNK_PRELIT_UNLIT;
370 break;
371 }
372
373 } else {
374
375 // For backwards compatibility, test for obsolete lightmap flag.
376 if (context->Header.Attributes & OBSOLETE_W3D_MESH_FLAG_LIGHTMAPPED) {
378 }
379
380 // Else this mesh has no prelighting.
381 }
382
383 read_chunks(cload,context);
384
385 /*
386 ** If this is a pre-3.0 mesh and it has vertex influences,
387 ** fixup the bone indices to account for the new root node
388 */
389 if ((context->Header.Version < W3D_MAKE_VERSION(3,0)) && (Get_Flag(SKIN))) {
390
391 uint16 * links = get_bone_links();
392 WWASSERT(links);
393
394 for (int bi = 0; bi < Get_Vertex_Count(); bi++) {
395 links[bi] += 1;
396 }
397 }
398
399 /*
400 ** If this mesh is collideable and no AABTree was in the file, generate one now
401 */
403 (CullTree == NULL))
404 {
406 }
407
408 /*
409 ** Transfer the materials into the MatInfo
410 */
411 install_materials(context);
412
413 /*
414 ** Delete the temporary LoadInfo object
415 */
416 delete context;
417
418 /*
419 ** Post-process the model: optimize passes, activate fog etc.
420 */
421 post_process();
422
423 return WW3D_ERROR_OK;
424
425Error:
426
428}
429
430
431/***********************************************************************************************
432 * MeshModelClass::read_chunks -- read all of the chunks for a mesh *
433 * *
434 * INPUT: *
435 * *
436 * OUTPUT: *
437 * *
438 * WARNINGS: *
439 * *
440 * HISTORY: *
441 * 2/16/99 GTH : Created. *
442 *=============================================================================================*/
444{
445 /*
446 ** Read in the chunk header
447 ** If there are no more chunks within the mesh chunk,
448 ** we are done.
449 */
450 while (cload.Open_Chunk()) {
451
452 /*
453 ** Process the chunk
454 */
456
457 switch (cload.Cur_Chunk_ID()) {
458
460 // call up to MeshGeometryClass
461 error = read_vertices(cload);
462 break;
463
466 // call up to MeshGeometryClass
467 error = read_vertex_normals(cload);
468 break;
469
471 error = read_texcoords(cload,context);
472 break;
473
476 WWDEBUG_SAY(( "Obsolete material chunk encountered in mesh: %s.%s\r\n", context->Header.ContainerName,context->Header.MeshName));
477 WWASSERT(0);
478 break;
479
481 WWDEBUG_SAY(( "Obsolete material chunk encountered in mesh: %s.%s\r\n", context->Header.ContainerName,context->Header.MeshName));
482 error = read_v3_materials(cload,context);
483 break;
484
486 WWASSERT_PRINT( 0, "Obsolete Triangle Chunk Encountered!\r\n" );
487 break;
488
490 // call up to MeshGeometryClass
491 error = read_triangles(cload);
492 break;
493
495 error = read_per_tri_materials(cload,context);
496 break;
497
499 // call up to MeshGeometryClass
500 error = read_user_text(cload);
501 break;
502
504 error = read_vertex_colors(cload,context);
505 break;
506
508 // call up to MeshGeometryClass
509 error = read_vertex_influences(cload);
510 break;
511
513 // call up to MeshGeometryClass
514 error = read_vertex_shade_indices(cload);
515 break;
516
518 error = read_material_info(cload,context);
519 break;
520
522 error = read_shaders(cload,context);
523 break;
524
526 error = read_vertex_materials(cload,context);
527 break;
528
530 error = read_textures(cload,context);
531 break;
532
534 error = read_material_pass(cload,context);
535 break;
536
537 case W3D_CHUNK_DEFORM:
538 WWDEBUG_SAY(("Obsolete deform chunk encountered in mesh: %s.%s\r\n", context->Header.ContainerName,context->Header.MeshName));
539 break;
540
541 case W3D_CHUNK_DAMAGE:
542 WWDEBUG_SAY(("Obsolete damage chunk encountered in mesh: %s.%s\r\n", context->Header.ContainerName,context->Header.MeshName));
543 break;
544
549 read_prelit_material (cload, context);
550 break;
551
553 // call up to MeshGeometryClass
554 read_aabtree(cload);
555 break;
556
557 default:
558 break;
559
560 }
561
562 cload.Close_Chunk();
563
564 if (error != WW3D_ERROR_OK) {
565 return error;
566 }
567 }
568
569 return WW3D_ERROR_OK;
570}
571
572
573/***********************************************************************************************
574 * MeshModelClass::read_texcoords -- read in the texture coordinates chunk *
575 * *
576 * INPUT: *
577 * *
578 * OUTPUT: *
579 * *
580 * WARNINGS: *
581 * *
582 * HISTORY: *
583 * 3/6/98 GTH : Created. *
584 * 2/16/99 GTH : Moved into MeshModel *
585 *=============================================================================================*/
587{
588 W3dTexCoordStruct texcoord;
589 Vector2 * uvarray = 0;
590 int elementcount = cload.Cur_Chunk_Length() / sizeof (W3dTexCoordStruct);
591
592 uvarray = context->Get_Temporary_UV_Array(elementcount);
593
594 if (uvarray != NULL) {
595 /*
596 ** Read the uv's into the first u-v pass array
597 ** NOTE: this is an obsolete function. Texture coordinates are now
598 ** loaded in the pass chunks
599 */
600 for (int i=0; i<VertexCount; i++) {
601 if (cload.Read(&(texcoord),sizeof(W3dTexCoordStruct)) != sizeof(W3dTexCoordStruct)) {
603 }
604 uvarray[i].Set(texcoord.U,1.0f - texcoord.V);
605 }
606
607 DefMatDesc->Install_UV_Array(context->CurPass,context->CurTexStage,uvarray,elementcount);
608 }
609
610 return WW3D_ERROR_OK;
611}
612
613/***********************************************************************************************
614 * MeshModelClass::read_v3_materials -- Reads in version 3 materials. *
615 * *
616 * INPUT: *
617 * *
618 * OUTPUT: *
619 * *
620 * WARNINGS: *
621 * *
622 * HISTORY: *
623 * 4/2/98 GTH : Created. *
624 * 2/16/99 GTH : Moved into MeshModelClass *
625 *=============================================================================================*/
627{
628 for (unsigned int mi=0; mi<context->Header.NumMaterials; mi++) {
629
630 /*
631 ** First, we expect a W3D_CHUNK_MATERIAL3 to wrap the entire material
632 */
633 if (!cload.Open_Chunk()) goto Error;
634 if (cload.Cur_Chunk_ID() != W3D_CHUNK_MATERIAL3) goto Error;
635
636 /*
637 ** Inside the MATERIAL3 will be the following:
638 **
639 ** W3D_MATERIAL3_NAME - name of the material
640 ** W3D_MATERIAL3_INFO - equivalent to 1.40 vertex material parameters
641 ** W3D_MATERIAL3_DC_MAP - diffuse color mapping
642 ** W3D_MAP3_FILENAME - filename of the texture map
643 ** W3D_MAP3_INFO - animation, etc information
644 ** W3D_MATERIAL3_DI_MAP - diffuse illumination map
645 ** W3D_MATERIAL3_SC_MAP - specular color map
646 ** W3D_MATERIAL3_SI_MAP - specular illumination map
647 */
648 VertexMaterialClass * vmat = NULL;
649 ShaderClass shader;
650 TextureClass * tex = NULL;
651 char name[256];
652
653 /*
654 ** Read the material name
655 */
656 if (!cload.Open_Chunk()) goto Error;
657 if (cload.Cur_Chunk_ID() != W3D_CHUNK_MATERIAL3_NAME) goto Error;
658 cload.Read(name,cload.Cur_Chunk_Length());
659 if (!cload.Close_Chunk()) goto Error;
660
661 /*
662 ** Read the vertex material parameters
663 */
664 if (!cload.Open_Chunk()) goto Error;
665
667 if (cload.Cur_Chunk_ID() != W3D_CHUNK_MATERIAL3_INFO) goto Error;
668 if (cload.Read(&mat,sizeof(W3dMaterial3Struct)) != sizeof(W3dMaterial3Struct)) goto Error;
670 vmat->Init_From_Material3(mat);
671 vmat->Set_Name(name);
672 shader.Init_From_Material3(mat);
673
674 /*
675 ** If this shader does alpha blending, the mesh must be sorted.
676 */
679 }
680
681 if (!cload.Close_Chunk()) goto Error;
682
683 /*
684 ** Look for the DC map and read it in
685 */
686 while (cload.Open_Chunk()) {
688
689 /*
690 ** Read in the texture filename
691 */
692 char filename[_MAX_FNAME + _MAX_EXT];
693 if (!cload.Open_Chunk()) goto Error;
694 if (cload.Cur_Chunk_ID() != W3D_CHUNK_MAP3_FILENAME) goto Error;
695 if (cload.Cur_Chunk_Length() >= sizeof(filename)) goto Error;
696 cload.Read(filename,cload.Cur_Chunk_Length());
697 if (!cload.Close_Chunk()) goto Error;
698
699 /*
700 ** Read in the auxiliary map info
701 */
702 W3dMap3Struct mapinfo;
703 if (!cload.Open_Chunk()) goto Error;
704 if (cload.Cur_Chunk_ID() != W3D_CHUNK_MAP3_INFO) goto Error;
705 if (cload.Read(&mapinfo,sizeof(W3dMap3Struct)) != sizeof(W3dMap3Struct)) goto Error;
706 if (!cload.Close_Chunk()) goto Error;
707
708 if ( mapinfo.FrameCount > 1 ) {
709 WWDEBUG_SAY(("ERROR: Obsolete Animated Texture detected in model: %s\r\n",context->Header.MeshName));
710 }
711
713
715
716 } else if (cload.Cur_Chunk_ID() == W3D_CHUNK_MATERIAL3_SI_MAP) {
717 Vector3 diffuse_color;
718 vmat->Get_Diffuse( &diffuse_color);
719 if ( diffuse_color == Vector3( 0,0,0 ) ) {
720
721 /*
722 ** Read in the texture filename
723 */
724 char filename[_MAX_FNAME + _MAX_EXT];
725 if (!cload.Open_Chunk()) goto Error;
726 if (cload.Cur_Chunk_ID() != W3D_CHUNK_MAP3_FILENAME) goto Error;
727 if (cload.Cur_Chunk_Length() >= sizeof(filename)) goto Error;
728 cload.Read(filename,cload.Cur_Chunk_Length());
729 if (!cload.Close_Chunk()) goto Error;
730
731 if (tex) tex->Release_Ref();
732
733 /*
734 ** Read in the auxiliary map info
735 */
736 W3dMap3Struct mapinfo;
737 if (!cload.Open_Chunk()) goto Error;
738 if (cload.Cur_Chunk_ID() != W3D_CHUNK_MAP3_INFO) goto Error;
739 if (cload.Read(&mapinfo,sizeof(W3dMap3Struct)) != sizeof(W3dMap3Struct)) goto Error;
740 if (!cload.Close_Chunk()) goto Error;
741
742 if ( mapinfo.FrameCount > 1 ) {
743 WWDEBUG_SAY(("ERROR: Obsolete Animated Texture detected in model: %s\r\n",context->Header.MeshName));
744 }
745
747
752 }
753 }
754
755 cload.Close_Chunk();
756 }
757
758 // If not texturing, move the diffuse color to ambient (simulating old behavior)
760 Vector3 color;
761 vmat->Get_Diffuse( &color );
762 vmat->Set_Ambient( color );
763 vmat->Set_Diffuse( Vector3( 0, 0, 0 ) );
764 }
765
766 context->Add_Legacy_Material(shader,vmat,tex);
767
768 vmat->Release_Ref();
769 if (tex) tex->Release_Ref();
770 vmat = NULL;
771 tex = NULL;
772
773 /*
774 ** Close the W3D_CHUNK_MATERIAL3
775 */
776 cload.Close_Chunk();
777 }
778
779 /*
780 ** Install the default materials to use in the absence of an array
781 */
782 if (context->Vertex_Material_Count() >= 1) {
783 Set_Single_Material(context->Peek_Vertex_Material(0),0);
784 }
785
786 if (context->Texture_Count() >= 1) {
787 Set_Single_Texture(context->Peek_Texture(0),0);
788 }
789
790 if (context->Shader_Count() >= 1) {
791 Set_Single_Shader(context->Peek_Shader(0),0);
792 }
793
794 return WW3D_ERROR_OK;
795
796Error:
797
799
800}
801
802
803/***********************************************************************************************
804 * MeshModelClass::read_per_tri_materials -- read the material indices for each triangle *
805 * *
806 * INPUT: *
807 * *
808 * OUTPUT: *
809 * *
810 * WARNINGS: *
811 * *
812 * HISTORY: *
813 * 4/7/98 GTH : Created. *
814 *=============================================================================================*/
816{
817 if (context->Header.NumMaterials == 1) return WW3D_ERROR_OK;
818
819 TriIndex * polys = get_polys();
820
821 bool multi_mtl = (context->Vertex_Material_Count() > 1);
822 bool multi_tex = (context->Texture_Count() > 1);
823 bool multi_shad = (context->Shader_Count() > 1);
824
825 if (!multi_mtl) {
826 Set_Single_Material(context->Peek_Legacy_Vertex_Material(0));
827 }
828 if (!multi_tex) {
829 Set_Single_Texture(context->Peek_Legacy_Texture(0));
830 }
831 if (!multi_shad) {
832 Set_Single_Shader(context->Peek_Legacy_Shader(0));
833 }
834
835 /*
836 ** Read in each polygon's material id and assign pointer to the
837 ** shader, texture, and vertex material as needed.
838 */
839 for (int i=0; i<Get_Polygon_Count(); i++) {
840
841 // read in the mat id for this poly
842 uint16 matid;
843
844 if (cload.Read(&matid,sizeof(uint16)) != sizeof(uint16)) {
846 }
847
848 if (multi_shad) {
849 Set_Shader(i,context->Peek_Legacy_Shader(matid));
850 }
851 if (multi_tex) {
852 Set_Texture(i,context->Peek_Legacy_Texture(matid));
853 }
854 if (multi_mtl) {
855 Set_Material(polys[i].I,context->Peek_Legacy_Vertex_Material(matid));
856 Set_Material(polys[i].J,context->Peek_Legacy_Vertex_Material(matid));
857 Set_Material(polys[i].K,context->Peek_Legacy_Vertex_Material(matid));
858 }
859 }
860
861 return WW3D_ERROR_OK;
862}
863
864
865/***********************************************************************************************
866 * MeshModelClass::read_vertex_colors -- read in the vertex colors chunk *
867 * *
868 * INPUT: *
869 * *
870 * OUTPUT: *
871 * *
872 * WARNINGS: *
873 * *
874 * HISTORY: *
875 * 10/28/1997 GH : Created. *
876 * 2/16/99 GTH : Moved into MeshModelClass *
877 *=============================================================================================*/
879{
880 /*
881 ** The W3D file format supports arbitrary vertex color arrays for each pass; however since
882 ** our conversion to hardware T&L, we only support two unique color arrays. So here is
883 ** what is happening in this function:
884 **
885 ** 1 - If this is the first diffuse color array we've encountered, load the values
886 ** 2 - Always set the DCG source for this pass to the array (vertex materials will be fixed later)
887 **
888 ** A side effect is that if two DCG chunks are encountered, only the first is used...
889 */
890 if (CurMatDesc->Has_Color_Array(0) == NULL) {
891 W3dRGBStruct color;
892 unsigned * dcg = Get_Color_Array(0,true);
893 assert(dcg != NULL);
894
895 for (int i=0; i<Get_Vertex_Count(); i++) {
896
897 if (cload.Read(&color,sizeof(W3dRGBStruct)) != sizeof(W3dRGBStruct)) {
899 }
900
901 Vector4 col;
902 col.Set((float)color.R / 255.0f,(float)color.G / 255.0f,(float)color.B / 255.0f, 1.0f);
903 dcg[i]=DX8Wrapper::Convert_Color(col);
904 }
905 }
906 CurMatDesc->Set_DCG_Source(context->CurPass,VertexMaterialClass::COLOR1);
907
908 return WW3D_ERROR_OK;
909}
910
911
912/***********************************************************************************************
913 * MeshModelClass::read_material_info -- read the material info chunk *
914 * *
915 * INPUT: *
916 * *
917 * OUTPUT: *
918 * *
919 * WARNINGS: *
920 * *
921 * HISTORY: *
922 * 2/16/99 GTH : Created. *
923 *=============================================================================================*/
925{
926 if (cload.Read(&(context->MatInfo),sizeof(W3dMaterialInfoStruct)) != sizeof(W3dMaterialInfoStruct)) {
928 }
929 Set_Pass_Count(context->MatInfo.PassCount);
930 return WW3D_ERROR_OK;
931}
932
933
934/***********************************************************************************************
935 * MeshModelClass::read_shaders -- read the shaders chunk *
936 * *
937 * INPUT: *
938 * *
939 * OUTPUT: *
940 * *
941 * WARNINGS: *
942 * *
943 * HISTORY: *
944 * 2/16/99 GTH : Created. *
945 *=============================================================================================*/
947{
948 W3dShaderStruct shader;
949 for (unsigned int i=0; i<context->MatInfo.ShaderCount; i++) {
950 if (cload.Read(&shader,sizeof(shader)) != sizeof(shader)) {
952 }
953 ShaderClass newshader;
954 W3dUtilityClass::Convert_Shader(shader,&newshader);
955
956 int index = context->Add_Shader(newshader);
957 WWASSERT(index == (int)i);
958 }
959 return WW3D_ERROR_OK;
960}
961
962
963/***********************************************************************************************
964 * MeshModelClass::read_vertex_materials -- read the vertex materials chunk *
965 * *
966 * INPUT: *
967 * *
968 * OUTPUT: *
969 * *
970 * WARNINGS: *
971 * *
972 * HISTORY: *
973 * 2/16/99 GTH : Created. *
974 *=============================================================================================*/
976{
977 while (cload.Open_Chunk()) {
980 WW3DErrorType error = vmat->Load_W3D(cload);
981 if (error != WW3D_ERROR_OK) {
982 return error;
983 }
984 context->Add_Vertex_Material(vmat);
985 vmat->Release_Ref();
986
987 cload.Close_Chunk();
988 }
989 return WW3D_ERROR_OK;
990}
991
992
993/***********************************************************************************************
994 * MeshModelClass::read_textures -- read the textures chunk *
995 * *
996 * INPUT: *
997 * *
998 * OUTPUT: *
999 * *
1000 * WARNINGS: *
1001 * *
1002 * HISTORY: *
1003 * 2/16/99 GTH : Created. *
1004 * 3/05/99 PDS : Broke the guts of this function into a util function in texture.cpp *
1005 *=============================================================================================*/
1007{
1008 // Keep reading textures until there are no more...
1009 for (TextureClass *newtex = ::Load_Texture (cload);
1010 newtex != NULL;
1011 newtex = ::Load_Texture (cload)) {
1012
1013 // Add this texture to our contex and release our local hold on it
1014 context->Add_Texture(newtex);
1015 newtex->Release_Ref();
1016 }
1017
1018 return WW3D_ERROR_OK;
1019}
1020
1021
1022/***********************************************************************************************
1023 * MeshModelClass::read_material_pass -- read a material pass chunk *
1024 * *
1025 * INPUT: *
1026 * *
1027 * OUTPUT: *
1028 * *
1029 * WARNINGS: *
1030 * *
1031 * HISTORY: *
1032 * 2/16/99 GTH : Created. *
1033 *=============================================================================================*/
1035{
1036 context->CurTexStage = 0;
1037
1038 while (cload.Open_Chunk()) {
1039
1041
1042 switch (cload.Cur_Chunk_ID()) {
1044 error = read_vertex_material_ids(cload,context);
1045 break;
1046
1048 error = read_shader_ids(cload,context);
1049 break;
1050
1051 case W3D_CHUNK_DCG:
1052 error = read_dcg(cload,context);
1053 break;
1054
1055 case W3D_CHUNK_DIG:
1056 error = read_dig(cload,context);
1057 break;
1058
1059 case W3D_CHUNK_SCG:
1060 error = read_scg(cload,context);
1061 break;
1062
1064 error = read_texture_stage(cload,context);
1065 break;
1066 };
1067
1068 if (error != WW3D_ERROR_OK) {
1069 return error;
1070 }
1071 cload.Close_Chunk();
1072 }
1073
1074 context->CurPass++;
1075 return WW3D_ERROR_OK;
1076}
1077
1078
1079/***********************************************************************************************
1080 * MeshModelClass::read_vertex_material_ids -- read the vmat ids for a pass *
1081 * *
1082 * INPUT: *
1083 * *
1084 * OUTPUT: *
1085 * *
1086 * WARNINGS: *
1087 * *
1088 * HISTORY: *
1089 * 2/16/99 GTH : Created. *
1090 * 9/1/2000 gth : Added alternate material desc support *
1091 *=============================================================================================*/
1093{
1094 /*
1095 ** Determine whether this chunk should be read into the default or alternate material description
1096 */
1097 MeshMatDescClass * matdesc = DefMatDesc;
1098 if (DefMatDesc->Has_Material_Data(context->CurPass)) {
1099 matdesc = &(context->AlternateMatDesc);
1100 }
1101
1102 /*
1103 ** This chunk will either have a single index in it or an array of indices
1104 ** with the length equal to the vertex count.
1105 */
1106 uint32 vmat;
1107#if (!MESH_SINGLE_MATERIAL_HACK)
1108 if (cload.Cur_Chunk_Length() == 1*sizeof(uint32)) {
1109
1110 cload.Read(&vmat,sizeof(uint32));
1111 matdesc->Set_Single_Material(context->Peek_Vertex_Material(vmat),context->CurPass);
1112
1113 } else {
1114
1115 for (int i=0; i<Get_Vertex_Count(); i++) {
1116 cload.Read(&vmat,sizeof(uint32));
1117 matdesc->Set_Material(i,context->Peek_Vertex_Material(vmat),context->CurPass);
1118 }
1119 }
1120#else
1121#pragma message ("(gth) Hacking to make Generals behave as if all meshes have 1 material")
1122 cload.Read(&vmat,sizeof(uint32));
1123 matdesc->Set_Single_Material(context->Peek_Vertex_Material(vmat),context->CurPass);
1124#endif //0
1125
1126 return WW3D_ERROR_OK;
1127}
1128
1129
1130/***********************************************************************************************
1131 * MeshModelClass::read_shader_ids -- read the shader indexes for a pass *
1132 * *
1133 * INPUT: *
1134 * *
1135 * OUTPUT: *
1136 * *
1137 * WARNINGS: *
1138 * *
1139 * HISTORY: *
1140 * 2/16/99 GTH : Created. *
1141 * 9/1/2000 gth : Added alternate material desc support *
1142 *=============================================================================================*/
1144{
1145 /*
1146 ** Determine whether this chunk should be read into the default or alternate material description
1147 */
1148 MeshMatDescClass * matdesc = DefMatDesc;
1149 if (DefMatDesc->Has_Shader_Data(context->CurPass)) {
1150 matdesc = &(context->AlternateMatDesc);
1151 }
1152
1153 /*
1154 ** Read in the shader id's and plug in the appropriate shader
1155 */
1156 uint32 shaderid;
1157#if (!MESH_SINGLE_MATERIAL_HACK)
1158 if (cload.Cur_Chunk_Length() == 1*sizeof(uint32)) {
1159
1160 cload.Read(&shaderid,sizeof(shaderid));
1161 ShaderClass shader = context->Peek_Shader(shaderid);
1162 matdesc->Set_Single_Shader(shader,context->CurPass);
1163
1164 // turn on sorting of pass 0 has non-zero dest blend (unless alpha testing on)
1165 if ( (context->CurPass == 0) &&
1169 {
1170#if (MESH_FORCE_STATIC_SORT_HACK)
1171 SortLevel = 1;
1172#else
1173 Set_Flag(SORT,true);
1174#endif
1175 }
1176
1177 } else {
1178
1179 for (int i=0; i<Get_Polygon_Count(); i++) {
1180 cload.Read(&shaderid,sizeof(uint32));
1181 ShaderClass shader = context->Peek_Shader(shaderid);
1182 matdesc->Set_Shader(i,shader,context->CurPass);
1183
1184 // turn on sorting of pass 0 has non-zero dest blend (unless alpha testing on)
1185 if ( (context->CurPass == 0) &&
1189 {
1190#if (MESH_FORCE_STATIC_SORT_HACK)
1191 SortLevel = 1;
1192#else
1193 Set_Flag(SORT,true);
1194#endif
1195 }
1196 }
1197 }
1198#else
1199#pragma message ("(gth) Hacking to make Generals behave as if all meshes have 1 material")
1200
1201 cload.Read(&shaderid,sizeof(shaderid));
1202 ShaderClass shader = context->Peek_Shader(shaderid);
1203 matdesc->Set_Single_Shader(shader,context->CurPass);
1204
1205 // turn on sorting of pass 0 has non-zero dest blend (unless alpha testing on)
1206 if ( (context->CurPass == 0) &&
1210 {
1211#if (MESH_FORCE_STATIC_SORT_HACK)
1212 SortLevel = 1;
1213#else
1214 Set_Flag(SORT,true);
1215#endif
1216 }
1217
1218#endif //0
1219 return WW3D_ERROR_OK;
1220}
1221
1222
1223/***********************************************************************************************
1224 * MeshModelClass::read_dcg -- read the per-vertex diffuse color for a pass *
1225 * *
1226 * INPUT: *
1227 * *
1228 * OUTPUT: *
1229 * *
1230 * WARNINGS: *
1231 * *
1232 * HISTORY: *
1233 * 2/16/99 GTH : Created. *
1234 * 9/1/2000 gth : Added alternate material desc support *
1235 * 2/9/2001 gth : converted to handle dx8 limitations *
1236 *=============================================================================================*/
1238{
1239 /*
1240 ** Determine whether this chunk should be read into the default or alternate material description
1241 */
1242 MeshMatDescClass * matdesc = DefMatDesc;
1243 if (DefMatDesc->Get_DCG_Source(context->CurPass) != VertexMaterialClass::MATERIAL) {
1244 matdesc = &(context->AlternateMatDesc);
1245 }
1246
1247 /*
1248 ** The W3D file format supports arbitrary vertex color arrays for each pass; however since
1249 ** our conversion to hardware T&L, we only support two unique color arrays. So here is
1250 ** what is happening in this function:
1251 **
1252 ** 1 - If this is the first diffuse color array we've encountered, load the values.
1253 ** 2 - Otherwise, if we are in PRELIT_VERTEX mode, put the alpha from this array into the color array.
1254 ** 3 - Always set the DCG source for this pass to the array.
1255 **
1256 ** Our tools *currently* will only generate two color arrays in the case where one of them
1257 ** is being used for alpha and the other is used for precomputed vertex lighting... This will
1258 ** break if our tools change. The file format isn't restricting you from defining something
1259 ** we can't render right now...
1260 */
1261 if (matdesc->Has_Color_Array(0) == false) {
1262 W3dRGBAStruct color;
1263 unsigned * dcg = matdesc->Get_Color_Array(0);
1264
1265 for (int i=0; i<Get_Vertex_Count(); i++) {
1266 cload.Read(&color,sizeof(color));
1267 Vector4 col;
1269 dcg[i]=DX8Wrapper::Convert_Color(col);
1270 }
1271 } else if (context->PrelitChunkID==W3D_CHUNK_PRELIT_VERTEX) {
1272
1273 W3dRGBAStruct color;
1274 unsigned * dcg = matdesc->Get_Color_Array(0);
1275
1276 for (int i=0; i<Get_Vertex_Count(); i++) {
1277 cload.Read(&color,sizeof(color));
1278 Vector4 col;
1279 col=DX8Wrapper::Convert_Color(dcg[i]);
1280 col.W = float(color.A)/255.0f;
1281 dcg[i]=DX8Wrapper::Convert_Color(col);
1282 }
1283 }
1284
1285 matdesc->Set_DCG_Source(context->CurPass,VertexMaterialClass::COLOR1);
1286
1287 return WW3D_ERROR_OK;
1288}
1289
1290
1291/***********************************************************************************************
1292 * MeshModelClass::read_dig -- read the per-vertex diffuse illumination for a pass *
1293 * *
1294 * INPUT: *
1295 * *
1296 * OUTPUT: *
1297 * *
1298 * WARNINGS: *
1299 * *
1300 * HISTORY: *
1301 * 2/16/99 GTH : Created. *
1302 * 9/1/2000 gth : Added alternate material desc support *
1303 * 2/9/2001 gth : converted to handle dx8 limitations *
1304 *=============================================================================================*/
1306{
1307 /*
1308 ** Determine whether this chunk should be read into the default or alternate material description
1309 */
1310 MeshMatDescClass * matdesc = DefMatDesc;
1311 if (context->Already_Loaded_DIG()) {
1312 matdesc = &(context->AlternateMatDesc);
1313 }
1314 context->Notify_Loaded_DIG_Chunk(true);
1315
1316 /*
1317 ** It appears that there isn't wide support for having the emissive material color source
1318 ** be a vertex color array so when there is a pre-existing color array, I'm just multiplying
1319 ** the DIG values into it.
1320 */
1321 W3dRGBAStruct color;
1322 if (matdesc->Has_Color_Array(0) == false) {
1323 unsigned * dcg = matdesc->Get_Color_Array(0);
1324 for (int i=0; i<Get_Vertex_Count(); i++) {
1325 cload.Read(&color,sizeof(color));
1326 Vector4 col;
1327 col.X = float(color.R)/255.0f;
1328 col.Y = float(color.G)/255.0f;
1329 col.Z = float(color.B)/255.0f;
1330 col.W = 1.0f;
1331 dcg[i]=DX8Wrapper::Convert_Color(col);
1332
1333
1334 }
1335 } else {
1336 unsigned * dcg = matdesc->Get_Color_Array(0);
1337 for (int i=0; i<Get_Vertex_Count(); i++) {
1338 cload.Read(&color,sizeof(color));
1340 col.X *= float(color.R)/255.0f;
1341 col.Y *= float(color.G)/255.0f;
1342 col.Z *= float(color.B)/255.0f;
1343 dcg[i]=DX8Wrapper::Convert_Color(col);
1344 }
1345 }
1346
1347 matdesc->Set_DCG_Source(context->CurPass,VertexMaterialClass::COLOR1);
1348
1349 return WW3D_ERROR_OK;
1350}
1351
1352
1353/***********************************************************************************************
1354 * MeshModelClass::read_scg -- read the specular color for a pass *
1355 * *
1356 * INPUT: *
1357 * *
1358 * OUTPUT: *
1359 * *
1360 * WARNINGS: *
1361 * *
1362 * HISTORY: *
1363 * 2/16/99 GTH : Created. *
1364 * 9/1/2000 gth : Added alternate material desc support *
1365 * 2/9/2001 gth : new dx8 code no longer supports this chunk *
1366 *=============================================================================================*/
1371
1372
1373/***********************************************************************************************
1374 * MeshModelClass::read_texture_stage -- read texture stage chunks *
1375 * *
1376 * INPUT: *
1377 * *
1378 * OUTPUT: *
1379 * *
1380 * WARNINGS: *
1381 * *
1382 * HISTORY: *
1383 * 2/16/99 GTH : Created. *
1384 *=============================================================================================*/
1386{
1387 while (cload.Open_Chunk()) {
1388
1390
1391 switch(cload.Cur_Chunk_ID()) {
1393 error = read_texture_ids(cload,context);
1394 break;
1395
1398 error = read_stage_texcoords(cload,context);
1399 break;
1400
1402 error = read_per_face_texcoord_ids (cload, context);
1403 break;
1404
1405 }
1406
1407 if (error != WW3D_ERROR_OK) {
1408 return error;
1409 }
1410
1411 cload.Close_Chunk();
1412 }
1413
1414 context->CurTexStage++;
1415 return WW3D_ERROR_OK;
1416}
1417
1418
1419/***********************************************************************************************
1420 * MeshModelClass::read_texture_ids -- read the texture ids for a pass,stage *
1421 * *
1422 * INPUT: *
1423 * *
1424 * OUTPUT: *
1425 * *
1426 * WARNINGS: *
1427 * *
1428 * HISTORY: *
1429 * 2/16/99 GTH : Created. *
1430 * 9/1/2000 gth : Added alternate material desc support *
1431 *=============================================================================================*/
1433{
1434 uint32 texid;
1435 int pass = context->CurPass;
1436 int stage = context->CurTexStage;
1437
1438 /*
1439 ** Determine whether this chunk should be read into the default or alternate material description
1440 */
1441 MeshMatDescClass * matdesc = DefMatDesc;
1442 if (DefMatDesc->Has_Texture_Data(pass,stage)) {
1443 matdesc = &(context->AlternateMatDesc);
1444 }
1445
1446 /*
1447 ** Read in the texture(s) array
1448 */
1449#if (!MESH_SINGLE_MATERIAL_HACK)
1450 if (cload.Cur_Chunk_Length() == 1*sizeof(uint32)) {
1451 cload.Read(&texid,sizeof(texid));
1452 matdesc->Set_Single_Texture(context->Peek_Texture(texid),pass,stage);
1453
1454 } else {
1455
1456 for (int i=0; i<Get_Polygon_Count(); i++) {
1457 cload.Read(&texid,sizeof(uint32));
1458 if (texid != 0xffffffff) {
1459 matdesc->Set_Texture(i,context->Peek_Texture(texid),pass,stage);
1460 }
1461 }
1462 }
1463#else
1464#pragma message ("(gth) Hacking to make Generals behave as if all meshes have 1 material")
1465
1466 cload.Read(&texid,sizeof(texid));
1467 matdesc->Set_Single_Texture(context->Peek_Texture(texid),pass,stage);
1468
1469#endif
1470
1471 return WW3D_ERROR_OK;
1472}
1473
1474
1475/***********************************************************************************************
1476 * MeshModelClass::read_stage_texcoords -- read the texcoords for a pass,stage *
1477 * *
1478 * INPUT: *
1479 * *
1480 * OUTPUT: *
1481 * *
1482 * WARNINGS: *
1483 * *
1484 * HISTORY: *
1485 * 2/16/99 GTH : Created. *
1486 * 7/14/99 IML : Lightmap support: calculate vertex count directly from chunk size. *
1487 * 9/1/2000 gth : Added alternate material desc support *
1488 *=============================================================================================*/
1490{
1491 unsigned elementcount;
1492 Vector2 *uvs;
1493 W3dTexCoordStruct texcoord;
1494
1495 /*
1496 ** Determine whether this chunk should be read into the default or alternate material description
1497 */
1498 MeshMatDescClass * matdesc = DefMatDesc;
1499 if (DefMatDesc->Has_UV(context->CurPass,context->CurTexStage)) {
1500 matdesc = &(context->AlternateMatDesc);
1501 }
1502
1503 /*
1504 ** Read in the texture coordiantes
1505 */
1506 elementcount = cload.Cur_Chunk_Length() / sizeof (W3dTexCoordStruct);
1507 uvs = context->Get_Temporary_UV_Array(elementcount);
1508
1509 if (uvs != NULL) {
1510 for (unsigned i = 0; i < elementcount; i++) {
1511 cload.Read (&texcoord, sizeof (texcoord));
1512 uvs[i].X = texcoord.U;
1513 uvs[i].Y = 1.0f - texcoord.V;
1514 }
1515 }
1516
1517 matdesc->Install_UV_Array(context->CurPass,context->CurTexStage,uvs,elementcount);
1518
1519 return (WW3D_ERROR_OK);
1520}
1521
1522
1523/***********************************************************************************************
1524 * MeshModelClass::read_per_face_texcoord_ids -- read uv indices for given (pass,stage). *
1525 * *
1526 * INPUT: *
1527 * *
1528 * OUTPUT: *
1529 * *
1530 * WARNINGS: *
1531 * *
1532 * HISTORY: *
1533 * 02/02/99 IML : Created. *
1534 * 9/1/2000 gth : Added alternate material desc support *
1535 *=============================================================================================*/
1537{
1538 unsigned size;
1539
1540 /*
1541 ** Determine whether this chunk should be read into the default or alternate material description
1542 */
1543// MeshMatDescClass * matdesc = DefMatDesc;
1544// if (DefMatDesc->Has_UVIndex(context->CurPass)) {
1545// matdesc = &(context->AlternateMatDesc);
1546// }
1547
1548 /*
1549 ** Read in the texture coordiante indices
1550 ** There must be polygon count vectors in this chunk.
1551 */
1552 size = sizeof (Vector3i) * Get_Polygon_Count();
1553 if (cload.Cur_Chunk_Length() == size) {
1554
1555// Vector3i *uvindices;
1556//
1557// uvindices = matdesc->Get_UVIndex_Array (context->CurPass, true);
1558// WWASSERT (uvindices != NULL);
1559
1560//uvindices=W3DNEWARRAY Vector3i[Get_Polygon_Count()];
1561// cload.Read (uvindices, size);
1562//delete[] uvindices;
1563 cload.Seek(size);
1564 return (WW3D_ERROR_OK);
1565
1566 } else {
1567 return (WW3D_ERROR_LOAD_FAILED);
1568 }
1569}
1570
1571
1572/***********************************************************************************************
1573 * MeshModelClass::read_prelit_material -- read prelit material chunks. *
1574 * *
1575 * INPUT: *
1576 * *
1577 * OUTPUT: *
1578 * *
1579 * WARNINGS: *
1580 * *
1581 * HISTORY: *
1582 * 02/02/99 IML : Created. *
1583 *=============================================================================================*/
1585{
1586 // If this chunk ID matches the selected prelit chunk ID then load it, otherwise skip it.
1587 if (cload.Cur_Chunk_ID() == context->PrelitChunkID) {
1588
1589 // While there are chunks in the prelit material chunk wrapper...
1590 while (cload.Open_Chunk()) {
1591
1593
1594 switch (cload.Cur_Chunk_ID()) {
1595
1597 error = read_material_info (cload,context);
1598 break;
1599
1601 error = read_vertex_materials (cload,context);
1602 break;
1603
1604 case W3D_CHUNK_SHADERS:
1605 error = read_shaders (cload,context);
1606 break;
1607
1608 case W3D_CHUNK_TEXTURES:
1609 error = read_textures (cload,context);
1610 break;
1611
1613 error = read_material_pass (cload,context);
1614 break;
1615
1616 default:
1617
1618 // Unknown chunk.
1619 break;
1620 }
1621 cload.Close_Chunk();
1622 if (error != WW3D_ERROR_OK) return (error);
1623 }
1624 }
1625
1626 return (WW3D_ERROR_OK);
1627}
1628
1629
1630/***********************************************************************************************
1631 * MeshModelClass::post_process -- post loading, perform any processing on this model. *
1632 * *
1633 * INPUT: *
1634 * *
1635 * OUTPUT: *
1636 * *
1637 * WARNINGS: *
1638 * *
1639 * HISTORY: *
1640 * 05/02/00 IML : Created. *
1641 * 7/13/2001 hy : Added static sort postprocessing *
1642 *=============================================================================================*/
1644{
1645#if 0
1646 // we want to allow this now due to usage of the static sort
1647 // Ensure no sorting, multipass meshes (for they are abomination...)
1648 if (DefMatDesc->Get_Pass_Count() > 1 && Get_Flag(SORT)) {
1649 WWDEBUG_SAY(( "Turning SORT off for multipass mesh %s\n",Get_Name() ));
1650 Set_Flag(SORT, false);
1651 }
1652#endif
1653
1654 // skinned meshes should not have cull trees
1656 if (CullTree) {
1658 }
1659 }
1660
1661 // turn off backface culling if the mesh is supposed to be two-sided
1663
1664 DefMatDesc->Disable_Backface_Culling();
1665 if (AlternateMatDesc != NULL) {
1666 AlternateMatDesc->Disable_Backface_Culling();
1667 }
1668
1669 }
1670
1671 // fog activation.
1672 if (WW3DAssetManager::Get_Instance()->Get_Activate_Fog_On_Load()) {
1674 }
1675
1676 // if the mesh is sorting, pick an appropriate static sort level
1677 // if default isn't set
1680 }
1681
1682 // If we need to, modify the mesh model to support overbrightening (change all
1683 // GRADIENT_MODULATE to GRADIENT_MODULATE2X)
1686 }
1687}
1688
1690{
1691 // If two pass...
1692 if (DefMatDesc->Get_Pass_Count() == 2) {
1693
1694 // If single shader on both passes...
1695 if (!DefMatDesc->ShaderArray[0] && !DefMatDesc->ShaderArray[1]) {
1696
1697 ShaderClass &shader0 = DefMatDesc->Shader [0];
1698 ShaderClass &shader1 = DefMatDesc->Shader [1];
1699
1700 // Analyze the mesh to determine if it is the emissive map effect and if it is, fix it up appropriately.
1701 bool emissive_map_effect = DefMatDesc->PassCount == 2 &&
1710
1711 if (emissive_map_effect) {
1712
1713 // Change the shader/texture setting into an equivalent one which will enable setting fog
1714 // correctly: Note that we are setting up pass 0 to have a texture now.
1719
1720 // Copy pass 1 texture/texture array to pass 0.
1721 REF_PTR_SET (DefMatDesc->Texture[0][0], DefMatDesc->Texture [1][0]);
1722 if (DefMatDesc->TextureArray [1][0]) {
1723 if (!DefMatDesc->TextureArray [0][0]) {
1724 DefMatDesc->TextureArray [0][0] = NEW_REF (TexBufferClass, (PolyCount, "MeshModelClass::DefMatDesc::TextureArray"));
1725 for (int i = 0; i < PolyCount; i++) {
1726 DefMatDesc->TextureArray [0][0]->Set_Element (i, DefMatDesc->TextureArray [1][0]->Peek_Element (i));
1727 }
1728 }
1729 }
1730
1731 // Make pass 0 point to the same UV array as pass 1. If pass 1 has a vertex material
1732 // array, we only take the first one for determining UV source. The UV source is
1733 // used to set the UV source of all the vertex materials in pass 0.
1734 int uv_source = 0;
1735 if (DefMatDesc->MaterialArray[1]) {
1736 uv_source = DefMatDesc->MaterialArray[1]->Peek_Element(0)->Get_UV_Source(0);
1737 } else {
1738 DefMatDesc->Material[1]->Get_UV_Source(0);
1739 }
1740 if (DefMatDesc->MaterialArray[0]) {
1741 for (int i = 0; i < VertexCount; i++) {
1742 DefMatDesc->MaterialArray[0]->Peek_Element(i)->Set_UV_Source(0, uv_source);
1743 }
1744 } else {
1745 DefMatDesc->Material[0]->Set_UV_Source(0, uv_source);
1746 }
1747
1748 return;
1749 }
1750
1751 // Analyze the mesh to determine if it is the shiny mask effect and if it is, fix it up appropriately.
1752 bool shiny_mask_effect = shader0.Get_Src_Blend_Func() == ShaderClass::SRCBLEND_ONE &&
1757
1758 if (shiny_mask_effect) {
1761 return;
1762 }
1763 }
1764 }
1765
1766 // Mesh is not one of the special two-pass combinations. Apply a per-pass generic fix-up.
1767 for (int pass = 0; pass < DefMatDesc->PassCount; pass++) {
1768 DefMatDesc->Shader [pass].Enable_Fog (Get_Name());
1769 if (DefMatDesc->ShaderArray [pass]) {
1770 for (int tri = 0; tri < DefMatDesc->ShaderArray [pass]->Get_Count(); tri++) {
1771 DefMatDesc->ShaderArray [pass]->Get_Element (tri).Enable_Fog (Get_Name());
1772 }
1773 }
1774 }
1775}
1776
1777unsigned int MeshModelClass::get_sort_flags(int pass) const
1778{
1779 unsigned int flags = 0;
1781 if (Has_Shader_Array(pass)) {
1782 for (int tri = 0; tri < CurMatDesc->ShaderArray[pass]->Get_Count(); tri++) {
1783 scat = CurMatDesc->ShaderArray[pass]->Get_Element(tri).Get_SS_Category();
1784 flags |= (1 << scat);
1785 }
1786 } else {
1787 scat = Get_Single_Shader(pass).Get_SS_Category();
1788 flags |= (1 << scat);
1789 }
1790 return flags;
1791}
1792
1793unsigned int MeshModelClass::get_sort_flags(void) const
1794{
1795 unsigned int flags = 0;
1796 for (int pass = 0; pass < Get_Pass_Count(); pass++) {
1797 flags |= get_sort_flags(pass);
1798 }
1799 return flags;
1800}
1801
1803{
1804 enum StaticSortCategoryBitFieldType
1805 {
1806 SSCAT_OPAQUE_BF = (1 << ShaderClass::SSCAT_OPAQUE),
1807 SSCAT_ALPHA_TEST_BF = (1 << ShaderClass::SSCAT_ALPHA_TEST),
1808 SSCAT_ADDITIVE_BF = (1 << ShaderClass::SSCAT_ADDITIVE),
1809 SSCAT_SCREEN_BF = (1 << ShaderClass::SSCAT_SCREEN),
1810 SSCAT_OTHER_BF = (1 << ShaderClass::SSCAT_OTHER)
1811 };
1812
1813 if (get_sort_flags(0) == SSCAT_OPAQUE_BF) {
1815 return;
1816 }
1817
1818 switch (get_sort_flags())
1819 {
1820 case (SSCAT_OPAQUE_BF | SSCAT_ALPHA_TEST_BF):
1822 break;
1823
1824 case SSCAT_ADDITIVE_BF:
1826 break;
1827
1828 case SSCAT_SCREEN_BF:
1830 break;
1831
1832 default:
1834 break;
1835 };
1836}
1837
1839{
1840 // Iterate over all passes
1841 int pass_cnt = Get_Pass_Count();
1842 for (int pass_idx = 0; pass_idx < pass_cnt; pass_idx++) {
1843
1844 // First do single shader
1845 ShaderClass shader = Get_Single_Shader(pass_idx);
1848 Set_Single_Shader(shader, pass_idx);
1849 }
1850
1851 // Now do all other shaders
1852 if (Has_Shader_Array(pass_idx)) {
1853 int p_cnt = Get_Polygon_Count();
1854 for (int p_idx = 0; p_idx < p_cnt; p_idx++) {
1855 shader = Get_Shader(p_idx, pass_idx);
1858 Set_Shader(p_idx, shader, pass_idx);
1859 }
1860 }
1861 }
1862 }
1863
1864}
1865
1867{
1868 int i;
1869
1870 /*
1871 ** If alternate material chunks were loaded, initialize the AlternateMatDesc
1872 */
1874
1875 /*
1876 ** Finish configuring the vertex materials and color arrays.
1877 */
1878 bool lighting_enabled=true;
1879 // vertex-lit models need the lighting turned off!
1881 lighting_enabled=false;
1882 }
1883 DefMatDesc->Post_Load_Process (lighting_enabled,this);
1884 if (AlternateMatDesc != NULL) {
1885 AlternateMatDesc->Post_Load_Process (lighting_enabled,this);
1886 }
1887
1888 /*
1889 ** transfer the refs to our textures into the MatInfo
1890 */
1891 for (i=0; i<context->Texture_Count(); i++) {
1892 MatInfo->Add_Texture(context->Peek_Texture(i));
1893 }
1894
1895 /*
1896 ** transfer the refs to our vertex materials into the MatInfo
1897 */
1898 for (i=0; i<context->Vertex_Material_Count(); i++) {
1899 MatInfo->Add_Vertex_Material(context->Peek_Vertex_Material(i));
1900 }
1901}
1902
1903
1905{
1906 /*
1907 ** Copy the material info and the materials within
1908 */
1910 MatInfo = NEW_REF( MaterialInfoClass,(*(srcmesh.MatInfo)));
1911
1912 /*
1913 ** remap!
1914 */
1915 MaterialRemapperClass remapper(srcmesh.MatInfo, MatInfo);
1916 remapper.Remap_Mesh(srcmesh.CurMatDesc, CurMatDesc);
1917}
1918
1919
1921{
1922 if (context->AlternateMatDesc.Is_Empty() == false) {
1925 AlternateMatDesc->Init_Alternate(*DefMatDesc,context->AlternateMatDesc);
1926 }
1927}
1928
1929/***********************************************************************************************
1930 * MeshLoadContextClass::MeshLoadContextClass -- constructor for MeshLoadContextClass *
1931 * *
1932 * INPUT: *
1933 * *
1934 * OUTPUT: *
1935 * *
1936 * WARNINGS: *
1937 * *
1938 * HISTORY: *
1939 * 12/10/98 GTH : Created. *
1940 *=============================================================================================*/
1941MeshLoadContextClass::MeshLoadContextClass(void)
1942{
1943 memset(&Header,0,sizeof(Header));
1944 memset(&MatInfo,0,sizeof(MatInfo));
1945 PrelitChunkID = 0xffffffff;
1946 CurPass = 0;
1947 CurTexStage = 0;
1948 TexCoords = NULL;
1949 LoadedDIG = false;
1950}
1951
1952
1953/***********************************************************************************************
1954 * MeshLoadContextClass::~MeshLoadContextClass -- destructor *
1955 * *
1956 * INPUT: *
1957 * *
1958 * OUTPUT: *
1959 * *
1960 * WARNINGS: *
1961 * *
1962 * HISTORY: *
1963 * 12/10/98 GTH : Created. *
1964 *=============================================================================================*/
1965MeshLoadContextClass::~MeshLoadContextClass(void)
1966{
1967 int i;
1968
1969 if (TexCoords != NULL) {
1970 delete TexCoords;
1971 TexCoords = NULL;
1972 }
1973 for (i=0; i<Textures.Count(); i++) {
1974 Textures[i]->Release_Ref();
1975 }
1976 for (i=0; i<VertexMaterials.Count(); i++) {
1977 VertexMaterials[i]->Release_Ref();
1978 }
1979 for (i=0; i<LegacyMaterials.Count(); i++) {
1980 delete LegacyMaterials[i];
1981 }
1982}
1983
1984
1985/***********************************************************************************************
1986 * MeshLoadContextClass::Get_Texcoord_Array -- returns the texture coordinates array *
1987 * *
1988 * This function mainly exists to support the obsolete version 3.0 w3d files *
1989 * *
1990 * INPUT: *
1991 * *
1992 * OUTPUT: *
1993 * *
1994 * WARNINGS: *
1995 * *
1996 * HISTORY: *
1997 * 12/10/98 GTH : Created. *
1998 *=============================================================================================*/
1999W3dTexCoordStruct * MeshLoadContextClass::Get_Texcoord_Array(void)
2000{
2001 if (TexCoords == NULL) {
2002 TexCoords = W3DNEWARRAY W3dTexCoordStruct[Header.NumVertices];
2003 }
2004 return TexCoords;
2005}
2006
2007
2008/***********************************************************************************************
2009 * MeshLoadContextClass::Add_Shader -- adds a shader to the array *
2010 * *
2011 * INPUT: *
2012 * *
2013 * OUTPUT: *
2014 * *
2015 * WARNINGS: *
2016 * *
2017 * HISTORY: *
2018 * 12/10/98 GTH : Created. *
2019 *=============================================================================================*/
2020int MeshLoadContextClass::Add_Shader(ShaderClass shader)
2021{
2022 int index = Shaders.Count();
2023 Shaders.Add(shader);
2024 return index;
2025}
2026
2027
2028/***********************************************************************************************
2029 * MeshLoadContextClass::Add_Vertex_Materail -- adds a vertex material *
2030 * *
2031 * INPUT: *
2032 * *
2033 * OUTPUT: *
2034 * *
2035 * WARNINGS: *
2036 * *
2037 * HISTORY: *
2038 * 12/10/98 GTH : Created. *
2039 *=============================================================================================*/
2040int MeshLoadContextClass::Add_Vertex_Material(VertexMaterialClass * vmat)
2041{
2042 WWASSERT(vmat != NULL);
2043 vmat->Add_Ref();
2044 int index = VertexMaterials.Count();
2045 VertexMaterials.Add(vmat);
2046 return index;
2047}
2048
2049
2050/***********************************************************************************************
2051 * MeshLoadContextClass::Add_Texture -- adds a texture *
2052 * *
2053 * INPUT: *
2054 * *
2055 * OUTPUT: *
2056 * *
2057 * WARNINGS: *
2058 * *
2059 * HISTORY: *
2060 * 12/10/98 GTH : Created. *
2061 *=============================================================================================*/
2062int MeshLoadContextClass::Add_Texture(TextureClass * tex)
2063{
2064 WWASSERT(tex != NULL);
2065 tex->Add_Ref();
2066 int index = Textures.Count();
2067 Textures.Add(tex);
2068 return index;
2069}
2070
2071
2072/***********************************************************************************************
2073 * MeshLoadContextClass::Add_Legacy_Material -- adds a legacy material *
2074 * *
2075 * This function will check to see if the parameters of any of the parts of the material are *
2076 * duplicated. Only unique shaders/vertexmaterials will be actually added. *
2077 * *
2078 * INPUT: *
2079 * *
2080 * OUTPUT: *
2081 * *
2082 * WARNINGS: *
2083 * *
2084 * HISTORY: *
2085 * 12/10/98 GTH : Created. *
2086 *=============================================================================================*/
2087void MeshLoadContextClass::Add_Legacy_Material(ShaderClass shader,VertexMaterialClass * vmat,TextureClass * tex)
2088{
2089 // create a new legacy material
2090 LegacyMaterialClass * mat = W3DNEW LegacyMaterialClass;
2091
2092 // add the shader if it is unique
2093 for (int si=0; si<Shaders.Count(); si++) {
2094 if (Shaders[si] == shader) break;
2095 }
2096 if (si == Shaders.Count()) {
2097 mat->ShaderIdx = Add_Shader(shader);
2098 } else {
2099 mat->ShaderIdx = si;
2100 }
2101
2102 // add the vertex material if it is unique
2103 if (vmat == NULL) {
2104 mat->VertexMaterialIdx = -1;
2105 } else {
2106 unsigned long crc = vmat->Get_CRC();
2107 for (int vi=0; vi<VertexMaterialCrcs.Count(); vi++) {
2108 if (VertexMaterialCrcs[vi] == crc) break;
2109 }
2110 if (vi == VertexMaterials.Count()) {
2111 mat->VertexMaterialIdx = Add_Vertex_Material(vmat);
2112 VertexMaterialCrcs.Add(crc);
2113 WWASSERT(VertexMaterialCrcs.Count() == VertexMaterials.Count());
2114 } else {
2115 mat->VertexMaterialIdx = vi;
2116 }
2117 }
2118
2119 // add the texture if it is unique
2120 if (tex == NULL) {
2121 mat->TextureIdx = -1;
2122 } else {
2123 for (int ti=0; ti<Textures.Count(); ti++) {
2124 if (Textures[ti] == tex) break;
2125 if (stricmp(Textures[ti]->Get_Texture_Name(),tex->Get_Texture_Name()) == 0) break;
2126 }
2127 if (ti == Textures.Count()) {
2128 mat->TextureIdx = Add_Texture(tex);
2129 } else {
2130 mat->TextureIdx = ti;
2131 }
2132 }
2133
2134 LegacyMaterials.Add(mat);
2135}
2136
2137
2138/***********************************************************************************************
2139 * MeshLoadContextClass::Peek_Legacy_Shader -- returns a legacy shader *
2140 * *
2141 * This function does the re-indexing to go from the legacy shader index to the actual shader *
2142 * index and then returns that shader *
2143 * *
2144 * INPUT: *
2145 * *
2146 * OUTPUT: *
2147 * *
2148 * WARNINGS: *
2149 * *
2150 * HISTORY: *
2151 * 12/10/98 GTH : Created. *
2152 *=============================================================================================*/
2153ShaderClass MeshLoadContextClass::Peek_Legacy_Shader(int legacy_material_index)
2154{
2155 WWASSERT(legacy_material_index >= 0);
2156 WWASSERT(legacy_material_index < LegacyMaterials.Count());
2157 int si = LegacyMaterials[legacy_material_index]->ShaderIdx;
2158 return Peek_Shader(si);
2159}
2160
2161
2162/***********************************************************************************************
2163 * MeshLoadContextClass::Peek_Legacy_Vertex_Material -- returns a pointer to a legacy vertex ma*
2164 * *
2165 * INPUT: *
2166 * *
2167 * OUTPUT: *
2168 * *
2169 * WARNINGS: *
2170 * *
2171 * HISTORY: *
2172 * 12/10/98 GTH : Created. *
2173 *=============================================================================================*/
2174VertexMaterialClass * MeshLoadContextClass::Peek_Legacy_Vertex_Material(int legacy_material_index)
2175{
2176 WWASSERT(legacy_material_index >= 0);
2177 WWASSERT(legacy_material_index < LegacyMaterials.Count());
2178 int vi = LegacyMaterials[legacy_material_index]->VertexMaterialIdx;
2179 if (vi != -1) {
2180 return Peek_Vertex_Material(vi);
2181 } else {
2182 return NULL;
2183 }
2184}
2185
2186
2187/***********************************************************************************************
2188 * MeshLoadContextClass::Peek_Legacy_Texture -- returns a pointer to a texture *
2189 * *
2190 * INPUT: *
2191 * *
2192 * OUTPUT: *
2193 * *
2194 * WARNINGS: *
2195 * *
2196 * HISTORY: *
2197 * 12/10/98 GTH : Created. *
2198 *=============================================================================================*/
2199TextureClass * MeshLoadContextClass::Peek_Legacy_Texture(int legacy_material_index)
2200{
2201 WWASSERT(legacy_material_index >= 0);
2202 WWASSERT(legacy_material_index < LegacyMaterials.Count());
2203 int ti = LegacyMaterials[legacy_material_index]->TextureIdx;
2204 if (ti != -1) {
2205 return Peek_Texture(ti);
2206 } else {
2207 return NULL;
2208 }
2209}
2210
2211
2212Vector2 * MeshLoadContextClass::Get_Temporary_UV_Array(int elementcount)
2213{
2214 TempUVArray.Uninitialised_Grow(elementcount);
2215 return &(TempUVArray[0]);
2216}
2217
2218
2219
2220/***********************************************************************************************
2221 * MeshSaveContextClass::MeshSaveContextClass -- constructor *
2222 * *
2223 * INPUT: *
2224 * *
2225 * OUTPUT: *
2226 * *
2227 * WARNINGS: *
2228 * *
2229 * HISTORY: *
2230 *=============================================================================================*/
2236
2237
2238/***********************************************************************************************
2239 * MeshSaveContextClass::~MeshSaveContextClass -- destructor *
2240 * *
2241 * INPUT: *
2242 * *
2243 * OUTPUT: *
2244 * *
2245 * WARNINGS: *
2246 * *
2247 * HISTORY: *
2248 *=============================================================================================*/
2252
2253
2254
2255
2256
2257#if 0 // MESH SAVING CODE HAS NOT BEEN MAINTAINED... Leaving here for future reference if we ever need it :-)
2258
2259/***********************************************************************************************
2260 * MeshModelClass::Save -- Save this mesh model! *
2261 * *
2262 * INPUT: *
2263 * *
2264 * OUTPUT: *
2265 * *
2266 * WARNINGS: *
2267 * *
2268 * HISTORY: *
2269 * 2/16/99 GTH : Created. *
2270 *=============================================================================================*/
2271WW3DErrorType MeshModelClass::Save_W3D(ChunkSaveClass & csave)
2272{
2274 context->Materials.Collect_Materials(this);
2275
2276 write_chunks(csave,context);
2277
2278 delete context;
2279 return WW3D_ERROR_OK;
2280}
2281
2282
2283WW3DErrorType MeshModelClass::write_chunks(ChunkSaveClass & csave,MeshSaveContextClass * context)
2284{
2285
2286 // write the header
2287 write_header(csave,context);
2288 write_user_text(csave,context);
2289
2290 // write the geometry
2291 write_triangles(csave,context);
2292 write_vertices(csave,context);
2293 write_vertex_normals(csave,context);
2294 write_vertex_shade_indices(csave,context);
2295 write_vertex_influences(csave,context);
2296 //write_cull_tree(csave);
2297
2298 // material stuff
2299 write_material_info(csave,context);
2300 write_vertex_materials(csave,context);
2301 write_shaders(csave,context);
2302 write_textures(csave,context);
2303
2304 // passes
2305 for (int i=0; i<Get_Pass_Count(); i++) {
2306 context->CurPass = i;
2307 write_material_pass(csave,context);
2308 }
2309 return WW3D_ERROR_OK;
2310}
2311
2312WW3DErrorType MeshModelClass::write_header(ChunkSaveClass & csave,MeshSaveContextClass * /*context*/)
2313{
2314 W3dMeshHeader3Struct header;
2315 memset(&header,0,sizeof(header));
2316
2317 // Set names
2318 if (MeshName) {
2319
2320 char * name = MeshName->Get_Array();
2321 char * mesh_name = strchr(name,'.');
2322
2323 int hierarchy_name_len = 0;
2324 if (mesh_name == NULL) {
2325 mesh_name = name;
2326 } else {
2327 hierarchy_name_len = (int)mesh_name - (int)name;
2328 mesh_name++;
2329 }
2330 assert( hierarchy_name_len <= W3D_NAME_LEN);
2331 strncpy( header.MeshName, mesh_name, W3D_NAME_LEN);
2332 strncpy( header.ContainerName, name, hierarchy_name_len);
2333 } else {
2334 sprintf(header.MeshName,"UnNamed");
2335 }
2336
2338 header.Attributes = W3dAttributes;
2339 header.NumTris = Get_Polygon_Count();
2340 header.NumVertices = Get_Vertex_Count();
2341 header.NumMaterials = 0;
2342 header.NumDamageStages = 0;
2343
2345 if (Get_Flag(SKIN)) {
2347 }
2348
2350
2355
2357 if (csave.Write(&header,sizeof(header)) != sizeof(header)) {
2359 }
2360 csave.End_Chunk();
2361
2362 return WW3D_ERROR_OK;
2363}
2364
2365WW3DErrorType MeshModelClass::write_user_text(ChunkSaveClass & csave,MeshSaveContextClass * /*context*/)
2366{
2367 if (UserText == NULL) return WW3D_ERROR_OK;
2368 if (strlen(UserText->Get_Array()) < 1) return WW3D_ERROR_OK;
2369
2371 csave.Write(UserText->Get_Array(),strlen(UserText->Get_Array()) + 1);
2372 csave.End_Chunk();
2373
2374 return WW3D_ERROR_OK;
2375}
2376
2377WW3DErrorType MeshModelClass::write_triangles(ChunkSaveClass & csave,MeshSaveContextClass * /*context*/)
2378{
2379 if (!csave.Begin_Chunk(W3D_CHUNK_TRIANGLES)) {
2381 }
2382
2383 TriIndex * poly_verts = Poly->Get_Array();
2384 Vector4 * poly_eq = (PlaneEq ? PlaneEq->Get_Array() : NULL);
2385
2386 for (int i=0; i<Get_Polygon_Count(); i++) {
2387
2388 W3dTriStruct tri;
2389 memset(&tri,0,sizeof(W3dTriStruct));
2390
2391 // convert each triangle into surrender format
2392 tri.Vindex[0] = poly_verts[i].I;
2393 tri.Vindex[1] = poly_verts[i].J;
2394 tri.Vindex[2] = poly_verts[i].K;
2395
2396 if (poly_eq) {
2397 tri.Attributes = 0;
2398 tri.Normal.X = poly_eq[i].X;
2399 tri.Normal.Y = poly_eq[i].Y;
2400 tri.Normal.Z = poly_eq[i].Z;
2401 tri.Dist = poly_eq[i].W;
2402 } else {
2403
2404 Vector3 a,b,normal;
2405 Vector3 * verts = Vertex->Get_Array();
2406 const Vector3 & p0= verts[poly_verts[i][0]];
2407
2408 Vector3::Subtract(verts[poly_verts[i][1]],p0,&a);
2409 Vector3::Subtract(verts[poly_verts[i][2]],p0,&b);
2410 Vector3::Cross_Product(a,b,&normal);
2411 normal.Normalize();
2412
2413 tri.Attributes = 0;
2414 tri.Normal.X = normal.X;
2415 tri.Normal.Y = normal.Y;
2416 tri.Normal.Z = normal.Z;
2417 tri.Dist = Vector3::Dot_Product(p0,normal);
2418 }
2419
2420 if (csave.Write(&tri,sizeof(W3dTriStruct)) != sizeof(W3dTriStruct)) {
2422 }
2423 }
2424
2425 if (!csave.End_Chunk()) {
2427 }
2428
2429 return WW3D_ERROR_OK;
2430}
2431
2432WW3DErrorType MeshModelClass::write_vertices(ChunkSaveClass & csave,MeshSaveContextClass * /*context*/)
2433{
2434 if (!csave.Begin_Chunk(W3D_CHUNK_VERTICES)) {
2436 }
2437
2439 Vector3 * verts = Vertex->Get_Array();
2440
2441 for (int i=0; i<Get_Vertex_Count(); i++) {
2442
2443 W3dVectorStruct vert;
2444 vert.X = verts[i].X;
2445 vert.Y = verts[i].Y;
2446 vert.Z = verts[i].Z;
2447
2448 if (csave.Write(&(vert),sizeof(W3dVectorStruct)) != sizeof(W3dVectorStruct)) {
2450 }
2451 }
2452
2453 if (!csave.End_Chunk()) {
2455 }
2456 return WW3D_ERROR_OK;
2457}
2458
2459WW3DErrorType MeshModelClass::write_vertex_normals(ChunkSaveClass & csave,MeshSaveContextClass * /*context*/)
2460{
2461 WWASSERT( Get_Vertex_Count() > 0);
2464 }
2465
2466 const Vector3 * verts = Get_Vertex_Normal_Array();
2467
2468 for (int i=0; i<Get_Vertex_Count(); i++) {
2469
2470 W3dVectorStruct vert;
2471 vert.X = verts[i].X;
2472 vert.Y = verts[i].Y;
2473 vert.Z = verts[i].Z;
2474
2475 if (csave.Write(&(vert),sizeof(W3dVectorStruct)) != sizeof(W3dVectorStruct)) {
2477 }
2478 }
2479
2480 if (!csave.End_Chunk()) {
2482 }
2483
2484 return WW3D_ERROR_OK;
2485}
2486
2487WW3DErrorType MeshModelClass::write_vertex_shade_indices(ChunkSaveClass & csave,MeshSaveContextClass * /*context*/)
2488{
2490 if (VertexShadeIdx == NULL) return WW3D_ERROR_OK;
2491
2494 }
2495
2496 for (int i=0; i<Get_Vertex_Count(); i++) {
2497 uint32 idx = VertexShadeIdx->Get_Array()[i];
2498 if (csave.Write(&idx,sizeof(idx)) != sizeof(idx)) {
2500 }
2501 }
2502
2503 if (!csave.End_Chunk()) {
2505 }
2506 return WW3D_ERROR_OK;
2507}
2508
2509WW3DErrorType MeshModelClass::write_vertex_influences(ChunkSaveClass & csave,MeshSaveContextClass * /*context*/)
2510{
2512 if (VertexBoneLink == NULL) return WW3D_ERROR_OK;
2513
2516 }
2517
2518 W3dVertInfStruct vinf;
2519 memset(&vinf,0,sizeof(vinf));
2520
2521 for (int i=0; i<Get_Vertex_Count(); i++) {
2522 vinf.BoneIdx = VertexBoneLink->Get_Array()[i];
2523 if (csave.Write(&vinf,sizeof(vinf)) != sizeof(vinf)) {
2525 }
2526 }
2527
2528 if (!csave.End_Chunk()) {
2530 }
2531 return WW3D_ERROR_OK;
2532}
2533
2534WW3DErrorType MeshModelClass::write_material_info(ChunkSaveClass & csave,MeshSaveContextClass * context)
2535{
2538 }
2539
2540 W3dMaterialInfoStruct info;
2541 memset(&info,0,sizeof(info));
2542
2543 info.PassCount = DefMatDesc->PassCount;
2545 info.TextureCount = context->Materials.Get_Texture_Count();
2546 info.ShaderCount = context->Materials.Get_Shader_Count();
2547
2548 if (csave.Write(&info,sizeof(info)) != sizeof(info)) {
2550 }
2551
2552 if (!csave.End_Chunk()) {
2554 }
2555
2556 return WW3D_ERROR_OK;
2557}
2558
2559WW3DErrorType MeshModelClass::write_shaders(ChunkSaveClass & csave,MeshSaveContextClass * context)
2560{
2561 if (context->Materials.Get_Shader_Count() <= 0) {
2562 return WW3D_ERROR_OK;
2563 }
2564
2566
2567 for (int si=0; si<context->Materials.Get_Shader_Count(); si++) {
2568 W3dShaderStruct file_shader;
2569 ShaderClass shader = context->Materials.Peek_Shader(si);
2570 W3dUtilityClass::Convert_Shader(shader,&file_shader);
2571
2572 if (csave.Write(&file_shader,sizeof(file_shader)) != sizeof(file_shader)) {
2574 }
2575 }
2576
2577 if (!csave.End_Chunk()) return WW3D_ERROR_SAVE_FAILED;
2578 return WW3D_ERROR_OK;
2579}
2580
2581WW3DErrorType MeshModelClass::write_vertex_materials(ChunkSaveClass & csave,MeshSaveContextClass * context)
2582{
2583 if (context->Materials.Get_Vertex_Material_Count() <= 0) return WW3D_ERROR_OK;
2585
2586 for (int vi=0; vi<context->Materials.Get_Vertex_Material_Count(); vi++) {
2587
2589 VertexMaterialClass * vmat = context->Materials.Peek_Vertex_Material(vi);
2590 vmat->Save_W3D(csave);
2591 csave.End_Chunk();
2592 }
2593
2594 if (!csave.End_Chunk()) return WW3D_ERROR_SAVE_FAILED;
2595 return WW3D_ERROR_OK;
2596}
2597
2598WW3DErrorType MeshModelClass::write_textures(ChunkSaveClass & csave,MeshSaveContextClass * context)
2599{
2600 if (context->Materials.Get_Texture_Count() <= 0) return WW3D_ERROR_OK;
2602
2603 for (int ti=0; ti<context->Materials.Get_Texture_Count(); ti++) {
2604 TextureClass * tex = context->Materials.Peek_Texture(ti);
2605 Save_Texture(tex,csave);
2606 }
2607
2608 if (!csave.End_Chunk()) return WW3D_ERROR_SAVE_FAILED;
2609 return WW3D_ERROR_OK;
2610}
2611
2612WW3DErrorType MeshModelClass::write_material_pass(ChunkSaveClass & csave,MeshSaveContextClass * context)
2613{
2614 context->CurStage = 0;
2616
2617 write_vertex_material_ids(csave,context);
2618 write_shader_ids(csave,context);
2619 write_dcg(csave,context);
2620 write_dig(csave,context);
2621 write_scg(csave,context);
2622 write_texture_stage(csave,context);
2623 write_texture_stage(csave,context);
2624
2625 csave.End_Chunk();
2626 context->CurPass++;
2627
2628 return WW3D_ERROR_OK;
2629}
2630
2631WW3DErrorType MeshModelClass::write_vertex_material_ids(ChunkSaveClass & csave,MeshSaveContextClass * context)
2632{
2633 // first check if all vertex material pointers are Null (is this legal?)
2634 if ( (DefMatDesc->Material[context->CurPass] == NULL) &&
2635 (DefMatDesc->MaterialArray[context->CurPass] == NULL)) return WW3D_ERROR_OK;
2636
2638
2639 uint32 id = 0;
2640 if (DefMatDesc->MaterialArray[context->CurPass] == NULL) {
2641
2642 id = context->Materials.Find_Vertex_Material(DefMatDesc->Material[context->CurPass]);
2643 csave.Write(&id,sizeof(id));
2644
2645 } else {
2646
2647 VertexMaterialClass ** array = DefMatDesc->MaterialArray[context->CurPass]->Get_Array();
2648 for (int vi=0; vi<Get_Vertex_Count(); vi++) {
2649 id = context->Materials.Find_Vertex_Material(array[vi]);
2650 csave.Write(&id,sizeof(id));
2651 }
2652
2653 }
2654
2655 csave.End_Chunk();
2656 return WW3D_ERROR_OK;
2657}
2658
2659WW3DErrorType MeshModelClass::write_shader_ids(ChunkSaveClass & csave,MeshSaveContextClass * context)
2660{
2662
2663 uint32 id = 0;
2664 if (DefMatDesc->ShaderArray[context->CurPass] == NULL) {
2665
2666 id = context->Materials.Find_Shader(DefMatDesc->Shader[context->CurPass]);
2667 csave.Write(&id,sizeof(id));
2668
2669 } else {
2670
2671 ShaderClass * array = DefMatDesc->ShaderArray[context->CurPass]->Get_Array();
2672 for (int pi=0; pi<Get_Polygon_Count(); pi++) {
2673 id = context->Materials.Find_Shader(array[pi]);
2674 csave.Write(&id,sizeof(id));
2675 }
2676 }
2677
2678 csave.End_Chunk();
2679 return WW3D_ERROR_OK;
2680}
2681
2682WW3DErrorType MeshModelClass::write_scg(ChunkSaveClass & csave,MeshSaveContextClass * context)
2683{
2684 if (DefMatDesc->SCG[context->CurPass] == NULL) return WW3D_ERROR_OK;
2686
2687 W3dRGBAStruct color;
2688 Vector4 * color_array = DefMatDesc->SCG[context->CurPass]->Get_Array();
2689 for (int vi=0; vi<Get_Vertex_Count(); vi++) {
2690 W3dUtilityClass::Convert_Color(color_array[vi],&color);
2691 csave.Write(&color,sizeof(color));
2692 }
2693
2694 csave.End_Chunk();
2695 return WW3D_ERROR_OK;
2696}
2697
2698WW3DErrorType MeshModelClass::write_dig(ChunkSaveClass & csave,MeshSaveContextClass * context)
2699{
2700 if (DefMatDesc->DIG[context->CurPass] == NULL) return WW3D_ERROR_OK;
2702
2703 W3dRGBStruct color;
2704 Vector3 * color_array = DefMatDesc->DIG[context->CurPass]->Get_Array();
2705 for (int vi=0; vi<Get_Vertex_Count(); vi++) {
2706 W3dUtilityClass::Convert_Color(color_array[vi],&color);
2707 csave.Write(&color,sizeof(color));
2708 }
2709 csave.End_Chunk();
2710 return WW3D_ERROR_OK;
2711}
2712
2713WW3DErrorType MeshModelClass::write_dcg(ChunkSaveClass & csave,MeshSaveContextClass * context)
2714{
2715 if (DefMatDesc->DCG[context->CurPass] == NULL) return WW3D_ERROR_OK;
2717
2718 W3dRGBAStruct color;
2719 Vector4 * color_array = DefMatDesc->DCG[context->CurPass]->Get_Array();
2720 for (int vi=0; vi<Get_Vertex_Count(); vi++) {
2721 W3dUtilityClass::Convert_Color(color_array[vi],&color);
2722 csave.Write(&color,sizeof(color));
2723 }
2724 csave.End_Chunk();
2725 return WW3D_ERROR_OK;
2726}
2727
2728WW3DErrorType MeshModelClass::write_texture_stage(ChunkSaveClass & csave,MeshSaveContextClass * context)
2729{
2730 if ( (DefMatDesc->Texture[context->CurPass][context->CurStage] == NULL) &&
2731 (DefMatDesc->TextureArray[context->CurPass][context->CurStage] == NULL)) return WW3D_ERROR_OK;
2732
2734 write_texture_ids(csave,context);
2735 write_stage_texcoords(csave,context);
2736 csave.End_Chunk();
2737
2738 context->CurStage++;
2739 return WW3D_ERROR_OK;
2740}
2741
2742WW3DErrorType MeshModelClass::write_texture_ids(ChunkSaveClass & csave,MeshSaveContextClass * context)
2743{
2745
2746 uint32 id = 0;
2747 if (DefMatDesc->TextureArray[context->CurPass][context->CurStage] == NULL) {
2748
2749 id = context->Materials.Find_Texture(DefMatDesc->Texture[context->CurPass][context->CurStage]);
2750 csave.Write(&id,sizeof(id));
2751
2752 } else {
2753
2754 srTextureIFace ** array = DefMatDesc->TextureArray[context->CurPass][context->CurStage]->Get_Array();
2755 for (int pi=0; pi<Get_Polygon_Count(); pi++) {
2756 id = context->Materials.Find_Texture(array[pi]);
2757 csave.Write(&id,sizeof(id));
2758 }
2759 }
2760
2761 csave.End_Chunk();
2762 return WW3D_ERROR_OK;
2763}
2764
2765WW3DErrorType MeshModelClass::write_stage_texcoords(ChunkSaveClass & csave,MeshSaveContextClass * context)
2766{
2767 if (DefMatDesc->UV[context->CurPass][context->CurStage] == NULL) return WW3D_ERROR_OK;
2769
2770 W3dTexCoordStruct tex;
2771 Vector2 * array = DefMatDesc->UV[context->CurPass][context->CurStage]->Get_Array();
2772
2773 for (int vi=0; vi<Get_Vertex_Count(); vi++) {
2774
2775 tex.U = array[vi].X;
2776 tex.V = 1.0f - array[vi].Y;
2777
2778 csave.Write(&tex,sizeof(tex));
2779 }
2780
2781 csave.End_Chunk();
2782 return WW3D_ERROR_OK;
2783}
2784
2785#endif // 0 (disabled mesh saving code)
#define NULL
Definition BaseType.h:92
#define WWASSERT
#define SORT_LEVEL_BIN1
Definition w3d_file.h:1197
#define W3D_MESH_FLAG_GEOMETRY_TYPE_MASK
Definition w3d_file.h:1157
#define OBSOLETE_W3D_MESH_FLAG_LIGHTMAPPED
Definition w3d_file.h:1153
#define W3D_MESH_FLAG_TWO_SIDED
Definition w3d_file.h:1152
#define W3D_MESH_FLAG_PRELIT_UNLIT
Definition w3d_file.h:1167
#define SORT_LEVEL_NONE
Definition w3d_file.h:1195
#define W3D_MESH_FLAG_PRELIT_MASK
Definition w3d_file.h:1166
#define SORT_LEVEL_BIN2
Definition w3d_file.h:1198
#define W3D_NAME_LEN
Definition w3d_file.h:319
#define W3D_MESH_FLAG_COLLISION_TYPE_SHIFT
Definition w3d_file.h:1144
#define W3D_VERTEX_CHANNEL_BONEID
Definition w3d_file.h:1190
#define W3D_MESH_FLAG_PRELIT_VERTEX
Definition w3d_file.h:1168
#define W3D_MESH_FLAG_NPATCHABLE
Definition w3d_file.h:1173
IOVector3Struct W3dVectorStruct
Definition w3d_file.h:532
#define W3D_MESH_FLAG_CAST_SHADOW
Definition w3d_file.h:1155
@ W3D_CHUNK_STAGE_TEXCOORDS
Definition w3d_file.h:380
@ W3D_CHUNK_MATERIAL_PASS
Definition w3d_file.h:371
@ W3D_CHUNK_TRIANGLES
Definition w3d_file.h:347
@ W3D_CHUNK_DIG
Definition w3d_file.h:375
@ W3D_CHUNK_DCG
Definition w3d_file.h:374
@ W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_PASS
Definition w3d_file.h:352
@ W3D_CHUNK_DEFORM
Definition w3d_file.h:384
@ W3D_CHUNK_VERTEX_SHADE_INDICES
Definition w3d_file.h:348
@ W3D_CHUNK_MESH_USER_TEXT
Definition w3d_file.h:344
@ W3D_CHUNK_VERTEX_NORMALS
Definition w3d_file.h:343
@ W3D_CHUNK_SHADERS
Definition w3d_file.h:357
@ W3D_CHUNK_VERTEX_MATERIALS
Definition w3d_file.h:359
@ W3D_CHUNK_TEXTURE_STAGE
Definition w3d_file.h:378
@ W3D_CHUNK_TEXTURES
Definition w3d_file.h:366
@ W3D_CHUNK_MESH_HEADER3
Definition w3d_file.h:346
@ W3D_CHUNK_VERTEX_MATERIAL
Definition w3d_file.h:360
@ W3D_CHUNK_VERTEX_INFLUENCES
Definition w3d_file.h:345
@ W3D_CHUNK_SCG
Definition w3d_file.h:376
@ W3D_CHUNK_PER_FACE_TEXCOORD_IDS
Definition w3d_file.h:381
@ W3D_CHUNK_SHADER_IDS
Definition w3d_file.h:373
@ W3D_CHUNK_PRELIT_LIGHTMAP_MULTI_TEXTURE
Definition w3d_file.h:353
@ W3D_CHUNK_PRELIT_UNLIT
Definition w3d_file.h:350
@ W3D_CHUNK_AABTREE
Definition w3d_file.h:391
@ W3D_CHUNK_VERTICES
Definition w3d_file.h:342
@ W3D_CHUNK_TEXTURE_IDS
Definition w3d_file.h:379
@ W3D_CHUNK_VERTEX_MATERIAL_IDS
Definition w3d_file.h:372
@ W3D_CHUNK_MATERIAL_INFO
Definition w3d_file.h:355
@ W3D_CHUNK_PRELIT_VERTEX
Definition w3d_file.h:351
#define W3D_MESH_FLAG_GEOMETRY_TYPE_NORMAL
Definition w3d_file.h:1158
#define W3D_MESH_FLAG_PRELIT_LIGHTMAP_MULTI_PASS
Definition w3d_file.h:1169
#define W3D_MESH_FLAG_COLLISION_TYPE_MASK
Definition w3d_file.h:1143
#define W3D_MAKE_VERSION(major, minor)
Definition w3d_file.h:315
#define W3D_MESH_FLAG_PRELIT_LIGHTMAP_MULTI_TEXTURE
Definition w3d_file.h:1170
#define W3D_MESH_FLAG_GEOMETRY_TYPE_SKIN
Definition w3d_file.h:1160
#define W3D_MESH_FLAG_GEOMETRY_TYPE_CAMERA_ALIGNED
Definition w3d_file.h:1159
#define W3D_VERTEX_CHANNEL_LOCATION
Definition w3d_file.h:1186
#define W3D_CURRENT_MESH_VERSION
Definition w3d_file.h:1184
#define SORT_LEVEL_BIN3
Definition w3d_file.h:1199
#define W3D_FACE_CHANNEL_FACE
Definition w3d_file.h:1192
#define W3D_MESH_FLAG_GEOMETRY_TYPE_CAMERA_ORIENTED
Definition w3d_file.h:1164
@ W3D_CHUNK_MATERIAL3_INFO
@ W3D_CHUNK_PER_TRI_MATERIALS
@ W3D_CHUNK_MAP3_FILENAME
@ W3D_CHUNK_MAP3_INFO
@ W3D_CHUNK_MATERIAL3_NAME
@ W3D_CHUNK_TEXCOORDS
@ O_W3D_CHUNK_MATERIALS2
@ W3D_CHUNK_MATERIAL3_DC_MAP
@ W3D_CHUNK_SURRENDER_NORMALS
@ W3D_CHUNK_VERTEX_COLORS
@ O_W3D_CHUNK_SURRENDER_TRIANGLES
@ O_W3D_CHUNK_MATERIALS
@ W3D_CHUNK_MATERIAL3
@ W3D_CHUNK_DAMAGE
@ W3D_CHUNK_MATERIAL3_SI_MAP
@ W3D_CHUNK_MATERIALS3
#define W3DNEWARRAY
Definition always.h:110
#define W3DMPO_GLUE(ARGCLASS)
Definition always.h:120
#define W3DNEW
Definition always.h:109
unsigned short uint16
Definition bittype.h:45
unsigned long uint32
Definition bittype.h:46
bool Close_Chunk()
Definition chunkio.cpp:448
uint32 Cur_Chunk_ID()
Definition chunkio.cpp:484
uint32 Cur_Chunk_Length()
Definition chunkio.cpp:503
uint32 Seek(uint32 nbytes)
Definition chunkio.cpp:650
uint32 Read(void *buf, uint32 nbytes)
Definition chunkio.cpp:692
bool Open_Chunk()
Definition chunkio.cpp:412
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 Vector4 Convert_Color(unsigned color)
Definition dx8wrapper.h:958
int Find_Vertex_Material(VertexMaterialClass *mat)
Definition matinfo.cpp:421
int Get_Texture_Count(void)
Definition matinfo.cpp:381
void Collect_Materials(MeshModelClass *mesh)
Definition matinfo.cpp:280
int Get_Vertex_Material_Count(void)
Definition matinfo.cpp:376
TextureClass * Peek_Texture(int i)
Definition matinfo.cpp:391
int Get_Shader_Count(void)
Definition matinfo.cpp:371
VertexMaterialClass * Peek_Vertex_Material(int i)
Definition matinfo.cpp:396
int Find_Shader(const ShaderClass &shader)
Definition matinfo.cpp:401
ShaderClass Peek_Shader(int i)
Definition matinfo.cpp:386
int Find_Texture(TextureClass *tex)
Definition matinfo.cpp:411
void Remap_Mesh(const MeshMatDescClass *srcmeshmatdesc, MeshMatDescClass *destmeshmatdesc)
Definition matinfo.cpp:216
WW3DErrorType read_vertex_shade_indices(ChunkLoadClass &cload)
ShareBufferClass< uint16 > * VertexBoneLink
WW3DErrorType read_vertex_influences(ChunkLoadClass &cload)
ShareBufferClass< char > * UserText
ShareBufferClass< Vector3 > * Vertex
ShareBufferClass< uint32 > * VertexShadeIdx
WW3DErrorType read_vertex_normals(ChunkLoadClass &cload)
ShareBufferClass< Vector4 > * PlaneEq
const Vector3 * Get_Vertex_Normal_Array(void)
int Get_Vertex_Count(void) const
const char * Get_Name(void) const
TriIndex * get_polys(void)
AABTreeClass * CullTree
WW3DErrorType read_user_text(ChunkLoadClass &cload)
WW3DErrorType read_vertices(ChunkLoadClass &cload)
uint16 * get_bone_links(bool create=true)
ShareBufferClass< TriIndex > * Poly
void Generate_Culling_Tree(void)
void Set_Flag(FlagsType flag, bool onoff)
ShareBufferClass< char > * MeshName
WW3DErrorType read_aabtree(ChunkLoadClass &cload)
void Set_Name(const char *newname)
int Get_Polygon_Count(void) const
Vector3 BoundSphereCenter
WW3DErrorType read_triangles(ChunkLoadClass &cload)
int Get_Flag(FlagsType flag)
friend class MeshClass
friend class MeshModelClass
unsigned * Get_Color_Array(int array, bool create=true)
void Install_UV_Array(int pass, int stage, Vector2 *uvs, int count)
void Set_Texture(int pidx, TextureClass *tex, int pass=0, int stage=0)
void Set_Single_Texture(TextureClass *tex, int pass=0, int stage=0)
void Set_Shader(int pidx, ShaderClass shader, int pass=0)
void Set_Vertex_Count(int vertcount)
Definition meshmatdesc.h:92
bool Has_Color_Array(int array)
void Set_Material(int vidx, VertexMaterialClass *vmat, int pass=0)
void Set_Single_Material(VertexMaterialClass *vmat, int pass=0)
bool Is_Empty(void)
void Set_DCG_Source(int pass, VertexMaterialClass::ColorSourceType source)
void Set_Polygon_Count(int polycount)
Definition meshmatdesc.h:94
void Set_Single_Shader(ShaderClass shader, int pass=0)
void Set_Texture(int pidx, TextureClass *tex, int pass=0, int stage=0)
Definition meshmdl.h:203
WW3DErrorType read_shader_ids(ChunkLoadClass &cload, MeshLoadContextClass *context)
MeshMatDescClass * DefMatDesc
Definition meshmdl.h:327
WW3DErrorType read_per_tri_materials(ChunkLoadClass &cload, MeshLoadContextClass *context)
bool Has_Shader_Array(int pass) const
Definition meshmdl.h:207
WW3DErrorType read_per_face_texcoord_ids(ChunkLoadClass &cload, MeshLoadContextClass *context)
unsigned * Get_Color_Array(int array_index, bool create=true)
Definition meshmdl.h:185
void compute_static_sort_levels(void)
void post_process(void)
WW3DErrorType read_texture_stage(ChunkLoadClass &cload, MeshLoadContextClass *context)
void Set_Single_Texture(TextureClass *tex, int pass=0, int stage=0)
Definition meshmdl.h:188
void Set_Material(int vidx, VertexMaterialClass *vmat, int pass=0)
Definition meshmdl.h:201
WW3DErrorType read_prelit_material(ChunkLoadClass &cload, MeshLoadContextClass *context)
MaterialInfoClass * MatInfo
Definition meshmdl.h:332
void install_materials(MeshLoadContextClass *loadinfo)
WW3DErrorType read_scg(ChunkLoadClass &cload, MeshLoadContextClass *context)
void Reset(int polycount, int vertcount, int passcount)
Definition meshmdl.cpp:157
void install_alternate_material_desc(MeshLoadContextClass *context)
int Get_Pass_Count(void) const
Definition meshmdl.h:174
WW3DErrorType read_vertex_colors(ChunkLoadClass &cload, MeshLoadContextClass *context)
WW3DErrorType read_vertex_material_ids(ChunkLoadClass &cload, MeshLoadContextClass *context)
WW3DErrorType read_vertex_materials(ChunkLoadClass &cload, MeshLoadContextClass *context)
void Set_Pass_Count(int passes)
Definition meshmdl.h:173
WW3DErrorType read_material_info(ChunkLoadClass &cload, MeshLoadContextClass *context)
WW3DErrorType read_material_pass(ChunkLoadClass &cload, MeshLoadContextClass *context)
WW3DErrorType read_textures(ChunkLoadClass &cload, MeshLoadContextClass *context)
WW3DErrorType read_texture_ids(ChunkLoadClass &cload, MeshLoadContextClass *context)
MeshMatDescClass * AlternateMatDesc
Definition meshmdl.h:328
MeshModelClass(void)
Definition meshmdl.cpp:71
unsigned int get_sort_flags(void) const
WW3DErrorType read_texcoords(ChunkLoadClass &cload, MeshLoadContextClass *context)
void Set_Single_Shader(ShaderClass shader, int pass=0)
Definition meshmdl.h:189
WW3DErrorType read_shaders(ChunkLoadClass &cload, MeshLoadContextClass *context)
void Set_Shader(int pidx, ShaderClass shader, int pass=0)
Definition meshmdl.h:202
WW3DErrorType Load_W3D(ChunkLoadClass &cload)
WW3DErrorType read_dig(ChunkLoadClass &cload, MeshLoadContextClass *context)
void post_process_fog(void)
void Set_Single_Material(VertexMaterialClass *vmat, int pass=0)
Definition meshmdl.h:187
friend class MeshLoadContextClass
Definition meshmdl.h:344
MeshMatDescClass * CurMatDesc
Definition meshmdl.h:329
void modify_for_overbright(void)
WW3DErrorType read_stage_texcoords(ChunkLoadClass &cload, MeshLoadContextClass *context)
WW3DErrorType read_v3_materials(ChunkLoadClass &cload, MeshLoadContextClass *context)
WW3DErrorType read_chunks(ChunkLoadClass &cload, MeshLoadContextClass *context)
WW3DErrorType read_dcg(ChunkLoadClass &cload, MeshLoadContextClass *context)
ShaderClass Get_Shader(int pidx, int pass=0) const
Definition meshmdl.h:213
ShaderClass Get_Single_Shader(int pass=0) const
Definition meshmdl.h:194
void clone_materials(const MeshModelClass &srcmesh)
MaterialCollectorClass Materials
WWINLINE void Release_Ref(void) const
Definition refcount.h:146
void Add_Ref(void) const
Definition refcount.cpp:171
void Set_Texturing(TexturingType x)
Definition shader.h:335
@ GRADIENT_DISABLE
Definition shader.h:192
@ GRADIENT_MODULATE
Definition shader.h:193
@ GRADIENT_MODULATE2X
Definition shader.h:197
void Set_Src_Blend_Func(SrcBlendFuncType x)
Definition shader.h:334
@ FOG_SCALE_FRAGMENT
Definition shader.h:185
void Set_Primary_Gradient(PriGradientType x)
Definition shader.h:332
StaticSortCategoryType
Definition shader.h:225
@ SSCAT_OPAQUE
Definition shader.h:226
@ SSCAT_ALPHA_TEST
Definition shader.h:227
@ SSCAT_ADDITIVE
Definition shader.h:228
@ SSCAT_SCREEN
Definition shader.h:229
@ SSCAT_OTHER
Definition shader.h:230
TexturingType Get_Texturing(void) const
Definition shader.h:320
void Init_From_Material3(const W3dMaterial3Struct &mat3)
Definition shader.cpp:254
@ TEXTURING_DISABLE
Definition shader.h:219
@ TEXTURING_ENABLE
Definition shader.h:220
SecGradientType Get_Secondary_Gradient(void) const
Definition shader.h:318
void Set_Fog_Func(FogFuncType x)
Definition shader.h:331
PriGradientType Get_Primary_Gradient(void) const
Definition shader.h:317
SrcBlendFuncType Get_Src_Blend_Func(void) const
Definition shader.h:319
void Set_Dst_Blend_Func(DstBlendFuncType x)
Definition shader.h:330
@ SECONDARY_GRADIENT_DISABLE
Definition shader.h:203
StaticSortCategoryType Get_SS_Category(void) const
Definition shader.cpp:1085
DstBlendFuncType Get_Dst_Blend_Func(void) const
Definition shader.h:315
@ SRCBLEND_SRC_ALPHA
Definition shader.h:212
@ SRCBLEND_ONE
Definition shader.h:211
AlphaTestType Get_Alpha_Test(void) const
Definition shader.h:313
@ ALPHATEST_DISABLE
Definition shader.h:96
@ DSTBLEND_ZERO
Definition shader.h:172
@ DSTBLEND_ONE_MINUS_SRC_ALPHA
Definition shader.h:177
@ DSTBLEND_SRC_COLOR
Definition shader.h:174
@ DSTBLEND_ONE
Definition shader.h:173
@ DSTBLEND_SRC_ALPHA
Definition shader.h:176
const StringClass & Get_Texture_Name(void) const
Definition texture.h:112
float Y
Definition vector2.h:79
WWINLINE void Set(float x, float y)
Definition vector2.h:92
float X
Definition vector2.h:74
static WWINLINE float Dot_Product(const Vector3 &a, const Vector3 &b)
Definition vector3.h:293
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
static WWINLINE void Subtract(const Vector3 &a, const Vector3 &b, Vector3 *c)
Definition vector3.h:576
void Normalize(void)
Definition vector3.h:417
static WWINLINE void Cross_Product(const Vector3 &a, const Vector3 &b, Vector3 *result)
Definition vector3.h:374
unsigned short K
Definition Vector3i.h:102
unsigned short J
Definition Vector3i.h:101
unsigned short I
Definition Vector3i.h:100
float Y
Definition vector4.h:67
float Z
Definition vector4.h:68
WWINLINE void Set(float x, float y, float z, float w)
Definition vector4.h:80
float X
Definition vector4.h:66
float W
Definition vector4.h:69
void Get_Diffuse(Vector3 *set_color) const
WW3DErrorType Save_W3D(ChunkSaveClass &csave)
unsigned long Get_CRC(void) const
void Set_Diffuse(const Vector3 &color)
void Set_Ambient(const Vector3 &color)
WW3DErrorType Load_W3D(ChunkLoadClass &cload)
void Set_Name(const char *name)
void Init_From_Material3(const W3dMaterial3Struct &mat3)
static void Convert_Vector(const W3dVectorStruct &v, Vector3 *set)
Definition w3d_util.cpp:45
static void Convert_Color(const W3dRGBStruct &rgb, Vector3 *set)
Definition w3d_util.cpp:75
static void Convert_Shader(const W3dShaderStruct &shader, ShaderClass *set)
Definition w3d_util.cpp:106
virtual TextureClass * Get_Texture(const char *filename, MipCountType mip_level_count=MIP_LEVELS_ALL, WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN, bool allow_compression=true, TextureBaseClass::TexAssetType type=TextureBaseClass::TEX_REGULAR, bool allow_reduction=true)
static WW3DAssetManager * Get_Instance(void)
Definition assetmgr.h:205
static bool Is_Overbright_Modify_On_Load_Enabled(void)
Definition ww3d.h:296
static PrelitModeEnum Get_Prelit_Mode()
Definition ww3d.h:239
@ PRELIT_MODE_LIGHTMAP_MULTI_PASS
Definition ww3d.h:83
@ PRELIT_MODE_VERTEX
Definition ww3d.h:82
@ PRELIT_MODE_LIGHTMAP_MULTI_TEXTURE
Definition ww3d.h:84
static bool Is_Munge_Sort_On_Load_Enabled(void)
Definition ww3d.h:284
#define I(x, y, z)
Definition md5.cpp:89
Vector3i16 TriIndex
#define REF_PTR_RELEASE(x)
Definition refcount.h:80
#define REF_PTR_SET(dst, src)
Definition refcount.h:79
#define NEW_REF(C, P)
Definition refcount.h:62
W3dVectorStruct Min
Definition w3d_file.h:1226
char MeshName[W3D_NAME_LEN]
Definition w3d_file.h:1206
W3dVectorStruct Max
Definition w3d_file.h:1227
char ContainerName[W3D_NAME_LEN]
Definition w3d_file.h:1207
W3dVectorStruct SphCenter
Definition w3d_file.h:1228
uint32 Vindex[3]
Definition w3d_file.h:1051
uint32 Attributes
Definition w3d_file.h:1052
float32 Dist
Definition w3d_file.h:1054
W3dVectorStruct Normal
Definition w3d_file.h:1053
TextureClass * Load_Texture(ChunkLoadClass &cload)
Definition texture.cpp:1051
void Save_Texture(TextureClass *texture, ChunkSaveClass &csave)
Definition texture.cpp:1184
WW3DErrorType
Definition w3derr.h:51
@ WW3D_ERROR_LOAD_FAILED
Definition w3derr.h:54
@ WW3D_ERROR_OK
Definition w3derr.h:52
@ WW3D_ERROR_SAVE_FAILED
Definition w3derr.h:55
#define WWASSERT_PRINT(expr, string)
Definition wwdebug.h:135
#define WWDEBUG_SAY(x)
Definition wwdebug.h:114