Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
meshmdl.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/meshmdl.cpp $*
26 * *
27 * Org Author:: Greg Hjelstrom *
28 * *
29 * $Author:: Kenny Mitchell *
30 * *
31 * $Modtime:: 06/26/02 4:04p $*
32 * *
33 * $Revision:: 48 $*
34 * *
35 * 06/26/02 KM Matrix name change to avoid MAX conflicts *
36 *---------------------------------------------------------------------------------------------*
37 * Functions: *
38 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
39
40#include "meshmdl.h"
41#include "matinfo.h"
42#include "aabtree.h"
43#include "htree.h"
44#include "vp.h"
45#include "visrasterizer.h"
46#include "dx8polygonrenderer.h"
47#include "bwrender.h"
48#include "camera.h"
49#include "dx8renderer.h"
50#include "hashtemplate.h"
51
52
53/*
54** Temporary Buffers
55** These buffers are used by the skin code for temporary storage of the deformed vertices and
56** vertex normals.
57*/
58static DynamicVectorClass<Vector3> _TempVertexBuffer;
59static DynamicVectorClass<Vector3> _TempNormalBuffer;
60static DynamicVectorClass<Vector4> _TempTransformedVertexBuffer;
61static DynamicVectorClass<unsigned long> _TempClipFlagBuffer;
62
63
64/*
65**
66** MeshModelClass Implementation
67**
68*/
69
70
87
106
108{
109// WWDEBUG_SAY(("Note: Mesh %s was never used\n",Get_Name()));
110 TheDX8MeshRenderer.Unregister_Mesh_Type(this);
111
112 Reset(0,0,0);
114
115 if (DefMatDesc != NULL) {
116 delete DefMatDesc;
117 }
118 if (AlternateMatDesc != NULL) {
119 delete AlternateMatDesc;
120 }
121 return ;
122}
123
125{
126 if (this != &that) {
127 // Remove all polygon renderers, this will remove the mesh from the rendering system.
128 // The mesh will be initialized to rendering system the next time it is rendered.
129 TheDX8MeshRenderer.Unregister_Mesh_Type(this);
130
132
133 *DefMatDesc = *(that.DefMatDesc);
135
136 if (AlternateMatDesc != NULL) {
137 delete AlternateMatDesc;
139 }
140
141 if (that.AlternateMatDesc != NULL) {
143 }
144
145 clone_materials(that);
146
147 if (GapFiller) {
148 // DMS - using approriate deallocation method
149 delete GapFiller;
151 }
153 }
154 return * this;
155}
156
157void MeshModelClass::Reset(int polycount,int vertcount,int passcount)
158{
159 //DMS - We must delete the gapfiller object BEFORE the geometry is reset. Otherwise,
160 // the number of stages and passes gets reset and the gapfiller cannot deallocate properly.
161 delete GapFiller;
163
164 Reset_Geometry(polycount,vertcount);
165
166 // Release everything we have and reset to initial state
167
168 TheDX8MeshRenderer.Unregister_Mesh_Type(this);
169
170 MatInfo->Reset();
171 DefMatDesc->Reset(polycount,vertcount,passcount);
172 if (AlternateMatDesc != NULL) {
173 delete AlternateMatDesc;
175 }
177
178 return ;
179}
180
182{
183 HasBeenInUse=true;
184//WW3D::Set_NPatches_Level(1);
185 if (WW3D::Get_NPatches_Level()>1) {
188 }
189 else if (GapFiller) {
190 delete GapFiller;
192 }
193 }
194 else {
197 }
198 else if (GapFiller) {
199 delete GapFiller;
201 }
202 }
203
204 TheDX8MeshRenderer.Register_Mesh_Type(this);
205}
206
208{
209 WWASSERT(texture);
210 WWASSERT(new_texture);
211 for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
212 for (int pass=0;pass<Get_Pass_Count();++pass) {
213 if (Has_Texture_Array(pass,stage)) {
214 for (int i=0;i<Get_Polygon_Count();++i) {
215 if (Peek_Texture(i,pass,stage)==texture) {
216 Set_Texture(i,new_texture,pass,stage);
217 }
218 }
219 }
220 else {
221 if (Peek_Single_Texture(pass,stage)==texture) {
222 Set_Single_Texture(new_texture,pass,stage);
223 }
224 }
225 // If this mesh model has been initialized for rendering we need to tell the rendering
226 // system to change texturing as well.
228 if (fvf_category) {
229 fvf_category->Change_Polygon_Renderer_Texture(PolygonRendererList,texture,new_texture,pass,stage);
230 }
231 }
232 }
233}
234
236{
237 WWASSERT(vmat);
238 WWASSERT(new_vmat);
239
240 for (int pass=0;pass<Get_Pass_Count();++pass) {
241 if (Has_Material_Array(pass)) {
242 for (int i=0;i<Get_Vertex_Count();++i) {
243 if (Peek_Material(i,pass)==vmat) {
244 Set_Material(i,new_vmat,pass);
245 }
246 }
247 }
248 else {
249 if (Peek_Single_Material(pass)==vmat) {
250 Set_Single_Material(new_vmat,pass);
251 }
252 }
253 // If this mesh model has been initialized for rendering we need to tell the rendering
254 // system to change texturing as well.
256 if (fvf_category) {
257 fvf_category->Change_Polygon_Renderer_Material(PolygonRendererList,vmat,new_vmat,pass);
258 }
259 }
260}
261
263{
264 if (PolygonRendererList.Is_Empty()) return NULL;
265 DX8PolygonRendererClass* polygon_renderer=PolygonRendererList.Get_Head();
266 WWASSERT(polygon_renderer);
267 DX8TextureCategoryClass* texture_category=polygon_renderer->Get_Texture_Category();
268 WWASSERT(texture_category);
269 DX8FVFCategoryContainer* fvf_category=texture_category->Get_Container();
270 WWASSERT(fvf_category);
271 return fvf_category;
272}
273
275{
276 if (rinfo.BWRenderer != NULL) {
277 if (_TempTransformedVertexBuffer.Length() < VertexCount) _TempTransformedVertexBuffer.Resize(VertexCount);
278 Vector4* transf_ptr=&(_TempTransformedVertexBuffer[0]);
279 get_deformed_screenspace_vertices(transf_ptr,rinfo,tm,htree);
280
281 Vector2* tptr = reinterpret_cast<Vector2 *>(transf_ptr);
282 Vector4* optr = transf_ptr;
283 for (int a=0;a<VertexCount;++a,++optr) *tptr++=Vector2((*optr)[0],-(*optr)[1]);
284
285 rinfo.BWRenderer->Set_Vertex_Locations(reinterpret_cast<Vector2*>(transf_ptr),VertexCount);
286 rinfo.BWRenderer->Render_Triangles(reinterpret_cast<const unsigned long*>(Poly->Get_Array()),PolyCount*3);
287 return;
288 }
289}
290
292{
294
296 REF_PTR_SET(Vertex,unique_verts);
297 REF_PTR_RELEASE(unique_verts);
298
300 REF_PTR_SET(VertexNorm,norms);
301 REF_PTR_RELEASE(norms);
302
303#if (!OPTIMIZE_PLANEEQ_RAM)
304 ShareBufferClass<Vector4> * peq = NEW_REF(ShareBufferClass<Vector4>,(*PlaneEq, "MeshModelClass::PlaneEq"));
305 REF_PTR_SET(PlaneEq,peq);
306 REF_PTR_RELEASE(peq);
307#endif
308}
309
311{
312 CurMatDesc->Make_UV_Array_Unique(pass,stage);
313}
314
316{
317 CurMatDesc->Make_Color_Array_Unique(array_index);
318}
319
321{
322 if ((onoff == true) && (AlternateMatDesc != NULL)) {
325
328
331
332 // TODO: Invalidate just this meshes DX8 data!!!
333 TheDX8MeshRenderer.Invalidate();
334 }
335 } else {
336 if (CurMatDesc != DefMatDesc) {
338
341
344
345 // TODO: Invalidate this meshes DX8 data!!!
346 TheDX8MeshRenderer.Invalidate();
347 }
348 }
349}
350
355/*
356void MeshModelClass::Process_Texture_Reduction(void)
357{
358 MatInfo->Process_Texture_Reduction();
359}
360*/
362{
364 return true;
365 }
366 return CurMatDesc->Do_Mappers_Need_Normals();
367}
368
370{
373 TriangleSide(const Vector3& l1,const Vector3& l2)
374 {
375 int i1=*(int*)&l1[0];
376 i1=37*i1+*(int*)&l1[1];
377 i1=37*i1+*(int*)&l1[2];
378 int i2=*(int*)&l2[0];
379 i2=37*i2+*(int*)&l2[1];
380 i2=37*i2+*(int*)&l2[2];
381 if (i1<i2) {
382 loc1=l1;
383 loc2=l2;
384 }
385 else {
386 loc2=l1;
387 loc1=l2;
388 }
389 }
391
392 bool operator== (const TriangleSide& s)
393 {
394 unsigned i=*(unsigned*)&loc1[0]^*(unsigned*)&s.loc1[0];
395 i|=*(unsigned*)&loc1[1]^*(unsigned*)&s.loc1[1];
396 i|=*(unsigned*)&loc1[2]^*(unsigned*)&s.loc1[2];
397 i|=*(unsigned*)&loc2[0]^*(unsigned*)&s.loc2[0];
398 i|=*(unsigned*)&loc2[1]^*(unsigned*)&s.loc2[1];
399 i|=*(unsigned*)&loc2[2]^*(unsigned*)&s.loc2[2];
400 return !i;
401 }
402};
403
404// Get_Hash_Value specialization for Vector3.
405
406template <> inline unsigned int HashTemplateKeyClass<Vector3>::Get_Hash_Value(const Vector3& location)
407{
408 const unsigned char* buffer=(const unsigned char*)&location;
409 unsigned int hval=0;
410 for (unsigned int a=0;a<sizeof(Vector3);++a) {
411 hval+=37*hval+buffer[a];
412 }
413 return hval;
414}
415
416// Get_Hash_Value specialization for TriangleSide.
417
418template <> inline unsigned int HashTemplateKeyClass<TriangleSide>::Get_Hash_Value(const TriangleSide& side)
419{
420 const unsigned char* buffer=(const unsigned char*)&side;
421 unsigned int hval=0;
422 for (unsigned int a=0;a<sizeof(TriangleSide);++a) {
423 hval+=37*hval+buffer[a];
424 }
425 return hval;
426}
427
429{
430 unsigned short vidx1;
431 unsigned short vidx2;
434 SideIndexInfo(int i) { WWASSERT(0); }
435};
436
437
441
442// ----------------------------------------------------------------------------
443//
444// Allocate a gap-filler object. The constructor allocates memory for the
445// maximum possible amount of gap polygons, which is quite much. After all
446// the gap polygons have been added to the arrays, Shrink_Arrays() should
447// be called to free up all unneeded memory.
448//
449// ----------------------------------------------------------------------------
450
452{
453 //DMS - We cannot take a reference to the mesh model here! This is because the mesh model
454 // class OWNS the GapFiller class (allocated via NEW). If we take a reference here, there
455 // will be an extra reference on the parent object, which will result in the parent object
456 // not being destroyed.
457 //
458// REF_PTR_SET(mmc,mmc_);
459 mmc = mmc_;
460
461 ArraySize=mmc->Get_Polygon_Count()*6; // Each side of each triangle can have 2 polygons added, in the worst case
462 PolygonArray=W3DNEWARRAY TriIndex[ArraySize];
463 for (int pass=0;pass<mmc->Get_Pass_Count();++pass) {
464 for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
465 if (mmc->Has_Texture_Array(pass,stage)) {
466 TextureArray[pass][stage]=W3DNEWARRAY TextureClass*[ArraySize];
467 }
468 else TextureArray[pass][stage]=NULL;
469 }
470
471 if (mmc->Has_Material_Array(pass)) {
472 MaterialArray[pass]=W3DNEWARRAY VertexMaterialClass*[ArraySize];
473 }
474 else MaterialArray[pass]=NULL;
475
476 if (mmc->Has_Shader_Array(pass)) {
477 ShaderArray[pass]=W3DNEWARRAY ShaderClass[ArraySize];
478 }
479 else ShaderArray[pass]=NULL;
480 }
481}
482
483GapFillerClass::GapFillerClass(const GapFillerClass& that) : mmc(NULL), PolygonCount(that.PolygonCount)
484{
485 //DMS - We cannot take a reference to the mesh model here! This is because the mesh model
486 // class OWNS the GapFiller class (allocated via NEW). If we take a reference here, there
487 // will be an extra reference on the parent object, which will result in the parent object
488 // not being destroyed.
489 //
490// REF_PTR_SET(mmc,that.mmc);
491 mmc = that.mmc;
492
493 ArraySize=that.ArraySize;
494 PolygonArray=W3DNEWARRAY TriIndex[ArraySize];
495 for (int pass=0;pass<mmc->Get_Pass_Count();++pass) {
496 for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
497 if (that.TextureArray[pass][stage]) {
498 TextureArray[pass][stage]=W3DNEWARRAY TextureClass*[ArraySize];
499 for (unsigned i=0;i<PolygonCount;++i) {
500 TextureArray[pass][stage][i]=that.TextureArray[pass][stage][i];
501 TextureArray[pass][stage][i]->Add_Ref();
502 }
503 }
504 else TextureArray[pass][stage]=NULL;
505 }
506
507 if (that.MaterialArray[pass]) {
508 MaterialArray[pass]=W3DNEWARRAY VertexMaterialClass*[ArraySize];
509 for (unsigned i=0;i<PolygonCount;++i) {
510 MaterialArray[pass][i]=that.MaterialArray[pass][i];
511 MaterialArray[pass][i]->Add_Ref();
512 }
513 }
514 else MaterialArray[pass]=NULL;
515
516 if (that.ShaderArray[pass]) {
517 ShaderArray[pass]=W3DNEWARRAY ShaderClass[ArraySize];
518 for (unsigned i=0;i<PolygonCount;++i) {
519 ShaderArray[pass][i]=that.ShaderArray[pass][i];
520 }
521 }
522 else ShaderArray[pass]=NULL;
523 }
524}
525
526// ----------------------------------------------------------------------------
527//
528// Destruct gap-filler object. Release references to all textures and release
529// the arrays.
530//
531// ----------------------------------------------------------------------------
532
534{
535 delete[] PolygonArray;
536
537 for (int pass=0;pass<mmc->Get_Pass_Count();++pass) {
538 for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
539 if (TextureArray[pass][stage]) {
540
541 for (unsigned i=0;i<PolygonCount;++i) {
542 REF_PTR_RELEASE(TextureArray[pass][stage][i]);
543 }
544 delete[] TextureArray[pass][stage];
545 }
546 }
547
548 if (MaterialArray[pass]) {
549 for (unsigned i=0;i<PolygonCount;++i) {
550 REF_PTR_RELEASE(MaterialArray[pass][i]);
551 }
552 delete[] MaterialArray[pass];
553 }
554
555 delete[] ShaderArray[pass];
556 }
557
558 // DMS - Removed - See constructor for details.
559// REF_PTR_RELEASE(mmc);
560}
561
562// ----------------------------------------------------------------------------
563//
564// Add polygon to gap filler.
565//
566// ----------------------------------------------------------------------------
567
568void GapFillerClass::Add_Polygon(unsigned polygon_index,unsigned vidx1,unsigned vidx2, unsigned vidx3)
569{
570 WWASSERT(PolygonCount<ArraySize);
571 WWASSERT(vidx1!=vidx2 && vidx1!=vidx3 && vidx2!=vidx3);
572Vector3 loc1=mmc->Get_Vertex_Array()[vidx1];
573Vector3 loc2=mmc->Get_Vertex_Array()[vidx2];
574Vector3 loc3=mmc->Get_Vertex_Array()[vidx3];
575WWASSERT(loc1==loc2 || loc1==loc3 || loc2==loc3);
576//sdflksdjflsdkf
577//vidx1=mmc->Get_Polygon_Array()[polygon_index][0];
578//vidx2=mmc->Get_Polygon_Array()[polygon_index][1];
579//vidx3=mmc->Get_Polygon_Array()[polygon_index][2];
580
581 PolygonArray[PolygonCount]=TriIndex(vidx1,vidx2,vidx3);
582 for (int pass=0;pass<mmc->Get_Pass_Count();++pass) {
583 if (mmc->Has_Shader_Array(pass)) {
584 ShaderArray[pass][PolygonCount]=mmc->Get_Shader(polygon_index,pass);
585 }
586 if (mmc->Has_Material_Array(pass)) {
587// MaterialArray[pass][PolygonCount]=mmc->Get_Material(polygon_index,pass);
588 MaterialArray[pass][PolygonCount]=mmc->Get_Material(mmc->Get_Polygon_Array()[polygon_index][0],pass);
589 }
590 for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
591 if (mmc->Has_Texture_Array(pass,stage)) {
592 TextureArray[pass][stage][PolygonCount]=mmc->Get_Texture(polygon_index,pass,stage);
593 }
594 }
595 }
596 PolygonCount++;
597}
598
599// ----------------------------------------------------------------------------
600//
601// Resize buffers to match the polygon count exatly. After this call no more
602// polygons can be added to the buffers.
603//
604// ----------------------------------------------------------------------------
605
607{
608 if (PolygonCount==ArraySize) return;
609
610 // Shrink the polygon array
611 TriIndex* new_polygon_array=W3DNEWARRAY TriIndex[PolygonCount];
612 memcpy(new_polygon_array,PolygonArray,PolygonCount*sizeof(TriIndex));
613 delete[] PolygonArray;
614 PolygonArray=new_polygon_array;
615
616 for (int pass=0;pass<mmc->Get_Pass_Count();++pass) {
617 for (int stage=0;stage<MeshMatDescClass::MAX_TEX_STAGES;++stage) {
618 if (TextureArray[pass][stage]) {
619 // Shrink the texture array
620 TextureClass** new_texture_array=W3DNEWARRAY TextureClass*[PolygonCount];
621 memcpy(new_texture_array,TextureArray[pass][stage],PolygonCount*sizeof(TextureClass*));
622 delete[] TextureArray[pass][stage];
623 TextureArray[pass][stage]=new_texture_array;
624 }
625 }
626
627 if (MaterialArray[pass]) {
628 // Shrink the material array
629 VertexMaterialClass** new_material_array=W3DNEWARRAY VertexMaterialClass*[PolygonCount];
630 memcpy(new_material_array,MaterialArray[pass],PolygonCount*sizeof(VertexMaterialClass*));
631 delete[] MaterialArray[pass];
632 MaterialArray[pass]=new_material_array;
633 }
634
635 if (ShaderArray[pass]) {
636 // Shrink the shader array
637 ShaderClass* new_shader_array=W3DNEWARRAY ShaderClass[PolygonCount];
638 memcpy(new_shader_array,ShaderArray[pass],PolygonCount*sizeof(ShaderClass));
639 delete[] ShaderArray[pass];
640 ShaderArray[pass]=new_shader_array;
641 }
642 }
643 ArraySize=PolygonCount;
644}
645
646// ----------------------------------------------------------------------------
647//
648// Hard edges cause gaps to n-patches meshes. This code searches for hard edges
649// and adds gaps filler polygons, using existing vertices.
650//
651// ----------------------------------------------------------------------------
652
654{
655 if (!DX8Wrapper::Get_Current_Caps()->Support_NPatches()) return;
657 if (GapFiller) return;
658
659 const Vector3* locations=Get_Vertex_Array();
660 unsigned vertex_count=Get_Vertex_Count();
661 const TriIndex* polygon_indices=Get_Polygon_Array();
662 unsigned polygon_count=Get_Polygon_Count();
663
664 LocationHash.Remove_All();
665 DuplicateLocationHash.Remove_All();
666 SideHash.Remove_All();
667
668 for (unsigned i=0;i<vertex_count;++i) {
669 if (LocationHash.Exists(locations[i])) {
670 if (!DuplicateLocationHash.Exists(locations[i])) {
671 DuplicateLocationHash.Insert(locations[i],i);
672 }
673 }
674 else {
675 LocationHash.Insert(locations[i],i);
676 }
677 }
678
679 for (i=0;i<polygon_count;++i) {
680 bool duplicates[3];
681 duplicates[0]=DuplicateLocationHash.Exists(locations[polygon_indices[i][0]]);
682 duplicates[1]=DuplicateLocationHash.Exists(locations[polygon_indices[i][1]]);
683 duplicates[2]=DuplicateLocationHash.Exists(locations[polygon_indices[i][2]]);
684 if (duplicates[0] && duplicates[1]) {
685 TriangleSide tri(locations[polygon_indices[i][0]],locations[polygon_indices[i][1]]);
686 if (SideHash.Exists(tri)) {
687 SideIndexInfo side_index=SideHash.Get(tri);
688 unsigned idx1=side_index.vidx1;
689 unsigned idx2=side_index.vidx2;
690 unsigned idx3=polygon_indices[i][0];
691 unsigned idx4=polygon_indices[i][1];
692 bool diff=!(idx1^idx3)|!(idx1^idx4)|!(idx2^idx3)|!(idx2^idx4);
693 if (!diff) {
695 GapFiller->Add_Polygon(i,idx4,idx2,idx1);
696 GapFiller->Add_Polygon(side_index.polygon_index,idx3,idx2,idx4);
697 }
698 }
699 else {
700 SideIndexInfo side_index;
701 side_index.vidx1=polygon_indices[i][0];
702 side_index.vidx2=polygon_indices[i][1];
703 side_index.polygon_index=i;
704 SideHash.Insert(tri,side_index);
705 }
706 }
707 if (duplicates[1] && duplicates[2]) {
708 TriangleSide tri(locations[polygon_indices[i][1]],locations[polygon_indices[i][2]]);
709 if (SideHash.Exists(tri)) {
710 SideIndexInfo side_index=SideHash.Get(tri);
711 unsigned idx1=side_index.vidx1;
712 unsigned idx2=side_index.vidx2;
713 unsigned idx3=polygon_indices[i][1];
714 unsigned idx4=polygon_indices[i][2];
715 bool diff=!(idx1^idx3)|!(idx1^idx4)|!(idx2^idx3)|!(idx2^idx4);
716 if (!diff) {
718 GapFiller->Add_Polygon(i,idx4,idx2,idx1);
719 GapFiller->Add_Polygon(side_index.polygon_index,idx3,idx2,idx4);
720 }
721 }
722 else {
723 SideIndexInfo side_index;
724 side_index.vidx1=polygon_indices[i][1];
725 side_index.vidx2=polygon_indices[i][2];
726 side_index.polygon_index=i;
727 SideHash.Insert(tri,side_index);
728 }
729 }
730 if (duplicates[2] && duplicates[0]) {
731 TriangleSide tri(locations[polygon_indices[i][2]],locations[polygon_indices[i][0]]);
732 if (SideHash.Exists(tri)) {
733 SideIndexInfo side_index=SideHash.Get(tri);
734 unsigned idx1=side_index.vidx1;
735 unsigned idx2=side_index.vidx2;
736 unsigned idx3=polygon_indices[i][2];
737 unsigned idx4=polygon_indices[i][0];
738 bool diff=!(idx1^idx3)|!(idx1^idx4)|!(idx2^idx3)|!(idx2^idx4);
739 if (!diff) {
741 GapFiller->Add_Polygon(i,idx4,idx2,idx1);
742 GapFiller->Add_Polygon(side_index.polygon_index,idx3,idx2,idx4);
743 }
744 }
745 else {
746 SideIndexInfo side_index;
747 side_index.vidx1=polygon_indices[i][2];
748 side_index.vidx2=polygon_indices[i][0];
749 side_index.polygon_index=i;
750 SideHash.Insert(tri,side_index);
751 }
752 }
753 }
754
755 LocationHash.Remove_All();
756 DuplicateLocationHash.Remove_All();
757 SideHash.Remove_All();
758
759 if (GapFiller) GapFiller->Shrink_Buffers();
760}
#define NULL
Definition BaseType.h:92
#define WWASSERT
#define W3DNEWARRAY
Definition always.h:110
#define W3DNEW
Definition always.h:109
@ false
Definition bool.h:59
void Set_Vertex_Locations(Vector2 *vertices, int count)
Definition bwrender.cpp:104
void Render_Triangles(const unsigned long *indices, int index_count)
Definition bwrender.cpp:162
void Change_Polygon_Renderer_Texture(DX8PolygonRendererList &polygon_renderer_list, TextureClass *texture, TextureClass *new_texture, unsigned pass, unsigned stage)
void Change_Polygon_Renderer_Material(DX8PolygonRendererList &polygon_renderer_list, VertexMaterialClass *vmat, VertexMaterialClass *new_vmat, unsigned pass)
DX8TextureCategoryClass * Get_Texture_Category()
DX8FVFCategoryContainer * Get_Container(void)
static const DX8Caps * Get_Current_Caps()
Definition dx8wrapper.h:536
void Add_Polygon(unsigned polygon_index, unsigned vidx1, unsigned vidx2, unsigned vidx3)
Definition meshmdl.cpp:568
GapFillerClass(MeshModelClass *mmc)
Definition meshmdl.cpp:451
void Shrink_Buffers()
Definition meshmdl.cpp:606
static unsigned int Get_Hash_Value(const Key &k)
void Reset_Geometry(int polycount, int vertcount)
ShareBufferClass< Vector3 > * Vertex
void get_deformed_screenspace_vertices(Vector4 *dst_vert, const RenderInfoClass &rinfo, const Matrix3D &mesh_tm, const HTreeClass *htree)
ShareBufferClass< Vector4 > * PlaneEq
int Get_Vertex_Count(void) const
const TriIndex * Get_Polygon_Array(void)
ShareBufferClass< Vector3 > * VertexNorm
MeshGeometryClass & operator=(const MeshGeometryClass &that)
ShareBufferClass< TriIndex > * Poly
Vector3 * Get_Vertex_Array(void)
void Set_Flag(FlagsType flag, bool onoff)
int Get_Polygon_Count(void) const
int Get_Flag(FlagsType flag)
void Set_Texture(int pidx, TextureClass *tex, int pass=0, int stage=0)
Definition meshmdl.h:203
MeshModelClass & operator=(const MeshModelClass &that)
Definition meshmdl.cpp:124
MeshMatDescClass * DefMatDesc
Definition meshmdl.h:327
GapFillerClass * GapFiller
Definition meshmdl.h:338
TextureClass * Peek_Texture(int pidx, int pass=0, int stage=0) const
Definition meshmdl.h:217
void Make_UV_Array_Unique(int pass=0, int stage=0)
Definition meshmdl.cpp:310
void compute_static_sort_levels(void)
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
void Make_Color_Array_Unique(int array_index=0)
Definition meshmdl.cpp:315
bool Needs_Vertex_Normals(void)
Definition meshmdl.cpp:361
MaterialInfoClass * MatInfo
Definition meshmdl.h:332
void Init_For_NPatch_Rendering()
Definition meshmdl.cpp:653
void Reset(int polycount, int vertcount, int passcount)
Definition meshmdl.cpp:157
void Enable_Alternate_Material_Description(bool onoff)
Definition meshmdl.cpp:320
VertexMaterialClass * Peek_Material(int vidx, int pass=0) const
Definition meshmdl.h:216
bool Has_Material_Array(int pass) const
Definition meshmdl.h:206
void Register_For_Rendering()
Definition meshmdl.cpp:181
int Get_Pass_Count(void) const
Definition meshmdl.h:174
~MeshModelClass(void)
Definition meshmdl.cpp:107
bool Has_Texture_Array(int pass, int stage) const
Definition meshmdl.h:208
DX8PolygonRendererList PolygonRendererList
Definition meshmdl.h:335
bool Is_Alternate_Material_Description_Enabled(void)
Definition meshmdl.cpp:351
DX8FVFCategoryContainer * Peek_FVF_Category_Container()
Definition meshmdl.cpp:262
MeshMatDescClass * AlternateMatDesc
Definition meshmdl.h:328
MeshModelClass(void)
Definition meshmdl.cpp:71
void Shadow_Render(SpecialRenderInfoClass &rinfo, const Matrix3D &tm, const HTreeClass *htree)
Definition meshmdl.cpp:274
void Set_Single_Material(VertexMaterialClass *vmat, int pass=0)
Definition meshmdl.h:187
MeshMatDescClass * CurMatDesc
Definition meshmdl.h:329
friend class DX8PolygonRendererClass
Definition meshmdl.h:347
void modify_for_overbright(void)
void Replace_Texture(TextureClass *texture, TextureClass *new_texture)
Definition meshmdl.cpp:207
VertexMaterialClass * Peek_Single_Material(int pass=0) const
Definition meshmdl.h:198
void Replace_VertexMaterial(VertexMaterialClass *vmat, VertexMaterialClass *new_vmat)
Definition meshmdl.cpp:235
void Make_Geometry_Unique()
Definition meshmdl.cpp:291
bool HasBeenInUse
Definition meshmdl.h:339
void clone_materials(const MeshModelClass &srcmesh)
TextureClass * Peek_Single_Texture(int pass=0, int stage=0) const
Definition meshmdl.h:199
void Add_Ref(void) const
Definition refcount.cpp:171
BWRenderClass * BWRenderer
Definition rinfo.h:157
static bool Is_Overbright_Modify_On_Load_Enabled(void)
Definition ww3d.h:296
static NPatchesGapFillingModeEnum Get_NPatches_Gap_Filling_Mode()
Definition ww3d.h:251
static unsigned Get_NPatches_Level()
Definition ww3d.h:254
static bool Is_Munge_Sort_On_Load_Enabled(void)
Definition ww3d.h:284
@ NPATCHES_GAP_FILLING_DISABLED
Definition ww3d.h:98
@ NPATCHES_GAP_FILLING_FORCE
Definition ww3d.h:100
DX8MeshRendererClass TheDX8MeshRenderer
Vector3i16 TriIndex
HashTemplateClass< TriangleSide, SideIndexInfo > SideHash
Definition meshmdl.cpp:440
HashTemplateClass< Vector3, unsigned > LocationHash
Definition meshmdl.cpp:438
HashTemplateClass< Vector3, unsigned > DuplicateLocationHash
Definition meshmdl.cpp:439
else return(RetVal)
#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
unsigned polygon_index
Definition meshmdl.cpp:432
unsigned short vidx2
Definition meshmdl.cpp:431
SideIndexInfo(int i)
Definition meshmdl.cpp:434
unsigned short vidx1
Definition meshmdl.cpp:430
TriangleSide(const Vector3 &l1, const Vector3 &l2)
Definition meshmdl.cpp:373
Vector3 loc2
Definition meshmdl.cpp:372
Vector3 loc1
Definition meshmdl.cpp:371
bool operator==(const TriangleSide &s)
Definition meshmdl.cpp:392