Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
distlod.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/distlod.cpp $*
26 * *
27 * Author:: Greg Hjelstrom *
28 * *
29 * $Modtime:: 2/06/01 3:21p $*
30 * *
31 * $Revision:: 3 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * DistLODDefClass -- default constructor for DistLODDefClass *
36 * DistLODDefClass::DistLODDefClass -- manual constructor for DistLODDefClass *
37 * DistLODDefClass::~DistLODDefClass -- destructor for DistLODDefClass *
38 * DistLODDefClass::Free -- releases all memory in use by this object *
39 * DistLODDefClass::Load -- initialize this object from a W3D file *
40 * DistLODDefClass::read_header -- read the header from a W3D file *
41 * DistLODDefClass::read_node -- read a model node description from a W3D file *
42 * DistLODClass::DistLODClass -- constructor *
43 * DistLODClass::DistLODClass -- copy constructor *
44 * DistLODClass::~DistLODClass -- destructor *
45 * DistLODClass::Free -- releases memory in use *
46 * DistLODClass::Get_Name -- returns the name of this LOD object *
47 * DistLODClass::Get_Num_Polys -- returns the number of polys in this model *
48 * DistLODClass::Render -- Render this LOD. *
49 * DistLODClass::Special_Render -- custom render function *
50 * DistLODCLass::Get_Num_Sub_Objects -- returns the number of subobjects (levels of detail) *
51 * DistLODClass::Get_Sub_Object -- returns pointer to the specified sub-object (LOD) *
52 * DistLODCLass::Set_Transform -- sets the transform for this model *
53 * DistLODClass::Set_Position -- set the position of this object *
54 * DistLODClass::Set_Animation -- set the animation state of this model *
55 * DistLODClass::Set_Animation -- set the animation state of this model *
56 * DistLODClass::Set_Animation -- set the animation state to a blend of two anims *
57 * DistLODClass::Set_Animation -- set the animation state to a combination of anims *
58 * DistLODClass::Get_Num_Bones -- returns the number of bones *
59 * DistLODClass::Get_Bone_Name -- returns the name of the specified bone *
60 * DistLODClass::Get_Bone_Index -- returns the index of the given bone (if found) *
61 * DistLODClass::Get_Bone_Transform -- returns the transform of the given bone *
62 * DistLODClass::Get_Bone_Transform -- returns the transform of the given bone *
63 * DistLODClass::Capture_Bone -- take control of a bone *
64 * DistLODClass::Release_Bone -- release control of a bone *
65 * DistLODClass::Is_Bone_Captured -- check whether the given bone is captured *
66 * DistLODClass::Control_Bone -- set the transform for a captured bone *
67 * DistLODClass::Cast_Ray -- cast a ray against this model *
68 * DistLODClass::Cast_AABox -- perform an AABox cast against this model *
69 * DistLODClass::Cast_OBBox -- perform an OBBox cast against this model *
70 * DistLODCLass::Get_Num_Snap_Points -- returns number of snap points in this model *
71 * DistLODClass::Get_Snap_Point -- returns the i'th snap point *
72 * DistLODCLass::Scale -- scale this model; passes on to each LOD *
73 * DistLODClass::Scale -- scale this model; passes on to each LOD *
74 * DistLODClass::Update_LOD -- adjusts the current LOD based on the distance *
75 * DistLODClass::Increment_Lod -- moves to a higher detail LOD *
76 * DistLODClass::Decrement_Lod -- moves to a lower detail LOD *
77 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
78
79
80#include "distlod.h"
81#include "nstrdup.h"
82#include "ww3d.h"
83#include "assetmgr.h"
84#include "camera.h"
85#include "w3derr.h"
86#include "wwdebug.h"
87#include "chunkio.h"
88#include "hlod.h"
89#include "rinfo.h"
90#include "coltest.h"
91#include "inttest.h"
92
93/*
94** Loader Instance
95*/
97
98
100{
101 DistLODClass * dist = NEW_REF( DistLODClass , ( *Definition ) );
102
103 // Have to pull each LOD out of the DistLOD, create a copy of the name
104 // and destroy the DistLOD so that the models are "containerless". Also
105 // invert the order of the models in the DistLOD
106 char * name = nstrdup(dist->Get_Name());
107 WWASSERT(name != NULL);
108
109 int count = dist->Get_Num_Sub_Objects();
110 RenderObjClass ** robj = W3DNEWARRAY RenderObjClass * [count];
111 for (int i=0; i<count; i++) {
112
113 robj[count - 1 - i] = dist->Get_Sub_Object(i);
114 WWASSERT(robj[count - 1 - i] != NULL);
115 }
116 dist->Release_Ref();
117
118 WWDEBUG_SAY(("OBSOLETE Dist-LOD model found! Please re-export %s!\r\n",name));
119 HLodClass * hlod = NEW_REF(HLodClass , (name,robj,count));
120
121 // Now, release the temporary refs and memory for the name
122 for (i=0; i<count; i++) {
123 robj[i]->Release_Ref();
124 }
125 free(name);
126
127 return hlod;
128}
129
130/*
131** The Prototype Loader
132*/
134{
135 DistLODDefClass * pCDistLODClass = W3DNEW DistLODDefClass;
136
137 if (pCDistLODClass == NULL)
138 {
139 return NULL;
140 }
141
142 if (pCDistLODClass->Load_W3D(cload) != WW3D_ERROR_OK)
143 {
144 // load failed, delete the model and return an error
145 delete pCDistLODClass;
146 return NULL;
147
148 } else {
149
150 // ok, accept this model!
151 DistLODPrototypeClass *pCLODProto = W3DNEW DistLODPrototypeClass (pCDistLODClass);
152 return pCLODProto;
153 }
154}
155
156
157/***********************************************************************************************
158 * DistLODDefClass -- default constructor for DistLODDefClass *
159 * *
160 * DistLODDefClass is a "blueprint" for constructing a DistLODClass *
161 * *
162 * INPUT: *
163 * *
164 * OUTPUT: *
165 * *
166 * WARNINGS: *
167 * *
168 * HISTORY: *
169 *=============================================================================================*/
171 Name(NULL),
172 LodCount(0),
173 Lods(NULL)
174{
175}
176
177
178/***********************************************************************************************
179 * DistLODDefClass::DistLODDefClass -- manual constructor for DistLODDefClass *
180 * *
181 * This constructor allows you to create a DistLODDef Manually (and then use it to create *
182 * the desired DistLODClass). The array of DistLODModelDefStructs which you pass in will *
183 * only be read from so you are responsible for the memory used by them. *
184 * *
185 * INPUT: *
186 * *
187 * OUTPUT: *
188 * *
189 * WARNINGS: *
190 * *
191 * HISTORY: *
192 * 7/15/98 GTH : Created. *
193 *=============================================================================================*/
194DistLODDefClass::DistLODDefClass(const char * name,int lodcount,DistLODNodeDefStruct * modeldefs) :
195 Name(NULL),
196 LodCount(0),
197 Lods(NULL)
198{
199 assert(name != NULL);
200 Name = nstrdup(name);
201
202 LodCount = lodcount;
203 Lods = W3DNEWARRAY DistLODNodeDefStruct[LodCount];
204 for (int i=0; i<LodCount; i++) {
205 Lods[i].Name = nstrdup(modeldefs[i].Name);
206 Lods[i].ResDownDist = modeldefs[i].ResDownDist;
207 Lods[i].ResUpDist = modeldefs[i].ResUpDist;
208 }
209}
210
211
212/***********************************************************************************************
213 * DistLODDefClass::~DistLODDefClass -- destructor for DistLODDefClass *
214 * *
215 * INPUT: *
216 * *
217 * OUTPUT: *
218 * *
219 * WARNINGS: *
220 * *
221 * HISTORY: *
222 * 7/15/98 GTH : Created. *
223 *=============================================================================================*/
225{
226 Free();
227}
228
229
230/***********************************************************************************************
231 * DistLODDefClass::Free -- releases all memory in use by this object *
232 * *
233 * INPUT: *
234 * *
235 * OUTPUT: *
236 * *
237 * WARNINGS: *
238 * *
239 * HISTORY: *
240 * 7/15/98 GTH : Created. *
241 *=============================================================================================*/
242void DistLODDefClass::Free(void)
243{
244 if (Name != NULL) {
245 delete[] Name;
246 Name = NULL;
247 }
248 if (Lods != NULL) {
249 for (int i=0; i<LodCount; i++) {
250 if (Lods[i].Name != NULL) {
251 delete[] Lods[i].Name;
252 }
253 }
254 delete[] Lods;
255 Lods = NULL;
256 }
257 LodCount = 0;
258}
259
260
261/***********************************************************************************************
262 * DistLODDefClass::Load -- initialize this object from a W3D file *
263 * *
264 * INPUT: *
265 * *
266 * OUTPUT: *
267 * *
268 * WARNINGS: *
269 * *
270 * HISTORY: *
271 * 7/15/98 GTH : Created. *
272 *=============================================================================================*/
274{
275 /*
276 ** First make sure we release any memory in use
277 */
278 Free();
279
280 if (read_header(cload) == false) {
282 }
283
284 /*
285 ** Loop through all the LODs and read the info from its chunk
286 */
287 for (int iLOD = 0; iLOD < LodCount; iLOD ++) {
288
289 /*
290 ** Open the next chunk, it should be a LOD struct
291 */
292 if (!cload.Open_Chunk()) return WW3D_ERROR_LOAD_FAILED;
293
294 if (cload.Cur_Chunk_ID() != W3D_CHUNK_LOD) {
295 // ERROR: Expected LOD struct!
297 }
298
299 /*
300 ** Read the data from the chunk into the LOD struct
301 */
302 W3dLODStruct lodStruct;
303 if (cload.Read(&lodStruct,sizeof(W3dLODStruct)) != sizeof(W3dLODStruct)) {
305 }
306
307 // Add the information from the chunk into the LOD array
308 Lods[iLOD].Name = nstrdup (lodStruct.RenderObjName);
309 Lods[iLOD].ResUpDist = lodStruct.LODMin;
310 Lods[iLOD].ResDownDist = lodStruct.LODMax;
311
312 // Close-out the chunk
313 cload.Close_Chunk();
314 }
315
316 return WW3D_ERROR_OK;
317}
318
319
320/***********************************************************************************************
321 * DistLODDefClass::read_header -- read the header from a W3D file *
322 * *
323 * INPUT: *
324 * *
325 * OUTPUT: *
326 * *
327 * WARNINGS: *
328 * *
329 * HISTORY: *
330 * 7/15/98 GTH : Created. *
331 *=============================================================================================*/
332bool DistLODDefClass::read_header(ChunkLoadClass & cload)
333{
334 /*
335 ** Open the first chunk, it should be the LOD header
336 */
337 if (!cload.Open_Chunk()) return false;
338
340 // ERROR: Expected LOD Header!
341 return false;
342 }
343
344 W3dLODModelHeaderStruct lodHeader;
345 if (cload.Read(&lodHeader,sizeof(W3dLODModelHeaderStruct)) != sizeof(W3dLODModelHeaderStruct)) {
346 return false;
347 }
348
349 cload.Close_Chunk();
350
351 // Copy the name into our internal variable
352 Name = ::nstrdup (lodHeader.Name);
353 LodCount = lodHeader.NumLODs;
354 Lods = W3DNEWARRAY DistLODNodeDefStruct[LodCount];
355 return true;
356}
357
358
359/***********************************************************************************************
360 * DistLODDefClass::read_node -- read a model node description from a W3D file *
361 * *
362 * INPUT: *
363 * *
364 * OUTPUT: *
365 * *
366 * WARNINGS: *
367 * *
368 * HISTORY: *
369 * 7/15/98 GTH : Created. *
370 *=============================================================================================*/
371bool DistLODDefClass::read_node(ChunkLoadClass & cload,DistLODNodeDefStruct * node)
372{
373 return true;
374}
375
376
377/***********************************************************************************************
378 * DistLODClass::DistLODClass -- constructor *
379 * *
380 * INPUT: *
381 * *
382 * OUTPUT: *
383 * *
384 * WARNINGS: *
385 * *
386 * HISTORY: *
387 * 3/3/99 GTH : Created. *
388 *=============================================================================================*/
390{
391 Set_Name(def.Get_Name());
392 LodCount = def.LodCount;
393 CurLod = 0;
394 Lods = W3DNEWARRAY LODNodeClass[LodCount];
395
396 for (int i=0; i<LodCount; i++) {
397 // create a render object
398 Lods[i].Model = WW3DAssetManager::Get_Instance()->Create_Render_Obj(def.Lods[i].Name);
399 assert(Lods[i].Model != NULL);
400 Lods[i].Model->Set_Container(this);
401
402 // copy the distances
403 Lods[i].ResUpDist = def.Lods[i].ResUpDist;
404 Lods[i].ResDownDist = def.Lods[i].ResDownDist;
405 }
406
409}
410
411
412/***********************************************************************************************
413 * DistLODClass::DistLODClass -- copy constructor *
414 * *
415 * INPUT: *
416 * *
417 * OUTPUT: *
418 * *
419 * WARNINGS: *
420 * *
421 * HISTORY: *
422 * 3/3/99 GTH : Created. *
423 *=============================================================================================*/
426{
427 LodCount = that.LodCount;
428 CurLod = VpPushLod = that.CurLod;
429
430 Lods = W3DNEWARRAY LODNodeClass[LodCount];
431 for (int i=0; i<LodCount; i++) {
432 // create a render object
433 Lods[i].Model = that.Lods[i].Model->Clone();
434 assert(Lods[i].Model != NULL);
435 Lods[i].Model->Set_Container(this);
436
437 // copy the distances
438 Lods[i].ResUpDist = that.Lods[i].ResUpDist;
439 Lods[i].ResDownDist = that.Lods[i].ResDownDist;
440 }
442}
443
444
445/***********************************************************************************************
446 * DistLODClass::~DistLODClass -- destructor *
447 * *
448 * INPUT: *
449 * *
450 * OUTPUT: *
451 * *
452 * WARNINGS: *
453 * *
454 * HISTORY: *
455 * 3/3/99 GTH : Created. *
456 *=============================================================================================*/
458{
459 Free();
460}
461
462
463/***********************************************************************************************
464 * DistLODClass::Free -- releases memory in use *
465 * *
466 * INPUT: *
467 * *
468 * OUTPUT: *
469 * *
470 * WARNINGS: *
471 * *
472 * HISTORY: *
473 * 3/3/99 GTH : Created. *
474 *=============================================================================================*/
475void DistLODClass::Free(void)
476{
477 if (Lods != NULL) {
478 for (int i=0; i<LodCount; i++) {
479 if (Lods[i].Model != NULL) {
480 Lods[i].Model->Set_Container(NULL);
481 Lods[i].Model->Release_Ref();
482 Lods[i].Model = NULL;
483 }
484 }
485 delete[] Lods;
486 Lods = NULL;
487 }
488 CurLod = 0;
489 LodCount = 0;
490}
491
492
493/***********************************************************************************************
494 * DistLODClass::Get_Num_Polys -- returns the number of polys in this model *
495 * *
496 * INPUT: *
497 * *
498 * OUTPUT: *
499 * *
500 * WARNINGS: *
501 * returns the number of polys in the *current* lod. *
502 * *
503 * HISTORY: *
504 * 3/3/99 GTH : Created. *
505 *=============================================================================================*/
507{
508 return Lods[CurLod].Model->Get_Num_Polys();
509}
510
511
512/***********************************************************************************************
513 * DistLODClass::Render -- Render this LOD. *
514 * *
515 * INPUT: *
516 * *
517 * OUTPUT: *
518 * *
519 * WARNINGS: *
520 * *
521 * HISTORY: *
522 * 3/3/99 GTH : Created. *
523 *=============================================================================================*/
525{
526 if (Is_Not_Hidden_At_All() == false) {
527 return;
528 }
529
530 Update_Lod(rinfo.Camera);
531 Lods[CurLod].Model->Render(rinfo);
532}
533
534
535/***********************************************************************************************
536 * DistLODClass::Special_Render -- custom render function *
537 * *
538 * INPUT: *
539 * *
540 * OUTPUT: *
541 * *
542 * WARNINGS: *
543 * *
544 * HISTORY: *
545 * 3/3/99 GTH : Created. *
546 *=============================================================================================*/
548{
549 Update_Lod(rinfo.Camera);
550 Lods[CurLod].Model->Special_Render(rinfo);
551}
552
553
554/***********************************************************************************************
555 * DistLODCLass::Get_Num_Sub_Objects -- returns the number of subobjects (levels of detail) *
556 * *
557 * INPUT: *
558 * *
559 * OUTPUT: *
560 * *
561 * WARNINGS: *
562 * *
563 * HISTORY: *
564 * 3/1/99 GTH : Created. *
565 *=============================================================================================*/
567{
568 return LodCount;
569}
570
571
572/***********************************************************************************************
573 * DistLODClass::Get_Sub_Object -- returns pointer to the specified sub-object (LOD) *
574 * *
575 * INPUT: *
576 * *
577 * OUTPUT: *
578 * *
579 * WARNINGS: *
580 * *
581 * HISTORY: *
582 * 3/1/99 GTH : Created. *
583 *=============================================================================================*/
585{
586 assert(index >= 0);
587 assert(index < LodCount);
588
589 if (Lods[index].Model == NULL) {
590 return NULL;
591 } else {
592 Lods[index].Model->Add_Ref();
593 return Lods[index].Model;
594 }
595}
596
598{
599 // NOTE: this is broken code, a render object cannot have two containers...
600 if (subobj->Class_ID() == CLASSID_DISTLOD) {
601 // Add each lod of the sub object to a cooresponding model of mine
602 DistLODClass * sub_lod_obj = (DistLODClass *)subobj;
603 for (int i=0; i< LodCount; i++) {
604 Lods[i].Model->Add_Sub_Object_To_Bone( sub_lod_obj->Lods[ MIN( i, sub_lod_obj->LodCount-1 ) ].Model, bone_index);
605 }
606 } else {
607 Lods[0].Model->Add_Sub_Object_To_Bone( subobj, bone_index);
608 }
609 return 0;
610}
611
612
613/***********************************************************************************************
614 * DistLODCLass::Set_Transform -- sets the transform for this model *
615 * *
616 * sets the transform in all LODs. *
617 * *
618 * INPUT: *
619 * *
620 * OUTPUT: *
621 * *
622 * WARNINGS: *
623 * *
624 * HISTORY: *
625 * 3/3/99 GTH : Created. *
626 *=============================================================================================*/
628{
630 for (int i=0; i<LodCount; i++) {
631 assert(Lods[i].Model != NULL);
632 Lods[i].Model->Set_Transform(m);
633 }
634}
635
636
637/***********************************************************************************************
638 * DistLODClass::Set_Position -- set the position of this object *
639 * *
640 * sets the position of all lods *
641 * *
642 * INPUT: *
643 * *
644 * OUTPUT: *
645 * *
646 * WARNINGS: *
647 * *
648 * HISTORY: *
649 * 3/3/99 GTH : Created. *
650 *=============================================================================================*/
652{
654 for (int i=0; i<LodCount; i++) {
655 assert(Lods[i].Model != NULL);
656 Lods[i].Model->Set_Position(v);
657 }
658}
659
660
661/***********************************************************************************************
662 * DistLODClass::Set_Animation -- set the animation state of this model *
663 * *
664 * INPUT: *
665 * *
666 * OUTPUT: *
667 * *
668 * WARNINGS: *
669 * *
670 * HISTORY: *
671 * 3/3/99 GTH : Created. *
672 *=============================================================================================*/
674{
675 for (int i=0; i<LodCount; i++) {
676 assert(Lods[i].Model != NULL);
677 Lods[i].Model->Set_Animation();
678 }
679}
680
681
682/***********************************************************************************************
683 * DistLODClass::Set_Animation -- set the animation state of this model *
684 * *
685 * INPUT: *
686 * *
687 * OUTPUT: *
688 * *
689 * WARNINGS: *
690 * *
691 * HISTORY: *
692 * 3/3/99 GTH : Created. *
693 *=============================================================================================*/
694void DistLODClass::Set_Animation( HAnimClass * motion,float frame,int mode)
695{
696 for (int i=0; i<LodCount; i++) {
697 assert(Lods[i].Model != NULL);
698 Lods[i].Model->Set_Animation(motion,frame,mode);
699 }
700}
701
702
703/***********************************************************************************************
704 * DistLODClass::Set_Animation -- set the animation state to a blend of two anims *
705 * *
706 * INPUT: *
707 * *
708 * OUTPUT: *
709 * *
710 * WARNINGS: *
711 * *
712 * HISTORY: *
713 * 3/3/99 GTH : Created. *
714 *=============================================================================================*/
715void DistLODClass::Set_Animation( HAnimClass * motion0,float frame0,HAnimClass * motion1,float frame1,float percentage)
716{
717 for (int i=0; i<LodCount; i++) {
718 assert(Lods[i].Model != NULL);
719 Lods[i].Model->Set_Animation(motion0,frame0,motion1,frame1,percentage);
720 }
721}
722
723
724/***********************************************************************************************
725 * DistLODClass::Set_Animation -- set the animation state to a combination of anims *
726 * *
727 * INPUT: *
728 * *
729 * OUTPUT: *
730 * *
731 * WARNINGS: *
732 * *
733 * HISTORY: *
734 * 3/3/99 GTH : Created. *
735 *=============================================================================================*/
737{
738 for (int i=0; i<LodCount; i++) {
739 assert(Lods[i].Model != NULL);
740 Lods[i].Model->Set_Animation( anim_combo);
741 }
742}
743
744
745/***********************************************************************************************
746 * DistLODClass::Peek_Animation *
747 * *
748 * INPUT: *
749 * *
750 * OUTPUT: *
751 * *
752 * WARNINGS: *
753 * *
754 * HISTORY: *
755 * 12/8/98 GTH : Created. *
756 *=============================================================================================*/
758{
759 return Lods[0].Model->Peek_Animation();
760}
761
762
763/***********************************************************************************************
764 * DistLODClass::Get_Num_Bones -- returns the number of bones *
765 * *
766 * INPUT: *
767 * *
768 * OUTPUT: *
769 * *
770 * WARNINGS: *
771 * *
772 * HISTORY: *
773 * 3/3/99 GTH : Created. *
774 *=============================================================================================*/
776{
777 return Lods[0].Model->Get_Num_Bones();
778}
779
780
781/***********************************************************************************************
782 * DistLODClass::Get_Bone_Name -- returns the name of the specified bone *
783 * *
784 * INPUT: *
785 * *
786 * OUTPUT: *
787 * *
788 * WARNINGS: *
789 * *
790 * HISTORY: *
791 * 3/3/99 GTH : Created. *
792 *=============================================================================================*/
793const char * DistLODClass::Get_Bone_Name(int bone_index)
794{
795 return Lods[0].Model->Get_Bone_Name(bone_index);
796}
797
798
799/***********************************************************************************************
800 * DistLODClass::Get_Bone_Index -- returns the index of the given bone (if found) *
801 * *
802 * INPUT: *
803 * *
804 * OUTPUT: *
805 * *
806 * WARNINGS: *
807 * *
808 * HISTORY: *
809 * 3/3/99 GTH : Created. *
810 *=============================================================================================*/
811int DistLODClass::Get_Bone_Index(const char * bonename)
812{
813 // Highest LOD is used since lowest may be a Null3DObjClass.
814 return Lods[0].Model->Get_Bone_Index(bonename);
815}
816
817
818/***********************************************************************************************
819 * DistLODClass::Get_Bone_Transform -- returns the transform of the given bone *
820 * *
821 * INPUT: *
822 * *
823 * OUTPUT: *
824 * *
825 * WARNINGS: *
826 * *
827 * HISTORY: *
828 * 3/3/99 GTH : Created. *
829 *=============================================================================================*/
830const Matrix3D & DistLODClass::Get_Bone_Transform(const char * bonename)
831{
832 // Highest LOD is used since lowest may be a Null3DObjClass.
833 return Lods[0].Model->Get_Bone_Transform(bonename);
834}
835
836
837/***********************************************************************************************
838 * DistLODClass::Get_Bone_Transform -- returns the transform of the given bone *
839 * *
840 * INPUT: *
841 * *
842 * OUTPUT: *
843 * *
844 * WARNINGS: *
845 * *
846 * HISTORY: *
847 * 3/3/99 GTH : Created. *
848 *=============================================================================================*/
850{
851 // Highest LOD is used since lowest may be a Null3DObjClass.
852 return Lods[0].Model->Get_Bone_Transform(boneindex);
853}
854
855
856/***********************************************************************************************
857 * DistLODClass::Capture_Bone -- take control of a bone *
858 * *
859 * INPUT: *
860 * *
861 * OUTPUT: *
862 * *
863 * WARNINGS: *
864 * *
865 * HISTORY: *
866 * 3/3/99 GTH : Created. *
867 *=============================================================================================*/
869{
870 for (int i=0; i<LodCount; i++) {
871 assert(Lods[i].Model != NULL);
872 Lods[i].Model->Capture_Bone(bindex);
873 }
874}
875
876
877/***********************************************************************************************
878 * DistLODClass::Release_Bone -- release control of a bone *
879 * *
880 * INPUT: *
881 * *
882 * OUTPUT: *
883 * *
884 * WARNINGS: *
885 * *
886 * HISTORY: *
887 * 3/3/99 GTH : Created. *
888 *=============================================================================================*/
890{
891 for (int i=0; i<LodCount; i++) {
892 assert(Lods[i].Model != NULL);
893 Lods[i].Model->Release_Bone(bindex);
894 }
895}
896
897
898/***********************************************************************************************
899 * DistLODClass::Is_Bone_Captured -- check whether the given bone is captured *
900 * *
901 * INPUT: *
902 * *
903 * OUTPUT: *
904 * *
905 * WARNINGS: *
906 * *
907 * HISTORY: *
908 * 3/3/99 GTH : Created. *
909 *=============================================================================================*/
910bool DistLODClass::Is_Bone_Captured(int bindex) const
911{
912 // Highest LOD is used since lowest may be a Null3DObjClass.
913 return Lods[0].Model->Is_Bone_Captured(bindex);
914}
915
916
917/***********************************************************************************************
918 * DistLODClass::Control_Bone -- set the transform for a captured bone *
919 * *
920 * INPUT: *
921 * *
922 * OUTPUT: *
923 * *
924 * WARNINGS: *
925 * *
926 * HISTORY: *
927 * 3/3/99 GTH : Created. *
928 *=============================================================================================*/
929void DistLODClass::Control_Bone(int bindex,const Matrix3D & tm,bool world_space_translation)
930{
931 for (int i=0; i<LodCount; i++) {
932 assert(Lods[i].Model != NULL);
933 Lods[i].Model->Control_Bone(bindex,tm,world_space_translation);
934 }
935}
936
937/***********************************************************************************************
938 * DistLODClass::Cast_Ray -- cast a ray against this model *
939 * *
940 * casts the ray against the top-level LOD *
941 * *
942 * INPUT: *
943 * *
944 * OUTPUT: *
945 * *
946 * WARNINGS: *
947 * *
948 * HISTORY: *
949 * 3/3/99 GTH : Created. *
950 *=============================================================================================*/
952{
953 if (raytest.CollisionType & Get_Collision_Type()) {
954 return Lods[HIGHEST_LOD].Model->Cast_Ray(raytest);
955 } else {
956 return false;
957 }
958}
959
960
961/***********************************************************************************************
962 * DistLODClass::Cast_AABox -- perform an AABox cast against this model *
963 * *
964 * tests against the top-level LOD *
965 * *
966 * INPUT: *
967 * *
968 * OUTPUT: *
969 * *
970 * WARNINGS: *
971 * *
972 * HISTORY: *
973 * 3/3/99 GTH : Created. *
974 *=============================================================================================*/
976{
977 if (boxtest.CollisionType & Get_Collision_Type()) {
978 return Lods[HIGHEST_LOD].Model->Cast_AABox(boxtest);
979 } else {
980 return false;
981 }
982}
983
984
985/***********************************************************************************************
986 * DistLODClass::Cast_OBBox -- perform an OBBox cast against this model *
987 * *
988 * INPUT: *
989 * *
990 * OUTPUT: *
991 * *
992 * WARNINGS: *
993 * *
994 * HISTORY: *
995 * 3/1/99 GTH : Created. *
996 *=============================================================================================*/
998{
999 if (boxtest.CollisionType & Get_Collision_Type()) {
1000 return Lods[HIGHEST_LOD].Model->Cast_OBBox(boxtest);
1001 } else {
1002 return false;
1003 }
1004}
1005
1006
1007/***********************************************************************************************
1008 * DistLODCLass::Get_Num_Snap_Points -- returns number of snap points in this model *
1009 * *
1010 * INPUT: *
1011 * *
1012 * OUTPUT: *
1013 * *
1014 * WARNINGS: *
1015 * *
1016 * HISTORY: *
1017 * 3/1/99 GTH : Created. *
1018 *=============================================================================================*/
1020{
1021 return Lods[0].Model->Get_Num_Snap_Points();
1022}
1023
1024
1025/***********************************************************************************************
1026 * DistLODClass::Get_Snap_Point -- returns the i'th snap point *
1027 * *
1028 * INPUT: *
1029 * *
1030 * OUTPUT: *
1031 * *
1032 * WARNINGS: *
1033 * *
1034 * HISTORY: *
1035 * 3/1/99 GTH : Created. *
1036 *=============================================================================================*/
1038{
1039 Lods[0].Model->Get_Snap_Point(index,set);
1040}
1041
1042
1043/***********************************************************************************************
1044 * DistLODCLass::Scale -- scale this model; passes on to each LOD *
1045 * *
1046 * INPUT: *
1047 * *
1048 * OUTPUT: *
1049 * *
1050 * WARNINGS: *
1051 * *
1052 * HISTORY: *
1053 * 3/1/99 GTH : Created. *
1054 *=============================================================================================*/
1056{
1057 for (int i=0; i<LodCount; i++) {
1058 assert(Lods[CurLod].Model != NULL);
1059 Lods[CurLod].Model->Scale(scale);
1060 }
1061}
1062
1063
1064/***********************************************************************************************
1065 * DistLODClass::Scale -- scale this model; passes on to each LOD *
1066 * *
1067 * INPUT: *
1068 * *
1069 * OUTPUT: *
1070 * *
1071 * WARNINGS: *
1072 * *
1073 * HISTORY: *
1074 * 3/1/99 GTH : Created. *
1075 *=============================================================================================*/
1076void DistLODClass::Scale(float scalex, float scaley, float scalez)
1077{
1078 for (int i=0; i<LodCount; i++) {
1079 assert(Lods[i].Model != NULL);
1080 Lods[i].Model->Scale(scalex,scaley,scalez);
1081 }
1082}
1083
1084
1085/***********************************************************************************************
1086 * DistLODClass::Update_LOD -- adjusts the current LOD based on the distance *
1087 * *
1088 * INPUT: *
1089 * *
1090 * OUTPUT: *
1091 * *
1092 * WARNINGS: *
1093 * *
1094 * HISTORY: *
1095 * 3/1/99 GTH : Created. *
1096 *=============================================================================================*/
1097void DistLODClass::Update_Lod(const CameraClass & camera)
1098{
1099 // evaluate the distance from the camera and select an LOD based on it.
1100 float dist = (
1101 camera.Get_Position() -
1102 Lods[CurLod].Model->Get_Bounding_Sphere().Center
1103 ).Quick_Length();
1104
1105 if (dist < Lods[CurLod].ResUpDist) {
1106 Increment_Lod();
1107 } else if (dist > Lods[CurLod].ResDownDist) {
1108 Decrement_Lod();
1109 }
1110}
1111
1112
1113/***********************************************************************************************
1114 * DistLODClass::Increment_Lod -- moves to a higher detail LOD *
1115 * *
1116 * INPUT: *
1117 * *
1118 * OUTPUT: *
1119 * *
1120 * WARNINGS: *
1121 * *
1122 * HISTORY: *
1123 * 3/1/99 GTH : Created. *
1124 *=============================================================================================*/
1125void DistLODClass::Increment_Lod(void)
1126{
1127 // TODO: change the order in which models are stored
1128 if (CurLod > 0) {
1129 if (Is_In_Scene()) {
1130 Lods[CurLod].Model->Notify_Removed(Scene);
1131 }
1132 CurLod--;
1133 if (Is_In_Scene()) {
1134 Lods[CurLod].Model->Notify_Added(Scene);
1135 }
1136 }
1137}
1138
1139
1140/***********************************************************************************************
1141 * DistLODClass::Decrement_Lod -- moves to a lower detail LOD *
1142 * *
1143 * INPUT: *
1144 * *
1145 * OUTPUT: *
1146 * *
1147 * WARNINGS: *
1148 * *
1149 * HISTORY: *
1150 * 3/1/99 GTH : Created. *
1151 *=============================================================================================*/
1152void DistLODClass::Decrement_Lod(void)
1153{
1154 if (CurLod < LodCount - 1) {
1155 if (Is_In_Scene()) {
1156 Lods[CurLod].Model->Notify_Removed(Scene);
1157 }
1158 CurLod++;
1159 if (Is_In_Scene()) {
1160 Lods[CurLod].Model->Notify_Added(Scene);
1161 }
1162 }
1163}
1164
1165
#define NULL
Definition BaseType.h:92
Color scale(const Color &a, const Color &b)
Definition GameMtl.cpp:722
#define WWASSERT
@ W3D_CHUNK_LODMODEL_HEADER
Definition w3d_file.h:427
@ W3D_CHUNK_LOD
Definition w3d_file.h:428
#define W3DNEWARRAY
Definition always.h:110
#define MIN(a, b)
Definition always.h:189
#define W3DNEW
Definition always.h:109
bool Close_Chunk()
Definition chunkio.cpp:448
uint32 Cur_Chunk_ID()
Definition chunkio.cpp:484
uint32 Read(void *buf, uint32 nbytes)
Definition chunkio.cpp:692
bool Open_Chunk()
Definition chunkio.cpp:412
virtual const char * Get_Name(void) const
virtual void Set_Name(const char *name)
virtual void Update_Obj_Space_Bounding_Volumes(void)
virtual int Get_Bone_Index(const char *bonename)
Definition distlod.cpp:811
virtual const char * Get_Bone_Name(int bone_index)
Definition distlod.cpp:793
virtual int Get_Num_Polys(void) const
Definition distlod.cpp:506
virtual void Capture_Bone(int bindex)
Definition distlod.cpp:868
virtual void Render(RenderInfoClass &rinfo)
Definition distlod.cpp:524
virtual bool Is_Bone_Captured(int bindex) const
Definition distlod.cpp:910
virtual void Control_Bone(int bindex, const Matrix3D &tm, bool world_space_translation=false)
Definition distlod.cpp:929
virtual RenderObjClass * Get_Sub_Object(int index) const
Definition distlod.cpp:584
virtual ~DistLODClass(void)
Definition distlod.cpp:457
virtual bool Cast_AABox(AABoxCollisionTestClass &boxtest)
Definition distlod.cpp:975
DistLODClass(const DistLODDefClass &desc)
Definition distlod.cpp:389
virtual void Get_Snap_Point(int index, Vector3 *set)
Definition distlod.cpp:1037
virtual HAnimClass * Peek_Animation(void)
Definition distlod.cpp:757
virtual void Set_Transform(const Matrix3D &m)
Definition distlod.cpp:627
virtual int Get_Num_Snap_Points(void)
Definition distlod.cpp:1019
virtual bool Cast_Ray(RayCollisionTestClass &raytest)
Definition distlod.cpp:951
virtual int Get_Num_Bones(void)
Definition distlod.cpp:775
virtual const Matrix3D & Get_Bone_Transform(const char *bonename)
Definition distlod.cpp:830
virtual int Get_Num_Sub_Objects(void) const
Definition distlod.cpp:566
virtual void Set_Position(const Vector3 &v)
Definition distlod.cpp:651
virtual int Add_Sub_Object_To_Bone(RenderObjClass *subobj, int bone_index)
Definition distlod.cpp:597
virtual bool Cast_OBBox(OBBoxCollisionTestClass &boxtest)
Definition distlod.cpp:997
virtual void Special_Render(SpecialRenderInfoClass &rinfo)
Definition distlod.cpp:547
virtual void Scale(float scale)
Definition distlod.cpp:1055
virtual void Set_Animation(void)
Definition distlod.cpp:673
virtual void Release_Bone(int bindex)
Definition distlod.cpp:889
const char * Get_Name(void) const
Definition distlod.h:204
DistLODDefClass(void)
Definition distlod.cpp:170
~DistLODDefClass(void)
Definition distlod.cpp:224
WW3DErrorType Load_W3D(ChunkLoadClass &cload)
Definition distlod.cpp:273
virtual PrototypeClass * Load_W3D(ChunkLoadClass &cload)
Definition distlod.cpp:133
virtual RenderObjClass * Create(void)
Definition distlod.cpp:99
WWINLINE void Release_Ref(void) const
Definition refcount.h:146
CameraClass & Camera
Definition rinfo.h:100
Vector3 Get_Position(void) const
Definition rendobj.cpp:508
virtual void Set_Transform(const Matrix3D &m)
Definition rendobj.cpp:423
virtual int Is_Not_Hidden_At_All(void)
Definition rendobj.h:463
RenderObjClass(void)
Definition rendobj.cpp:170
virtual void Set_Position(const Vector3 &v)
Definition rendobj.cpp:444
virtual void Update_Sub_Object_Bits(void)
Definition rendobj.cpp:730
SceneClass * Scene
Definition rendobj.h:557
virtual int Class_ID(void) const
Definition rendobj.h:249
virtual RenderObjClass * Clone(void) const =0
virtual bool Is_In_Scene(void)
Definition rendobj.h:487
virtual void Set_Container(RenderObjClass *con)
Definition rendobj.cpp:382
virtual int Get_Collision_Type(void) const
Definition rendobj.h:484
virtual RenderObjClass * Create_Render_Obj(const char *name)
Definition assetmgr.cpp:799
static WW3DAssetManager * Get_Instance(void)
Definition assetmgr.h:205
DistLODLoaderClass _DistLODLoader
Definition distlod.cpp:96
char * nstrdup(const char *str)
Definition nstrdup.cpp:56
#define NEW_REF(C, P)
Definition refcount.h:62
char Name[W3D_NAME_LEN]
Definition w3d_file.h:1609
float32 LODMax
Definition w3d_file.h:1617
float32 LODMin
Definition w3d_file.h:1616
char RenderObjName[2 *W3D_NAME_LEN]
Definition w3d_file.h:1615
WW3DErrorType
Definition w3derr.h:51
@ WW3D_ERROR_LOAD_FAILED
Definition w3derr.h:54
@ WW3D_ERROR_OK
Definition w3derr.h:52
#define WWDEBUG_SAY(x)
Definition wwdebug.h:114