Fixed system rendering
parent
64885a8b6d
commit
03b6ea5ed7
|
@ -104,7 +104,7 @@ pub struct Object {
|
|||
|
||||
/// This object's position, in game coordinates,
|
||||
/// relative to the system's center (0, 0).
|
||||
pub position: Point3<f32>,
|
||||
pub pos: Point3<f32>,
|
||||
|
||||
/// This object's sprite's angle.
|
||||
pub angle: Rad<f32>,
|
||||
|
@ -200,13 +200,14 @@ impl crate::Build for System {
|
|||
|
||||
objects.push(Object {
|
||||
sprite: handle,
|
||||
position: resolve_position(&system.object, &obj, cycle_detector)
|
||||
pos: resolve_position(&system.object, &obj, cycle_detector)
|
||||
.with_context(|| format!("In object {:#?}", label))?,
|
||||
size: obj.size,
|
||||
angle: Deg(obj.angle.unwrap_or(0.0)).into(),
|
||||
});
|
||||
}
|
||||
|
||||
objects.sort_by(|a, b| a.pos.z.total_cmp(&b.pos.z));
|
||||
content.systems.push(Self {
|
||||
name: system_name,
|
||||
objects,
|
||||
|
|
|
@ -157,10 +157,11 @@ impl Game {
|
|||
camera_zoom: self.camera.zoom,
|
||||
current_time: self.start_instant.elapsed().as_secs_f32(),
|
||||
content: &self.content,
|
||||
world: &self.world,
|
||||
world: &self.world, // TODO: maybe system should be stored here?
|
||||
particles: &mut self.new_particles,
|
||||
player_data: self.player,
|
||||
data: &self.gamedata,
|
||||
current_system: content::SystemHandle { index: 0 },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
mod gamedata;
|
||||
mod handles;
|
||||
pub mod ship;
|
||||
mod system;
|
||||
|
||||
pub use gamedata::*;
|
||||
pub use handles::*;
|
||||
pub use system::{System, SystemObject};
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
use cgmath::{Point3, Rad};
|
||||
use galactica_content as content;
|
||||
|
||||
// TODO: rework
|
||||
|
||||
pub struct System {
|
||||
pub name: String,
|
||||
pub bodies: Vec<SystemObject>,
|
||||
}
|
||||
|
||||
impl System {
|
||||
pub fn new(ct: &content::Content, handle: content::SystemHandle) -> Self {
|
||||
let sys = ct.get_system(handle);
|
||||
let mut s = System {
|
||||
name: sys.name.clone(),
|
||||
bodies: Vec::new(),
|
||||
};
|
||||
|
||||
for o in &sys.objects {
|
||||
s.bodies.push(SystemObject {
|
||||
pos: o.position,
|
||||
sprite: o.sprite,
|
||||
size: o.size,
|
||||
angle: o.angle,
|
||||
});
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SystemObject {
|
||||
pub sprite: content::SpriteHandle,
|
||||
pub pos: Point3<f32>,
|
||||
pub size: f32,
|
||||
pub angle: Rad<f32>,
|
||||
}
|
|
@ -19,7 +19,7 @@ impl GPUState {
|
|||
let radar_size = 300.0;
|
||||
let hide_range = 0.85;
|
||||
let shrink_distance = 20.0;
|
||||
//let system_object_scale = 1.0 / 600.0;
|
||||
let system_object_scale = 1.0 / 600.0;
|
||||
let ship_scale = 1.0 / 10.0;
|
||||
|
||||
let player_world_object = state.world.get_ship(state.player_data).unwrap();
|
||||
|
@ -29,7 +29,7 @@ impl GPUState {
|
|||
.unwrap();
|
||||
|
||||
let player_position = util::rigidbody_position(player_body);
|
||||
//let planet_sprite = state.content.get_sprite_handle("ui::planetblip");
|
||||
let planet_sprite = state.content.get_sprite_handle("ui::planetblip");
|
||||
let ship_sprite = state.content.get_sprite_handle("ui::shipblip");
|
||||
let arrow_sprite = state.content.get_sprite_handle("ui::centerarrow");
|
||||
|
||||
|
@ -54,9 +54,9 @@ impl GPUState {
|
|||
);
|
||||
self.vertex_buffers.ui_counter += 1;
|
||||
|
||||
/*
|
||||
// Draw system objects
|
||||
for o in &system.bodies {
|
||||
let system = state.content.get_system(state.current_system);
|
||||
for o in &system.objects {
|
||||
let size = (o.size / o.pos.z) / (radar_range * system_object_scale);
|
||||
let p = Point2 {
|
||||
x: o.pos.x,
|
||||
|
@ -72,24 +72,35 @@ impl GPUState {
|
|||
// Don't draw super tiny sprites, they flicker
|
||||
continue;
|
||||
}
|
||||
out.push(UiSprite {
|
||||
sprite: planet_sprite,
|
||||
pos: AnchoredUiPosition::NwC(
|
||||
Point2 {
|
||||
|
||||
// Enforce buffer limit
|
||||
if self.vertex_buffers.ui_counter as u64
|
||||
> galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("UI limit exceeded!")
|
||||
}
|
||||
|
||||
// Push this object's instance
|
||||
self.queue.write_buffer(
|
||||
&self.vertex_buffers.ui.instances,
|
||||
UiInstance::SIZE * self.vertex_buffers.ui_counter,
|
||||
bytemuck::cast_slice(&[UiInstance {
|
||||
anchor: PositionAnchor::NwC.to_int(),
|
||||
position: (Point2 {
|
||||
x: radar_size / 2.0 + 10.0,
|
||||
y: radar_size / -2.0 - 10.0,
|
||||
} + (d * (radar_size / 2.0)),
|
||||
),
|
||||
dimensions: Point2 {
|
||||
x: planet_sprite.aspect,
|
||||
y: 1.0,
|
||||
} * size,
|
||||
angle: o.angle,
|
||||
color: Some([0.5, 0.5, 0.5, 1.0]),
|
||||
});
|
||||
} + (d * (radar_size / 2.0)))
|
||||
.into(),
|
||||
angle: o.angle.0,
|
||||
size,
|
||||
color: [0.5, 0.5, 0.5, 1.0],
|
||||
sprite_index: planet_sprite.get_index(),
|
||||
}]),
|
||||
);
|
||||
self.vertex_buffers.ui_counter += 1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Draw ships
|
||||
for (s, r) in state.world.iter_ship_body() {
|
||||
|
@ -123,6 +134,7 @@ impl GPUState {
|
|||
} + (d * (radar_size / 2.0));
|
||||
|
||||
// Enforce buffer limit
|
||||
// TODO: cleaner solution. don't do this everywhere.
|
||||
if self.vertex_buffers.ui_counter as u64
|
||||
> galactica_constants::UI_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
|
|
|
@ -364,13 +364,9 @@ impl GPUState {
|
|||
// Order matters, it determines what is drawn on top.
|
||||
// The order inside ships and projectiles doesn't matter,
|
||||
// but ships should always be under projectiles.
|
||||
for s in state.world.iter_ships() {
|
||||
self.world_push_ship(state, (clip_ne, clip_sw), &s);
|
||||
}
|
||||
|
||||
for p in state.world.iter_projectiles() {
|
||||
self.world_push_projectile(state, (clip_ne, clip_sw), &p);
|
||||
}
|
||||
self.world_push_system(state, (clip_ne, clip_sw));
|
||||
self.world_push_ship(state, (clip_ne, clip_sw));
|
||||
self.world_push_projectile(state, (clip_ne, clip_sw));
|
||||
|
||||
self.hud_add_radar(state);
|
||||
self.hud_add_status(state);
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
|
||||
use bytemuck;
|
||||
use cgmath::{EuclideanSpace, InnerSpace, Point2, Vector2};
|
||||
use galactica_world::{
|
||||
objects::{ProjectileWorldObject, ShipWorldObject},
|
||||
util,
|
||||
};
|
||||
use galactica_world::util;
|
||||
|
||||
use crate::{
|
||||
globaluniform::ObjectData,
|
||||
|
@ -19,8 +16,8 @@ impl GPUState {
|
|||
state: &RenderState,
|
||||
// NE and SW corners of screen
|
||||
screen_clip: (Point2<f32>, Point2<f32>),
|
||||
s: &ShipWorldObject,
|
||||
) {
|
||||
for s in state.world.iter_ships() {
|
||||
let r = state.world.get_rigid_body(s.rigid_body).unwrap();
|
||||
let ship_pos = util::rigidbody_position(&r);
|
||||
let ship_rot = util::rigidbody_rotation(r);
|
||||
|
@ -45,7 +42,7 @@ impl GPUState {
|
|||
|| pos.x > screen_clip.1.x + m
|
||||
|| pos.y < screen_clip.1.y - m
|
||||
{
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
let idx = self.vertex_buffers.object_counter;
|
||||
|
@ -88,7 +85,7 @@ impl GPUState {
|
|||
// (physics object stays around to complete the death animation)
|
||||
// If that is the case, we're done, no flares to draw anyway!
|
||||
let ship = match state.data.get_ship(s.data_handle) {
|
||||
None => return,
|
||||
None => continue,
|
||||
Some(s) => s,
|
||||
};
|
||||
|
||||
|
@ -130,14 +127,15 @@ impl GPUState {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn world_push_projectile(
|
||||
&mut self,
|
||||
state: &RenderState,
|
||||
// NE and SW corners of screen
|
||||
screen_clip: (Point2<f32>, Point2<f32>),
|
||||
p: &ProjectileWorldObject,
|
||||
) {
|
||||
for p in state.world.iter_projectiles() {
|
||||
let r = state.world.get_rigid_body(p.rigid_body).unwrap();
|
||||
let proj_pos = util::rigidbody_position(&r);
|
||||
let proj_rot = util::rigidbody_rotation(r);
|
||||
|
@ -162,7 +160,7 @@ impl GPUState {
|
|||
|| pos.x > screen_clip.1.x + m
|
||||
|| pos.y < screen_clip.1.y - m
|
||||
{
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
let idx = self.vertex_buffers.object_counter;
|
||||
|
@ -202,3 +200,74 @@ impl GPUState {
|
|||
self.vertex_buffers.object_counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn world_push_system(
|
||||
&mut self,
|
||||
state: &RenderState,
|
||||
// NE and SW corners of screen
|
||||
screen_clip: (Point2<f32>, Point2<f32>),
|
||||
) {
|
||||
let system = state.content.get_system(state.current_system);
|
||||
|
||||
for o in &system.objects {
|
||||
// Position adjusted for parallax
|
||||
let pos: Point2<f32> = (Point2 {
|
||||
x: o.pos.x,
|
||||
y: o.pos.y,
|
||||
} - state.camera_pos.to_vec())
|
||||
/ o.pos.z;
|
||||
|
||||
// Game dimensions of this sprite post-scale.
|
||||
// Post-scale width or height, whichever is larger.
|
||||
// This is in game units.
|
||||
//
|
||||
// We take the maximum to account for rotated sprites.
|
||||
let m = (o.size / o.pos.z) * o.sprite.aspect.max(1.0);
|
||||
|
||||
// Don't draw sprites that are off the screen
|
||||
if pos.x < screen_clip.0.x - m
|
||||
|| pos.y > screen_clip.0.y + m
|
||||
|| pos.x > screen_clip.1.x + m
|
||||
|| pos.y < screen_clip.1.y - m
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let idx = self.vertex_buffers.object_counter;
|
||||
// Write this object's location data
|
||||
self.queue.write_buffer(
|
||||
&self.global_uniform.object_buffer,
|
||||
ObjectData::SIZE * idx as u64,
|
||||
bytemuck::cast_slice(&[ObjectData {
|
||||
xpos: o.pos.x,
|
||||
ypos: o.pos.y,
|
||||
zpos: o.pos.z,
|
||||
angle: o.angle.0,
|
||||
size: o.size,
|
||||
parent: 0,
|
||||
is_child: 0,
|
||||
_padding: Default::default(),
|
||||
}]),
|
||||
);
|
||||
|
||||
// Enforce buffer limit
|
||||
if self.vertex_buffers.object_counter as u64
|
||||
> galactica_constants::OBJECT_SPRITE_INSTANCE_LIMIT
|
||||
{
|
||||
// TODO: no panic, handle this better.
|
||||
panic!("Sprite limit exceeded!")
|
||||
}
|
||||
|
||||
// Push this object's instance
|
||||
self.queue.write_buffer(
|
||||
&self.vertex_buffers.object.instances,
|
||||
ObjectInstance::SIZE * self.vertex_buffers.object_counter,
|
||||
bytemuck::cast_slice(&[ObjectInstance {
|
||||
sprite_index: o.sprite.get_index(),
|
||||
object_index: idx as u32,
|
||||
}]),
|
||||
);
|
||||
self.vertex_buffers.object_counter += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use cgmath::Point2;
|
||||
use galactica_content::Content;
|
||||
use galactica_content::{Content, SystemHandle};
|
||||
use galactica_gameobject::{GameData, GameShipHandle};
|
||||
use galactica_world::{ParticleBuilder, World};
|
||||
|
||||
|
@ -11,6 +11,9 @@ pub struct RenderState<'a> {
|
|||
/// Player ship data
|
||||
pub player_data: GameShipHandle,
|
||||
|
||||
/// The system we're currently in
|
||||
pub current_system: SystemHandle,
|
||||
|
||||
/// Height of screen, in world units
|
||||
pub camera_zoom: f32,
|
||||
|
||||
|
|
Loading…
Reference in New Issue