This repository has been archived on 2025-02-27. You can view files and clone it, but cannot push or open issues or pull requests.
CnC_Renegade/Code/ww3d2/hlod.h

388 lines
No EOL
14 KiB
C++

/*
** 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 <http://www.gnu.org/licenses/>.
*/
/***********************************************************************************************
*** 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<ModelNodeClass>
{
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