mirror of
https://github.com/jmarshall23/DoomRTX.git
synced 2026-08-19 12:14:35 +02:00
Quake 4 integrated with DoomRTX
This commit is contained in:
@@ -0,0 +1,387 @@
|
||||
// BSE_Manager.cpp
|
||||
//
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "BSE_Envelope.h"
|
||||
#include "BSE_Particle.h"
|
||||
#include "BSE.h"
|
||||
#include "BSE_SpawnDomains.h"
|
||||
|
||||
namespace {
|
||||
ID_INLINE int BSE_GetFrameCounterMode(void) {
|
||||
return cvarSystem ? cvarSystem->GetCVarInteger("bse_frameCounters") : 0;
|
||||
}
|
||||
}
|
||||
|
||||
rvBSEManagerLocal bseManagerLocal;
|
||||
rvBSEManager* bse = &bseManagerLocal;
|
||||
|
||||
idCVar bse_speeds("bse_speeds", "0", CVAR_INTEGER, "print bse frame statistics");
|
||||
idCVar bse_enabled("bse_enabled", "1", CVAR_BOOL, "set to false to disable all effects");
|
||||
idCVar bse_render("bse_render", "1", CVAR_BOOL, "disable effect rendering");
|
||||
idCVar bse_debug("bse_debug", "0", CVAR_INTEGER, "BSE debug level (0=off, 1=log, 2=log+onscreen)");
|
||||
idCVar bse_showBounds("bse_showbounds", "0", CVAR_BOOL, "display debug bounding boxes effect");
|
||||
idCVar bse_physics("bse_physics", "1", CVAR_BOOL, "disable effect physics");
|
||||
idCVar bse_debris("bse_debris", "1", CVAR_BOOL, "disable effect debris");
|
||||
idCVar bse_singleEffect("bse_singleEffect", "", 0, "set to the name of the effect that is only played");
|
||||
idCVar bse_rateLimit("bse_rateLimit", "1", CVAR_FLOAT, "rate limit for spawned effects");
|
||||
idCVar bse_rateCost("bse_rateCost", "1", CVAR_FLOAT, "rate cost multiplier for spawned effects");
|
||||
idCVar bse_scale("bse_scale", "1", CVAR_FLOAT, "global BSE scaling for spawn/detail");
|
||||
idCVar bse_maxParticles("bse_maxParticles", "2048", CVAR_INTEGER, "maximum per-segment particle allocation");
|
||||
|
||||
int bse_frameSpawned = 0;
|
||||
int bse_frameServiced = 0;
|
||||
int bse_frameRendered = 0;
|
||||
|
||||
void BSE_ResetFrameCounters(void) {
|
||||
bse_frameSpawned = 0;
|
||||
bse_frameServiced = 0;
|
||||
bse_frameRendered = 0;
|
||||
}
|
||||
|
||||
void BSE_AddSpawned(int count) {
|
||||
if (count > 0) {
|
||||
bse_frameSpawned += count;
|
||||
}
|
||||
}
|
||||
|
||||
void BSE_AddServiced(int count) {
|
||||
if (count > 0) {
|
||||
bse_frameServiced += count;
|
||||
}
|
||||
}
|
||||
|
||||
void BSE_AddRendered(int count) {
|
||||
if (count > 0) {
|
||||
bse_frameRendered += count;
|
||||
}
|
||||
}
|
||||
|
||||
float effectCosts[EC_MAX] = { 0.0f, 0.1f, 0.1f };
|
||||
|
||||
idBlockAlloc<rvBSE, 256> rvBSEManagerLocal::effects;
|
||||
idVec3 rvBSEManagerLocal::mCubeNormals[6];
|
||||
idMat3 rvBSEManagerLocal::mModelToBSE;
|
||||
idList<idTraceModel*> rvBSEManagerLocal::mTraceModels;
|
||||
const char* rvBSEManagerLocal::mSegmentNames[SEG_COUNT];
|
||||
int rvBSEManagerLocal::mPerfCounters[NUM_PERF_COUNTERS];
|
||||
float rvBSEManagerLocal::mEffectRates[EC_MAX];
|
||||
/*
|
||||
====================
|
||||
rvBSEManagerLocal::Init
|
||||
====================
|
||||
*/
|
||||
bool rvBSEManagerLocal::Init(void) {
|
||||
common->Printf("----------------- BSE Init ------------------\n");
|
||||
|
||||
declManager->FindEffect("_default");
|
||||
declManager->FindMaterial("_default");
|
||||
declManager->FindMaterial("gfx/effects/particles_shapes/motionblur");
|
||||
declManager->FindType(DECL_TABLE, "halfsintable", true);
|
||||
renderModelManager->FindModel("_default");
|
||||
pauseTime = -1.0f;
|
||||
|
||||
common->Printf("--------- BSE Created Successfully ----------\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
rvBSEManagerLocal::Shutdown
|
||||
====================
|
||||
*/
|
||||
bool rvBSEManagerLocal::Shutdown(void) {
|
||||
common->Printf("--------------- BSE Shutdown ----------------\n");
|
||||
|
||||
for (int i = 0; i < mTraceModels.Num(); ++i) {
|
||||
delete mTraceModels[i];
|
||||
}
|
||||
mTraceModels.Clear();
|
||||
mEffectRates[0] = 0.0f;
|
||||
mEffectRates[1] = 0.0f;
|
||||
mEffectRates[2] = 0.0f;
|
||||
pauseTime = -1.0f;
|
||||
|
||||
common->Printf("---------------------------------------------\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
rvBSEManagerLocal::AddTraceModel
|
||||
=======================
|
||||
*/
|
||||
int rvBSEManagerLocal::AddTraceModel(idTraceModel* model)
|
||||
{
|
||||
mTraceModels.Append(model);
|
||||
return mTraceModels.Num() - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
rvBSEManagerLocal::GetTraceModel
|
||||
=======================
|
||||
*/
|
||||
idTraceModel* rvBSEManagerLocal::GetTraceModel(int index)
|
||||
{
|
||||
idTraceModel* result; // eax
|
||||
|
||||
if (index < 0 || index >= mTraceModels.Num())
|
||||
result = 0;
|
||||
else
|
||||
result = mTraceModels[index];
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
rvBSEManagerLocal::FreeTraceModel
|
||||
=======================
|
||||
*/
|
||||
void rvBSEManagerLocal::FreeTraceModel(int index)
|
||||
{
|
||||
if (index >= 0 && index < mTraceModels.Num())
|
||||
{
|
||||
delete mTraceModels[index];
|
||||
mTraceModels[index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool rvBSEManagerLocal::PlayEffect(class rvRenderEffectLocal* def, float time) {
|
||||
if (!bse_enabled.GetBool() || !def || !def->parms.declEffect) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const rvDeclEffect* v3 = (const rvDeclEffect*)def->parms.declEffect;
|
||||
const idStr effectName = def->parms.declEffect->GetName();
|
||||
|
||||
if (Filtered(effectName, EC_IGNORE)) {
|
||||
def->effect = NULL;
|
||||
def->expired = true;
|
||||
return false;
|
||||
}
|
||||
if (bse_debug.GetInteger())
|
||||
{
|
||||
common->Printf("Playing effect: %s at %g\n", effectName.c_str(), time);
|
||||
}
|
||||
++v3->mPlayCount;
|
||||
rvBSE* effectState = effects.Alloc();
|
||||
if (!effectState) {
|
||||
def->effect = NULL;
|
||||
def->expired = true;
|
||||
return false;
|
||||
}
|
||||
def->effect = effectState;
|
||||
def->expired = false;
|
||||
def->newEffect = true;
|
||||
effectState->SetRenderWorld( reinterpret_cast<idRenderWorld*>(def->world) );
|
||||
effectState->Init(v3, &def->parms, time);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rvBSEManagerLocal::ServiceEffect(class rvRenderEffectLocal* def, float time) {
|
||||
BSE_AddServiced(1);
|
||||
|
||||
if (!def || !def->effect) {
|
||||
if (def) {
|
||||
def->expired = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!bse_enabled.GetBool()) {
|
||||
def->expired = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool forcePush = false;
|
||||
|
||||
if (pauseTime >= 0.0f) {
|
||||
time = pauseTime;
|
||||
}
|
||||
|
||||
const idStr effectName = def->parms.declEffect ? def->parms.declEffect->GetName() : "";
|
||||
if (Filtered(effectName.c_str(), EC_IGNORE)) {
|
||||
def->expired = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
def->effect->SetRenderWorld( reinterpret_cast<idRenderWorld*>(def->world) );
|
||||
|
||||
if (def->effect->Service(&def->parms, time, def->gameTime > def->serviceTime, forcePush)) {
|
||||
def->expired = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
def->expired = false;
|
||||
def->newEffect = false;
|
||||
def->serviceTime = def->gameTime;
|
||||
const idBounds currentLocalBounds = def->effect->GetCurrentLocalBounds();
|
||||
def->referenceBounds = currentLocalBounds;
|
||||
if (bse_speeds.GetBool())
|
||||
++rvBSEManagerLocal::mPerfCounters[0];
|
||||
if (bse_debug.GetInteger())
|
||||
def->effect->EvaluateCost();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
idRenderModel* rvBSEManagerLocal::RenderEffect(class rvRenderEffectLocal* def, const struct viewDef_s* view) {
|
||||
if (!def || !def->effect) {
|
||||
if (def && def->dynamicModel) {
|
||||
delete def->dynamicModel;
|
||||
def->dynamicModel = NULL;
|
||||
def->dynamicModelFrameCount = 0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
def->dynamicModel = def->effect->Render(def->dynamicModel, &def->parms, view);
|
||||
if (!def->dynamicModel) {
|
||||
def->dynamicModelFrameCount = 0;
|
||||
}
|
||||
return def->dynamicModel;
|
||||
}
|
||||
|
||||
void rvBSEManagerLocal::StopEffect(rvRenderEffectLocal* def) {
|
||||
if (def && def->index >= 0 && def->effect)
|
||||
{
|
||||
if (bse_debug.GetInteger())
|
||||
{
|
||||
idStr effectName = def->parms.declEffect->GetName();
|
||||
common->Printf("Stopping effect %s\n", effectName.c_str());
|
||||
}
|
||||
def->effect->SetStopped(true);
|
||||
def->newEffect = false;
|
||||
}
|
||||
else if (def)
|
||||
{
|
||||
def->newEffect = false;
|
||||
def->expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
void rvBSEManagerLocal::FreeEffect(rvRenderEffectLocal* def) {
|
||||
if (def && def->index >= 0 && def->effect)
|
||||
{
|
||||
if (bse_debug.GetInteger())
|
||||
{
|
||||
idStr effectName = def->parms.declEffect->GetName();
|
||||
common->Printf("Freeing effect %s\n", effectName.c_str());
|
||||
}
|
||||
def->effect->Destroy();
|
||||
effects.Free(def->effect);
|
||||
def->effect = NULL;
|
||||
}
|
||||
if (def) {
|
||||
def->newEffect = false;
|
||||
def->expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
float rvBSEManagerLocal::EffectDuration(const rvRenderEffectLocal* def) {
|
||||
if (!def) {
|
||||
return 0.0f;
|
||||
}
|
||||
if (def->effect) {
|
||||
return def->effect->GetDuration();
|
||||
}
|
||||
if (def->parms.declEffect) {
|
||||
const rvDeclEffect* decl = (const rvDeclEffect*)def->parms.declEffect;
|
||||
return decl->GetMaxDuration();
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
bool rvBSEManagerLocal::CheckDefForSound(const renderEffect_t* def) {
|
||||
if (!def || !def->declEffect) {
|
||||
return false;
|
||||
}
|
||||
const rvDeclEffect* decl = (const rvDeclEffect*)def->declEffect;
|
||||
return decl->GetHasSound();
|
||||
}
|
||||
|
||||
void rvBSEManagerLocal::BeginLevelLoad(void) {
|
||||
mEffectRates[0] = 0.0f;
|
||||
mEffectRates[1] = 0.0f;
|
||||
mEffectRates[2] = 0.0f;
|
||||
}
|
||||
|
||||
void rvBSEManagerLocal::EndLevelLoad(void) {
|
||||
mEffectRates[0] = 0.0f;
|
||||
mEffectRates[1] = 0.0f;
|
||||
mEffectRates[2] = 0.0f;
|
||||
}
|
||||
|
||||
void rvBSEManagerLocal::StartFrame(void) {
|
||||
BSE_ResetFrameCounters();
|
||||
UpdateRateTimes();
|
||||
|
||||
if (bse_speeds.GetInteger())
|
||||
{
|
||||
rvBSEManagerLocal::mPerfCounters[0] = 0;
|
||||
rvBSEManagerLocal::mPerfCounters[1] = 0;
|
||||
rvBSEManagerLocal::mPerfCounters[2] = 0;
|
||||
rvBSEManagerLocal::mPerfCounters[3] = 0;
|
||||
rvBSEManagerLocal::mPerfCounters[4] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void rvBSEManagerLocal::EndFrame(void) {
|
||||
if (BSE_GetFrameCounterMode() > 0) {
|
||||
common->Printf(
|
||||
"BSE manager frame counters: spawned=%d serviced=%d rendered=%d\n",
|
||||
bse_frameSpawned,
|
||||
bse_frameServiced,
|
||||
bse_frameRendered);
|
||||
}
|
||||
|
||||
if (bse_speeds.GetInteger()) {
|
||||
common->Printf("bse_active: %i particles: %i traces: %i texels: %i\n",
|
||||
rvBSEManagerLocal::mPerfCounters[0],
|
||||
rvBSEManagerLocal::mPerfCounters[2],
|
||||
rvBSEManagerLocal::mPerfCounters[1],
|
||||
(double)rvBSEManagerLocal::mPerfCounters[3] * 0.00000095367431640625);
|
||||
}
|
||||
}
|
||||
|
||||
bool rvBSEManagerLocal::Filtered(const char* name, effectCategory_t category) {
|
||||
if (!name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* singleFilter = bse_singleEffect.GetString();
|
||||
if (singleFilter && singleFilter[0] != '\0') {
|
||||
if (idStr::FindText(name, singleFilter, false) < 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return !CanPlayRateLimited(category);
|
||||
}
|
||||
|
||||
void rvBSEManagerLocal::UpdateRateTimes(void) {
|
||||
const float decay = Max(0.0f, bse_rateCost.GetFloat()) * 0.1f;
|
||||
for (int i = 0; i < EC_MAX; ++i) {
|
||||
mEffectRates[i] = Max(0.0f, mEffectRates[i] - decay);
|
||||
}
|
||||
}
|
||||
|
||||
bool rvBSEManagerLocal::CanPlayRateLimited(effectCategory_t category) {
|
||||
if (category <= EC_IGNORE || category >= EC_MAX) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const float limit = Max(0.0f, bse_rateLimit.GetFloat());
|
||||
if (limit <= 0.0f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const float cost = effectCosts[category] * Max(0.0f, bse_rateCost.GetFloat());
|
||||
if (mEffectRates[category] + cost > limit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mEffectRates[category] += cost;
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user