308 lines
12 KiB
C++
308 lines
12 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/decalsys.h $*
|
|
* *
|
|
* Original Author:: Greg Hjelstrom *
|
|
* *
|
|
* $Author:: Greg_h $*
|
|
* *
|
|
* $Modtime:: 6/29/01 11:30a $*
|
|
* *
|
|
* $Revision:: 6 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#if defined(_MSC_VER)
|
|
#pragma once
|
|
#endif
|
|
|
|
#ifndef DECALSYS_H
|
|
#define DECALSYS_H
|
|
|
|
#include "always.h"
|
|
#include "matrix3d.h"
|
|
#include "matrix4.h"
|
|
#include "obbox.h"
|
|
#include "robjlist.h"
|
|
#include "matpass.h"
|
|
#include "projector.h"
|
|
|
|
class DecalGeneratorClass;
|
|
class DecalMeshClass;
|
|
|
|
/**
|
|
** DecalSystemClass
|
|
** This is a class that manages creation and destruction of decals in the system. It is
|
|
** meant to be over-ridden for game-specific behaviors.
|
|
**
|
|
** Sample Code:
|
|
** 1 - Create the generator. The system gives it a unique id and gives you a clean decal generator
|
|
**
|
|
** DecalGeneratorClass * gen = DecalSystem->Lock_Decal_Generator();
|
|
** gen->Set_Transform(tm);
|
|
** gen->Set_Projection(proj_tm);
|
|
** gen->Set_Bounds(OBBox);
|
|
**
|
|
** 2 - Apply the generator to any objects that you want it to affect. It wont do anything if it
|
|
** does not overlap any polygons in those objects
|
|
**
|
|
** Scene->Collect_Objects(gen->Get_Bounding_Box(),objectlist);
|
|
** for (iterator.First(objectlist); !iterator.Is_Done(); iterator.Next()) {
|
|
** iterator.Peek_Object()->Create_Decal(gen);
|
|
** }
|
|
**
|
|
** 3 - Release the generator back to the system. At this point, the system may record which meshes
|
|
** actually generated extra decal polygons for future removal. All of this information will be
|
|
** tied together with the unique 'decal ID' that was assigned to the generator.
|
|
**
|
|
** DecalSystem->Unlock_Decal_Generator(gen);
|
|
**
|
|
*/
|
|
class DecalSystemClass
|
|
{
|
|
public:
|
|
DecalSystemClass(void);
|
|
virtual ~DecalSystemClass(void);
|
|
|
|
/*
|
|
** Create and release DecalGenerators. Note that this is the point at which the
|
|
** decal system can track "logical" decals. The generator will keep an internal list
|
|
** of all of the render objects which generated decals which you should copy if you
|
|
** want to track them (e.g. if you want to cap the maximum number of active decals and
|
|
** kill the old ones...)
|
|
*/
|
|
virtual DecalGeneratorClass * Lock_Decal_Generator(void);
|
|
virtual void Unlock_Decal_Generator(DecalGeneratorClass * generator);
|
|
|
|
/*
|
|
** When a decal-mesh is destroyed, it must inform the DecalSystem. Otherwise, systems
|
|
** which track decals can get dangling pointers.
|
|
*/
|
|
virtual void Decal_Mesh_Destroyed(uint32 decal_id,DecalMeshClass * mesh) { }
|
|
|
|
protected:
|
|
|
|
/*
|
|
** This generates the decal ID when a generator is created. This decal system reroutes this
|
|
** to Generate_Unique_Global_Decal_Id(), but other decal systems may use a different method.
|
|
*/
|
|
virtual uint32 Generate_Decal_Id(void) { return Generate_Unique_Global_Decal_Id(); }
|
|
|
|
/*
|
|
** Unique ID generation for decals. Not all decal systems have to use
|
|
** this method of generating ids. Some may wish to assign the id as the
|
|
** array index of the logical id or use some other aritrary method.
|
|
*/
|
|
static uint32 Generate_Unique_Global_Decal_Id(void);
|
|
|
|
static uint32 DecalIDGenerator;
|
|
};
|
|
|
|
|
|
/**
|
|
** DecalGeneratorClass
|
|
** This class encapsulates the information needed to generate a decal. It also tracks
|
|
** what meshes actually used it to generate new decal polygons.
|
|
*/
|
|
class DecalGeneratorClass : public ProjectorClass
|
|
{
|
|
public:
|
|
|
|
/*
|
|
** All meshes that actually generate decal polygons should register themselves in the
|
|
** list. Then when the decal generation is finished, this list can be copied so that
|
|
** we can come back to those meshes and remove the decals if we want to.
|
|
*/
|
|
void Add_Mesh(RenderObjClass * mesh);
|
|
NonRefRenderObjListClass & Get_Mesh_List(void);
|
|
|
|
/*
|
|
** Decal generator parameters.
|
|
** see ProjectorClass for control over the coordinate system, projection, etc
|
|
*/
|
|
uint32 Get_Decal_ID(void) { return DecalID; }
|
|
DecalSystemClass * Peek_Decal_System(void) { return System; }
|
|
|
|
/*
|
|
** Backface rejection thresh-hold. The dot-product between the projection vector and
|
|
** the normal of each polygon is taken, if the result is greater than this value the polygon
|
|
** is accepted into the decal. Set it to -1 if you want to accept all polygons.
|
|
*/
|
|
void Set_Backface_Threshhold(float val) { BackfaceVal = val; }
|
|
float Get_Backface_Threshhold(void) { return BackfaceVal; }
|
|
|
|
/*
|
|
** Normally, decals are not generated on translucent meshes. This is due to the "floating
|
|
** decals" that you can get on things like trees. The user can override this behavior
|
|
** through the following interface.
|
|
*/
|
|
void Apply_To_Translucent_Meshes(bool onoff) { ApplyToTranslucentMeshes = onoff; }
|
|
bool Is_Applied_To_Translucent_Meshes(void) { return ApplyToTranslucentMeshes; }
|
|
|
|
/*
|
|
** Material parameters: just grab a pointer the material pass and modify it.
|
|
** Remember to release your ref to it when you are done.
|
|
*/
|
|
MaterialPassClass * Get_Material(void) { WWASSERT(Material != NULL); Material->Add_Ref(); return Material; }
|
|
|
|
/*
|
|
** Decal generation support. Call Set_Mesh_Transform for the mesh you want to add
|
|
** a decal to. Then for each vertex, you can call 'Compute_Texture_Coordinate'
|
|
*/
|
|
void Set_Mesh_Transform(const Matrix3D & tm);
|
|
|
|
protected:
|
|
|
|
DecalGeneratorClass(uint32 id,DecalSystemClass * system);
|
|
~DecalGeneratorClass(void);
|
|
|
|
/*
|
|
** Logical Decal ID, DecalSystem that this generator is tied to
|
|
*/
|
|
DecalSystemClass * System;
|
|
uint32 DecalID; // unique ID generated by the DecalSystem
|
|
|
|
/*
|
|
** Backface Threshhold, Translucent mesh decal enable
|
|
*/
|
|
float BackfaceVal;
|
|
bool ApplyToTranslucentMeshes;
|
|
|
|
/*
|
|
** Material settings
|
|
*/
|
|
MaterialPassClass * Material; // material settings for the decal
|
|
|
|
/*
|
|
** Results, list of the meshes which actually generated decal polygons for this logical decal.
|
|
*/
|
|
NonRefRenderObjListClass MeshList;
|
|
|
|
friend class DecalSystemClass;
|
|
};
|
|
|
|
|
|
/**
|
|
** MultiFixedPoolDecalSystemClass: This is for decal systems which use several fixed-size decal
|
|
** pools (If more than one pool is used, it is usually to have separate pools for several
|
|
** different classes of decals). Note that here the decal IDs are a combination of the pool and
|
|
** slot ids. (decal ids only have to be unique within a given decal system)
|
|
*/
|
|
|
|
class MultiFixedPoolDecalSystemClass : public DecalSystemClass
|
|
{
|
|
|
|
public:
|
|
|
|
MultiFixedPoolDecalSystemClass(uint32 num_pools, const uint32 *pool_sizes);
|
|
MultiFixedPoolDecalSystemClass(const MultiFixedPoolDecalSystemClass & that);
|
|
virtual ~MultiFixedPoolDecalSystemClass(void);
|
|
|
|
// This clears the slot in addition to locking the generator, thus preventing any decal id
|
|
// collisions (since any decal previously in that slot will have the same id as the new one).
|
|
virtual DecalGeneratorClass * Lock_Decal_Generator(void);
|
|
|
|
// This will register the decal in the system in the appropriate pool and slot (determined by
|
|
// the generator's pool and slot ids), removing any decal which may have been there before.
|
|
virtual void Unlock_Decal_Generator(DecalGeneratorClass * generator);
|
|
|
|
// This notifies the system that a mesh which has decals on it was destroyed - therefore we
|
|
// need to remove the mesh from our list to avoid dangling pointers.
|
|
virtual void Decal_Mesh_Destroyed(uint32 id,DecalMeshClass * mesh);
|
|
|
|
// Not part of the DecalSystemClass interface - this function removes any decal currently in
|
|
// the given slot in the given pool.
|
|
void Clear_Decal_Slot(uint32 pool_id, uint32 slot_id);
|
|
|
|
// This one removes all decals in a given pool.
|
|
void Clear_Pool(uint32 pool_id);
|
|
|
|
// And this one removes all decals in the system.
|
|
void Clear_All_Decals(void);
|
|
|
|
protected:
|
|
|
|
/*
|
|
** This generates the decal ID when a generator is created. This decal system generates the
|
|
** decal ID from a pool ID and slot ID which are part of the state of the system so someone
|
|
** can set them before calling Lock_Decal_Generator() (which is where this function is called).
|
|
** We do it this way to avoid needing to override Lock_Decal_Generator().
|
|
*/
|
|
virtual uint32 Generate_Decal_Id(void) { return encode_decal_id(Generator_PoolID, Generator_SlotID); }
|
|
uint32 Generator_PoolID; // These should be set before calling Lock_Decal_Generator()
|
|
uint32 Generator_SlotID; // These should be set before calling Lock_Decal_Generator()
|
|
|
|
class LogicalDecalClass;
|
|
|
|
// Get a reference to the logical decal at the given pool and slot id (performs range chacking)
|
|
LogicalDecalClass & find_logical_decal(uint32 pool_id, uint32 slot_id);
|
|
|
|
// Get a reference to the logical decal with the given decal id
|
|
LogicalDecalClass & find_logical_decal(uint32 decal_id);
|
|
|
|
// The decal ids are formed so that the upper 16 bits are equal to the pool id and the lower
|
|
// 16 bits are equal to the slot id.
|
|
static uint32 encode_decal_id(uint32 pool_id, uint32 slot_id) { return (slot_id & 0xFFFF) | (pool_id << 16); }
|
|
static void decode_decal_id(uint32 decal_id, uint32 & pool_id, uint32 & slot_id) { slot_id = decal_id & 0xFFFF; pool_id = decal_id >> 16; }
|
|
|
|
// A class to store the meshes to which the decal has been applied (so that they can be removed when needed)
|
|
class LogicalDecalClass
|
|
{
|
|
public:
|
|
LogicalDecalClass(void);
|
|
~LogicalDecalClass(void);
|
|
|
|
void Set(DecalGeneratorClass * generator);
|
|
|
|
// Just clears any existing logical decal information, leaving the decal empty.
|
|
void Clear(uint32 decal_id);
|
|
|
|
NonRefRenderObjListClass MeshList;
|
|
};
|
|
|
|
class LogicalDecalPoolClass
|
|
{
|
|
public:
|
|
LogicalDecalPoolClass(void);
|
|
~LogicalDecalPoolClass(void);
|
|
|
|
void Initialize(uint32 size);
|
|
|
|
LogicalDecalClass * Array;
|
|
uint32 Size;
|
|
};
|
|
|
|
LogicalDecalPoolClass * Pools;
|
|
uint32 PoolCount;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif //DECALSYS_H
|
|
|