mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 07:47:57 +03:00

* Added fog bulbs * WIP raymarch * constant fog formula with simplex noise * Improved fog formula and handling * Raymarch less expansive; Added fog bulbs to sprites; Removed premultiplication of fog density by color at load time; * Avoid raymarch if fog > 1 * Sorting fog bulbs front to back; Performance improvements; * Added frustum culling for fog bulbs * Tryiing without raymarch * Refactored fog code; Added noise and wibble to fog; Fixed sprites; * Disabled wibble for fog * Removed noise * Fof bulbs like TR5 * Fixed Pascal Case in RenderView; Fixed formatting things; Fixed sprites; * Optimizations * Fixed sprites in fog bulbs * Fixed project paths * Fix compiler warning * Fixed repository * Fog bulbs for sky and horizon * Sky tessellation * Update Renderer11Draw.cpp --------- Co-authored-by: MontyTRC89 <montyhammet@hotmail.it> Co-authored-by: Raildex <n@a.com> Co-authored-by: Lwmte <3331699+Lwmte@users.noreply.github.com>
286 lines
8.9 KiB
C++
286 lines
8.9 KiB
C++
#include "framework.h"
|
|
#include "Game/effects/smoke.h"
|
|
|
|
#include <algorithm>
|
|
#include "Game/collision/collide_room.h"
|
|
#include "Game/control/control.h"
|
|
#include "Game/effects/weather.h"
|
|
#include "Game/items.h"
|
|
#include "Game/Lara/lara.h"
|
|
#include "Game/room.h"
|
|
#include "Game/Setup.h"
|
|
#include "Math/Math.h"
|
|
#include "Specific/level.h"
|
|
|
|
using namespace TEN::Effects::Environment;
|
|
using namespace TEN::Math;
|
|
|
|
namespace TEN::Effects::Smoke
|
|
{
|
|
std::array<SmokeParticle, 128> SmokeParticles;
|
|
|
|
auto& GetFreeSmokeParticle()
|
|
{
|
|
for (int i = 0; i < SmokeParticles.size(); i++)
|
|
{
|
|
if (!SmokeParticles[i].active)
|
|
return SmokeParticles[i];
|
|
}
|
|
|
|
return SmokeParticles[0];
|
|
}
|
|
|
|
void DisableSmokeParticles()
|
|
{
|
|
for (int i = 0; i < SmokeParticles.size(); i++)
|
|
SmokeParticles[i].active = false;
|
|
}
|
|
|
|
void UpdateSmokeParticles()
|
|
{
|
|
for (int i = 0; i < SmokeParticles.size(); i++)
|
|
{
|
|
auto& s = SmokeParticles[i];
|
|
|
|
if (!s.active)
|
|
continue;
|
|
|
|
s.age += 1;
|
|
if (s.age > s.life)
|
|
{
|
|
s.active = false;
|
|
continue;
|
|
}
|
|
|
|
s.velocity.y += s.gravity;
|
|
|
|
if (s.terminalVelocity != 0)
|
|
{
|
|
float velocityLength = s.velocity.Length();
|
|
|
|
if (velocityLength > s.terminalVelocity)
|
|
s.velocity *= (s.terminalVelocity / velocityLength);
|
|
}
|
|
|
|
s.position += s.velocity;
|
|
|
|
if (s.affectedByWind)
|
|
{
|
|
if (TestEnvironment(ENV_FLAG_WIND, s.room))
|
|
{
|
|
s.position.x += Weather.Wind().x;
|
|
s.position.z += Weather.Wind().z;
|
|
}
|
|
}
|
|
|
|
float normalizedLife = std::clamp(s.age / s.life,0.0f,1.0f);
|
|
s.size = Lerp(s.sourceSize, s.destinationSize, normalizedLife);
|
|
s.angularVelocity *= s.angularDrag;
|
|
s.rotation += s.angularVelocity;
|
|
s.color = DirectX::SimpleMath::Vector4::Lerp(s.sourceColor, s.destinationColor, normalizedLife);
|
|
int numSprites = -Objects[ID_SMOKE_SPRITES].nmeshes;
|
|
s.sprite = Lerp(0, numSprites - 1, normalizedLife);
|
|
}
|
|
}
|
|
|
|
void TriggerFlareSmoke(const Vector3& pos, const Vector3& direction, int life, int room)
|
|
{
|
|
auto& s = GetFreeSmokeParticle();
|
|
s = {};
|
|
s.position = pos;
|
|
s.age = 0;
|
|
constexpr float d = 0.2f;
|
|
|
|
auto randomDir = Vector3(Random::GenerateFloat(-d, d), Random::GenerateFloat(-d, d), Random::GenerateFloat(-d, d));
|
|
auto direction2 = Vector3::Zero;
|
|
(direction + randomDir).Normalize(direction2);
|
|
|
|
s.velocity = direction2 * Random::GenerateFloat(7, 9);
|
|
s.gravity = -0.2f;
|
|
s.friction = Random::GenerateFloat(0.7f, 0.85f);
|
|
s.sourceColor = Vector4(1, 131 / 255.0f, 100 / 255.0f, 1);
|
|
s.destinationColor = Vector4(1, 1, 1, 0);
|
|
s.life = Random::GenerateFloat(25, 35);
|
|
s.angularVelocity = Random::GenerateFloat(-0.3f, 0.3f);
|
|
s.angularDrag = 0.97f;
|
|
s.sourceSize = life > 4 ? Random::GenerateFloat(16, 24) : Random::GenerateFloat(100, 128);
|
|
s.destinationSize = life > 4 ? Random::GenerateFloat(160, 200) : Random::GenerateFloat(256, 300);
|
|
s.affectedByWind = true;
|
|
s.active = true;
|
|
s.room = room;
|
|
}
|
|
|
|
//TODO: add additional "Weapon Special" param or something. Currently initial == 2 means Rocket Launcher backwards smoke.
|
|
//TODO: Refactor different weapon types out of it
|
|
void TriggerGunSmokeParticles(int x, int y, int z, int xv, int yv, int zv, byte initial, LaraWeaponType weaponType, byte count)
|
|
{
|
|
SpawnGunSmokeParticles(Vector3(x, y, z), Vector3(xv, yv, zv), LaraItem->RoomNumber, initial, weaponType, count);
|
|
}
|
|
|
|
void SpawnGunSmokeParticles(const Vector3& pos, const Vector3& direction, int roomNumber, byte initial, LaraWeaponType weaponType, int count)
|
|
{
|
|
auto& s = GetFreeSmokeParticle();
|
|
s = {};
|
|
s.active = true;
|
|
s.position = pos;
|
|
|
|
auto directionNorm = direction;
|
|
directionNorm.Normalize();
|
|
|
|
s.velocity = directionNorm;
|
|
s.gravity = -.1f;
|
|
s.affectedByWind = TestEnvironment(ENV_FLAG_WIND, pos.x, pos.y, pos.z, roomNumber);
|
|
s.sourceColor = Vector4(0.4f, 0.4f, 0.4f, 1);
|
|
s.destinationColor = Vector4::Zero;
|
|
|
|
if (initial)
|
|
{
|
|
if (weaponType == LaraWeaponType::RocketLauncher)
|
|
{
|
|
float size = Random::GenerateFloat(48, 80);
|
|
s.sourceSize = size * 2;
|
|
s.destinationSize = size * 8;
|
|
s.sourceColor = { 0.75, 0.75, 1, 1 };
|
|
s.terminalVelocity = 0;
|
|
s.friction = 0.82f;
|
|
s.life = Random::GenerateFloat(60, 90);
|
|
|
|
if (initial == 1)
|
|
{
|
|
float size = Random::GenerateFloat(48, 80);
|
|
s.sourceSize = size * 2;
|
|
s.destinationSize = size * 16;
|
|
s.velocity = Random::GenerateDirectionInCone(directionNorm, 25);
|
|
s.velocity *= Random::GenerateFloat(0, 32);
|
|
}
|
|
else
|
|
{
|
|
float size = Random::GenerateFloat(48, 80);
|
|
s.sourceSize = size;
|
|
s.destinationSize = size * 8;
|
|
s.velocity = Random::GenerateDirectionInCone(directionNorm, 3);
|
|
s.velocity *= Random::GenerateFloat(0, 16);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float size = Random::GenerateFloat(48, 73);
|
|
s.sourceSize = size * 2;
|
|
s.destinationSize = size * 8;
|
|
s.terminalVelocity = 0;
|
|
s.friction = 0.88f;
|
|
s.life = Random::GenerateFloat(60, 90);
|
|
s.velocity = Random::GenerateDirectionInCone(directionNorm, 10);
|
|
s.velocity *= Random::GenerateFloat(16, 30);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float size = (float)((GetRandomControl() & 0x0F) + 48); // -TriggerGunSmoke_SubFunction(weaponType);
|
|
|
|
if (weaponType == LaraWeaponType::RocketLauncher)
|
|
s.sourceColor = { 0.75, 0.75, 1, 1 };
|
|
|
|
s.sourceSize = size / 2;
|
|
s.destinationSize = size * 4;
|
|
s.terminalVelocity = 0;
|
|
s.friction = 0.97f;
|
|
s.life = Random::GenerateFloat(42, 62);
|
|
s.velocity *= Random::GenerateFloat(16, 40);
|
|
}
|
|
|
|
s.position = pos;
|
|
s.position += Vector3(Random::GenerateFloat(-8, 8), Random::GenerateFloat(-8, 8), Random::GenerateFloat(-8, 8));
|
|
s.angularVelocity = Random::GenerateFloat(-PI_DIV_4, PI_DIV_4);
|
|
s.angularDrag = 0.95f;
|
|
s.room = roomNumber;
|
|
}
|
|
|
|
void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int velocity, int moving)
|
|
{
|
|
auto& s = GetFreeSmokeParticle();
|
|
s = {};
|
|
s.position = Vector3(x, y, z) + Vector3(Random::GenerateFloat(8, 16), Random::GenerateFloat(8, 16), Random::GenerateFloat(8, 16));
|
|
|
|
float xVel = std::sin(TO_RAD(angle)) * velocity;
|
|
float zVel = std::cos(TO_RAD(angle)) * velocity;
|
|
|
|
s.velocity = Vector3(xVel, Random::GenerateFloat(-1, 4), zVel);
|
|
s.sourceColor = Vector4(1, 1, 1, 1);
|
|
s.destinationColor = Vector4::Zero;
|
|
s.sourceSize = Random::GenerateFloat(8,24);
|
|
s.active = true;
|
|
s.affectedByWind = true;
|
|
s.friction = 0.999f;
|
|
s.gravity = -0.1f;
|
|
s.life = Random::GenerateFloat(16, 24);
|
|
s.destinationSize = Random::GenerateFloat(128, 160);
|
|
s.angularVelocity = Random::GenerateFloat(-1, 1);
|
|
s.angularDrag = Random::GenerateFloat(0.97f, 0.999f);
|
|
}
|
|
|
|
void TriggerRocketSmoke(int x, int y, int z)
|
|
{
|
|
auto& s = GetFreeSmokeParticle();
|
|
s = {};
|
|
s.position = Vector3(x, y, z) + Vector3(Random::GenerateFloat(8.0f, 16.0f), Random::GenerateFloat(8.0f, 16.0f), Random::GenerateFloat(8.0f, 16.0f));
|
|
s.sourceColor = Vector4(0.8f, 0.8f, 1, 1);
|
|
s.destinationColor = Vector4::Zero;
|
|
s.sourceSize = Random::GenerateFloat(32.0f, 64.0f);
|
|
s.active = true;
|
|
s.velocity = Random::GenerateDirection() * Random::GenerateFloat(1.0f, 3.0f);
|
|
s.affectedByWind = true;
|
|
s.friction = 0.979f;
|
|
s.gravity = -0.1f;
|
|
s.life = Random::GenerateFloat(80, 120);
|
|
s.destinationSize = Random::GenerateFloat(1024, 1152);
|
|
s.angularVelocity = Random::GenerateFloat(-0.6f, 0.6f);
|
|
s.angularDrag = Random::GenerateFloat(0.87f, 0.99f);
|
|
}
|
|
|
|
void SpawnCorpseEffect(const Vector3& pos)
|
|
{
|
|
auto& smoke = GetFreeSmokeParticle();
|
|
smoke = {};
|
|
|
|
auto sphere = BoundingSphere(pos, Random::GenerateFloat(8.0f, 16.0f));
|
|
auto spherePos = Random::GeneratePointInSphere(sphere);
|
|
|
|
smoke.position = spherePos;
|
|
smoke.sourceColor = Vector4(0.8f, 0.8f, 0.0f, 1.0f);
|
|
smoke.destinationColor = Vector4::Zero;
|
|
smoke.sourceSize = Random::GenerateFloat(32.0f, 64.0f);
|
|
smoke.active = true;
|
|
smoke.velocity = Random::GenerateDirection() * Random::GenerateFloat(0.1f, 0.2f);
|
|
smoke.affectedByWind = true;
|
|
smoke.friction = 0.9f;
|
|
smoke.gravity = 0;;
|
|
smoke.life = Random::GenerateFloat(100.0f, 220.0f);
|
|
smoke.destinationSize = Random::GenerateFloat(BLOCK(1), BLOCK(1.1f));
|
|
smoke.angularVelocity = Random::GenerateFloat(-0.1f, 0.1f);
|
|
smoke.angularDrag = Random::GenerateFloat(0.8f, 0.9f);
|
|
}
|
|
|
|
void TriggerBreathSmoke(long x, long y, long z, short angle)
|
|
{
|
|
auto& s = GetFreeSmokeParticle();
|
|
s = {};
|
|
s.position = Vector3(x, y, z) + Vector3(Random::GenerateFloat(8, 16), Random::GenerateFloat(8, 16), Random::GenerateFloat(8, 16));
|
|
|
|
float xVel = std::sin(TO_RAD(angle)) * Random::GenerateFloat(8, 12);
|
|
float zVel = std::cos(TO_RAD(angle)) * Random::GenerateFloat(8, 12);
|
|
|
|
s.velocity = Vector3(xVel, 0, zVel);
|
|
s.sourceColor = Vector4(1, 1, 1, 0.7f);
|
|
s.destinationColor = Vector4(1, 1, 1, 0);
|
|
s.sourceSize = Random::GenerateFloat(8, 24);
|
|
s.active = true;
|
|
s.affectedByWind = true;
|
|
s.friction = 0.999f;
|
|
s.gravity = -0.1f;
|
|
s.life = Random::GenerateFloat(12, 20);
|
|
s.destinationSize = Random::GenerateFloat(128, 160);
|
|
s.angularVelocity = Random::GenerateFloat(-0.5f, 0.5f);
|
|
s.angularDrag = Random::GenerateFloat(0.95f, 0.95f);
|
|
}
|
|
}
|