/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** 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 *** *********************************************************************************************** * * * Project Name : WW3D * * * * $Archive:: /Commando/Code/ww3d2/hlod.h $* * * * Author:: Greg Hjelstrom * * * * $Modtime:: 5/25/01 1:37p $* * * * $Revision:: 3 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(_MSC_VER) #pragma once #endif #ifndef HLOD_H #define HLOD_H #ifndef ANIMOBJ_H #include "animobj.h" #endif #ifndef VECTOR_H #include "vector.h" #endif #ifndef SNAPPTS_H #include "snappts.h" #endif #ifndef PROTO_H #include "proto.h" #endif #ifndef W3DERR_H #include "w3derr.h" #endif #ifndef __PROXY_H #include "proxy.h" #endif class DistLODClass; class HModelClass; class HLodDefClass; class HModelDefClass; class ProxyArrayClass; /* HLodClass This is an hierarchical, animatable level-of-detail model. */ class HLodClass : public Animatable3DObjClass { public: HLodClass(const HLodClass & src); HLodClass(const char * name,RenderObjClass ** lods,int count); HLodClass(const HLodDefClass & def); HLodClass(const HModelDefClass & def); HLodClass & operator = (const HLodClass &); virtual ~HLodClass(void); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - Cloning and Identification ///////////////////////////////////////////////////////////////////////////// virtual RenderObjClass * Clone(void) const; virtual int Class_ID(void) const { return CLASSID_HLOD; } virtual int Get_Num_Polys(void) const; ///////////////////////////////////////////////////////////////////////////// // HLod Interface - Editing and information ///////////////////////////////////////////////////////////////////////////// virtual void Set_Max_Screen_Size(int lod_index, float size); virtual float Get_Max_Screen_Size(int lod_index) const; virtual int Get_Lod_Count(void) const; virtual int Get_Lod_Model_Count (int lod_index) const; virtual RenderObjClass * Peek_Lod_Model (int lod_index, int model_index) const; virtual RenderObjClass * Get_Lod_Model (int lod_index, int model_index) const; virtual int Get_Lod_Model_Bone (int lod_index, int model_index) const; virtual int Get_Additional_Model_Count(void) const; virtual RenderObjClass * Peek_Additional_Model (int model_index) const; virtual RenderObjClass * Get_Additional_Model (int model_index) const; virtual int Get_Additional_Model_Bone (int model_index) const; virtual bool Is_NULL_Lod_Included (void) const; virtual void Include_NULL_Lod (bool include = true); ///////////////////////////////////////////////////////////////////////////// // Proxy interface ///////////////////////////////////////////////////////////////////////////// virtual int Get_Proxy_Count (void) const; virtual bool Get_Proxy (int index, ProxyClass &proxy) const; ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - Rendering ///////////////////////////////////////////////////////////////////////////// virtual void Render(RenderInfoClass & rinfo); virtual void Special_Render(SpecialRenderInfoClass & rinfo); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - "Scene Graph" ///////////////////////////////////////////////////////////////////////////// virtual void Set_Transform(const Matrix3D &m); virtual void Set_Position(const Vector3 &v); virtual void Notify_Added(SceneClass * scene); virtual void Notify_Removed(SceneClass * scene); virtual int Get_Num_Sub_Objects(void) const; virtual RenderObjClass * Get_Sub_Object(int index) const; virtual int Add_Sub_Object(RenderObjClass * subobj); virtual int Remove_Sub_Object(RenderObjClass * robj); virtual int Get_Num_Sub_Objects_On_Bone(int boneindex) const; virtual RenderObjClass * Get_Sub_Object_On_Bone(int index,int boneindex) const; virtual int Get_Sub_Object_Bone_Index(RenderObjClass * subobj) const; virtual int Add_Sub_Object_To_Bone(RenderObjClass * subobj,int bone_index); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - Hierarchical Animation ///////////////////////////////////////////////////////////////////////////// virtual void Set_Animation(void); virtual void Set_Animation( HAnimClass * motion, float frame, int anim_mode = ANIM_MODE_MANUAL); virtual void Set_Animation( HAnimClass * motion0, float frame0, HAnimClass * motion1, float frame1, float percentage); virtual void Set_Animation( HAnimComboClass * anim_combo); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - Collision Detection, Ray Tracing ///////////////////////////////////////////////////////////////////////////// virtual bool Cast_Ray(RayCollisionTestClass & raytest); virtual bool Cast_AABox(AABoxCollisionTestClass & boxtest); virtual bool Cast_OBBox(OBBoxCollisionTestClass & boxtest); virtual bool Intersect_AABox(AABoxIntersectionTestClass & boxtest); virtual bool Intersect_OBBox(OBBoxIntersectionTestClass & boxtest); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - Predictive LOD ///////////////////////////////////////////////////////////////////////////// virtual void Prepare_LOD(CameraClass &camera); virtual void Recalculate_Static_LOD_Factors(void); virtual void Increment_LOD(void); virtual void Decrement_LOD(void); virtual float Get_Cost(void) const; virtual float Get_Value(void) const; virtual float Get_Post_Increment_Value(void) const; virtual void Set_LOD_Level(int lod); virtual int Get_LOD_Level(void) const; virtual int Get_LOD_Count(void) const; virtual void Set_LOD_Bias(float bias); virtual int Calculate_Cost_Value_Arrays(float screen_area, float *values, float *costs) const; virtual RenderObjClass * Get_Current_LOD(void); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Render Object Interface - Bounding Volumes /////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual const SphereClass & Get_Bounding_Sphere(void) const; virtual const AABoxClass & Get_Bounding_Box(void) const; virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const; virtual void Get_Obj_Space_Bounding_Box(AABoxClass & box) const; /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Render Object Interface - Decals /////////////////////////////////////////////////////////////////////////////////////////////////////////////// virtual void Create_Decal(DecalGeneratorClass * generator); virtual void Delete_Decal(uint32 decal_id); ///////////////////////////////////////////////////////////////////////////// // Render Object Interface - Attributes, Options, Properties, etc ///////////////////////////////////////////////////////////////////////////// // virtual void Set_Texture_Reduction_Factor(float trf); virtual void Scale(float scale); virtual void Scale(float scalex, float scaley, float scalez) { } virtual int Get_Num_Snap_Points(void); virtual void Get_Snap_Point(int index,Vector3 * set); virtual void Set_Hidden(int onoff); // (gth) TESTING DYNAMICALLY SWAPPING SKELETONS! virtual void Set_HTree(HTreeClass * htree); protected: HLodClass(void); void Free(void); virtual void Update_Sub_Object_Transforms(void); virtual void Update_Obj_Space_Bounding_Volumes(void); void add_lod_model(int lod,RenderObjClass * robj,int boneindex); protected: class ModelNodeClass { public: RenderObjClass * Model; int BoneIndex; bool operator == (const ModelNodeClass & that) { return (Model == that.Model) && (BoneIndex == that.BoneIndex); } bool operator != (const ModelNodeClass & that) { return !operator == (that); } }; class ModelArrayClass : public DynamicVectorClass { public: ModelArrayClass(void) : MaxScreenSize(NO_MAX_SCREEN_SIZE), NonPixelCost(0.0f), PixelCostPerArea(0.0f), BenefitFactor(0.0f) {} float MaxScreenSize; // Maximum screen size for this LOD float NonPixelCost; // Cost heuristics of LODS (w/o per-pixel cost) float PixelCostPerArea; // PixelCostPerArea * area(normalized) + NonPixelCost = total Cost float BenefitFactor; // BenefitFactor * area(normalized) = Benefit }; // Lod Render Objects, basically one of the LOD Models will be rendered. Typically // each model in an HLodModel will be a mesh or a "simple" HLod (one with a single LOD) int LodCount; int CurLod; ModelArrayClass * Lod; // // An animating heirarchy can use a hidden CLASSID_OBBOX mesh to represent its bounding // box as it animates. This is the sub object index of that mesh (if it exists). // int BoundingBoxIndex; float * Cost; // Cost array (recalculated every frame) float * Value; // Value array (recalculated every frame) // Additional Models, these models have been linked to one of the bones in this // model. They are all always rendered. They can be HLODs themselves in order // to implement switching on sub models. // NOTE: This uses ModelArrayClass for convenience, but MaxScreenSize, // NonPixelCost, PixelCostPerArea, BenefitFactor are not used here. ModelArrayClass AdditionalModels; // possible array of snap points. SnapPointsClass * SnapPoints; // possible array of proxy objects (names and bone indexes for application defined usage) ProxyArrayClass * ProxyArray; // Current LOD Bias (affects recalculation of the Value array) float LODBias; }; /* ** Loaders for HLodClass */ class HLodLoaderClass : public PrototypeLoaderClass { public: virtual int Chunk_Type (void) { return W3D_CHUNK_HLOD; } virtual PrototypeClass * Load_W3D(ChunkLoadClass & cload); }; /** ** HLodDefClass ** This description object is generated when reading a W3D_CHUNK_HLOD. It ** directly describes the contents of an HLod model. */ class HLodDefClass { public: HLodDefClass(void); HLodDefClass(HLodClass &src_lod); ~HLodDefClass(void); WW3DErrorType Load_W3D(ChunkLoadClass & cload); WW3DErrorType Save(ChunkSaveClass & csave); const char * Get_Name(void) const { return Name; } void Initialize(HLodClass &src_lod); protected: /* ** Serializtion methods */ WW3DErrorType Save_Header (ChunkSaveClass &csave); WW3DErrorType Save_Lod_Array (ChunkSaveClass &csave); WW3DErrorType Save_Aggregate_Array(ChunkSaveClass & csave); private: /* ** SubObjectArrayClass ** Describes a level-of-detail in an HLod object. Note that this is ** a render object which will be exploded when the HLod is constructed (its ** sub-objects, if any, will be placed into the HLod). */ class SubObjectArrayClass { public: SubObjectArrayClass(void); ~SubObjectArrayClass(void); void Reset(void); void operator = (const SubObjectArrayClass & that); bool Load_W3D(ChunkLoadClass & cload); bool Save_W3D(ChunkSaveClass & csave); float MaxScreenSize; int ModelCount; char ** ModelName; // array of model names int * BoneIndex; // array of bone indices }; char * Name; char * HierarchyTreeName; int LodCount; SubObjectArrayClass * Lod; SubObjectArrayClass Aggregates; ProxyArrayClass * ProxyArray; void Free(void); bool read_header(ChunkLoadClass & cload); bool read_proxy_array(ChunkLoadClass & cload); friend class HLodClass; }; /* ** Prototype for HLod objects */ class HLodPrototypeClass : public PrototypeClass { public: HLodPrototypeClass( HLodDefClass *def ) { Definition = def; } virtual ~HLodPrototypeClass(void) { delete Definition; } virtual const char * Get_Name(void) const { return Definition->Get_Name(); } virtual int Get_Class_ID(void) const { return RenderObjClass::CLASSID_HLOD; } virtual RenderObjClass * Create(void); HLodDefClass * Get_Definition(void) const { return Definition; } private: HLodDefClass * Definition; }; /* ** Instance of the loaders which the asset manager install */ extern HLodLoaderClass _HLodLoader; #endif