mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add fireball and bomb particle effects
This commit is contained in:
@ -6,10 +6,7 @@
|
|||||||
in vec3 v_pos;
|
in vec3 v_pos;
|
||||||
in uint v_col;
|
in uint v_col;
|
||||||
in uint v_norm_ao;
|
in uint v_norm_ao;
|
||||||
in vec4 inst_mat0;
|
in vec3 inst_pos;
|
||||||
in vec4 inst_mat1;
|
|
||||||
in vec4 inst_mat2;
|
|
||||||
in vec4 inst_mat3;
|
|
||||||
in float inst_time;
|
in float inst_time;
|
||||||
in float inst_entropy;
|
in float inst_entropy;
|
||||||
in int inst_mode;
|
in int inst_mode;
|
||||||
@ -22,7 +19,8 @@ out float f_light;
|
|||||||
|
|
||||||
const float SCALE = 1.0 / 11.0;
|
const float SCALE = 1.0 / 11.0;
|
||||||
|
|
||||||
float PHI = 1.61803398874989484820459; // Φ = Golden Ratio
|
// Φ = Golden Ratio
|
||||||
|
float PHI = 1.61803398874989484820459;
|
||||||
|
|
||||||
float gold_noise(in vec2 xy, in float seed){
|
float gold_noise(in vec2 xy, in float seed){
|
||||||
return fract(tan(distance(xy * PHI, xy) * seed) * xy.x);
|
return fract(tan(distance(xy * PHI, xy) * seed) * xy.x);
|
||||||
@ -31,46 +29,54 @@ float gold_noise(in vec2 xy, in float seed){
|
|||||||
// Modes
|
// Modes
|
||||||
const int SMOKE = 0;
|
const int SMOKE = 0;
|
||||||
const int FIRE = 1;
|
const int FIRE = 1;
|
||||||
const int FLAMETHROWER = 2;
|
const int GUN_POWDER_SPARK = 2;
|
||||||
|
|
||||||
|
// meters per second
|
||||||
|
const float earth_gravity = 9.807;
|
||||||
|
|
||||||
|
mat4 translate(vec3 vec){
|
||||||
|
return mat4(
|
||||||
|
vec4(1.0, 0.0, 0.0, 0.0),
|
||||||
|
vec4(0.0, 1.0, 0.0, 0.0),
|
||||||
|
vec4(0.0, 0.0, 1.0, 0.0),
|
||||||
|
vec4(vec.x, vec.y, vec.z, 1.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
mat4 inst_mat;
|
mat4 inst_mat = translate(inst_pos);
|
||||||
inst_mat[0] = inst_mat0;
|
|
||||||
inst_mat[1] = inst_mat1;
|
|
||||||
inst_mat[2] = inst_mat2;
|
|
||||||
inst_mat[3] = inst_mat3;
|
|
||||||
|
|
||||||
float rand1 = gold_noise(vec2(0.0, 0.0), inst_entropy);
|
float rand1 = gold_noise(vec2(0.0, 0.0), inst_entropy);
|
||||||
float rand2 = gold_noise(vec2(1.0, 1.0), inst_entropy);
|
float rand2 = gold_noise(vec2(10.0, 10.0), inst_entropy);
|
||||||
float rand3 = gold_noise(vec2(2.0, 2.0), inst_entropy);
|
float rand3 = gold_noise(vec2(20.0, 20.0), inst_entropy);
|
||||||
float rand4 = gold_noise(vec2(3.0, 3.0), inst_entropy);
|
float rand4 = gold_noise(vec2(30.0, 30.0), inst_entropy);
|
||||||
float rand5 = gold_noise(vec2(4.0, 4.0), inst_entropy);
|
float rand5 = gold_noise(vec2(40.0, 40.0), inst_entropy);
|
||||||
float rand6 = gold_noise(vec2(5.0, 5.0), inst_entropy);
|
float rand6 = gold_noise(vec2(50.0, 50.0), inst_entropy);
|
||||||
|
|
||||||
vec3 inst_vel = vec3(0.0, 0.0, 0.0);
|
vec3 inst_vel = vec3(0.0, 0.0, 0.0);
|
||||||
vec3 inst_pos = vec3(0.0, 0.0, 0.0);
|
vec3 inst_pos2 = vec3(0.0, 0.0, 0.0);
|
||||||
vec3 inst_col = vec3(1.0, 1.0, 1.0);
|
vec3 inst_col = vec3(1.0, 1.0, 1.0);
|
||||||
|
|
||||||
if (inst_mode == SMOKE) {
|
if (inst_mode == SMOKE) {
|
||||||
inst_col = vec3(1.0, 1.0, 1.0);
|
inst_col = vec3(1.0, 1.0, 1.0);
|
||||||
inst_vel = vec3(rand1 * 0.2 - 0.1, rand2 * 0.2 - 0.1, 1.0 + rand3);
|
inst_vel = vec3(rand1 * 0.2 - 0.1, rand2 * 0.2 - 0.1, 1.0 + rand3);
|
||||||
inst_pos = vec3(rand4 * 5.0 - 2.5, rand5 * 5.0 - 2.5, 0.0);
|
inst_pos2 = vec3(rand4 * 5.0 - 2.5, rand5 * 5.0 - 2.5, 0.0);
|
||||||
} else if (inst_mode == FIRE) {
|
} else if (inst_mode == FIRE) {
|
||||||
inst_col = vec3(1.0, 1.0 * inst_entropy, 0.0);
|
inst_col = vec3(1.0, 1.0 * inst_entropy, 0.0);
|
||||||
inst_vel = vec3(rand1 * 0.2 - 0.1, rand2 * 0.2 - 0.1, 4.0 + rand3);
|
inst_vel = vec3(rand1 * 0.2 - 0.1, rand2 * 0.2 - 0.1, 4.0 + rand3);
|
||||||
inst_pos = vec3(rand4 * 5.0 - 2.5, rand5 * 5.0 - 2.5, 0.0);
|
inst_pos2 = vec3(rand4 * 5.0 - 2.5, rand5 * 5.0 - 2.5, 0.0);
|
||||||
} else if (inst_mode == FLAMETHROWER) {
|
} else if (inst_mode == GUN_POWDER_SPARK) {
|
||||||
// TODO: velocity based on attack range, angle and parent orientation.
|
inst_col = vec3(1.0, 1.0, 0.0);
|
||||||
inst_col = vec3(1.0, 1.0 * inst_entropy, 0.0);
|
inst_vel = vec3(rand2 * 2.0 - 1.0, rand1 * 2.0 - 1.0, 5.0 + rand3);
|
||||||
inst_vel = vec3(rand1 * 0.1, rand2 * 0.1, 3.0 + rand3);
|
inst_vel -= vec3(0.0, 0.0, earth_gravity * (tick.x - inst_time));
|
||||||
inst_pos = vec3(rand4 * 5.0 - 2.5, rand5 * 5.0 - 2.5, 0.0);
|
inst_pos2 = vec3(0.0, 0.0, 0.0);
|
||||||
} else {
|
} else {
|
||||||
inst_col = vec3(rand1, rand2, rand3);
|
inst_col = vec3(rand1, rand2, rand3);
|
||||||
inst_vel = vec3(rand4, rand5, rand6);
|
inst_vel = vec3(rand4, rand5, rand6);
|
||||||
inst_pos = vec3(rand1, rand2, rand3);
|
inst_pos2 = vec3(rand1, rand2, rand3);
|
||||||
}
|
}
|
||||||
|
|
||||||
f_pos = (inst_mat * vec4((v_pos + inst_pos) * SCALE, 1)).xyz;
|
f_pos = (inst_mat * vec4((v_pos + inst_pos2) * SCALE, 1)).xyz;
|
||||||
|
|
||||||
f_pos += inst_vel * (tick.x - inst_time);
|
f_pos += inst_vel * (tick.x - inst_time);
|
||||||
|
|
||||||
|
@ -46,67 +46,3 @@ impl Default for LightAnimation {
|
|||||||
impl Component for LightAnimation {
|
impl Component for LightAnimation {
|
||||||
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
|
type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
|
||||||
}
|
}
|
||||||
// #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
// pub enum ParticleEmitterMode {
|
|
||||||
// Sprinkler,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] // Copy
|
|
||||||
// pub struct ParticleEmitters(pub Vec<ParticleEmitter>);
|
|
||||||
|
|
||||||
// impl Default for ParticleEmitters {
|
|
||||||
// fn default() -> Self {
|
|
||||||
// Self(vec![ParticleEmitter::default(), ParticleEmitter {
|
|
||||||
// mode: ParticleEmitterMode::Sprinkler,
|
|
||||||
// // model_key: "voxygen.voxel.not_found",
|
|
||||||
// count: (7, 10),
|
|
||||||
// frequency: Duration::from_millis(100),
|
|
||||||
// initial_lifespan: Duration::from_millis(500),
|
|
||||||
// initial_offset: (Vec3::broadcast(-0.2), Vec3::broadcast(0.2)),
|
|
||||||
// initial_orientation: (Vec3::broadcast(0.0),
|
|
||||||
// Vec3::broadcast(1.0)), initial_scale: (1.0, 2.5),
|
|
||||||
// initial_velocity: (Vec3::new(0.0, 0.0, 1.0), Vec3::new(0.01,
|
|
||||||
// 0.01, 3.0)), initial_col: (Rgb::new(0.999, 0.0, 0.0),
|
|
||||||
// Rgb::new(1.0, 1.0, 0.001)), }])
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
||||||
// pub struct ParticleEmitter {
|
|
||||||
// pub mode: ParticleEmitterMode,
|
|
||||||
|
|
||||||
// // spawn X particles per Y, that live for Z
|
|
||||||
// // pub model_ref: &str, // can we have some kind of stack based key like
|
|
||||||
// a u8? pub count: (u8, u8),
|
|
||||||
// pub frequency: Duration,
|
|
||||||
|
|
||||||
// // relative to Pos, Ori components?
|
|
||||||
// // can these be functions that returns a Vec3<f32>?
|
|
||||||
// pub initial_lifespan: Duration,
|
|
||||||
// pub initial_offset: (Vec3<f32>, Vec3<f32>), // fn() -> Vec3<f32>,
|
|
||||||
// pub initial_scale: (f32, f32), // fn() -> Vec3<f32>,
|
|
||||||
// pub initial_orientation: (Vec3<f32>, Vec3<f32>), // fn() -> Vec3<f32>,
|
|
||||||
// pub initial_velocity: (Vec3<f32>, Vec3<f32>), // fn() -> Vec3<f32>,
|
|
||||||
// pub initial_col: (Rgb<f32>, Rgb<f32>), // fn() -> Vec3<f32>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Default for ParticleEmitter {
|
|
||||||
// fn default() -> Self {
|
|
||||||
// Self {
|
|
||||||
// mode: ParticleEmitterMode::Sprinkler,
|
|
||||||
// // model_key: "voxygen.voxel.not_found",
|
|
||||||
// count: (2, 5),
|
|
||||||
// frequency: Duration::from_millis(100),
|
|
||||||
// initial_lifespan: Duration::from_secs(20),
|
|
||||||
// initial_offset: (Vec3::broadcast(-0.1), Vec3::broadcast(0.1)),
|
|
||||||
// initial_orientation: (Vec3::broadcast(0.0),
|
|
||||||
// Vec3::broadcast(1.0)), initial_scale: (0.1, 2.0),
|
|
||||||
// initial_velocity: (Vec3::new(0.0, 0.0, 0.2), Vec3::new(0.01,
|
|
||||||
// 0.01, 1.0)), initial_col: (Rgb::new(0.999, 0.999, 0.999),
|
|
||||||
// Rgb::new(1.0, 1.0, 1.0)), }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Component for ParticleEmitter {
|
|
||||||
// type Storage = FlaggedStorage<Self, IdvStorage<Self>>;
|
|
||||||
// }
|
|
||||||
|
@ -26,21 +26,24 @@ gfx_defines! {
|
|||||||
inst_time: f32 = "inst_time",
|
inst_time: f32 = "inst_time",
|
||||||
|
|
||||||
// a seed value for randomness
|
// a seed value for randomness
|
||||||
|
// can save 32 bits per instance, for particles that don't need randomness/uniqueness.
|
||||||
inst_entropy: f32 = "inst_entropy",
|
inst_entropy: f32 = "inst_entropy",
|
||||||
|
|
||||||
// modes should probably be seperate shaders, as a part of scaling and optimisation efforts
|
// modes should probably be seperate shaders, as a part of scaling and optimisation efforts.
|
||||||
|
// can save 32 bits per instance, and have cleaner tailor made code.
|
||||||
inst_mode: i32 = "inst_mode",
|
inst_mode: i32 = "inst_mode",
|
||||||
|
|
||||||
// a triangle is: f32 x 3 x 3 x 1 = 288 bits
|
// a triangle is: f32 x 3 x 3 x 1 = 288 bits
|
||||||
// a quad is: f32 x 3 x 3 x 2 = 576 bits
|
// a quad is: f32 x 3 x 3 x 2 = 576 bits
|
||||||
// a cube is: f32 x 3 x 3 x 12 = 3456 bits
|
// a cube is: f32 x 3 x 3 x 12 = 3456 bits
|
||||||
// this matrix is: f32 x 4 x 4 x 1 = 512 bits (per instance!)
|
// this vec is: f32 x 3 x 1 x 1 = 96 bits (per instance!)
|
||||||
// consider using vertex postion & entropy instead;
|
// consider using a throw-away mesh and
|
||||||
// to determine initial offset, scale, orientation etc.
|
// positioning the vertex verticies instead,
|
||||||
inst_mat0: [f32; 4] = "inst_mat0",
|
// if we have:
|
||||||
inst_mat1: [f32; 4] = "inst_mat1",
|
// - a triangle mesh, and 3 or more instances.
|
||||||
inst_mat2: [f32; 4] = "inst_mat2",
|
// - a quad mesh, and 6 or more instances.
|
||||||
inst_mat3: [f32; 4] = "inst_mat3",
|
// - a cube mesh, and 36 or more instances.
|
||||||
|
inst_pos: [f32; 3] = "inst_pos",
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
@ -82,6 +85,7 @@ impl Vertex {
|
|||||||
pub enum ParticleMode {
|
pub enum ParticleMode {
|
||||||
CampfireSmoke,
|
CampfireSmoke,
|
||||||
CampfireFire,
|
CampfireFire,
|
||||||
|
GunPowderSpark,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParticleMode {
|
impl ParticleMode {
|
||||||
@ -93,24 +97,19 @@ impl Instance {
|
|||||||
inst_time: f64,
|
inst_time: f64,
|
||||||
inst_entropy: f32,
|
inst_entropy: f32,
|
||||||
inst_mode: ParticleMode,
|
inst_mode: ParticleMode,
|
||||||
inst_mat: Mat4<f32>,
|
inst_pos: Vec3<f32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let inst_mat_col = inst_mat.into_col_arrays();
|
|
||||||
Self {
|
Self {
|
||||||
inst_time: inst_time as f32,
|
inst_time: inst_time as f32,
|
||||||
inst_entropy,
|
inst_entropy,
|
||||||
inst_mode: inst_mode as i32,
|
inst_mode: inst_mode as i32,
|
||||||
|
inst_pos: inst_pos.into_array(),
|
||||||
inst_mat0: inst_mat_col[0],
|
|
||||||
inst_mat1: inst_mat_col[1],
|
|
||||||
inst_mat2: inst_mat_col[2],
|
|
||||||
inst_mat3: inst_mat_col[3],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Instance {
|
impl Default for Instance {
|
||||||
fn default() -> Self { Self::new(0.0, 0.0, ParticleMode::CampfireSmoke, Mat4::identity()) }
|
fn default() -> Self { Self::new(0.0, 0.0, ParticleMode::CampfireSmoke, Vec3::zero()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ParticlePipeline;
|
pub struct ParticlePipeline;
|
||||||
|
@ -16,7 +16,7 @@ use hashbrown::HashMap;
|
|||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use specs::{Join, WorldExt};
|
use specs::{Join, WorldExt};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use vek::{Mat4, Vec3};
|
use vek::Vec3;
|
||||||
|
|
||||||
struct Particles {
|
struct Particles {
|
||||||
alive_until: Instant, // created_at + lifespan
|
alive_until: Instant, // created_at + lifespan
|
||||||
@ -66,63 +66,231 @@ impl ParticleMgr {
|
|||||||
// remove dead particles
|
// remove dead particles
|
||||||
self.particles.retain(|p| p.alive_until > now);
|
self.particles.retain(|p| p.alive_until > now);
|
||||||
|
|
||||||
self.maintain_waypoint_particles(renderer, scene_data);
|
self.maintain_body_particles(renderer, scene_data);
|
||||||
|
|
||||||
self.maintain_boost_particles(renderer, scene_data);
|
self.maintain_boost_particles(renderer, scene_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maintain_waypoint_particles(&mut self, renderer: &mut Renderer, scene_data: &SceneData) {
|
fn maintain_body_particles(&mut self, renderer: &mut Renderer, scene_data: &SceneData) {
|
||||||
let state = scene_data.state;
|
let ecs = scene_data.state.ecs();
|
||||||
let ecs = state.ecs();
|
for (_i, (_entity, body, pos)) in (
|
||||||
let time = state.get_time();
|
|
||||||
let now = Instant::now();
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
|
|
||||||
for (_i, (_entity, pos, body)) in (
|
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<Pos>(),
|
|
||||||
&ecs.read_storage::<Body>(),
|
&ecs.read_storage::<Body>(),
|
||||||
|
&ecs.read_storage::<Pos>(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
match body {
|
match body {
|
||||||
Body::Object(object::Body::CampfireLit) => {
|
Body::Object(object::Body::CampfireLit) => {
|
||||||
let fire_cpu_insts = vec![ParticleInstance::new(
|
self.maintain_campfirelit_particles(renderer, scene_data, pos)
|
||||||
time,
|
|
||||||
rng.gen(),
|
|
||||||
ParticleMode::CampfireFire,
|
|
||||||
Mat4::identity().translated_3d(pos.0),
|
|
||||||
)];
|
|
||||||
|
|
||||||
self.particles.push(Particles {
|
|
||||||
alive_until: now + Duration::from_millis(250),
|
|
||||||
instances: renderer
|
|
||||||
.create_instances(&fire_cpu_insts)
|
|
||||||
.expect("Failed to upload particle instances to the GPU!"),
|
|
||||||
});
|
|
||||||
|
|
||||||
let smoke_cpu_insts = vec![ParticleInstance::new(
|
|
||||||
time,
|
|
||||||
rng.gen(),
|
|
||||||
ParticleMode::CampfireSmoke,
|
|
||||||
Mat4::identity().translated_3d(pos.0),
|
|
||||||
)];
|
|
||||||
|
|
||||||
let smoke_cpu_insts = renderer
|
|
||||||
.create_instances(&smoke_cpu_insts)
|
|
||||||
.expect("Failed to upload particle instances to the GPU!");
|
|
||||||
|
|
||||||
self.particles.push(Particles {
|
|
||||||
alive_until: now + Duration::from_secs(10),
|
|
||||||
instances: smoke_cpu_insts,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
Body::Object(object::Body::BoltFire) => {
|
||||||
|
self.maintain_boltfire_particles(renderer, scene_data, pos)
|
||||||
|
},
|
||||||
|
Body::Object(object::Body::BoltFireBig) => {
|
||||||
|
self.maintain_boltfirebig_particles(renderer, scene_data, pos)
|
||||||
|
},
|
||||||
|
Body::Object(object::Body::Bomb) => {
|
||||||
|
self.maintain_bomb_particles(renderer, scene_data, pos)
|
||||||
|
},
|
||||||
|
// Body::Object(object::Body::Pouch) => {
|
||||||
|
// self.maintain_pouch_particles(renderer, scene_data, pos)
|
||||||
|
// },
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn maintain_campfirelit_particles(
|
||||||
|
&mut self,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
scene_data: &SceneData,
|
||||||
|
pos: &Pos,
|
||||||
|
) {
|
||||||
|
let time = scene_data.state.get_time();
|
||||||
|
let now = Instant::now();
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let fire_cpu_insts = vec![ParticleInstance::new(
|
||||||
|
time,
|
||||||
|
rng.gen(),
|
||||||
|
ParticleMode::CampfireFire,
|
||||||
|
pos.0,
|
||||||
|
)];
|
||||||
|
|
||||||
|
self.particles.push(Particles {
|
||||||
|
alive_until: now + Duration::from_millis(250),
|
||||||
|
instances: renderer
|
||||||
|
.create_instances(&fire_cpu_insts)
|
||||||
|
.expect("Failed to upload particle instances to the GPU!"),
|
||||||
|
});
|
||||||
|
|
||||||
|
let smoke_cpu_insts = vec![ParticleInstance::new(
|
||||||
|
time,
|
||||||
|
rng.gen(),
|
||||||
|
ParticleMode::CampfireSmoke,
|
||||||
|
pos.0,
|
||||||
|
)];
|
||||||
|
|
||||||
|
let smoke_cpu_insts = renderer
|
||||||
|
.create_instances(&smoke_cpu_insts)
|
||||||
|
.expect("Failed to upload particle instances to the GPU!");
|
||||||
|
|
||||||
|
self.particles.push(Particles {
|
||||||
|
alive_until: now + Duration::from_secs(10),
|
||||||
|
instances: smoke_cpu_insts,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maintain_boltfire_particles(
|
||||||
|
&mut self,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
scene_data: &SceneData,
|
||||||
|
pos: &Pos,
|
||||||
|
) {
|
||||||
|
let time = scene_data.state.get_time();
|
||||||
|
let now = Instant::now();
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let fire_cpu_insts = vec![ParticleInstance::new(
|
||||||
|
time,
|
||||||
|
rng.gen(),
|
||||||
|
ParticleMode::CampfireFire,
|
||||||
|
pos.0,
|
||||||
|
)];
|
||||||
|
|
||||||
|
self.particles.push(Particles {
|
||||||
|
alive_until: now + Duration::from_millis(250),
|
||||||
|
instances: renderer
|
||||||
|
.create_instances(&fire_cpu_insts)
|
||||||
|
.expect("Failed to upload particle instances to the GPU!"),
|
||||||
|
});
|
||||||
|
|
||||||
|
let smoke_cpu_insts = vec![ParticleInstance::new(
|
||||||
|
time,
|
||||||
|
rng.gen(),
|
||||||
|
ParticleMode::CampfireSmoke,
|
||||||
|
pos.0,
|
||||||
|
)];
|
||||||
|
|
||||||
|
let smoke_cpu_insts = renderer
|
||||||
|
.create_instances(&smoke_cpu_insts)
|
||||||
|
.expect("Failed to upload particle instances to the GPU!");
|
||||||
|
|
||||||
|
self.particles.push(Particles {
|
||||||
|
alive_until: now + Duration::from_secs(1),
|
||||||
|
instances: smoke_cpu_insts,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maintain_boltfirebig_particles(
|
||||||
|
&mut self,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
scene_data: &SceneData,
|
||||||
|
pos: &Pos,
|
||||||
|
) {
|
||||||
|
let time = scene_data.state.get_time();
|
||||||
|
let now = Instant::now();
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let fire_cpu_insts = vec![
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::CampfireFire, pos.0),
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::CampfireFire, pos.0),
|
||||||
|
];
|
||||||
|
|
||||||
|
self.particles.push(Particles {
|
||||||
|
alive_until: now + Duration::from_millis(250),
|
||||||
|
instances: renderer
|
||||||
|
.create_instances(&fire_cpu_insts)
|
||||||
|
.expect("Failed to upload particle instances to the GPU!"),
|
||||||
|
});
|
||||||
|
|
||||||
|
let smoke_cpu_insts = vec![
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::CampfireSmoke, pos.0),
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::CampfireSmoke, pos.0),
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::CampfireSmoke, pos.0),
|
||||||
|
];
|
||||||
|
|
||||||
|
let smoke_cpu_insts = renderer
|
||||||
|
.create_instances(&smoke_cpu_insts)
|
||||||
|
.expect("Failed to upload particle instances to the GPU!");
|
||||||
|
|
||||||
|
self.particles.push(Particles {
|
||||||
|
alive_until: now + Duration::from_secs(2),
|
||||||
|
instances: smoke_cpu_insts,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maintain_bomb_particles(
|
||||||
|
&mut self,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
scene_data: &SceneData,
|
||||||
|
pos: &Pos,
|
||||||
|
) {
|
||||||
|
let time = scene_data.state.get_time();
|
||||||
|
let now = Instant::now();
|
||||||
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
let fire_cpu_insts = vec![
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::GunPowderSpark, pos.0),
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::GunPowderSpark, pos.0),
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::GunPowderSpark, pos.0),
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::GunPowderSpark, pos.0),
|
||||||
|
ParticleInstance::new(time, rng.gen(), ParticleMode::GunPowderSpark, pos.0),
|
||||||
|
];
|
||||||
|
|
||||||
|
self.particles.push(Particles {
|
||||||
|
alive_until: now + Duration::from_millis(1500),
|
||||||
|
instances: renderer
|
||||||
|
.create_instances(&fire_cpu_insts)
|
||||||
|
.expect("Failed to upload particle instances to the GPU!"),
|
||||||
|
});
|
||||||
|
|
||||||
|
let smoke_cpu_insts = vec![ParticleInstance::new(
|
||||||
|
time,
|
||||||
|
rng.gen(),
|
||||||
|
ParticleMode::CampfireSmoke,
|
||||||
|
pos.0,
|
||||||
|
)];
|
||||||
|
|
||||||
|
let smoke_cpu_insts = renderer
|
||||||
|
.create_instances(&smoke_cpu_insts)
|
||||||
|
.expect("Failed to upload particle instances to the GPU!");
|
||||||
|
|
||||||
|
self.particles.push(Particles {
|
||||||
|
alive_until: now + Duration::from_secs(2),
|
||||||
|
instances: smoke_cpu_insts,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// fn maintain_pouch_particles(
|
||||||
|
// &mut self,
|
||||||
|
// renderer: &mut Renderer,
|
||||||
|
// scene_data: &SceneData,
|
||||||
|
// pos: &Pos,
|
||||||
|
// ) {
|
||||||
|
// let time = scene_data.state.get_time();
|
||||||
|
// let now = Instant::now();
|
||||||
|
// let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
|
// let smoke_cpu_insts = vec![ParticleInstance::new(
|
||||||
|
// time,
|
||||||
|
// rng.gen(),
|
||||||
|
// ParticleMode::CampfireSmoke,
|
||||||
|
// pos.0,
|
||||||
|
// )];
|
||||||
|
|
||||||
|
// let smoke_cpu_insts = renderer
|
||||||
|
// .create_instances(&smoke_cpu_insts)
|
||||||
|
// .expect("Failed to upload particle instances to the GPU!");
|
||||||
|
|
||||||
|
// self.particles.push(Particles {
|
||||||
|
// alive_until: now + Duration::from_secs(1),
|
||||||
|
// instances: smoke_cpu_insts,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
fn maintain_boost_particles(&mut self, renderer: &mut Renderer, scene_data: &SceneData) {
|
fn maintain_boost_particles(&mut self, renderer: &mut Renderer, scene_data: &SceneData) {
|
||||||
let state = scene_data.state;
|
let state = scene_data.state;
|
||||||
let ecs = state.ecs();
|
let ecs = state.ecs();
|
||||||
@ -143,7 +311,7 @@ impl ParticleMgr {
|
|||||||
time,
|
time,
|
||||||
rng.gen(),
|
rng.gen(),
|
||||||
ParticleMode::CampfireSmoke,
|
ParticleMode::CampfireSmoke,
|
||||||
Mat4::identity().translated_3d(pos.0),
|
pos.0,
|
||||||
)];
|
)];
|
||||||
|
|
||||||
let gpu_insts = renderer
|
let gpu_insts = renderer
|
||||||
@ -165,17 +333,13 @@ impl ParticleMgr {
|
|||||||
lights: &Consts<Light>,
|
lights: &Consts<Light>,
|
||||||
shadows: &Consts<Shadow>,
|
shadows: &Consts<Shadow>,
|
||||||
) {
|
) {
|
||||||
|
let model = &self
|
||||||
|
.model_cache
|
||||||
|
.get(MODEL_KEY)
|
||||||
|
.expect("Expected particle model in cache");
|
||||||
|
|
||||||
for particle in &self.particles {
|
for particle in &self.particles {
|
||||||
renderer.render_particles(
|
renderer.render_particles(model, globals, &particle.instances, lights, shadows);
|
||||||
&self
|
|
||||||
.model_cache
|
|
||||||
.get(MODEL_KEY)
|
|
||||||
.expect("Expected particle model in cache"),
|
|
||||||
globals,
|
|
||||||
&particle.instances,
|
|
||||||
lights,
|
|
||||||
shadows,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user