summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-05-01 16:02:59 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-05-01 16:02:59 -0400
commitb14dd1c1f3e198137fa8b9e0c4f5e56949b11cd0 (patch)
tree68d47ea946136025890265cc2185a728e4593b96
parent961f8c6d405c9c6fcf9aaf4fb6f199b0e5c60d88 (diff)
downloadsystemic4x-b14dd1c1f3e198137fa8b9e0c4f5e56949b11cd0.tar.gz
systemic4x-b14dd1c1f3e198137fa8b9e0c4f5e56949b11cd0.tar.bz2
systemic4x-b14dd1c1f3e198137fa8b9e0c4f5e56949b11cd0.zip
i don't know how to get the line segments to render right
-rw-r--r--assets/shaders/tacmap/body.wgsl15
-rw-r--r--assets/shaders/tacmap/orbit.wgsl34
-rw-r--r--src/tacmap/camera.rs2
-rw-r--r--src/tacmap/render.rs81
4 files changed, 83 insertions, 49 deletions
diff --git a/assets/shaders/tacmap/body.wgsl b/assets/shaders/tacmap/body.wgsl
index 7156150..217a0b2 100644
--- a/assets/shaders/tacmap/body.wgsl
+++ b/assets/shaders/tacmap/body.wgsl
@@ -1,6 +1,7 @@
struct InstanceInput {
@location(0) position: vec3<f32>,
- @location(1) radius: f32
+ @location(1) origin: vec3<f32>,
+ @location(2) radius: f32
};
struct VertexOutput {
@@ -47,7 +48,17 @@ fn vs_main(
//Scale the world around the camera scale and translate about the camera's
//absolute (/target) position
- let instance_pos = (instance.position - camera.pos) * camera.scale;
+ let relative_pos = instance.position * camera.scale;
+ let origin_pos = (instance.origin - camera.pos) * camera.scale;
+
+ if all(relative_pos != origin_pos) {
+ if length(relative_pos) < 0.01 {
+ out.clip_position = vec4<f32>(0.0, 0.0, 0.0, 1.0);
+ return out;
+ }
+ }
+
+ let instance_pos = relative_pos + origin_pos;
let view_proj = camera.proj * view;
diff --git a/assets/shaders/tacmap/orbit.wgsl b/assets/shaders/tacmap/orbit.wgsl
index d054a05..901200f 100644
--- a/assets/shaders/tacmap/orbit.wgsl
+++ b/assets/shaders/tacmap/orbit.wgsl
@@ -1,7 +1,7 @@
struct VertexInput {
@builtin(vertex_index) index: u32,
@location(0) origin: u32,
- @location(1) position: vec3<f32>,
+ @location(1) position: vec3<f32>
};
struct VertexOutput {
@@ -21,11 +21,8 @@ var<uniform> camera: CameraUniform;
@group(1) @binding(0)
var<storage> origins: array<array<f32,3>>;
-const POINT_NORMALS = array<vec2<f32>,4>(
- vec2<f32>(0.0, -0.5),
- vec2<f32>(0.0, 0.5),
- vec2<f32>(0.5, -0.5),
- vec2<f32>(0.5, 0.5)
+const POINT_NORMALS = array<f32,2>(
+ -0.5, 0.5
);
@vertex
@@ -34,22 +31,33 @@ fn vs_main(
) -> VertexOutput {
var out: VertexOutput;
- let index = model.index % 4u;
- let normal = POINT_NORMALS[index];
+ let index = model.index % 2u;
let origin = vec3<f32>(
origins[model.origin][0],
origins[model.origin][1],
origins[model.origin][2]);
- let model_pos = (origin + model.position - camera.pos) * camera.scale;
+ let model_pos = ((origin - camera.pos) + model.position) * camera.scale;
+ let origin_pos = (origin - camera.pos) * camera.scale;
+
+ let view = camera.view;
+ let camera_right = vec3<f32>(view[0][0], view[1][0], view[2][0]);
+ let camera_up = vec3<f32>(view[0][1], view[1][1], view[2][1]);
+ let camera_forward = vec3<f32>(view[0][2], view[1][2], view[2][2]);
+
+ let orbit_normal = normalize(model.position);
+ var normal = orbit_normal;
+
+ if length(model_pos - origin_pos) > 0.01 {
+ normal *= POINT_NORMALS[index];
+ }
+
let view_proj = camera.proj * camera.view;
//Scale the world around the camera scale and translate about the camera's
//absolute (/target) position
-
- let point_view_pos = view_proj * vec4<f32>(model_pos, 1.0);
+ let point_view_pos = view_proj * vec4<f32>(model_pos + normal * 0.005, 1.0);
out.clip_position = point_view_pos;
- out.clip_position += vec4<f32>(normal * 0.01, 0.0, 0.0) * point_view_pos.w;
return out;
}
@@ -57,5 +65,5 @@ fn vs_main(
@fragment
fn fs_main(in: VertexOutput
) -> @location(0) vec4<f32> {
- return vec4<f32>(0.25, 1.0, 0.25, 1.0);
+ return vec4<f32>(0.0, 0.5, 0.0, 1.0);
}
diff --git a/src/tacmap/camera.rs b/src/tacmap/camera.rs
index ae9bcfa..ada36ee 100644
--- a/src/tacmap/camera.rs
+++ b/src/tacmap/camera.rs
@@ -285,7 +285,7 @@ impl CameraController
let (az_sin, az_cos) = camera.yaw.0.sin_cos();
let (p_sin, p_cos) = camera.pitch.0.sin_cos();
- let radius = f32::max(target_radius * camera.scale, current_radius + dist_diff).max(0.1);
+ let radius = 1.0;
camera.rel_position = Vector3::new(
radius * p_cos * az_cos,
radius * p_sin,
diff --git a/src/tacmap/render.rs b/src/tacmap/render.rs
index c2bd354..48823e2 100644
--- a/src/tacmap/render.rs
+++ b/src/tacmap/render.rs
@@ -1,28 +1,16 @@
use std::{fmt::Display, num::NonZero};
use std::error::Error;
+use cgmath::InnerSpace;
use wgpu::RenderPass;
use crate::canvas::Canvas;
use crate::solar_system::Kilometers;
use crate::tacmap::camera::Camera;
+use crate::timeman::DAY;
use crate::wgpuctx::{RenderPassBuilder, SceneCtx};
use crate::{solar_system::{SolarSystem, SystemId}, timeman::Second, vertex::{self, Vertex}, wgpuctx::{WgpuCtx, pipeline::RenderPipelineBuilder}};
-struct BodyInstance
-{
- position: cgmath::Vector3<Kilometers>,
- radius: f32
-}
-
-#[repr(C)]
-#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
-struct BodyInstanceRaw
-{
- position: [f32;3],
- radius: f32
-}
-
#[derive(Debug, Clone)]
pub struct NeedsRebuildError;
@@ -129,9 +117,17 @@ impl BodyRenderer
let bodies = solar_system.bodies();
let body_instances = bodies.iter().map(|body| {
- let position = solar_system.body_position(body);
+ let position = body.position();
+ let origin = match body.get_orbits() {
+ Some(origin_id) => {
+ let origin_body = &bodies[origin_id];
+ origin_body.position()
+ },
+ None => cgmath::Vector3::new(0.0, 0.0, 0.0)
+ };
BodyInstance {
position: position,
+ origin: origin,
radius: body.radius()
}.raw()
}).collect::<Vec<_>>();
@@ -160,6 +156,22 @@ impl BodyRenderer
}
} // impl RenderState
+struct BodyInstance
+{
+ position: cgmath::Vector3<Kilometers>,
+ origin: cgmath::Vector3<Kilometers>,
+ radius: f32
+}
+
+#[repr(C)]
+#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
+struct BodyInstanceRaw
+{
+ position: [f32;3],
+ origin: [f32;3],
+ radius: f32
+}
+
impl BodyInstance
{
fn raw(&self) -> BodyInstanceRaw
@@ -169,6 +181,10 @@ impl BodyInstance
self.position.x as f32,
self.position.y as f32,
self.position.z as f32 ],
+ origin: [
+ self.origin.x as f32,
+ self.origin.y as f32,
+ self.origin.z as f32 ],
radius: self.radius
}
}
@@ -176,23 +192,17 @@ impl BodyInstance
impl BodyInstanceRaw
{
- fn descr() -> wgpu::VertexBufferLayout<'static> {
+ const ATTRIBS: [wgpu::VertexAttribute;3] =
+ wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3, 2 => Float32];
+
+ pub fn descr()
+ -> wgpu::VertexBufferLayout<'static> {
use std::mem;
+
wgpu::VertexBufferLayout {
- array_stride: mem::size_of::<BodyInstanceRaw>() as wgpu::BufferAddress,
+ array_stride: mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Instance,
- attributes: &[
- wgpu::VertexAttribute {
- offset: 0,
- shader_location: 0,
- format: wgpu::VertexFormat::Float32x3
- },
- wgpu::VertexAttribute {
- offset: mem::size_of::<[f32;3]>() as wgpu::BufferAddress,
- shader_location: 1,
- format: wgpu::VertexFormat::Float32
- }
- ]
+ attributes: &Self::ATTRIBS
}
}
}
@@ -360,11 +370,12 @@ impl OrbitRenderer
if !body.does_orbit() { return (0, None); }
let period = body.orbital_period();
- let period_interval = period as f64 / 360.0;
+ let num_points = ((period / (5 * DAY)) as usize).max(360);
+ let period_interval = period as f64 / num_points as f64;
let mut points = vec![
- OrbitVertex::default();361*2];
- for i in 0..361 {
+ OrbitVertex::default();(num_points+1)*2];
+ for i in 0..num_points {
let position = body.calculate_orbit_at(
(i as f64 * period_interval) as u64);
@@ -374,8 +385,12 @@ impl OrbitRenderer
position.y as f32,
position.z as f32
];
+
points[(i*2)+1] = points[i*2].clone();
}
+ points[num_points*2] = points[0].clone();
+ points[num_points*2+1] = points[1].clone();
+
let buffer = wgpuctx.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: None,
@@ -383,7 +398,7 @@ impl OrbitRenderer
contents: bytemuck::cast_slice(&points)
}
);
- (361*2, Some(buffer))
+ ((num_points+1)*2, Some(buffer))
}).collect::<Vec<_>>());
}