Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
hlod.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:: /VSS_Sync/ww3d2/hlod.cpp $*
26 * *
27 * Author:: Greg Hjelstrom *
28 * *
29 * $Modtime:: 8/29/01 7:29p $*
30 * *
31 * $Revision:: 10 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * HLodLoaderClass::Load_W3D -- Loads an HlodDef from a W3D file *
36 * HLodPrototypeClass::Create -- Creates an HLod from an HLodDef *
37 * HLodDefClass::HLodDefClass -- Constructor *
38 * HLodDefClass::HLodDefClass -- Copy Constructor *
39 * HLodDefClass::~HLodDefClass -- Destructor *
40 * HLodDefClass::Free -- releases all resources being used *
41 * HLodDefClass::Initialize -- init this def from an HLod *
42 * HLodDefClass::Save -- save this HLodDef *
43 * HLodDefClass::Save_Header -- writes the HLodDef header *
44 * HLodDefClass::Save_Lod_Array -- Saves the lod array *
45 * HLodDefClass::Save_Aggregate_Array -- Save the array of aggregate models *
46 * HLodDefClass::Load_W3D -- Loads this HLodDef from a W3d File *
47 * HLodDefClass::read_header -- loads the HLodDef header from a W3d file *
48 * HLodDefClass::read_proxy_array -- load the proxy names *
49 * HLodDefClass::SubObjectArrayClass::SubObjectArrayClass -- LodArray constructor *
50 * HLodDefClass::SubObjectArrayClass::~SubObjectArrayClass -- LodArray destructor *
51 * HLodDefClass::SubObjectArrayClass::Save_W3D -- saves a w3d file for this HLodDef *
52 * HLodDefClass::SubObjectArrayClass::Load_W3D -- LodArray load function *
53 * HLodDefClass::SubObjectArrayClass::Reset -- release the contents of this array *
54 * HLodClass::HLodClass -- Constructor *
55 * HLodClass::HLodClass -- copy constructor *
56 * HLodClass::HLodClass -- Constructor *
57 * HLodClass::HLodClass -- Constructs an HLod from an HLodDef *
58 * HLodClass::HLodClass -- Constructs an HLod from an HModelDef *
59 * HLodClass::operator -- assignment operator *
60 * HLodClass::~HLodClass -- Destructor *
61 * HLodClass::Free -- releases all resources *
62 * HLodClass::Clone -- virtual copy constructor *
63 * HLodClass::Set_Max_Screen_Size -- Set max-screen-size for an LOD *
64 * HLodClass::Get_Max_Screen_Size -- get max-screen-size for an LOD *
65 * HLodClass::Get_Lod_Count -- returns number of levels of detail *
66 * HLodClass::Get_Lod_Model_Count -- number of sub-objs in a given level of detail *
67 * HLodClass::Peek_Lod_Model -- returns pointer to a model in one of the LODs *
68 * HLodClass::Get_Lod_Model -- returns a pointer to a model in one of the LODs *
69 * HLodClass::Get_Lod_Model_Bone -- returns the bone index of a model *
70 * HLodClass::Get_Additional_Model_Count -- number of additional sub-objs *
71 * HLodClass::Peek_Additional_Model -- returns pointer to an additional model *
72 * HLodClass::Get_Additional_Model -- returns pointer to an additional model *
73 * HLodClass::Get_Additional_Model_Bone -- returns the bone index of an additional model *
74 * HLodClass::Is_NULL_Lod_Included -- does this HLod have NULL as its lowest LOD *
75 * HLodClass::Include_NULL_Lod -- Add NULL as the lowest LOD *
76 * HLodClass::Get_Num_Polys -- returns polycount of the current LOD *
77 * HLodClass::Render -- render this HLod *
78 * HLodClass::Special_Render -- Special_Render for HLod *
79 * HLodClass::Set_Transform -- Sets the transform *
80 * HLodClass::Set_Position -- Sets the position *
81 * HLodClass::Notify_Added -- callback notifies subobjs that they were added *
82 * HLodClass::Notify_Removed -- notifies subobjs that they were removed *
83 * HLodClass::Get_Num_Sub_Objects -- returns total number of sub-objects *
84 * HLodClass::Get_Sub_Object -- returns a pointer to specified sub-object *
85 * HLodClass::Add_Sub_Object -- add a sub-object to this HLod *
86 * HLodClass::Remove_Sub_Object -- remove a sub-object from this HLod *
87 * HLodClass::Get_Num_Sub_Objects_On_Bone -- returns the number of objects on the given bone *
88 * HLodClass::Get_Sub_Object_On_Bone -- returns obj on the given bone *
89 * HLodClass::Get_Sub_Object_Bone_Index -- returns bone index of given object *
90 * HLodClass::Add_Sub_Object_To_Bone -- adds a sub-object to a bone *
91 * HLodClass::Set_Animation -- set animation state to the base-pose *
92 * HLodClass::Set_Animation -- set animation state to an animation frame *
93 * HLodClass::Set_Animation -- set animation state to a blend of two animations *
94 * HLodClass::Set_Animation -- set animation state to a combination of anims *
95 * HLodClass::Cast_Ray -- cast a ray against this HLod *
96 * HLodClass::Cast_AABox -- Cast a swept AABox against this HLod *
97 * HLodClass::Cast_OBBox -- Cast a swept OBBox against this HLod *
98 * HLodClass::Intersect_AABox -- Intersect an AABox with this HLod *
99 * HLodClass::Intersect_OBBox -- Intersect an OBBox with this HLod *
100 * HLodClass::Prepare_LOD -- Prepare for LOD processing *
101 * HLodClass::Recalculate_Static_LOD_Factors -- compute lod factors *
102 * HLodClass::Increment_LOD -- move to next lod *
103 * HLodClass::Decrement_LOD -- move to previous lod *
104 * HLodClass::Get_Cost -- returns the cost of this LOD *
105 * HLodClass::Get_Value -- returns the value of this LOD *
106 * HLodClass::Get_Post_Increment_Value -- returns the post increment value *
107 * HLodClass::Set_LOD_Level -- set the current lod level *
108 * HLodClass::Get_LOD_Level -- returns the current LOD level *
109 * HLodClass::Get_LOD_Count -- returns the number of levels of detail *
110 * HLodClass::Calculate_Cost_Value_Arrays -- computes the cost-value arrays *
111 * HLodClass::Get_Current_LOD -- returns a render object which represents the current LOD *
112 * HLodClass::Set_Texture_Reduction_Factor -- resizeable texture support *
113 * HLodClass::Scale -- scale this HLod model *
114 * HLodClass::Get_Num_Snap_Points -- returns the number of snap points in this model *
115 * HLodClass::Get_Snap_Point -- returns specified snap-point *
116 * HLodClass::Update_Sub_Object_Transforms -- updates transforms of all sub-objects *
117 * HLodClass::Update_Obj_Space_Bounding_Volumes -- update object-space bounding volumes *
118 * HLodClass::Add_Lod_Model -- adds a model to one of the lods *
119 * HLodClass::Create_Decal -- create a decal on this HLod *
120 * HLodClass::Delete_Decal -- remove a decal from this HLod *
121 * HLodClass::Set_HTree -- replace the hierarchy tree *
122 * HLodClass::Get_Proxy_Count -- Returns the number of proxy objects *
123 * HLodClass::Get_Proxy -- returns the information for the i'th proxy *
124 * HLodClass::Set_Hidden -- Propogates the hidden bit to particle emitters. *
125 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
126
127
128
129#include "hlod.h"
130#include "assetmgr.h"
131#include "hmdldef.h"
132#include "w3derr.h"
133#include "chunkio.h"
134#include "predlod.h"
135#include "rinfo.h"
136#include <string.h>
137#include <win.h>
138#include "sphere.h"
139#include "boxrobj.h"
140
141
142/*
143** Loader Instance
144*/
146
147
155{
156public:
158 {
159 memset(Name,0,sizeof(Name));
160 }
161
162 bool operator == (const ProxyRecordClass & that) { return false; }
163 bool operator != (const ProxyRecordClass & that) { return !(*this == that); }
164
165 void Init(const W3dHLodSubObjectStruct & w3d_data)
166 {
167 BoneIndex = w3d_data.BoneIndex;
168 strncpy(Name,w3d_data.Name,sizeof(Name));
169 }
170
171 int Get_Bone_Index(void) { return BoneIndex; }
172 const char * Get_Name(void) { return Name; }
173
174protected:
175
178
179};
180
186class ProxyArrayClass : public W3DMPO, public VectorClass<ProxyRecordClass>, public RefCountClass
187{
189public:
191 {
192 }
193};
194
195
196
197/*
198** The HLod Loader Implementation
199*/
200
201/***********************************************************************************************
202 * HLodLoaderClass::Load_W3D -- Loads an HlodDef from a W3D file *
203 * *
204 * INPUT: *
205 * *
206 * OUTPUT: *
207 * *
208 * WARNINGS: *
209 * *
210 * HISTORY: *
211 * 1/26/00 gth : Created. *
212 *=============================================================================================*/
214{
216
217 if (def == NULL)
218 {
219 return NULL;
220 }
221
222 if (def->Load_W3D(cload) != WW3D_ERROR_OK) {
223 // load failed, delete the model and return an error
224 delete def;
225 return NULL;
226 } else {
227 // ok, accept this model!
229 return proto;
230 }
231 return NULL;
232}
233
234
235/*
236** HLod Prototype Implementation
237*/
238
239/***********************************************************************************************
240 * HLodPrototypeClass::Create -- Creates an HLod from an HLodDef *
241 * *
242 * INPUT: *
243 * *
244 * OUTPUT: *
245 * *
246 * WARNINGS: *
247 * *
248 * HISTORY: *
249 * 1/26/00 gth : Created. *
250 *=============================================================================================*/
252{
253 HLodClass * hlod = NEW_REF( HLodClass , ( *Definition ) );
254 return hlod;
255}
256
257
258/*
259** HLodDef Implementation
260*/
261
262/***********************************************************************************************
263 * HLodDefClass::HLodDefClass -- Constructor *
264 * *
265 * INPUT: *
266 * *
267 * OUTPUT: *
268 * *
269 * WARNINGS: *
270 * *
271 * HISTORY: *
272 *=============================================================================================*/
274 Name(NULL),
275 HierarchyTreeName(NULL),
276 LodCount(0),
277 Lod(NULL),
278 ProxyArray(NULL)
279{
280}
281
282
283/***********************************************************************************************
284 * HLodDefClass::HLodDefClass -- Copy Constructor *
285 * *
286 * INPUT: *
287 * *
288 * OUTPUT: *
289 * *
290 * WARNINGS: *
291 * *
292 * HISTORY: *
293 * 1/26/00 gth : Created. *
294 *=============================================================================================*/
296 Name(NULL),
297 HierarchyTreeName(NULL),
298 LodCount(0),
299 Lod(NULL),
300 ProxyArray(NULL)
301{
302 Initialize (src_lod);
303 return ;
304}
305
306
307/***********************************************************************************************
308 * HLodDefClass::~HLodDefClass -- Destructor *
309 * *
310 * INPUT: *
311 * *
312 * OUTPUT: *
313 * *
314 * WARNINGS: *
315 * *
316 * HISTORY: *
317 * 1/26/00 gth : Created. *
318 *=============================================================================================*/
320{
321 Free ();
322 return ;
323}
324
325
326/***********************************************************************************************
327 * HLodDefClass::Free -- releases all resources being used *
328 * *
329 * INPUT: *
330 * *
331 * OUTPUT: *
332 * *
333 * WARNINGS: *
334 * *
335 * HISTORY: *
336 * 1/26/00 gth : Created. *
337 *=============================================================================================*/
338void HLodDefClass::Free(void)
339{
340 if (Name) {
341 ::free(Name);
342 Name = NULL;
343 }
344
345 if (HierarchyTreeName) {
346 ::free(HierarchyTreeName);
347 HierarchyTreeName = NULL;
348 }
349
350 if (Lod) {
351 delete[] Lod;
352 Lod = NULL;
353 }
354 LodCount = 0;
355
356 REF_PTR_RELEASE(ProxyArray);
357
358 return ;
359}
360
361
362/***********************************************************************************************
363 * HLodDefClass::Initialize -- init this def from an HLod *
364 * *
365 * INPUT: *
366 * *
367 * OUTPUT: *
368 * *
369 * WARNINGS: *
370 * *
371 * HISTORY: *
372 * 1/26/00 gth : Created. *
373 *=============================================================================================*/
375{
376 // Start with a fresh set of data
377 Free ();
378
379 // Copy the name and hierarcy name from the source object
380 Name = ::strdup (src_lod.Get_Name ());
381 const HTreeClass *phtree = src_lod.Get_HTree ();
382 if (phtree != NULL) {
383 HierarchyTreeName = ::strdup (phtree->Get_Name ());
384 }
385
386 // Determine the number of LODs in the src object
387 LodCount = src_lod.Get_LOD_Count ();
388 WWASSERT (LodCount > 0);
389 if (LodCount > 0) {
390
391 // Allocate an array large enough to hold all the LODs and
392 // loop through each LOD.
393 Lod = W3DNEWARRAY SubObjectArrayClass[LodCount];
394 for (int index = 0; index < LodCount; index ++) {
395
396 // Fill in the maximum screen size for this LOD
397 Lod[index].MaxScreenSize = src_lod.Get_Max_Screen_Size (index);
398 Lod[index].ModelCount = src_lod.Get_Lod_Model_Count (index);
399
400 // Loop through all the models that compose this LOD and generate a
401 // list of model's and the bones they live on
402 char **model_names = W3DNEWARRAY char *[Lod[index].ModelCount];
403 int *bone_indicies = W3DNEWARRAY int[Lod[index].ModelCount];
404 for (int model_index = 0; model_index < Lod[index].ModelCount; model_index ++) {
405
406 // Record information about this model (if possible)
407 RenderObjClass *prender_obj = src_lod.Peek_Lod_Model (index, model_index);
408 if (prender_obj != NULL) {
409 model_names[model_index] = ::strdup (prender_obj->Get_Name ());
410 bone_indicies[model_index] = src_lod.Get_Lod_Model_Bone (index, model_index);
411 } else {
412 model_names[model_index] = NULL;
413 bone_indicies[model_index] = 0;
414 }
415 }
416
417 // Pass these arrays of information onto our internal data
418 Lod[index].ModelName = model_names;
419 Lod[index].BoneIndex = bone_indicies;
420 }
421 }
422
423 return;
424}
425
426
427/***********************************************************************************************
428 * HLodDefClass::Save -- save this HLodDef *
429 * *
430 * INPUT: *
431 * *
432 * OUTPUT: *
433 * *
434 * WARNINGS: *
435 * *
436 * HISTORY: *
437 * 1/26/00 gth : Created. *
438 *=============================================================================================*/
440{
441 // Assume error
443
444 // Begin a chunk that identifies an aggregate
445 if (csave.Begin_Chunk (W3D_CHUNK_HLOD) == TRUE) {
446
447 // Attempt to save the different sections of the aggregate definition
448 if ((Save_Header (csave) == WW3D_ERROR_OK) &&
449 (Save_Lod_Array (csave) == WW3D_ERROR_OK)) {
450
451 // Success!
452 ret_val = WW3D_ERROR_OK;
453 }
454
455 // Close the aggregate chunk
456 csave.End_Chunk ();
457 }
458
459 // Return the WW3DErrorType return code
460 return ret_val;
461}
462
463
464/***********************************************************************************************
465 * HLodDefClass::Save_Header -- writes the HLodDef header *
466 * *
467 * INPUT: *
468 * *
469 * OUTPUT: *
470 * *
471 * WARNINGS: *
472 * *
473 * HISTORY: *
474 * 1/26/00 gth : Created. *
475 *=============================================================================================*/
477{
478 // Assume error
480
481 // Begin a chunk that identifies the aggregate
482 if (csave.Begin_Chunk (W3D_CHUNK_HLOD_HEADER) == TRUE) {
483
484 // Fill the header structure
485 W3dHLodHeaderStruct header = { 0 };
487 header.LodCount = LodCount;
488
489 // Copy the name to the header
490 ::lstrcpyn (header.Name, Name, sizeof (header.Name));
491 header.Name[sizeof (header.Name) - 1] = 0;
492
493 // Copy the hierarchy tree name to the header
494 ::lstrcpyn (header.HierarchyName, HierarchyTreeName, sizeof (header.HierarchyName));
495 header.HierarchyName[sizeof (header.HierarchyName) - 1] = 0;
496
497 // Write the header out to the chunk
498 if (csave.Write (&header, sizeof (header)) == sizeof (header)) {
499
500 // Success!
501 ret_val = WW3D_ERROR_OK;
502 }
503
504 // End the header chunk
505 csave.End_Chunk ();
506 }
507
508 // Return the WW3DErrorType return code
509 return ret_val;
510}
511
512
513/***********************************************************************************************
514 * HLodDefClass::Save_Lod_Array -- Saves the lod array *
515 * *
516 * INPUT: *
517 * *
518 * OUTPUT: *
519 * *
520 * WARNINGS: *
521 * *
522 * HISTORY: *
523 * 1/26/00 gth : Created. *
524 *=============================================================================================*/
526{
527 // Loop through all the LODs and save their model array to the chunk
528 bool success = true;
529 for (int lod_index = 0;
530 (lod_index < LodCount) && success;
531 lod_index ++) {
532 success = Lod[lod_index].Save_W3D (csave);
533 }
534
535 // Return the WW3DErrorType return code
536 return success ? WW3D_ERROR_OK : WW3D_ERROR_SAVE_FAILED;
537}
538
539
540/***********************************************************************************************
541 * HLodDefClass::Save_Aggregate_Array -- Save the array of aggregate models *
542 * *
543 * aggregate models are ones that are attached as "additional" models. *
544 * *
545 * *
546 * INPUT: *
547 * *
548 * OUTPUT: *
549 * *
550 * WARNINGS: *
551 * *
552 * HISTORY: *
553 * 10/25/2000 gth : Created. *
554 *=============================================================================================*/
556{
557 if (Aggregates.ModelCount > 0) {
559 Aggregates.Save_W3D(csave);
560 csave.End_Chunk();
561 }
562 return WW3D_ERROR_OK;
563}
564
565
566/***********************************************************************************************
567 * HLodDefClass::Load_W3D -- Loads this HLodDef from a W3d File *
568 * *
569 * INPUT: *
570 * *
571 * OUTPUT: *
572 * *
573 * WARNINGS: *
574 * *
575 * HISTORY: *
576 * 1/26/00 gth : Created. *
577 *=============================================================================================*/
579{
580 /*
581 ** First make sure we release any memory in use
582 */
583 Free();
584
585 if (read_header(cload) == FALSE) {
587 }
588
589 /*
590 ** Loop through all the LODs and read the info from its chunk
591 */
592 for (int iLOD = 0; iLOD < LodCount; iLOD ++) {
593
594 /*
595 ** Open the next chunk, it should be a LOD struct
596 */
597 if (!cload.Open_Chunk()) return WW3D_ERROR_LOAD_FAILED;
598
599 if (cload.Cur_Chunk_ID() != W3D_CHUNK_HLOD_LOD_ARRAY) {
600 // ERROR: Expected LOD struct!
602 }
603
604 Lod[iLOD].Load_W3D(cload);
605
606 // Close-out the chunk
607 cload.Close_Chunk();
608 }
609
610 /*
611 ** Parse the rest of the chunks
612 */
613 while (cload.Open_Chunk()) {
614 switch(cload.Cur_Chunk_ID())
615 {
617 Aggregates.Load_W3D(cload);
618 break;
620 read_proxy_array(cload);
621 break;
622 }
623 cload.Close_Chunk();
624 }
625
626 return WW3D_ERROR_OK;
627}
628
629
630/***********************************************************************************************
631 * HLodDefClass::read_header -- loads the HLodDef header from a W3d file *
632 * *
633 * INPUT: *
634 * *
635 * OUTPUT: *
636 * *
637 * WARNINGS: *
638 * *
639 * HISTORY: *
640 * 1/26/00 gth : Created. *
641 *=============================================================================================*/
642bool HLodDefClass::read_header(ChunkLoadClass & cload)
643{
644 /*
645 ** Open the first chunk, it should be the LOD header
646 */
647 if (!cload.Open_Chunk()) return false;
648
649 if (cload.Cur_Chunk_ID() != W3D_CHUNK_HLOD_HEADER) {
650 // ERROR: Expected HLOD Header!
651 return false;
652 }
653
654 W3dHLodHeaderStruct header;
655 if (cload.Read(&header,sizeof(header)) != sizeof(header)) {
656 return false;
657 }
658 cload.Close_Chunk();
659
660 // Copy the name into our internal variable
661 Name = ::_strdup(header.Name);
662 HierarchyTreeName = ::strdup(header.HierarchyName);
663 LodCount = header.LodCount;
664 Lod = W3DNEWARRAY SubObjectArrayClass[LodCount];
665 return true;
666}
667
668
669/***********************************************************************************************
670 * HLodDefClass::read_proxy_array -- load the proxy names *
671 * *
672 * This function is coded separately from SubObjectArrayClass::Load because we are going *
673 * to store the proxies in a shared data structure. Because all of the proxy data is *
674 * constant, each instanced HLOD can just add-ref a pointer to its proxy array. *
675 * *
676 * INPUT: *
677 * *
678 * OUTPUT: *
679 * *
680 * WARNINGS: *
681 * *
682 * HISTORY: *
683 * 10/27/2000 gth : Created. *
684 *=============================================================================================*/
685bool HLodDefClass::read_proxy_array(ChunkLoadClass & cload)
686{
687 REF_PTR_RELEASE(ProxyArray);
688
689 /*
690 ** Open the first chunk, it should be a Lod Array Header
691 */
692 if (!cload.Open_Chunk()) return false;
693 if (cload.Cur_Chunk_ID() != W3D_CHUNK_HLOD_SUB_OBJECT_ARRAY_HEADER) return false;
694
695 W3dHLodArrayHeaderStruct header;
696 if (cload.Read(&header,sizeof(header)) != sizeof(header)) return false;
697
698 if (!cload.Close_Chunk()) return false;
699
700 ProxyArray = NEW_REF(ProxyArrayClass,(header.ModelCount));
701
702 /*
703 ** Read each sub object definition
704 */
705 for (int imodel=0; imodel<ProxyArray->Length(); ++imodel) {
706 if (!cload.Open_Chunk()) return false;
707 if (cload.Cur_Chunk_ID() != W3D_CHUNK_HLOD_SUB_OBJECT) return false;
708
709 W3dHLodSubObjectStruct subobjdef;
710 if (cload.Read(&subobjdef,sizeof(subobjdef)) != sizeof(subobjdef)) return false;
711 if (!cload.Close_Chunk()) return false;
712
713 (*ProxyArray)[imodel].Init(subobjdef);
714 }
715 return true;
716}
717
718
719/***********************************************************************************************
720 * HLodDefClass::SubObjectArrayClass::SubObjectArrayClass -- LodArray constructor *
721 * *
722 * INPUT: *
723 * *
724 * OUTPUT: *
725 * *
726 * WARNINGS: *
727 * *
728 * HISTORY: *
729 *=============================================================================================*/
730HLodDefClass::SubObjectArrayClass::SubObjectArrayClass(void) :
731 MaxScreenSize(NO_MAX_SCREEN_SIZE),
732 ModelCount(0),
733 ModelName(NULL),
734 BoneIndex(NULL)
735{
736}
737
738
739/***********************************************************************************************
740 * HLodDefClass::SubObjectArrayClass::~SubObjectArrayClass -- LodArray destructor *
741 * *
742 * INPUT: *
743 * *
744 * OUTPUT: *
745 * *
746 * WARNINGS: *
747 * *
748 * HISTORY: *
749 * 1/26/00 gth : Created. *
750 *=============================================================================================*/
751HLodDefClass::SubObjectArrayClass::~SubObjectArrayClass(void)
752{
753 Reset();
754}
755
756
757/***********************************************************************************************
758 * HLodDefClass::SubObjectArrayClass::Reset -- release the contents of this array *
759 * *
760 * INPUT: *
761 * *
762 * OUTPUT: *
763 * *
764 * WARNINGS: *
765 * *
766 * HISTORY: *
767 * 10/25/2000 gth : Created. *
768 *=============================================================================================*/
769void HLodDefClass::SubObjectArrayClass::Reset(void)
770{
771 MaxScreenSize = NO_MAX_SCREEN_SIZE;
772
773 if (ModelName != NULL) {
774 for (int imodel=0; imodel<ModelCount;imodel++) {
775 free(ModelName[imodel]);
776 }
777 delete[] ModelName;
778 ModelName = NULL;
779 }
780 if (BoneIndex != NULL) {
781 delete[] BoneIndex;
782 BoneIndex = NULL;
783 }
784
785 ModelCount = 0;
786}
787
788
789/***********************************************************************************************
790 * HLodDefClass::SubObjectArrayClass::Load_W3D -- LodArray load function *
791 * *
792 * INPUT: *
793 * *
794 * OUTPUT: *
795 * *
796 * WARNINGS: *
797 * *
798 * HISTORY: *
799 * 1/26/00 gth : Created. *
800 *=============================================================================================*/
801bool HLodDefClass::SubObjectArrayClass::Load_W3D(ChunkLoadClass & cload)
802{
803 /*
804 ** Open the first chunk, it should be a Lod Array Header
805 */
806 if (!cload.Open_Chunk()) return false;
807 if (cload.Cur_Chunk_ID() != W3D_CHUNK_HLOD_SUB_OBJECT_ARRAY_HEADER) return false;
808
809 W3dHLodArrayHeaderStruct header;
810 if (cload.Read(&header,sizeof(header)) != sizeof(header)) return false;
811
812 if (!cload.Close_Chunk()) return false;
813
814 ModelCount = header.ModelCount;
815 MaxScreenSize = header.MaxScreenSize;
816 ModelName = W3DNEWARRAY char * [ModelCount];
817 BoneIndex = W3DNEWARRAY int [ModelCount];
818
819 /*
820 ** Read each sub object definition
821 */
822 for (int imodel=0; imodel<ModelCount; ++imodel) {
823 if (!cload.Open_Chunk()) return false;
824 if (cload.Cur_Chunk_ID() != W3D_CHUNK_HLOD_SUB_OBJECT) return false;
825
826 W3dHLodSubObjectStruct subobjdef;
827 if (cload.Read(&subobjdef,sizeof(subobjdef)) != sizeof(subobjdef)) return false;
828
829 if (!cload.Close_Chunk()) return false;
830
831 ModelName[imodel] = strdup(subobjdef.Name);
832 BoneIndex[imodel] = subobjdef.BoneIndex;
833 }
834 return true;
835}
836
837/***********************************************************************************************
838 * HLodDefClass::SubObjectArrayClass::Save_W3D -- saves a w3d file for this HLodDef *
839 * *
840 * INPUT: *
841 * *
842 * OUTPUT: *
843 * *
844 * WARNINGS: *
845 * *
846 * HISTORY: *
847 * 1/26/00 gth : Created. *
848 *=============================================================================================*/
849bool HLodDefClass::SubObjectArrayClass::Save_W3D(ChunkSaveClass &csave)
850{
851 // Assume error
852 bool ret_val = false;
853
854 // Begin a chunk that identifies the LOD array
856
857 // Begin a chunk that identifies the LOD header
859
860 W3dHLodArrayHeaderStruct header = { 0 };
861 header.ModelCount = ModelCount;
862 header.MaxScreenSize = MaxScreenSize;
863
864 // Write the LOD header structure out to the chunk
865 ret_val = (csave.Write (&header, sizeof (header)) == sizeof (header));
866
867 // End the header chunk
868 csave.End_Chunk ();
869 }
870
871 if (ret_val) {
872
873 // Write all of this LOD's models to the file
874 for (int index = 0;
875 (index < ModelCount) && ret_val;
876 index ++) {
877
878 // Save this LOD sub-obj to the chunk
879 ret_val &= (csave.Begin_Chunk (W3D_CHUNK_HLOD_SUB_OBJECT) == TRUE);
880 if (ret_val) {
881
882 W3dHLodSubObjectStruct info = { 0 };
883 info.BoneIndex = BoneIndex[index];
884
885 // Copy this model name into the structure
886 ::lstrcpyn (info.Name, ModelName[index], sizeof (info.Name));
887 info.Name[sizeof (info.Name) - 1] = 0;
888
889 // Write the LOD sub-obj structure out to the chunk
890 ret_val &= (csave.Write (&info, sizeof (info)) == sizeof (info));
891
892 // End the sub-obj chunk
893 csave.End_Chunk ();
894 }
895 }
896 }
897
898 // End the HLOD-Array chunk
899 csave.End_Chunk ();
900 }
901
902 // Return the true/false result code
903 return ret_val;
904}
905
906
907
908
909/***********************************************************************************************
910 * HLodClass::HLodClass -- Constructor *
911 * *
912 * INPUT: *
913 * *
914 * OUTPUT: *
915 * *
916 * WARNINGS: *
917 * *
918 * HISTORY: *
919 *=============================================================================================*/
922 LodCount(0),
923 CurLod(0),
924 Lod(NULL),
926 Cost(NULL),
927 Value(NULL),
931 LODBias(1.0f)
932{
933}
934
935
936/***********************************************************************************************
937 * HLodClass::HLodClass -- copy constructor *
938 * *
939 * INPUT: *
940 * *
941 * OUTPUT: *
942 * *
943 * WARNINGS: *
944 * *
945 * HISTORY: *
946 * 1/26/00 gth : Created. *
947 *=============================================================================================*/
950 LodCount(0),
951 CurLod(0),
952 Lod(NULL),
954 Cost(NULL),
955 Value(NULL),
959 LODBias(1.0f)
960{
961 *this = src;
962}
963
964
965/***********************************************************************************************
966 * HLodClass::HLodClass -- Constructor *
967 * *
968 * Creates an HLodClass from an array of render objects. Each render object is assumed to *
969 * be an alternate level of detail. *
970 * *
971 * INPUT: *
972 * *
973 * OUTPUT: *
974 * *
975 * WARNINGS: *
976 * *
977 * HISTORY: *
978 * 1/26/00 gth : Created. *
979 *=============================================================================================*/
980HLodClass::HLodClass(const char * name,RenderObjClass ** lods,int count) :
982 LodCount(0),
983 CurLod(0),
984 Lod(NULL),
986 Cost(NULL),
987 Value(NULL),
991 LODBias(1.0f)
992{
993 // enforce parameters
994 WWASSERT(name != NULL);
995 WWASSERT(lods != NULL);
996 WWASSERT((count > 0) && (count < 256));
997
998 // Set the name
999 Set_Name(name);
1000
1001 LodCount = count;
1002 WWASSERT(LodCount >= 1);
1004 WWASSERT(Lod);
1005 Cost = W3DNEWARRAY float[LodCount];
1006 WWASSERT(Cost);
1007 // Value has LodCount + 1 entries so PostIncrementValue can always use
1008 // Value[CurLod + 1] (the last entry wil be AT_MAX_LOD).
1009 Value = W3DNEWARRAY float[LodCount + 1];
1010 WWASSERT(Value);
1011
1012 // Create our HTree from the highest LOD if it is an HModel
1013 // Otherwise, create a single node tree
1014 const HTreeClass * tree = lods[count-1]->Get_HTree();
1015 if (tree != NULL) {
1016 HTree = W3DNEW HTreeClass(*tree);
1017 } else {
1019 HTree->Init_Default();
1020 }
1021
1022 // Ok, now suck the sub-objects out of each LOD model and place them into this HLOD.
1023 for (int lod_index=0; lod_index < LodCount; lod_index++) {
1024 RenderObjClass * lod_obj = lods[lod_index];
1025 WWASSERT(lod_obj);
1026
1027 if ( (lod_obj->Class_ID() == RenderObjClass::CLASSID_HMODEL) ||
1028 (lod_obj->Class_ID() == RenderObjClass::CLASSID_HLOD) ||
1029 (lod_obj->Get_Num_Sub_Objects() > 1) ) {
1030
1031 // here we insert all sub-objects of this render object into the current LOD array
1032 while (lod_obj->Get_Num_Sub_Objects() > 0) {
1033
1034 RenderObjClass * sub_obj = lod_obj->Get_Sub_Object(0);
1035 int boneindex = lod_obj->Get_Sub_Object_Bone_Index(sub_obj);
1036 lod_obj->Remove_Sub_Object(sub_obj);
1037
1038 Add_Lod_Model(lod_index,sub_obj,boneindex);
1039
1040 sub_obj->Release_Ref();
1041 }
1042
1043 } else {
1044
1045 // just insert the render object as the sole member of the current LOD array. This
1046 // case happens if this level of detail is a simple object such as a mesh or NullRenderObj
1047 Add_Lod_Model(lod_index,lod_obj,0);
1048 }
1049 }
1050
1052
1053 // So that the object is ready for use after construction, we will
1054 // complete its initialization by initializing its cost and value arrays
1055 // according to a screen area of 1 pixel.
1056 int minlod = Calculate_Cost_Value_Arrays(1.0f, Value, Cost);
1057
1058 // Ensure lod is no less than minimum allowed
1059 if (CurLod < minlod) Set_LOD_Level(minlod);
1060
1061 // Flag our sub-objects as having dirty transforms
1063
1064 // Normal render object processing whenever sub-objects are added or removed:
1067}
1068
1069
1070/***********************************************************************************************
1071 * HLodClass::HLodClass -- Constructs an HLod from an HLodDef *
1072 * *
1073 * INPUT: *
1074 * *
1075 * OUTPUT: *
1076 * *
1077 * WARNINGS: *
1078 * *
1079 * HISTORY: *
1080 * 1/26/00 gth : Created. *
1081 *=============================================================================================*/
1083 Animatable3DObjClass(def.HierarchyTreeName),
1084 LodCount(0),
1085 CurLod(0),
1086 Lod(NULL),
1087 BoundingBoxIndex(-1),
1088 Cost(NULL),
1089 Value(NULL),
1093 LODBias(1.0f)
1094{
1095 // Set the name
1096 Set_Name(def.Get_Name());
1097
1098
1099 // Number of LODs comes from the distlod
1100 LodCount = def.LodCount;
1101 WWASSERT(LodCount >= 1);
1103 WWASSERT(Lod);
1104 Cost = W3DNEWARRAY float[LodCount];
1105 WWASSERT(Cost);
1106 // Value has LodCount + 1 entries so PostIncrementValue can always use
1107 // Value[CurLod + 1] (the last entry wil be AT_MAX_LOD).
1108 Value = W3DNEWARRAY float[LodCount + 1];
1109 WWASSERT(Value);
1110
1111 // Add Models to the ModelArrays
1112 for (int ilod=0; ilod < def.LodCount; ilod++) {
1113
1114 Lod[ilod].MaxScreenSize = def.Lod[ilod].MaxScreenSize;
1115
1116 for (int imodel=0; imodel < def.Lod[ilod].ModelCount; imodel++) {
1117
1118 RenderObjClass * robj = WW3DAssetManager::Get_Instance()->Create_Render_Obj(def.Lod[ilod].ModelName[imodel]);
1119 int boneindex = def.Lod[ilod].BoneIndex[imodel];
1120 if (robj != NULL) {
1121 Add_Lod_Model(ilod,robj,boneindex);
1122 robj->Release_Ref();
1123 }
1124 }
1125 }
1126
1128
1129 // Add aggregates to this model
1130 for (int iagg=0; iagg<def.Aggregates.ModelCount; iagg++) {
1131 RenderObjClass * robj = WW3DAssetManager::Get_Instance()->Create_Render_Obj(def.Aggregates.ModelName[iagg]);
1132 int boneindex = def.Aggregates.BoneIndex[iagg];
1133 if (robj != NULL) {
1134 Add_Sub_Object_To_Bone(robj,boneindex);
1135 robj->Release_Ref();
1136 }
1137 }
1138
1139 // Add a reference to the proxy array
1140 REF_PTR_SET(ProxyArray,def.ProxyArray);
1141
1142 // So that the object is ready for use after construction, we will
1143 // complete its initialization by initializing its cost and value arrays
1144 // according to a screen area of 1 pixel.
1145 int minlod = Calculate_Cost_Value_Arrays(1.0f, Value, Cost);
1146
1147 // Ensure lod is no less than minimum allowed
1148 if (CurLod < minlod) Set_LOD_Level(minlod);
1149
1150 // Flag our sub-objects as having dirty transforms
1152
1155 return ;
1156}
1157
1158
1159/***********************************************************************************************
1160 * HLodClass::HLodClass -- Constructs an HLod from an HModelDef *
1161 * *
1162 * INPUT: *
1163 * *
1164 * OUTPUT: *
1165 * *
1166 * WARNINGS: *
1167 * *
1168 * HISTORY: *
1169 * 1/26/00 gth : Created. *
1170 *=============================================================================================*/
1172 Animatable3DObjClass(def.BasePoseName),
1173 LodCount(0),
1174 CurLod(0),
1175 Lod(NULL),
1176 BoundingBoxIndex(-1),
1177 Cost(NULL),
1178 Value(NULL),
1182 LODBias(1.0f)
1183{
1184 // Set the name
1185 Set_Name(def.Get_Name());
1186
1187 // This is a "simple" HLod, only one LOD
1188 LodCount = 1;
1190 WWASSERT(Lod);
1191 Cost = W3DNEWARRAY float[1];
1192 WWASSERT(Cost);
1193 // Value has LodCount + 1 entries so PostIncrementValue can always use
1194 // Value[CurLod + 1] (the last entry wil be AT_MAX_LOD).
1195 Value = W3DNEWARRAY float[2];
1196 WWASSERT(Value);
1197
1198 // no lod size clamping
1199 Lod[0].MaxScreenSize = NO_MAX_SCREEN_SIZE;
1200
1201 // create the sub-objects
1202 int imodel;
1203 for (imodel=0; imodel < def.SubObjectCount; ++imodel) {
1205 if (robj) {
1206 int boneindex = def.SubObjects[imodel].PivotID;
1207 Add_Lod_Model(0,robj,boneindex);
1208 robj->Release_Ref();
1209 }
1210 }
1211
1213
1214 // So that the object is ready for use after construction, we will
1215 // complete its initialization by initializing its cost and value arrays
1216 // according to a screen area of 1 pixel.
1217 int minlod = Calculate_Cost_Value_Arrays(1.0f, Value, Cost);
1218
1219 // Ensure lod is no less than minimum allowed
1220 if (CurLod < minlod) Set_LOD_Level(minlod);
1221
1222 // Flag our sub-objects as having dirty transforms
1224
1227 return ;
1228}
1229
1230
1231/***********************************************************************************************
1232 * HLodClass::operator -- assignment operator *
1233 * *
1234 * INPUT: *
1235 * *
1236 * OUTPUT: *
1237 * *
1238 * WARNINGS: *
1239 * *
1240 * HISTORY: *
1241 * 1/26/00 gth : Created. *
1242 *=============================================================================================*/
1244{
1245 int lod,model;
1246
1247 if (this != &that) {
1248 Free();
1251
1252 LodCount = that.LodCount;
1253 WWASSERT(LodCount >= 1);
1254
1256 WWASSERT(Lod != NULL);
1257 Cost = W3DNEWARRAY float[LodCount];
1258 WWASSERT(Cost);
1259 // Value has LodCount + 1 entries so PostIncrementValue can always use
1260 // Value[CurLod + 1] (the last entry wil be AT_MAX_LOD).
1261 Value = W3DNEWARRAY float[LodCount + 1];
1262 WWASSERT(Value);
1263
1264 for (lod=0; lod<LodCount;lod++) {
1265 Lod[lod].Resize(that.Lod[lod].Count());
1266 Lod[lod].MaxScreenSize = that.Lod[lod].MaxScreenSize;
1267
1268 for (model = 0; model < that.Lod[lod].Count(); model++) {
1269
1270 ModelNodeClass newnode;
1271 newnode.Model = that.Lod[lod][model].Model->Clone();
1272 newnode.BoneIndex = that.Lod[lod][model].BoneIndex;
1273 newnode.Model->Set_Container(this);
1274 if (Is_In_Scene()) {
1275 newnode.Model->Notify_Added(Scene);
1276 }
1277
1278 Lod[lod].Add(newnode);
1279 }
1280 }
1281
1283 for (model = 0; model < that.AdditionalModels.Count(); model++) {
1284
1285 ModelNodeClass newnode;
1286 newnode.Model = that.AdditionalModels[model].Model->Clone();
1287 newnode.BoneIndex = that.AdditionalModels[model].BoneIndex;
1288 newnode.Model->Set_Container(this);
1289 if (Is_In_Scene()) {
1290 newnode.Model->Notify_Added(Scene);
1291 }
1292
1293 AdditionalModels.Add(newnode);
1294 }
1295
1296 LODBias = that.LODBias;
1297 }
1298
1300
1301
1302 // So that the object is ready for use after construction, we will
1303 // complete its initialization by initializing its cost and value arrays
1304 // according to a screen area of 1 pixel.
1305 int minlod = Calculate_Cost_Value_Arrays(1.0f, Value, Cost);
1306
1307 // Ensure lod is no less than minimum allowed
1308 if (CurLod < minlod) Set_LOD_Level(minlod);
1309
1310 // Flag our sub-objects as having dirty transforms
1312
1315 return *this;
1316}
1317
1318
1319/***********************************************************************************************
1320 * HLodClass::~HLodClass -- Destructor *
1321 * *
1322 * INPUT: *
1323 * *
1324 * OUTPUT: *
1325 * *
1326 * WARNINGS: *
1327 * *
1328 * HISTORY: *
1329 * 1/26/00 gth : Created. *
1330 *=============================================================================================*/
1332{
1333 Free();
1334}
1335
1336
1337/***********************************************************************************************
1338 * HLodClass::Free -- releases all resources *
1339 * *
1340 * INPUT: *
1341 * *
1342 * OUTPUT: *
1343 * *
1344 * WARNINGS: *
1345 * *
1346 * HISTORY: *
1347 * 1/26/00 gth : Created. *
1348 *=============================================================================================*/
1350{
1351 int lod,model;
1352
1353 for (lod = 0; lod < LodCount; lod++) {
1354 for (model = 0; model < Lod[lod].Count(); model++) {
1355
1356 RenderObjClass * robj = Lod[lod][model].Model;
1357 Lod[lod][model].Model = NULL;
1358
1359 WWASSERT(robj);
1360 robj->Set_Container(NULL);
1361 robj->Release_Ref();
1362
1363 }
1364
1365 Lod[lod].Delete_All();
1366 }
1367 if (Lod != NULL) {
1368 delete[] Lod;
1369 Lod = NULL;
1370 }
1371 LodCount = 0;
1372
1373 if (Cost != NULL) {
1374 delete[] Cost;
1375 Cost = NULL;
1376 }
1377 if (Value != NULL) {
1378 delete[] Value;
1379 Value = NULL;
1380 }
1381
1382 for (model = 0; model < AdditionalModels.Count(); model++) {
1383 RenderObjClass * robj = AdditionalModels[model].Model;
1384 AdditionalModels[model].Model = NULL;
1385
1386 WWASSERT(robj);
1387 robj->Set_Container(NULL);
1388 robj->Release_Ref();
1389 }
1390 AdditionalModels.Delete_All();
1391
1394}
1395
1396
1397/***********************************************************************************************
1398 * HLodClass::Clone -- virtual copy constructor *
1399 * *
1400 * INPUT: *
1401 * *
1402 * OUTPUT: *
1403 * *
1404 * WARNINGS: *
1405 * *
1406 * HISTORY: *
1407 * 1/26/00 gth : Created. *
1408 *=============================================================================================*/
1410{
1411 return W3DNEW HLodClass(*this);
1412}
1413
1414
1415/***********************************************************************************************
1416 * HLodClass::Get_Obj_Space_Bounding_Box -- Return the bounding box mesh if we have one. *
1417 * *
1418 * INPUT: *
1419 * *
1420 * OUTPUT: *
1421 * *
1422 * WARNINGS: *
1423 * *
1424 * HISTORY: *
1425 * 4/13/00 pds : Created. *
1426 *=============================================================================================*/
1428{
1429 //
1430 // Do we have a bounding box mesh?
1431 //
1432 int count = Lod[LodCount - 1].Count ();
1433 if (BoundingBoxIndex >= 0 && BoundingBoxIndex < count) {
1434
1435 RenderObjClass *mesh = Lod[LodCount - 1][BoundingBoxIndex].Model;
1436 if (mesh != NULL && mesh->Class_ID () == RenderObjClass::CLASSID_OBBOX) {
1437
1438 OBBoxRenderObjClass *obbox_mesh = (OBBoxRenderObjClass *)mesh;
1439
1440 //
1441 // Determine what the box's transform 'should' be this frame.
1442 // Note: We do this because some animation types don't update
1443 // unless they are visible.
1444 //
1445 Matrix3D box_tm;
1446 Simple_Evaluate_Bone (Lod[LodCount - 1][BoundingBoxIndex].BoneIndex, &box_tm);
1447
1448 //
1449 // Convert the OBBox from its coordinate system to the coordinate
1450 // system of the HLOD.
1451 //
1452 Matrix3D world_to_hlod_tm;
1453 Matrix3D box_to_hlod_tm;
1454
1455 Get_Transform ().Get_Orthogonal_Inverse (world_to_hlod_tm);
1456 Matrix3D::Multiply(world_to_hlod_tm,box_tm,&box_to_hlod_tm);
1457
1458 box_to_hlod_tm.Transform_Center_Extent_AABox( obbox_mesh->Get_Local_Center(),
1459 obbox_mesh->Get_Local_Extent(),
1460 &box.Center,&box.Extent);
1461 }
1462
1463 } else {
1465 }
1466}
1467
1468
1469/***********************************************************************************************
1470 * HLodClass::Get_Obj_Space_Bounding_Sphere -- Use the bounding box mesh to calculate a sphere.*
1471 * *
1472 * INPUT: *
1473 * *
1474 * OUTPUT: *
1475 * *
1476 * WARNINGS: *
1477 * *
1478 * HISTORY: *
1479 * 4/13/00 pds : Created. *
1480 *=============================================================================================*/
1482{
1483 AABoxClass box;
1485 sphere.Center = box.Center;
1486 sphere.Radius = box.Extent.Length();
1487}
1488
1489
1490/***********************************************************************************************
1491 * HLodClass::Get_Obj_Space_Bounding_Sphere -- Use the bounding box mesh to calculate a sphere.*
1492 * *
1493 * INPUT: *
1494 * *
1495 * OUTPUT: *
1496 * *
1497 * WARNINGS: *
1498 * *
1499 * HISTORY: *
1500 * 4/13/00 pds : Created. *
1501 *=============================================================================================*/
1503{
1504 if (BoundingBoxIndex >= 0) {
1505 //
1506 // Get the bounding sphere in local coordinates
1507 //
1508 SphereClass sphere;
1510
1511 //
1512 // Transform the sphere into world coords and return the sphere
1513 //
1514#ifdef ALLOW_TEMPORARIES
1515 CachedBoundingSphere.Center = Get_Transform () * sphere.Center;
1516#else
1518#endif
1519 CachedBoundingSphere.Radius = sphere.Radius;
1520 } else {
1522 }
1523
1524 return CachedBoundingSphere;
1525}
1526
1527
1528/***********************************************************************************************
1529 * HLodClass::Get_Obj_Space_Bounding_Box -- Return the bounding box mesh if we have one. *
1530 * *
1531 * INPUT: *
1532 * *
1533 * OUTPUT: *
1534 * *
1535 * WARNINGS: *
1536 * *
1537 * HISTORY: *
1538 * 4/13/00 pds : Created. *
1539 *=============================================================================================*/
1541{
1542 if (BoundingBoxIndex >= 0) {
1543
1544 //
1545 // Get the bounding box in local coordinates
1546 //
1547 AABoxClass box;
1549
1550 //
1551 // Transform the bounding box to world coordinates
1552 //
1554 box.Extent,
1555 &CachedBoundingBox.Center,
1556 &CachedBoundingBox.Extent );
1557 } else {
1559 }
1560
1561 return CachedBoundingBox;
1562}
1563
1564
1565/***********************************************************************************************
1566 * HLodClass::Set_Max_Screen_Size -- Set max-screen-size for an LOD *
1567 * *
1568 * INPUT: *
1569 * *
1570 * OUTPUT: *
1571 * *
1572 * WARNINGS: *
1573 * *
1574 * HISTORY: *
1575 * 1/26/00 gth : Created. *
1576 *=============================================================================================*/
1577void HLodClass::Set_Max_Screen_Size(int lod_index, float size)
1578{
1579 // Params valid?
1580 WWASSERT(lod_index >= 0);
1581 WWASSERT(lod_index < LodCount);
1582 if ((lod_index >= 0) && (lod_index < LodCount)) {
1583
1584 // Set the new screen size for this LOD
1585 Lod[lod_index].MaxScreenSize = size;
1586
1588
1589 // So that the object is ready for use after construction, we will
1590 // complete its initialization by initializing its cost and value arrays
1591 // according to a screen area of 1 pixel.
1592 int minlod = Calculate_Cost_Value_Arrays(1.0f, Value, Cost);
1593
1594 // Ensure lod is no less than minimum allowed
1595 if (CurLod < minlod) Set_LOD_Level(minlod);
1596 }
1597
1598 return ;
1599}
1600
1601
1602/***********************************************************************************************
1603 * HLodClass::Get_Max_Screen_Size -- get max-screen-size for an LOD *
1604 * *
1605 * INPUT: *
1606 * *
1607 * OUTPUT: *
1608 * *
1609 * WARNINGS: *
1610 * *
1611 * HISTORY: *
1612 * 1/26/00 gth : Created. *
1613 *=============================================================================================*/
1614float HLodClass::Get_Max_Screen_Size(int lod_index) const
1615{
1616 float size = NO_MAX_SCREEN_SIZE;
1617
1618 // Params valid?
1619 WWASSERT(lod_index >= 0);
1620 WWASSERT(lod_index < LodCount);
1621 if ((lod_index >= 0) && (lod_index < LodCount)) {
1622
1623 // Get the screen size for this LOD
1624 size = Lod[lod_index].MaxScreenSize;
1625 }
1626
1627 // Return the LOD's screen size to the caller
1628 return size;
1629}
1630
1631
1632/***********************************************************************************************
1633 * HLodClass::Get_Lod_Count -- returns number of levels of detail *
1634 * *
1635 * INPUT: *
1636 * *
1637 * OUTPUT: *
1638 * *
1639 * WARNINGS: *
1640 * *
1641 * HISTORY: *
1642 * 1/26/00 gth : Created. *
1643 *=============================================================================================*/
1645{
1646 return LodCount;
1647}
1648
1649
1650/***********************************************************************************************
1651 * HLodClass::Set_LOD_Bias -- sets LOD bias *
1652 * *
1653 * INPUT: *
1654 * *
1655 * OUTPUT: *
1656 * *
1657 * WARNINGS: *
1658 * *
1659 * HISTORY: *
1660 * 2/08/00 nh : Created. *
1661 *=============================================================================================*/
1663{
1664 assert(bias > 0.0f);
1665 bias = MAX(bias, 0.0f);
1666 LODBias = bias;
1667
1668 int additional_count = AdditionalModels.Count();
1669 for (int i = 0; i < additional_count; i++) {
1670 AdditionalModels[i].Model->Set_LOD_Bias(bias);
1671 }
1672}
1673
1674
1675/***********************************************************************************************
1676 * HLodClass::Get_Lod_Model_Count -- number of sub-objs in a given level of detail *
1677 * *
1678 * INPUT: *
1679 * *
1680 * OUTPUT: *
1681 * *
1682 * WARNINGS: *
1683 * *
1684 * HISTORY: *
1685 * 1/26/00 gth : Created. *
1686 *=============================================================================================*/
1687int HLodClass::Get_Lod_Model_Count(int lod_index) const
1688{
1689 int count = 0;
1690
1691 // Params valid?
1692 WWASSERT(lod_index >= 0);
1693 WWASSERT(lod_index < LodCount);
1694 if ((lod_index >= 0) && (lod_index < LodCount)) {
1695
1696 // Get the number of models in this Lod
1697 count = Lod[lod_index].Count ();
1698 }
1699
1700 // Return the number of models that compose this Lod
1701 return count;
1702}
1703
1704
1705/***********************************************************************************************
1706 * HLodClass::Peek_Lod_Model -- returns pointer to a model in one of the LODs *
1707 * *
1708 * INPUT: *
1709 * *
1710 * OUTPUT: *
1711 * *
1712 * WARNINGS: *
1713 * *
1714 * HISTORY: *
1715 * 1/26/00 gth : Created. *
1716 *=============================================================================================*/
1717RenderObjClass *HLodClass::Peek_Lod_Model(int lod_index, int model_index) const
1718{
1719 RenderObjClass *pmodel = NULL;
1720
1721 // Params valid?
1722 WWASSERT(lod_index >= 0);
1723 WWASSERT(lod_index < LodCount);
1724 if ((lod_index >= 0) &&
1725 (lod_index < LodCount) &&
1726 (model_index < Lod[lod_index].Count ())) {
1727
1728 // Get a pointer to the requested model
1729 pmodel = Lod[lod_index][model_index].Model;
1730 }
1731
1732 // Return a pointer to the requested model
1733 return pmodel;
1734}
1735
1736
1737/***********************************************************************************************
1738 * HLodClass::Get_Lod_Model -- returns a pointer to a model in one of the LODs *
1739 * *
1740 * INPUT: *
1741 * *
1742 * OUTPUT: *
1743 * *
1744 * WARNINGS: *
1745 * *
1746 * HISTORY: *
1747 * 1/26/00 gth : Created. *
1748 *=============================================================================================*/
1749RenderObjClass *HLodClass::Get_Lod_Model(int lod_index, int model_index) const
1750{
1751 RenderObjClass *pmodel = NULL;
1752
1753 // Params valid?
1754 WWASSERT(lod_index >= 0);
1755 WWASSERT(lod_index < LodCount);
1756 if ((lod_index >= 0) &&
1757 (lod_index < LodCount) &&
1758 (model_index < Lod[lod_index].Count ())) {
1759
1760 // Get a pointer to the requested model
1761 pmodel = Lod[lod_index][model_index].Model;
1762 if (pmodel != NULL) {
1763 pmodel->Add_Ref ();
1764 }
1765 }
1766
1767 // Return the number of models that compose this Lod
1768 return pmodel;
1769}
1770
1771
1772/***********************************************************************************************
1773 * HLodClass::Get_Lod_Model_Bone -- returns the bone index of a model *
1774 * *
1775 * INPUT: *
1776 * *
1777 * OUTPUT: *
1778 * *
1779 * WARNINGS: *
1780 * *
1781 * HISTORY: *
1782 * 1/26/00 gth : Created. *
1783 *=============================================================================================*/
1784int HLodClass::Get_Lod_Model_Bone(int lod_index, int model_index) const
1785{
1786 int bone_index = 0;
1787
1788 // Params valid?
1789 WWASSERT(lod_index >= 0);
1790 WWASSERT(lod_index < LodCount);
1791 if ((lod_index >= 0) &&
1792 (lod_index < LodCount) &&
1793 (model_index < Lod[lod_index].Count ())) {
1794
1795 // Get the bone that this model resides on
1796 bone_index = Lod[lod_index][model_index].BoneIndex;
1797 }
1798
1799 // Return the bone that this model resides on
1800 return bone_index;
1801}
1802
1803
1804/***********************************************************************************************
1805 * HLodClass::Get_Additional_Model_Count -- number of additional sub-objs *
1806 * *
1807 * INPUT: *
1808 * *
1809 * OUTPUT: *
1810 * *
1811 * WARNINGS: *
1812 * *
1813 * HISTORY: *
1814 * 8/23/00 NH : Created. *
1815 *=============================================================================================*/
1817{
1818 return AdditionalModels.Count();
1819}
1820
1821
1822/***********************************************************************************************
1823 * HLodClass::Peek_Additional_Model -- returns pointer to an additional model *
1824 * *
1825 * INPUT: *
1826 * *
1827 * OUTPUT: *
1828 * *
1829 * WARNINGS: *
1830 * *
1831 * HISTORY: *
1832 * 8/23/00 NH : Created. *
1833 *=============================================================================================*/
1835{
1836 RenderObjClass *pmodel = NULL;
1837
1838 // Param valid?
1839 WWASSERT(model_index >= 0);
1840 WWASSERT(model_index < AdditionalModels.Count());
1841 if ((model_index >= 0) &&
1842 (model_index < AdditionalModels.Count())) {
1843
1844 // Get a pointer to the requested model
1845 pmodel = AdditionalModels[model_index].Model;
1846 }
1847
1848 // Return a pointer to the requested model
1849 return pmodel;
1850}
1851
1852
1853/***********************************************************************************************
1854 * HLodClass::Get_Additional_Model -- returns pointer to an additional model *
1855 * *
1856 * INPUT: *
1857 * *
1858 * OUTPUT: *
1859 * *
1860 * WARNINGS: *
1861 * *
1862 * HISTORY: *
1863 * 8/23/00 NH : Created. *
1864 *=============================================================================================*/
1866{
1867 RenderObjClass *pmodel = NULL;
1868
1869 // Param valid?
1870 WWASSERT(model_index >= 0);
1871 WWASSERT(model_index < AdditionalModels.Count());
1872 if ((model_index >= 0) &&
1873 (model_index < AdditionalModels.Count())) {
1874
1875 // Get a pointer to the requested model
1876 pmodel = AdditionalModels[model_index].Model;
1877 if (pmodel != NULL) {
1878 pmodel->Add_Ref ();
1879 }
1880 }
1881
1882 // Return a pointer to the requested model
1883 return pmodel;
1884}
1885
1886
1887/***********************************************************************************************
1888 * HLodClass::Get_Additional_Model_Bone -- returns the bone index of an additional model *
1889 * *
1890 * INPUT: *
1891 * *
1892 * OUTPUT: *
1893 * *
1894 * WARNINGS: *
1895 * *
1896 * HISTORY: *
1897 * 8/23/00 NH : Created. *
1898 *=============================================================================================*/
1899int HLodClass::Get_Additional_Model_Bone (int model_index) const
1900{
1901 int bone_index = 0;
1902
1903 // Params valid?
1904 WWASSERT(model_index >= 0);
1905 WWASSERT(model_index < AdditionalModels.Count());
1906 if ((model_index >= 0) &&
1907 (model_index < AdditionalModels.Count())) {
1908
1909 // Get the bone that this model resides on
1910 bone_index = AdditionalModels[model_index].BoneIndex;
1911 }
1912
1913 // Return the bone that this model resides on
1914 return bone_index;
1915}
1916
1917
1918/***********************************************************************************************
1919 * HLodClass::Is_NULL_Lod_Included -- does this HLod have NULL as its lowest LOD *
1920 * *
1921 * INPUT: *
1922 * *
1923 * OUTPUT: *
1924 * *
1925 * WARNINGS: *
1926 * *
1927 * HISTORY: *
1928 * 1/26/00 gth : Created. *
1929 *=============================================================================================*/
1931{
1932 bool included = false;
1933
1934 // Determine if the lowest-level LOD is the null render object or not...
1935 if ((LodCount > 0) && (Lod[0][0].Model != NULL)) {
1936 included = (Lod[0][0].Model->Class_ID () == RenderObjClass::CLASSID_NULL);
1937 }
1938
1939 // Return the true/false result code
1940 return included;
1941}
1942
1943
1944/***********************************************************************************************
1945 * HLodClass::Include_NULL_Lod -- Add NULL as the lowest LOD *
1946 * *
1947 * INPUT: *
1948 * *
1949 * OUTPUT: *
1950 * *
1951 * WARNINGS: *
1952 * *
1953 * HISTORY: *
1954 * 1/26/00 gth : Created. *
1955 *=============================================================================================*/
1957{
1958 if ((include == false) && Is_NULL_Lod_Included ()) {
1959
1960 // Free the 'NULL' object's stored information
1961 int index = 0;
1962 for (int model = 0; model < Lod[index].Count (); model++) {
1963
1964 RenderObjClass * robj = Lod[index][model].Model;
1965 Lod[index][model].Model = NULL;
1966
1967 WWASSERT(robj);
1968 robj->Set_Container (NULL);
1969 robj->Release_Ref ();
1970 }
1971
1972 // Resize the lod array
1973 LodCount -= 1;
1974 Lod[index].Delete_All ();
1976 for (index = 0; index < LodCount; index ++) {
1977 temp_lods[index] = Lod[index + 1];
1978 }
1979
1980 // Now resize the value and cost arrays
1981 float *temp_cost = W3DNEWARRAY float[LodCount];
1982 float *temp_value = W3DNEWARRAY float[LodCount + 1];
1983 ::memcpy (temp_cost, &Cost[1], sizeof (float) * LodCount);
1984 ::memcpy (temp_value, &Value[1], sizeof (float) * (LodCount + 1));
1985
1986 delete [] Lod;
1987 delete [] Value;
1988 delete [] Cost;
1989 Lod = temp_lods;
1990 Value = temp_value;
1991 Cost = temp_cost;
1992 CurLod = (CurLod >= LodCount) ? (LodCount - 1) : CurLod;
1993
1994 } else if (include && (Is_NULL_Lod_Included () == false)) {
1995
1996 // Tag the NULL render object onto the end
1998 WWASSERT (null_object != NULL);
1999 if (null_object != NULL) {
2000
2001 // Resize the lod array
2003 for (int index = 0; index < LodCount; index ++) {
2004 temp_lods[index + 1] = Lod[index];
2005 }
2006
2007 // Now resize the value and cost arrays
2008 float *temp_cost = W3DNEWARRAY float[LodCount + 1];
2009 float *temp_value = W3DNEWARRAY float[LodCount + 2];
2010 ::memcpy (&temp_cost[1], Cost, sizeof (float) * LodCount);
2011 ::memcpy (&temp_value[1], Value, sizeof (float) * (LodCount + 1));
2012
2013 delete [] Lod;
2014 delete [] Value;
2015 delete [] Cost;
2016 Lod = temp_lods;
2017 Value = temp_value;
2018 Cost = temp_cost;
2019 LodCount ++;
2020
2021 // Add this NULL object to the start of the lod list
2022 Add_Lod_Model (0, null_object, 0);
2023 null_object->Release_Ref ();
2024 }
2025 }
2026
2027 // recalculate cost/value arrays and ensure the current LOD is still valid.
2028 int minlod = Calculate_Cost_Value_Arrays(1.0f, Value, Cost);
2029
2030 // Ensure lod is no less than minimum allowed
2031 if (CurLod < minlod) Set_LOD_Level(minlod);
2032
2033 return ;
2034}
2035
2036
2037/***********************************************************************************************
2038 * HLodClass::Get_Proxy_Count -- Returns the number of proxy records *
2039 * *
2040 * INPUT: *
2041 * *
2042 * OUTPUT: *
2043 * *
2044 * WARNINGS: *
2045 * *
2046 * HISTORY: *
2047 * 10/27/2000 gth : Created. *
2048 *=============================================================================================*/
2050{
2051 if (ProxyArray != NULL) {
2052 return ProxyArray->Length();
2053 } else {
2054 return 0;
2055 }
2056}
2057
2058
2059/***********************************************************************************************
2060 * HLodClass::Get_Proxy -- returns the information for the i'th proxy *
2061 * *
2062 * INPUT: *
2063 * *
2064 * OUTPUT: *
2065 * *
2066 * WARNINGS: *
2067 * *
2068 * HISTORY: *
2069 * 10/27/2000 gth : Created. *
2070 *=============================================================================================*/
2071bool HLodClass::Get_Proxy (int index, ProxyClass &proxy) const
2072{
2073 bool retval = false;
2074
2075 if (ProxyArray != NULL) {
2076
2077 //
2078 // Lookup the proxy's transform
2079 //
2080 HTree->Base_Update(Get_Transform());
2081 Matrix3D transform = HTree->Get_Transform((*ProxyArray)[index].Get_Bone_Index());
2082 Set_Hierarchy_Valid(false);
2083
2084 //
2085 // Pass the data onto the proxy object
2086 //
2087 proxy.Set_Transform(transform);
2088 proxy.Set_Name((*ProxyArray)[index].Get_Name());
2089 retval = true;
2090
2091 } else {
2092 proxy.Set_Name ("");
2093 proxy.Set_Transform (Matrix3D (1));
2094 }
2095
2096 return retval;
2097}
2098
2099
2100/***********************************************************************************************
2101 * HLodClass::Get_Num_Polys -- returns polycount of the current LOD *
2102 * *
2103 * INPUT: *
2104 * *
2105 * OUTPUT: *
2106 * *
2107 * WARNINGS: *
2108 * *
2109 * HISTORY: *
2110 * 1/26/00 gth : Created. *
2111 *=============================================================================================*/
2113{
2114 int polycount = 0;
2115 int i;
2116 int model_count = Lod[CurLod].Count();
2117 for (i = 0; i < model_count; i++) {
2118 if (Lod[CurLod][i].Model->Is_Not_Hidden_At_All()) {
2119 polycount += Lod[CurLod][i].Model->Get_Num_Polys();
2120 }
2121 }
2122
2123 int additional_count = AdditionalModels.Count();
2124 for (i = 0; i < additional_count; i++) {
2125 if (AdditionalModels[i].Model->Is_Not_Hidden_At_All()) {
2126 polycount += AdditionalModels[i].Model->Get_Num_Polys();
2127 }
2128 }
2129
2130 return polycount;
2131}
2132
2133
2134/***********************************************************************************************
2135 * HLodClass::Render -- render this HLod *
2136 * *
2137 * INPUT: *
2138 * *
2139 * OUTPUT: *
2140 * *
2141 * WARNINGS: *
2142 * *
2143 * HISTORY: *
2144 * 1/26/00 gth : Created. *
2145 *=============================================================================================*/
2147{
2148 int i;
2149
2150 if (Is_Not_Hidden_At_All() == false) {
2151 return;
2152 }
2153
2155
2156 for (i = 0; i < Lod[CurLod].Count(); i++) {
2157 if (Lod[CurLod][i].Model->Class_ID() != CLASSID_OBBOX)
2158 Lod[CurLod][i].Model->Render(rinfo);
2159 }
2160
2162 for (i = 0; i < AdditionalModels.Count(); i++) {
2163 AdditionalModels[i].Model->Set_LOD_Level(Get_LOD_Level());
2164 AdditionalModels[i].Model->Render(rinfo);
2165 }
2166 } else {
2167 for (i = 0; i < AdditionalModels.Count(); i++) {
2168 AdditionalModels[i].Model->Render(rinfo);
2169 }
2170 }
2171}
2172
2173
2174/***********************************************************************************************
2175 * HLodClass::Special_Render -- Special_Render for HLod *
2176 * *
2177 * INPUT: *
2178 * *
2179 * OUTPUT: *
2180 * *
2181 * WARNINGS: *
2182 * *
2183 * HISTORY: *
2184 * 1/26/00 gth : Created. *
2185 *=============================================================================================*/
2187{
2188 int i;
2189 if (Is_Not_Hidden_At_All() == false) {
2190 return;
2191 }
2192
2194
2195 int lod_index = CurLod;
2196 if (rinfo.RenderType == SpecialRenderInfoClass::RENDER_SHADOW) { // (gth) HACK HACK! yikes
2197 lod_index = LodCount-1;
2198 }
2199
2200 for (i = 0; i < Lod[lod_index].Count(); i++) {
2201 Lod[lod_index][i].Model->Special_Render(rinfo);
2202 }
2203
2204 for (i = 0; i < AdditionalModels.Count(); i++) {
2205 AdditionalModels[i].Model->Special_Render(rinfo);
2206 }
2207}
2208
2209
2210/***********************************************************************************************
2211 * HLodClass::Set_Transform -- Sets the transform *
2212 * *
2213 * INPUT: *
2214 * *
2215 * OUTPUT: *
2216 * *
2217 * WARNINGS: *
2218 * *
2219 * HISTORY: *
2220 * 1/26/00 gth : Created. *
2221 *=============================================================================================*/
2227
2228
2229/***********************************************************************************************
2230 * HLodClass::Set_Position -- Sets the position *
2231 * *
2232 * INPUT: *
2233 * *
2234 * OUTPUT: *
2235 * *
2236 * WARNINGS: *
2237 * *
2238 * HISTORY: *
2239 * 1/26/00 gth : Created. *
2240 *=============================================================================================*/
2246
2247
2248/***********************************************************************************************
2249 * HLodClass::Notify_Added -- callback notifies subobjs that they were added *
2250 * *
2251 * INPUT: *
2252 * *
2253 * OUTPUT: *
2254 * *
2255 * WARNINGS: *
2256 * *
2257 * HISTORY: *
2258 * 1/26/00 gth : Created. *
2259 *=============================================================================================*/
2261{
2263 int i;
2264 int model_count = Lod[CurLod].Count();
2265 for (i = 0; i < model_count; i++) {
2266 Lod[CurLod][i].Model->Notify_Added(scene);
2267 }
2268
2269 int additional_count = AdditionalModels.Count();
2270 for (i = 0; i < additional_count; i++) {
2271 AdditionalModels[i].Model->Notify_Added(scene);
2272 }
2273}
2274
2275
2276/***********************************************************************************************
2277 * HLodClass::Notify_Removed -- notifies subobjs that they were removed *
2278 * *
2279 * INPUT: *
2280 * *
2281 * OUTPUT: *
2282 * *
2283 * WARNINGS: *
2284 * *
2285 * HISTORY: *
2286 * 1/26/00 gth : Created. *
2287 *=============================================================================================*/
2289{
2290 int i;
2291 int model_count = Lod[CurLod].Count();
2292 for (i = 0; i < model_count; i++) {
2293 Lod[CurLod][i].Model->Notify_Removed(scene);
2294 }
2295
2296 int additional_count = AdditionalModels.Count();
2297 for (i = 0; i < additional_count; i++) {
2298 AdditionalModels[i].Model->Notify_Removed(scene);
2299 }
2301}
2302
2303
2304/***********************************************************************************************
2305 * HLodClass::Get_Num_Sub_Objects -- returns total number of sub-objects *
2306 * *
2307 * INPUT: *
2308 * *
2309 * OUTPUT: *
2310 * *
2311 * WARNINGS: *
2312 * *
2313 * HISTORY: *
2314 * 1/26/00 gth : Created. *
2315 *=============================================================================================*/
2317{
2318 int count = 0;
2319 for (int lod=0; lod<LodCount;lod++) {
2320 count += Lod[lod].Count();
2321 }
2322 count += AdditionalModels.Count();
2323 return count;
2324}
2325
2326
2327/***********************************************************************************************
2328 * HLodClass::Get_Sub_Object -- returns a pointer to specified sub-object *
2329 * *
2330 * INPUT: *
2331 * *
2332 * OUTPUT: *
2333 * *
2334 * WARNINGS: *
2335 * *
2336 * HISTORY: *
2337 * 1/26/00 gth : Created. *
2338 *=============================================================================================*/
2340{
2341 WWASSERT(index >= 0);
2342 for (int lod=0; lod<LodCount; lod++) {
2343 if (index < Lod[lod].Count()) {
2344 Lod[lod][index].Model->Add_Ref();
2345 return Lod[lod][index].Model;
2346 }
2347 index -= Lod[lod].Count();
2348 }
2349 WWASSERT(index < AdditionalModels.Count());
2350 AdditionalModels[index].Model->Add_Ref();
2351 return AdditionalModels[index].Model;
2352}
2353
2354
2355/***********************************************************************************************
2356 * HLodClass::Add_Sub_Object -- add a sub-object to this HLod *
2357 * *
2358 * INPUT: *
2359 * *
2360 * OUTPUT: *
2361 * *
2362 * WARNINGS: *
2363 * *
2364 * HISTORY: *
2365 * 1/26/00 gth : Created. *
2366 *=============================================================================================*/
2368{
2369 return Add_Sub_Object_To_Bone(subobj,0);
2370}
2371
2372
2373/***********************************************************************************************
2374 * HLodClass::Remove_Sub_Object -- remove a sub-object from this HLod *
2375 * *
2376 * INPUT: *
2377 * *
2378 * OUTPUT: *
2379 * *
2380 * WARNINGS: *
2381 * *
2382 * HISTORY: *
2383 * 1/26/00 gth : Created. *
2384 *=============================================================================================*/
2386{
2387 // no object given?
2388 if (removeme == NULL) {
2389 return 0;
2390 }
2391
2392 // find the sub-object
2393 bool found = false;
2394 bool iscurrent = false;
2395
2396 for (int lod = 0; (lod < LodCount) && (!found); lod++) {
2397 for (int model = 0; (model < Lod[lod].Count()) && (!found); model++) {
2398
2399 if (Lod[lod][model].Model == removeme) {
2400
2401 // remove the model from the array.
2402 Lod[lod].Delete(model);
2403
2404 // record that we found it
2405 found = true;
2406
2407 if (lod == CurLod) {
2408 iscurrent = true;
2409 }
2410 }
2411 }
2412 }
2413
2414 for (int model = 0; (model < AdditionalModels.Count()) && (!found); model++) {
2415 if (AdditionalModels[model].Model == removeme) {
2416 AdditionalModels.Delete(model);
2417 found = true;
2418 iscurrent = true;
2419 }
2420 }
2421
2422 if (found) {
2423
2424 // clear the object's container pointer
2425 removeme->Set_Container(NULL);
2426
2427 // let him know in case he is removed from the scene as a result of this
2428 // this is the combination of this HLod being in the scene and and this model
2429 // either being in the current LOD or being in the additional model list...
2430 if (iscurrent && Is_In_Scene()) {
2431 removeme->Notify_Removed(Scene);
2432 }
2433
2434 // release our reference to this render object
2435 // object may delete itself here...
2436 removeme->Release_Ref();
2437
2440
2441 return 1;
2442 }
2443
2444 return 0;
2445}
2446
2447
2448/***********************************************************************************************
2449 * HLodClass::Get_Num_Sub_Objects_On_Bone -- returns the number of objects on the given bone *
2450 * *
2451 * INPUT: *
2452 * *
2453 * OUTPUT: *
2454 * *
2455 * WARNINGS: *
2456 * *
2457 * HISTORY: *
2458 * 1/26/00 gth : Created. *
2459 *=============================================================================================*/
2461{
2462 int count = 0;
2463
2464 for (int lod = 0; lod < LodCount; lod++) {
2465 for (int model = 0; model < Lod[lod].Count(); model++) {
2466 if (Lod[lod][model].BoneIndex == boneindex) count++;
2467 }
2468 }
2469 for (int model = 0; model < AdditionalModels.Count(); model++) {
2470 if (AdditionalModels[model].BoneIndex == boneindex) count++;
2471 }
2472 return count;
2473}
2474
2475
2476/***********************************************************************************************
2477 * HLodClass::Get_Sub_Object_On_Bone -- returns obj on the given bone *
2478 * *
2479 * INPUT: *
2480 * *
2481 * OUTPUT: *
2482 * *
2483 * WARNINGS: *
2484 * *
2485 * HISTORY: *
2486 * 1/26/00 gth : Created. *
2487 *=============================================================================================*/
2489{
2490 int count = 0;
2491 for (int lod = 0; lod < LodCount; lod++) {
2492 for (int model = 0; model < Lod[lod].Count(); model++) {
2493 if (Lod[lod][model].BoneIndex == boneindex) {
2494 if (count == index) {
2495 Lod[lod][model].Model->Add_Ref();
2496 return Lod[lod][model].Model;
2497 }
2498 count++;
2499 }
2500 }
2501 }
2502 for (int model = 0; model < AdditionalModels.Count(); model++) {
2503 if (AdditionalModels[model].BoneIndex == boneindex) {
2504 if (count == index) {
2505 AdditionalModels[model].Model->Add_Ref();
2506 return AdditionalModels[model].Model;
2507 }
2508 count++;
2509 }
2510 }
2511 return NULL;
2512}
2513
2514
2515/***********************************************************************************************
2516 * HLodClass::Get_Sub_Object_Bone_Index -- returns bone index of given object *
2517 * *
2518 * INPUT: *
2519 * *
2520 * OUTPUT: *
2521 * *
2522 * WARNINGS: *
2523 * *
2524 * HISTORY: *
2525 * 1/26/00 gth : Created. *
2526 *=============================================================================================*/
2528{
2529 for (int lod = 0; lod < LodCount; lod++) {
2530 for (int model = 0; model < Lod[lod].Count(); model++) {
2531 if (Lod[lod][model].Model == subobj) {
2532 return Lod[lod][model].BoneIndex;
2533 }
2534 }
2535 }
2536 for (int model = 0; model < AdditionalModels.Count(); model++) {
2537 if (AdditionalModels[model].Model == subobj) {
2538 return AdditionalModels[model].BoneIndex;
2539 }
2540 }
2541 return 0;
2542}
2543
2544//Custom version of above function for cases where we know the lod/model index. -MW
2545int HLodClass::Get_Sub_Object_Bone_Index(int LodIndex, int ModelIndex) const
2546{
2547 return Lod[LodIndex][ModelIndex].BoneIndex;
2548}
2549
2550/***********************************************************************************************
2551 * HLodClass::Add_Sub_Object_To_Bone -- adds a sub-object to a bone *
2552 * *
2553 * INPUT: *
2554 * *
2555 * OUTPUT: *
2556 * *
2557 * WARNINGS: *
2558 * *
2559 * HISTORY: *
2560 * 1/26/00 gth : Created. *
2561 *=============================================================================================*/
2563{
2564 WWASSERT(subobj);
2565 if ((boneindex < 0) || (boneindex >= HTree->Num_Pivots())) return 0;
2566
2567 subobj->Set_LOD_Bias(LODBias);
2568
2569 ModelNodeClass newnode;
2570 newnode.Model = subobj;
2571 newnode.Model->Add_Ref();
2572 newnode.Model->Set_Container(this);
2573 newnode.Model->Set_Animation_Hidden(HTree->Get_Visibility (boneindex) == false);
2574 newnode.BoneIndex = boneindex;
2575
2576 int result = AdditionalModels.Add(newnode);
2577
2580 Set_Hierarchy_Valid (false);
2582
2583 if (Is_In_Scene()) {
2584 subobj->Notify_Added(Scene);
2585 }
2586
2587 return result;
2588}
2589
2590
2591/***********************************************************************************************
2592 * HLodClass::Set_Animation -- set animation state to the base-pose *
2593 * *
2594 * INPUT: *
2595 * *
2596 * OUTPUT: *
2597 * *
2598 * WARNINGS: *
2599 * *
2600 * HISTORY: *
2601 * 1/26/00 gth : Created. *
2602 *=============================================================================================*/
2608
2609
2610/***********************************************************************************************
2611 * HLodClass::Set_Animation -- set animation state to an animation frame *
2612 * *
2613 * INPUT: *
2614 * *
2615 * OUTPUT: *
2616 * *
2617 * WARNINGS: *
2618 * *
2619 * HISTORY: *
2620 * 1/26/00 gth : Created. *
2621 *=============================================================================================*/
2622void HLodClass::Set_Animation(HAnimClass * motion,float frame,int mode)
2623{
2624 Animatable3DObjClass::Set_Animation(motion,frame,mode);
2626}
2627
2628
2629/***********************************************************************************************
2630 * HLodClass::Set_Animation -- set animation state to a blend of two animations *
2631 * *
2632 * INPUT: *
2633 * *
2634 * OUTPUT: *
2635 * *
2636 * WARNINGS: *
2637 * *
2638 * HISTORY: *
2639 * 1/26/00 gth : Created. *
2640 *=============================================================================================*/
2642(
2643 HAnimClass * motion0,
2644 float frame0,
2645 HAnimClass * motion1,
2646 float frame1,
2647 float percentage
2648)
2649{
2650 Animatable3DObjClass::Set_Animation(motion0,frame0,motion1,frame1,percentage);
2652}
2653
2654
2655/***********************************************************************************************
2656 * HLodClass::Set_Animation -- set animation state to a combination of anims *
2657 * *
2658 * INPUT: *
2659 * *
2660 * OUTPUT: *
2661 * *
2662 * WARNINGS: *
2663 * *
2664 * HISTORY: *
2665 * 1/26/00 gth : Created. *
2666 *=============================================================================================*/
2672
2673
2674/***********************************************************************************************
2675 * HLodClass::Cast_Ray -- cast a ray against this HLod *
2676 * *
2677 * INPUT: *
2678 * *
2679 * OUTPUT: *
2680 * *
2681 * WARNINGS: *
2682 * *
2683 * HISTORY: *
2684 * 1/26/00 gth : Created. *
2685 *=============================================================================================*/
2687{
2690 }
2691
2692 bool res = false;
2693 int i;
2694
2695 // collide against the top LOD
2696 int top = LodCount-1;
2697 for (i = 0; i < Lod[top].Count(); i++) {
2698 res |= Lod[top][i].Model->Cast_Ray(raytest);
2699 }
2700
2701 for (i = 0; i < AdditionalModels.Count(); i++) {
2702 res |= AdditionalModels[i].Model->Cast_Ray(raytest);
2703 }
2704
2705 return res;
2706}
2707
2708
2709/***********************************************************************************************
2710 * HLodClass::Cast_AABox -- Cast a swept AABox against this HLod *
2711 * *
2712 * INPUT: *
2713 * *
2714 * OUTPUT: *
2715 * *
2716 * WARNINGS: *
2717 * *
2718 * HISTORY: *
2719 * 1/26/00 gth : Created. *
2720 *=============================================================================================*/
2722{
2725 }
2726
2727 bool res = false;
2728 int i;
2729
2730 // collide against the top LOD
2731 int top = LodCount-1;
2732 for (i = 0; i < Lod[top].Count(); i++) {
2733 res |= Lod[top][i].Model->Cast_AABox(boxtest);
2734 }
2735
2736 for (i = 0; i < AdditionalModels.Count(); i++) {
2737 res |= AdditionalModels[i].Model->Cast_AABox(boxtest);
2738 }
2739
2740 return res;
2741}
2742
2743
2744/***********************************************************************************************
2745 * HLodClass::Cast_OBBox -- Cast a swept OBBox against this HLod *
2746 * *
2747 * INPUT: *
2748 * *
2749 * OUTPUT: *
2750 * *
2751 * WARNINGS: *
2752 * *
2753 * HISTORY: *
2754 * 1/26/00 gth : Created. *
2755 *=============================================================================================*/
2757{
2760 }
2761
2762 bool res = false;
2763 int i;
2764
2765 // collide against the top LOD
2766 int top = LodCount-1;
2767 for (i = 0; i < Lod[top].Count(); i++) {
2768 res |= Lod[top][i].Model->Cast_OBBox(boxtest);
2769 }
2770
2771 for (i = 0; i < AdditionalModels.Count(); i++) {
2772 res |= AdditionalModels[i].Model->Cast_OBBox(boxtest);
2773 }
2774
2775 return res;
2776}
2777
2778
2779/***********************************************************************************************
2780 * HLodClass::Intersect_AABox -- Intersect an AABox with this HLod *
2781 * *
2782 * INPUT: *
2783 * *
2784 * OUTPUT: *
2785 * *
2786 * WARNINGS: *
2787 * *
2788 * HISTORY: *
2789 * 1/26/00 gth : Created. *
2790 *=============================================================================================*/
2792{
2795 }
2796
2797 bool res = false;
2798 int i;
2799
2800 // collide against the top LOD
2801 int top = LodCount-1;
2802 for (i = 0; i < Lod[top].Count(); i++) {
2803 res |= Lod[top][i].Model->Intersect_AABox(boxtest);
2804 }
2805
2806 for (i = 0; i < AdditionalModels.Count(); i++) {
2807 res |= AdditionalModels[i].Model->Intersect_AABox(boxtest);
2808 }
2809
2810 return res;
2811}
2812
2813
2814/***********************************************************************************************
2815 * HLodClass::Intersect_OBBox -- Intersect an OBBox with this HLod *
2816 * *
2817 * INPUT: *
2818 * *
2819 * OUTPUT: *
2820 * *
2821 * WARNINGS: *
2822 * *
2823 * HISTORY: *
2824 * 1/26/00 gth : Created. *
2825 *=============================================================================================*/
2827{
2830 }
2831
2832 bool res = false;
2833 int i;
2834
2835 // collide against the top LOD
2836 int top = LodCount-1;
2837 for (i = 0; i < Lod[top].Count(); i++) {
2838 res |= Lod[top][i].Model->Intersect_OBBox(boxtest);
2839 }
2840
2841 for (i = 0; i < AdditionalModels.Count(); i++) {
2842 res |= AdditionalModels[i].Model->Intersect_OBBox(boxtest);
2843 }
2844
2845 return res;
2846}
2847
2848
2849/***********************************************************************************************
2850 * HLodClass::Prepare_LOD -- Prepare for LOD processing *
2851 * *
2852 * INPUT: *
2853 * *
2854 * OUTPUT: *
2855 * *
2856 * WARNINGS: *
2857 * *
2858 * HISTORY: *
2859 * 1/26/00 gth : Created. *
2860 *=============================================================================================*/
2862{
2863 if (Is_Not_Hidden_At_All() == false) {
2864 return;
2865 }
2866
2867 // Find the maximum screen dimension of the object in pixels
2868 float norm_area = Get_Screen_Size(camera);
2869
2870 /*
2871 ** Set texture reduction factor for the (non-additional) subobjects:
2872 */
2873// Texture reduction system broken, don't call!
2874// Set_Texture_Reduction_Factor(Calculate_Texture_Reduction_Factor(norm_area));
2875
2876 // Prepare LOD processing if this object has more than one LOD:
2877 if (LodCount > 1) {
2878 /*
2879 ** Prepare cost and value arrays (and ensure current LOD doesn't violate clamping):
2880 */
2881 int minlod = Calculate_Cost_Value_Arrays(norm_area, Value, Cost);
2882 if (CurLod < minlod) Set_LOD_Level(minlod);
2883
2884
2885 /*
2886 ** Add myself to the LOD optimizer:
2887 */
2889
2890 } else {
2891
2892 // Not added to optimizer, need to add cost
2894
2895 }
2896
2897 /*
2898 ** Recursively call for the additional objects:
2899 */
2900 int additional_count = AdditionalModels.Count();
2901 for (int i = 0; i < additional_count; i++) {
2902 if (AdditionalModels[i].Model->Is_Not_Hidden_At_All()) {
2903 AdditionalModels[i].Model->Prepare_LOD(camera);
2904 }
2905 }
2906
2907}
2908
2909
2910/***********************************************************************************************
2911 * HLodClass::Recalculate_Static_LOD_Factors -- compute lod factors *
2912 * *
2913 * INPUT: *
2914 * *
2915 * OUTPUT: *
2916 * *
2917 * WARNINGS: *
2918 * *
2919 * HISTORY: *
2920 * 1/26/00 gth : Created. *
2921 *=============================================================================================*/
2923{
2924 /*
2925 ** Calculate NonPixelCost, PixelCostPerArea, BenefitFactor for all LOD
2926 ** levels.
2927 ** NOTE: for now we are using vastly simplified Cost and Benefit metrics.
2928 ** (these will be improved after initial experimentation).
2929 ** the Cost metric is simply the number of polygons, and the Benefit
2930 ** Metric is 1 - 0.5 / #polygons^2.
2931 */
2932
2933 for (int i = 0; i < LodCount; i++) {
2934
2935 // Currently there are no pixel-related costs taken into account
2936 Lod[i].PixelCostPerArea = 0.0f;
2937
2938 // Sum polycount over all non-hidden models in array
2939 int model_count = Lod[i].Count();
2940 int polycount = 0;
2941 for (int j = 0; j < model_count; j++) {
2942 if (Lod[i][j].Model->Is_Not_Hidden_At_All()) {
2943 polycount += Lod[i][j].Model->Get_Num_Polys();
2944 }
2945 }
2946 // If polycount is zero set Cost to a small nonzero amount to avoid divisions by zero.
2947 Lod[i].NonPixelCost = (polycount != 0)? polycount : 0.000001f;
2948
2949 // A polycount of zero yields a benefit factor of zero: otherwise apply formula.
2950 Lod[i].BenefitFactor = (polycount != 0) ? (1 - (0.5f / (polycount * polycount))) : 0.0f;
2951 }
2952
2953}
2954
2955
2956/***********************************************************************************************
2957 * HLodClass::Increment_LOD -- move to next lod *
2958 * *
2959 * INPUT: *
2960 * *
2961 * OUTPUT: *
2962 * *
2963 * WARNINGS: *
2964 * *
2965 * HISTORY: *
2966 * 1/26/00 gth : Created. *
2967 *=============================================================================================*/
2969{
2970 if (CurLod >= (LodCount-1)) return;
2971
2972 if (Is_In_Scene()) {
2973 int model_count = Lod[CurLod].Count();
2974 for (int i = 0; i < model_count; i++) {
2975 Lod[CurLod][i].Model->Notify_Removed(Scene);
2976 }
2977 }
2978
2979 CurLod++;
2980
2981 if (Is_In_Scene()) {
2982 int model_count = Lod[CurLod].Count();
2983 for (int i = 0; i < model_count; i++) {
2984 Lod[CurLod][i].Model->Notify_Added(Scene);
2985 }
2986 }
2987}
2988
2989
2990/***********************************************************************************************
2991 * HLodClass::Decrement_LOD -- move to previous lod *
2992 * *
2993 * INPUT: *
2994 * *
2995 * OUTPUT: *
2996 * *
2997 * WARNINGS: *
2998 * *
2999 * HISTORY: *
3000 * 1/26/00 gth : Created. *
3001 *=============================================================================================*/
3003{
3004 if (CurLod < 1) return;
3005
3006 if (Is_In_Scene()) {
3007 int model_count = Lod[CurLod].Count();
3008 for (int i = 0; i < model_count; i++) {
3009 Lod[CurLod][i].Model->Notify_Removed(Scene);
3010 }
3011 }
3012
3013 CurLod--;
3014
3015 if (Is_In_Scene()) {
3016 int model_count = Lod[CurLod].Count();
3017 for (int i = 0; i < model_count; i++) {
3018 Lod[CurLod][i].Model->Notify_Added(Scene);
3019 }
3020 }
3021}
3022
3023
3024/***********************************************************************************************
3025 * HLodClass::Get_Cost -- returns the cost of this LOD *
3026 * *
3027 * INPUT: *
3028 * *
3029 * OUTPUT: *
3030 * *
3031 * WARNINGS: *
3032 * *
3033 * HISTORY: *
3034 * 1/26/00 gth : Created. *
3035 *=============================================================================================*/
3036float HLodClass::Get_Cost(void) const
3037{
3038 return(Cost[CurLod]);
3039}
3040
3041
3042/***********************************************************************************************
3043 * HLodClass::Get_Value -- returns the value of this LOD *
3044 * *
3045 * INPUT: *
3046 * *
3047 * OUTPUT: *
3048 * *
3049 * WARNINGS: *
3050 * *
3051 * HISTORY: *
3052 * 1/26/00 gth : Created. *
3053 *=============================================================================================*/
3054float HLodClass::Get_Value(void) const
3055{
3056 return(Value[CurLod]);
3057}
3058
3059
3060/***********************************************************************************************
3061 * HLodClass::Get_Post_Increment_Value -- returns the post increment value *
3062 * *
3063 * INPUT: *
3064 * *
3065 * OUTPUT: *
3066 * *
3067 * WARNINGS: *
3068 * *
3069 * HISTORY: *
3070 * 1/26/00 gth : Created. *
3071 *=============================================================================================*/
3073{
3074 return(Value[CurLod + 1]);
3075}
3076
3077
3078/***********************************************************************************************
3079 * HLodClass::Set_LOD_Level -- set the current lod level *
3080 * *
3081 * INPUT: *
3082 * *
3083 * OUTPUT: *
3084 * *
3085 * WARNINGS: *
3086 * *
3087 * HISTORY: *
3088 * 1/26/00 gth : Created. *
3089 *=============================================================================================*/
3091{
3092 lod = MAX(0, lod);
3093 lod = MIN(lod, (LodCount - 1));
3094
3095 if (lod == CurLod) return;
3096
3097
3098 if (Is_In_Scene()) {
3099 int model_count = Lod[CurLod].Count();
3100 for (int i = 0; i < model_count; i++) {
3101 Lod[CurLod][i].Model->Notify_Removed(Scene);
3102 }
3103 }
3104
3105 CurLod = lod;
3106
3107 if (Is_In_Scene()) {
3108 int model_count = Lod[CurLod].Count();
3109 for (int i = 0; i < model_count; i++) {
3110 Lod[CurLod][i].Model->Notify_Added(Scene);
3111 }
3112 }
3113}
3114
3115
3116/***********************************************************************************************
3117 * HLodClass::Get_LOD_Level -- returns the current LOD level *
3118 * *
3119 * INPUT: *
3120 * *
3121 * OUTPUT: *
3122 * *
3123 * WARNINGS: *
3124 * *
3125 * HISTORY: *
3126 * 1/26/00 gth : Created. *
3127 *=============================================================================================*/
3129{
3130 return CurLod;
3131}
3132
3133
3134/***********************************************************************************************
3135 * HLodClass::Get_LOD_Count -- returns the number of levels of detail *
3136 * *
3137 * INPUT: *
3138 * *
3139 * OUTPUT: *
3140 * *
3141 * WARNINGS: *
3142 * *
3143 * HISTORY: *
3144 * 1/26/00 gth : Created. *
3145 *=============================================================================================*/
3147{
3148 return LodCount;
3149}
3150
3151
3152/***********************************************************************************************
3153 * HLodClass::Calculate_Cost_Value_Arrays -- computes the cost-value arrays *
3154 * *
3155 * INPUT: *
3156 * *
3157 * OUTPUT: *
3158 * *
3159 * WARNINGS: *
3160 * *
3161 * HISTORY: *
3162 * 1/26/00 gth : Created. *
3163 *=============================================================================================*/
3164int HLodClass::Calculate_Cost_Value_Arrays(float screen_area, float *values, float *costs) const
3165{
3166 int lod = 0;
3167
3168 // Calculate Cost heuristic for each LOD based on normalized screen area:
3169 for (lod = 0; lod < LodCount; lod++) {
3170 costs[lod] = Lod[lod].NonPixelCost + Lod[lod].PixelCostPerArea * screen_area;
3171 }
3172
3173 // Calculate Value heuristic. First, all LOD levels for which
3174 // MaxScreenSize is smaller than screen_area have their Value set to
3175 // AT_MIN_LOD, as well as the first LOD after that (unless there are no
3176 // other LODs):
3177 for (lod = 0; lod < LodCount && Lod[lod].MaxScreenSize < screen_area; lod++) {
3178 values[lod] = AT_MIN_LOD;
3179 }
3180
3181 if (lod >= LodCount) {
3182 lod = LodCount - 1;
3183 } else {
3184 values[lod] = AT_MIN_LOD;
3185 }
3186
3187 // Now lod is the lowest allowed - return this value.
3188 int minlod = lod;
3189
3190 // Calculate Value heuristic for any remaining LODs based on normalized screen area:
3191 lod++;
3192 for (; lod < LodCount; lod++) {
3193 values[lod] = (Lod[lod].BenefitFactor * screen_area * LODBias) / costs[lod];
3194 }
3195 values[LodCount] = AT_MAX_LOD; // Post-inc value will flag max LOD.
3196
3197 return minlod;
3198}
3199
3200
3201/***********************************************************************************************
3202 * HLodClass::Get_Current_LOD -- returns a render object which represents the current LOD *
3203 * *
3204 * INPUT: *
3205 * *
3206 * OUTPUT: *
3207 * *
3208 * WARNINGS: *
3209 * *
3210 * HISTORY: *
3211 * 1/26/00 gth : Created. *
3212 *=============================================================================================*/
3214{
3215 int count = Get_Lod_Model_Count(CurLod);
3216
3217 if(!count)
3218 return 0;
3219
3220 return Get_Lod_Model(CurLod, 0);
3221}
3222
3223
3224/***********************************************************************************************
3225 * HLodClass::Set_Texture_Reduction_Factor -- resizeable texture support *
3226 * *
3227 * INPUT: *
3228 * *
3229 * OUTPUT: *
3230 * *
3231 * WARNINGS: *
3232 * *
3233 * HISTORY: *
3234 * 1/26/00 gth : Created. *
3235 *=============================================================================================*/
3236/*
3237void HLodClass::Set_Texture_Reduction_Factor(float trf)
3238{
3239 WWASSERT(0); // don't call to tex reduction system, it's broken!
3240 // We don't touch the additional subobjects: they will get Prepare_LOD
3241 // called on them individually which is where texture reduction will be
3242 // set also.
3243 for (int lod = 0; lod < LodCount; lod++) {
3244 int model_count = Lod[lod].Count();
3245 for (int model_id = 0; model_id < model_count; model_id++) {
3246 Lod[lod][model_id].Model->Set_Texture_Reduction_Factor(trf);
3247 }
3248 }
3249}
3250*/
3251
3252/***********************************************************************************************
3253 * HLodClass::Scale -- scale this HLod model *
3254 * *
3255 * INPUT: *
3256 * *
3257 * OUTPUT: *
3258 * *
3259 * WARNINGS: *
3260 * *
3261 * HISTORY: *
3262 * 1/26/00 gth : Created. *
3263 *=============================================================================================*/
3265{
3266 if (scale==1.0f) return;
3267
3268 int lod;
3269 int model;
3270
3271 //. Scale all subobjects.
3272 for (lod = 0; lod < LodCount; lod++) {
3273 for (model = 0; model < Lod[lod].Count(); model++) {
3274 Lod[lod][model].Model->Scale(scale);
3275 }
3276 }
3277
3278 for (model = 0; model < AdditionalModels.Count(); model++) {
3279 AdditionalModels[model].Model->Scale(scale);
3280 }
3281
3282 // Scale HTree:
3283 HTree->Scale(scale);
3284
3285 // Invalidate hierarchy
3286 Set_Hierarchy_Valid(false);
3287
3288 // Now update the object space bounding volumes of this object's container:
3289 RenderObjClass *container = Get_Container();
3290 if (container) container->Update_Obj_Space_Bounding_Volumes();
3291}
3292
3293
3294/***********************************************************************************************
3295 * HLodClass::Get_Num_Snap_Points -- returns the number of snap points in this model *
3296 * *
3297 * INPUT: *
3298 * *
3299 * OUTPUT: *
3300 * *
3301 * WARNINGS: *
3302 * *
3303 * HISTORY: *
3304 * 1/26/00 gth : Created. *
3305 *=============================================================================================*/
3307{
3308 if (SnapPoints) {
3309 return SnapPoints->Count();
3310 } else {
3311 return 0;
3312 }
3313}
3314
3315
3316/***********************************************************************************************
3317 * HLodClass::Get_Snap_Point -- returns specified snap-point *
3318 * *
3319 * INPUT: *
3320 * *
3321 * OUTPUT: *
3322 * *
3323 * WARNINGS: *
3324 * *
3325 * HISTORY: *
3326 * 1/26/00 gth : Created. *
3327 *=============================================================================================*/
3329{
3330 WWASSERT(set != NULL);
3331 if (SnapPoints) {
3332 *set = (*SnapPoints)[index];
3333 } else {
3334 set->X = set->Y = set->Z = 0;
3335 }
3336}
3337
3338
3339/***********************************************************************************************
3340 * HLodClass::Update_Sub_Object_Transforms -- updates transforms of all sub-objects *
3341 * *
3342 * INPUT: *
3343 * *
3344 * OUTPUT: *
3345 * *
3346 * WARNINGS: *
3347 * *
3348 * HISTORY: *
3349 * 1/26/00 gth : Created. *
3350 *=============================================================================================*/
3352{
3353 /*
3354 ** Update the animation transforms, recurse up to the
3355 ** top of the tree...
3356 */
3358
3359 /*
3360 ** Put the computed transforms into our sub objects.
3361 */
3362 int lod,model;
3363
3364 for (lod = 0; lod < LodCount; lod++) {
3365 for (model = 0; model < Lod[lod].Count(); model++) {
3366
3367 RenderObjClass * robj = Lod[lod][model].Model;
3368 int bone = Lod[lod][model].BoneIndex;
3369
3370 robj->Set_Transform(HTree->Get_Transform(bone));
3371 robj->Set_Animation_Hidden(!HTree->Get_Visibility(bone));
3373 }
3374 }
3375
3376 for (model = 0; model < AdditionalModels.Count(); model++) {
3377
3378 RenderObjClass * robj = AdditionalModels[model].Model;
3379 int bone = AdditionalModels[model].BoneIndex;
3380
3381 robj->Set_Transform(HTree->Get_Transform(bone));
3382 robj->Set_Animation_Hidden(!HTree->Get_Visibility(bone));
3384 }
3385
3387}
3388
3389
3390/***********************************************************************************************
3391 * HLodClass::Update_Obj_Space_Bounding_Volumes -- update object-space bounding volumes *
3392 * *
3393 * INPUT: *
3394 * *
3395 * OUTPUT: *
3396 * *
3397 * WARNINGS: *
3398 * *
3399 * HISTORY: *
3400 * 1/26/00 gth : Created. *
3401 *=============================================================================================*/
3403{
3404 //
3405 // Do we still have a valid bounding box index?
3406 //
3407 ModelArrayClass &high_lod = Lod[LodCount - 1];
3408 int count = high_lod.Count ();
3409 if ( BoundingBoxIndex < 0 ||
3410 BoundingBoxIndex >= count ||
3411 high_lod[BoundingBoxIndex].Model->Class_ID () != RenderObjClass::CLASSID_OBBOX)
3412 {
3413 BoundingBoxIndex = -1;
3414 }
3415
3416 //
3417 // Attempt to find an OBBox mesh inside the heirarchy
3418 //
3419 int index = high_lod.Count ();
3420 while (index -- && BoundingBoxIndex == -1) {
3421 RenderObjClass *model = high_lod[index].Model;
3422
3423 //
3424 // Is this an OBBox mesh?
3425 //
3426 if (model->Class_ID () == RenderObjClass::CLASSID_OBBOX)
3427 {
3428 const char *name = model->Get_Name ();
3429 const char *name_seg = ::strchr (name, '.');
3430 if (name_seg != NULL) {
3431 name = name_seg + 1;
3432 }
3433
3434 //
3435 // Does the name match the designator we are looking for?
3436 //
3437 if (::stricmp (name, "BOUNDINGBOX") == 0) {
3438 BoundingBoxIndex = index;
3439 }
3440 }
3441 }
3442
3443
3444 int i;
3445 RenderObjClass * robj = NULL;
3446
3447 // if we don't have any sub objects, just set default bounds
3448 if (Get_Num_Sub_Objects() <= 0) {
3449 ObjSphere.Init(Vector3(0,0,0),0);
3450 ObjBox.Center.Set(0,0,0);
3451 ObjBox.Extent.Set(0,0,0);
3452 return;
3453 }
3454
3455 // loop through all sub-objects, combining their object-space bounding spheres and boxes.
3456 // Put our HTree in its base pose at the origin.
3457 SphereClass sphere;
3458 AABoxClass obj_aabox;
3459 MinMaxAABoxClass box;
3460
3461 HTree->Base_Update(Matrix3D(1));
3462
3463 robj = Get_Sub_Object(0);
3464 WWASSERT(robj);
3465
3466 const Matrix3D & bonetm = HTree->Get_Transform(Get_Sub_Object_Bone_Index(robj));
3467 robj->Get_Obj_Space_Bounding_Sphere(sphere);
3468 sphere.Transform(bonetm);
3469 robj->Get_Obj_Space_Bounding_Box(obj_aabox);
3470
3471 box.Init(obj_aabox);
3472 box.Transform(bonetm);
3473
3474 robj->Release_Ref();
3475
3476 for (i=1; i<Get_Num_Sub_Objects(); i++) {
3477 robj = Get_Sub_Object(i);
3478 WWASSERT(robj);
3479
3480 const Matrix3D & bonetm = HTree->Get_Transform(Get_Sub_Object_Bone_Index(robj));
3481
3482 SphereClass tmpsphere;
3483 robj->Get_Obj_Space_Bounding_Sphere(tmpsphere);
3484 tmpsphere.Transform(bonetm);
3485 sphere.Add_Sphere(tmpsphere);
3486
3487 AABoxClass tmpbox;
3488 robj->Get_Obj_Space_Bounding_Box(tmpbox);
3489 tmpbox.Transform(bonetm);
3490 box.Add_Box(tmpbox);
3491
3492 robj->Release_Ref();
3493 }
3494
3495 ObjSphere = sphere;
3496 ObjBox = box;
3497
3499 Set_Hierarchy_Valid(false);
3500
3501 // Now update the object space bounding volumes of this object's container:
3502 RenderObjClass *container = Get_Container();
3503 if (container) container->Update_Obj_Space_Bounding_Volumes();
3504}
3505
3506
3507/***********************************************************************************************
3508 * HLodClass::Add_Lod_Model -- adds a model to one of the lods *
3509 * *
3510 * INPUT: *
3511 * *
3512 * OUTPUT: *
3513 * *
3514 * WARNINGS: *
3515 * *
3516 * HISTORY: *
3517 * 1/26/00 gth : Created. *
3518 *=============================================================================================*/
3519void HLodClass::Add_Lod_Model(int lod, RenderObjClass * robj, int boneindex)
3520{
3521 WWASSERT(robj != NULL);
3522
3523 // (gth) survive the case where the skeleton for this object no longer has
3524 // the bone that we're trying to use. This happens when a skeleton is re-exported
3525 // but the models that depend on it aren't re-exported...
3526 if (boneindex >= HTree->Num_Pivots()) {
3527 WWDEBUG_SAY(("ERROR: Model %s tried to use bone %d in skeleton %s. Please re-export!\n",Get_Name(),boneindex,HTree->Get_Name()));
3528 boneindex = 0;
3529 }
3530
3531 ModelNodeClass newnode;
3532 newnode.Model = robj;
3533 newnode.Model->Add_Ref();
3534 newnode.BoneIndex = boneindex;
3535 newnode.Model->Set_Container(this);
3536 newnode.Model->Set_Transform(HTree->Get_Transform(boneindex));
3537
3538 if (Is_In_Scene() && lod == CurLod) {
3539 newnode.Model->Notify_Added(Scene);
3540 }
3541 Lod[lod].Add(newnode);
3542}
3543
3544
3545/***********************************************************************************************
3546 * HLodClass::Create_Decal -- create a decal on this HLod *
3547 * *
3548 * INPUT: *
3549 * *
3550 * OUTPUT: *
3551 * *
3552 * WARNINGS: *
3553 * *
3554 * HISTORY: *
3555 * 1/26/00 gth : Created. *
3556 *=============================================================================================*/
3558{
3559 for (int lod=0; lod<LodCount; lod++) {
3560 for (int model=0; model<Lod[lod].Count(); model++) {
3561 Lod[lod][model].Model->Create_Decal(generator);
3562 }
3563 }
3564
3565 for (int model=0; model<AdditionalModels.Count(); model++) {
3566 AdditionalModels[model].Model->Create_Decal(generator);
3567 }
3568}
3569
3570
3571/***********************************************************************************************
3572 * HLodClass::Delete_Decal -- remove a decal from this HLod *
3573 * *
3574 * The decal_id is the ID which was assigned to the DecalGeneratorClass when you created *
3575 * the decal. *
3576 * *
3577 * INPUT: *
3578 * *
3579 * OUTPUT: *
3580 * *
3581 * WARNINGS: *
3582 * *
3583 * HISTORY: *
3584 * 1/26/00 gth : Created. *
3585 *=============================================================================================*/
3587{
3588 for (int lod=0; lod<LodCount; lod++) {
3589 for (int model=0; model<Lod[lod].Count(); model++) {
3590 Lod[lod][model].Model->Delete_Decal(decal_id);
3591 }
3592 }
3593
3594 for (int model=0; model<AdditionalModels.Count(); model++) {
3595 AdditionalModels[model].Model->Delete_Decal(decal_id);
3596 }
3597}
3598
3599
3600/***********************************************************************************************
3601 * HLodClass::Set_HTree -- replace the hierarchy tree *
3602 * *
3603 * INPUT: *
3604 * *
3605 * OUTPUT: *
3606 * *
3607 * WARNINGS: *
3608 * *
3609 * HISTORY: *
3610 * 1/26/00 gth : Created. *
3611 *=============================================================================================*/
3616
3617
3618/***********************************************************************************************
3619 * HLodClass::Set_Hidden -- Propogates the hidden bit to particle emitters. *
3620 * *
3621 * INPUT: *
3622 * *
3623 * OUTPUT: *
3624 * *
3625 * WARNINGS: *
3626 * *
3627 * HISTORY: *
3628 * 3/19/01 pds : Created. *
3629 *=============================================================================================*/
3631{
3632 //
3633 // Loop over all attached models
3634 //
3635 int additional_count = AdditionalModels.Count();
3636 for (int index = 0; index < additional_count; index ++) {
3637
3638 //
3639 // Is this a particle emitter?
3640 //
3641 RenderObjClass *model = AdditionalModels[index].Model;
3643
3644 //
3645 // Pass the hidden bit onto the emitter
3646 //
3647 model->Set_Hidden(onoff);
3648 }
3649 }
3650
3652 return ;
3653}
3654
#define NULL
Definition BaseType.h:92
#define TRUE
Definition BaseType.h:109
#define FALSE
Definition BaseType.h:113
Color scale(const Color &a, const Color &b)
Definition GameMtl.cpp:722
#define WWASSERT
#define W3D_NAME_LEN
Definition w3d_file.h:319
@ W3D_CHUNK_HLOD_AGGREGATE_ARRAY
Definition w3d_file.h:470
@ W3D_CHUNK_HLOD_PROXY_ARRAY
Definition w3d_file.h:471
@ W3D_CHUNK_HLOD
Definition w3d_file.h:465
@ W3D_CHUNK_HLOD_LOD_ARRAY
Definition w3d_file.h:467
@ W3D_CHUNK_HLOD_SUB_OBJECT
Definition w3d_file.h:469
@ W3D_CHUNK_HLOD_HEADER
Definition w3d_file.h:466
@ W3D_CHUNK_HLOD_SUB_OBJECT_ARRAY_HEADER
Definition w3d_file.h:468
#define W3D_CURRENT_HLOD_VERSION
Definition w3d_file.h:2044
#define NO_MAX_SCREEN_SIZE
Definition w3d_file.h:2045
#define W3DNEWARRAY
Definition always.h:110
#define MIN(a, b)
Definition always.h:189
#define W3DMPO_GLUE(ARGCLASS)
Definition always.h:120
#define W3DNEW
Definition always.h:109
#define MAX(a, b)
Definition always.h:185
unsigned long uint32
Definition bittype.h:46
void Transform(const Matrix3D &tm)
Definition aabox.h:185
Vector3 Center
Definition aabox.h:123
Vector3 Extent
Definition aabox.h:124
virtual bool Simple_Evaluate_Bone(int boneindex, Matrix3D *tm) const
Definition animobj.cpp:870
void Set_Hierarchy_Valid(bool onoff) const
Definition animobj.h:158
Animatable3DObjClass(const char *htree_name)
Definition animobj.cpp:84
virtual void Render(RenderInfoClass &rinfo)
Definition animobj.cpp:288
virtual void Update_Sub_Object_Transforms(void)
Definition animobj.cpp:780
Animatable3DObjClass & operator=(const Animatable3DObjClass &)
Definition animobj.cpp:198
virtual const HTreeClass * Get_HTree(void) const
Definition animobj.h:112
virtual int Get_Bone_Index(const char *bonename)
Definition animobj.cpp:429
virtual void Special_Render(SpecialRenderInfoClass &rinfo)
Definition animobj.cpp:319
virtual void Set_HTree(HTreeClass *htree)
Definition animobj.cpp:1131
virtual void Set_Animation(void)
Definition animobj.cpp:452
virtual void Set_Position(const Vector3 &v)
Definition animobj.cpp:366
virtual void Set_Transform(const Matrix3D &m)
Definition animobj.cpp:347
HTreeClass * HTree
Definition animobj.h:172
const Vector3 & Get_Local_Center(void)
Definition boxrobj.h:100
const Vector3 & Get_Local_Extent(void)
Definition boxrobj.h:101
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
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
virtual const char * Get_Name(void) const
virtual void Set_Name(const char *name)
SphereClass ObjSphere
Definition composite.h:93
virtual void Get_Obj_Space_Bounding_Box(AABoxClass &box) const
Definition composite.h:84
int Count(void) const
Definition Vector.H:507
RenderObjClass * Model
Definition hlod.h:237
HLodClass(void)
Definition hlod.cpp:920
virtual int Get_Lod_Model_Bone(int lod_index, int model_index) const
Definition hlod.cpp:1784
virtual void Special_Render(SpecialRenderInfoClass &rinfo)
Definition hlod.cpp:2186
virtual int Add_Sub_Object_To_Bone(RenderObjClass *subobj, int bone_index)
Definition hlod.cpp:2562
virtual float Get_Value(void) const
Definition hlod.cpp:3054
virtual float Get_Max_Screen_Size(int lod_index) const
Definition hlod.cpp:1614
virtual void Render(RenderInfoClass &rinfo)
Definition hlod.cpp:2146
virtual float Get_Cost(void) const
Definition hlod.cpp:3036
virtual void Scale(float scale)
Definition hlod.cpp:3264
virtual void Decrement_LOD(void)
Definition hlod.cpp:3002
virtual RenderObjClass * Peek_Additional_Model(int model_index) const
Definition hlod.cpp:1834
virtual void Set_Position(const Vector3 &v)
Definition hlod.cpp:2241
int CurLod
Definition hlod.h:257
virtual void Prepare_LOD(CameraClass &camera)
Definition hlod.cpp:2861
virtual void Get_Obj_Space_Bounding_Box(AABoxClass &box) const
Definition hlod.cpp:1427
virtual void Update_Sub_Object_Transforms(void)
Definition hlod.cpp:3351
ModelArrayClass AdditionalModels
Definition hlod.h:274
virtual int Get_Num_Sub_Objects_On_Bone(int boneindex) const
Definition hlod.cpp:2460
float * Cost
Definition hlod.h:266
virtual bool Cast_Ray(RayCollisionTestClass &raytest)
Definition hlod.cpp:2686
virtual void Set_LOD_Bias(float bias)
Definition hlod.cpp:1662
float * Value
Definition hlod.h:267
virtual bool Cast_OBBox(OBBoxCollisionTestClass &boxtest)
Definition hlod.cpp:2756
virtual int Get_LOD_Level(void) const
Definition hlod.cpp:3128
virtual int Calculate_Cost_Value_Arrays(float screen_area, float *values, float *costs) const
Definition hlod.cpp:3164
virtual int Get_Num_Polys(void) const
Definition hlod.cpp:2112
ModelArrayClass * Lod
Definition hlod.h:258
virtual void Increment_LOD(void)
Definition hlod.cpp:2968
virtual void Add_Lod_Model(int lod, RenderObjClass *robj, int boneindex)
Definition hlod.cpp:3519
virtual bool Intersect_OBBox(OBBoxIntersectionTestClass &boxtest)
Definition hlod.cpp:2826
virtual bool Get_Proxy(int index, ProxyClass &proxy) const
Definition hlod.cpp:2071
SnapPointsClass * SnapPoints
Definition hlod.h:277
virtual void Get_Obj_Space_Bounding_Sphere(SphereClass &sphere) const
Definition hlod.cpp:1481
virtual void Set_Max_Screen_Size(int lod_index, float size)
Definition hlod.cpp:1577
virtual int Get_Proxy_Count(void) const
Definition hlod.cpp:2049
HLodClass(const HLodClass &src)
Definition hlod.cpp:948
virtual int Get_LOD_Count(void) const
Definition hlod.cpp:3146
void Free(void)
Definition hlod.cpp:1349
virtual RenderObjClass * Get_Sub_Object_On_Bone(int index, int boneindex) const
Definition hlod.cpp:2488
virtual RenderObjClass * Get_Additional_Model(int model_index) const
Definition hlod.cpp:1865
virtual void Recalculate_Static_LOD_Factors(void)
Definition hlod.cpp:2922
virtual const AABoxClass & Get_Bounding_Box(void) const
Definition hlod.cpp:1540
HLodClass & operator=(const HLodClass &)
Definition hlod.cpp:1243
float LODBias
Definition hlod.h:283
ProxyArrayClass * ProxyArray
Definition hlod.h:280
virtual int Get_Sub_Object_Bone_Index(RenderObjClass *subobj) const
Definition hlod.cpp:2527
virtual int Add_Sub_Object(RenderObjClass *subobj)
Definition hlod.cpp:2367
virtual void Notify_Added(SceneClass *scene)
Definition hlod.cpp:2260
virtual bool Cast_AABox(AABoxCollisionTestClass &boxtest)
Definition hlod.cpp:2721
virtual int Get_Lod_Model_Count(int lod_index) const
Definition hlod.cpp:1687
virtual void Get_Snap_Point(int index, Vector3 *set)
Definition hlod.cpp:3328
virtual void Update_Obj_Space_Bounding_Volumes(void)
Definition hlod.cpp:3402
virtual RenderObjClass * Clone(void) const
Definition hlod.cpp:1409
virtual void Notify_Removed(SceneClass *scene)
Definition hlod.cpp:2288
virtual RenderObjClass * Peek_Lod_Model(int lod_index, int model_index) const
Definition hlod.cpp:1717
virtual int Remove_Sub_Object(RenderObjClass *robj)
Definition hlod.cpp:2385
int LodCount
Definition hlod.h:256
virtual RenderObjClass * Get_Current_LOD(void)
Definition hlod.cpp:3213
virtual bool Is_NULL_Lod_Included(void) const
Definition hlod.cpp:1930
virtual int Get_Lod_Count(void) const
Definition hlod.cpp:1644
virtual void Set_Transform(const Matrix3D &m)
Definition hlod.cpp:2222
virtual int Get_Num_Snap_Points(void)
Definition hlod.cpp:3306
virtual void Create_Decal(DecalGeneratorClass *generator)
Definition hlod.cpp:3557
virtual int Get_Additional_Model_Count(void) const
Definition hlod.cpp:1816
virtual RenderObjClass * Get_Lod_Model(int lod_index, int model_index) const
Definition hlod.cpp:1749
virtual ~HLodClass(void)
Definition hlod.cpp:1331
virtual const SphereClass & Get_Bounding_Sphere(void) const
Definition hlod.cpp:1502
virtual void Set_LOD_Level(int lod)
Definition hlod.cpp:3090
virtual int Get_Additional_Model_Bone(int model_index) const
Definition hlod.cpp:1899
int BoundingBoxIndex
Definition hlod.h:264
virtual void Set_HTree(HTreeClass *htree)
Definition hlod.cpp:3612
virtual void Set_Animation(void)
Definition hlod.cpp:2603
virtual void Include_NULL_Lod(bool include=true)
Definition hlod.cpp:1956
virtual void Set_Hidden(int onoff)
Definition hlod.cpp:3630
virtual float Get_Post_Increment_Value(void) const
Definition hlod.cpp:3072
virtual void Delete_Decal(uint32 decal_id)
Definition hlod.cpp:3586
virtual int Get_Num_Sub_Objects(void) const
Definition hlod.cpp:2316
virtual RenderObjClass * Get_Sub_Object(int index) const
Definition hlod.cpp:2339
virtual bool Intersect_AABox(AABoxIntersectionTestClass &boxtest)
Definition hlod.cpp:2791
friend class HLodClass
Definition hlod.h:362
HLodDefClass(void)
Definition hlod.cpp:273
WW3DErrorType Save(ChunkSaveClass &csave)
Definition hlod.cpp:439
WW3DErrorType Save_Header(ChunkSaveClass &csave)
Definition hlod.cpp:476
~HLodDefClass(void)
Definition hlod.cpp:319
WW3DErrorType Save_Aggregate_Array(ChunkSaveClass &csave)
Definition hlod.cpp:555
const char * Get_Name(void) const
Definition hlod.h:314
WW3DErrorType Load_W3D(ChunkLoadClass &cload)
Definition hlod.cpp:578
void Initialize(HLodClass &src_lod)
Definition hlod.cpp:374
WW3DErrorType Save_Lod_Array(ChunkSaveClass &csave)
Definition hlod.cpp:525
virtual PrototypeClass * Load_W3D(ChunkLoadClass &cload)
Definition hlod.cpp:213
virtual RenderObjClass * Create(void)
Definition hlod.cpp:251
const char * Get_Name(void) const
Definition hmdldef.H:88
WWINLINE const char * Get_Name(void) const
Definition htree.h:92
static void Multiply(const Matrix3D &A, const Matrix3D &B, Matrix3D *set_result)
Definition matrix3d.cpp:640
void mulVector3(const Vector3 &in, Vector3 &out) const
Definition matrix3d.h:1650
void Get_Orthogonal_Inverse(Matrix3D &set_inverse) const
Definition matrix3d.cpp:570
void Transform_Center_Extent_AABox(const Vector3 &center, const Vector3 &extent, Vector3 *set_center, Vector3 *set_extent) const
void Add_Box(const MinMaxAABoxClass &box)
Definition aabox.h:586
WWINLINE void Init(Vector3 *points, int num)
Definition aabox.h:523
void Transform(const Matrix3D &tm)
Definition aabox.h:652
static void Add_Object(RenderObjClass *robj)
Definition predlod.cpp:226
static void Add_Cost(float cost)
Definition predlod.h:67
ProxyArrayClass(int size)
Definition hlod.cpp:190
void Set_Transform(const Matrix3D &tm)
Definition proxy.h:82
void Set_Name(const char *name)
Definition proxy.h:79
bool operator==(const ProxyRecordClass &that)
Definition hlod.cpp:162
char Name[2 *W3D_NAME_LEN]
Definition hlod.cpp:177
bool operator!=(const ProxyRecordClass &that)
Definition hlod.cpp:163
const char * Get_Name(void)
Definition hlod.cpp:172
int Get_Bone_Index(void)
Definition hlod.cpp:171
ProxyRecordClass(void)
Definition hlod.cpp:157
void Init(const W3dHLodSubObjectStruct &w3d_data)
Definition hlod.cpp:165
WWINLINE void Release_Ref(void) const
Definition refcount.h:146
void Add_Ref(void) const
Definition refcount.cpp:171
RefCountClass(void)
Definition refcount.h:108
virtual float Get_Screen_Size(CameraClass &camera)
Definition rendobj.cpp:324
virtual void Set_Transform(const Matrix3D &m)
Definition rendobj.cpp:423
virtual void Get_Obj_Space_Bounding_Sphere(SphereClass &sphere) const
Definition rendobj.cpp:932
virtual int Is_Not_Hidden_At_All(void)
Definition rendobj.h:463
RenderObjClass(void)
Definition rendobj.cpp:170
int Is_Sub_Objects_Match_LOD_Enabled(void)
Definition rendobj.h:492
virtual void Update_Obj_Space_Bounding_Volumes(void)
Definition rendobj.h:394
virtual const SphereClass & Get_Bounding_Sphere(void) const
Definition rendobj.h:567
AABoxClass CachedBoundingBox
Definition rendobj.h:553
virtual void Notify_Added(SceneClass *scene)
Definition rendobj.cpp:862
virtual void Update_Sub_Object_Transforms(void)
Definition rendobj.cpp:777
virtual void Get_Obj_Space_Bounding_Box(AABoxClass &box) const
Definition rendobj.cpp:952
void Invalidate_Cached_Bounding_Volumes(void) const
Definition rendobj.h:523
virtual const AABoxClass & Get_Bounding_Box(void) const
Definition rendobj.h:575
virtual void Update_Sub_Object_Bits(void)
Definition rendobj.cpp:730
SceneClass * Scene
Definition rendobj.h:557
void Set_Sub_Object_Transforms_Dirty(bool onoff)
Definition rendobj.h:494
virtual const HTreeClass * Get_HTree(void) const
Definition rendobj.h:363
static const float AT_MAX_LOD
Definition rendobj.h:405
virtual int Class_ID(void) const
Definition rendobj.h:249
virtual void Set_Hidden(int onoff)
Definition rendobj.h:472
virtual bool Is_In_Scene(void)
Definition rendobj.h:487
bool Are_Sub_Object_Transforms_Dirty(void)
Definition rendobj.h:495
virtual void Set_LOD_Bias(float bias)
Definition rendobj.h:417
virtual void Notify_Removed(SceneClass *scene)
Definition rendobj.cpp:884
virtual void Set_Container(RenderObjClass *con)
Definition rendobj.cpp:382
virtual const char * Get_Name(void) const
Definition rendobj.h:250
const Matrix3D & Get_Transform(void) const
Definition rendobj.h:617
virtual int Get_Num_Sub_Objects(void) const
Definition rendobj.h:309
friend class SceneClass
Definition rendobj.h:563
RenderObjClass * Get_Container(void) const
Definition rendobj.h:291
@ CLASSID_PARTICLEEMITTER
Definition rendobj.h:214
virtual RenderObjClass * Get_Sub_Object(int index) const
Definition rendobj.h:310
virtual void Set_Animation_Hidden(int onoff)
Definition rendobj.h:474
virtual int Remove_Sub_Object(RenderObjClass *robj)
Definition rendobj.h:312
SphereClass CachedBoundingSphere
Definition rendobj.h:552
virtual int Get_Sub_Object_Bone_Index(RenderObjClass *subobj) const
Definition rendobj.h:317
static const float AT_MIN_LOD
Definition rendobj.h:404
float Radius
Definition sphere.h:91
Vector3 Center
Definition sphere.h:90
void Transform(const Matrix3D &tm)
Definition sphere.h:354
void Add_Sphere(const SphereClass &s)
Definition sphere.h:309
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
WWINLINE float Length(void) const
Definition vector3.h:453
WWINLINE VectorClass(NoInitClass const &)
Definition Vector.H:91
virtual RenderObjClass * Create_Render_Obj(const char *name)
Definition assetmgr.cpp:799
static WW3DAssetManager * Get_Instance(void)
Definition assetmgr.h:205
HLodLoaderClass _HLodLoader
Definition hlod.cpp:145
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
char RenderObjName[2 *W3D_NAME_LEN]
Definition hmdldef.H:61
char Name[W3D_NAME_LEN]
Definition w3d_file.h:2051
char HierarchyName[W3D_NAME_LEN]
Definition w3d_file.h:2052
char Name[W3D_NAME_LEN *2]
Definition w3d_file.h:2064
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 WWDEBUG_SAY(x)
Definition wwdebug.h:114