center coordinate system of renderer at player camera
this avoids rendering glitches when camera is far away from the center of the coordinate system.
This commit is contained in:
parent
8fbbcc3708
commit
5894a2443c
|
@ -34,7 +34,7 @@ struct ParserState {
|
||||||
|
|
||||||
// Actor fields
|
// Actor fields
|
||||||
id: String,
|
id: String,
|
||||||
pos: Vec3,
|
pos: DVec3,
|
||||||
model: String,
|
model: String,
|
||||||
model_scale: f32,
|
model_scale: f32,
|
||||||
rotation: Quat,
|
rotation: Quat,
|
||||||
|
@ -84,7 +84,7 @@ impl Default for ParserState {
|
||||||
chat: "".to_string(),
|
chat: "".to_string(),
|
||||||
|
|
||||||
id: "".to_string(),
|
id: "".to_string(),
|
||||||
pos: Vec3::new(0.0, 0.0, 0.0),
|
pos: DVec3::new(0.0, 0.0, 0.0),
|
||||||
model: "".to_string(),
|
model: "".to_string(),
|
||||||
model_scale: 1.0,
|
model_scale: 1.0,
|
||||||
rotation: Quat::IDENTITY,
|
rotation: Quat::IDENTITY,
|
||||||
|
@ -205,8 +205,8 @@ pub fn load_defs(
|
||||||
state.class = DefClass::Actor;
|
state.class = DefClass::Actor;
|
||||||
state.model = model.to_string();
|
state.model = model.to_string();
|
||||||
if let (Ok(x_float), Ok(y_float), Ok(z_float)) =
|
if let (Ok(x_float), Ok(y_float), Ok(z_float)) =
|
||||||
(x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>()) {
|
(x.parse::<f64>(), y.parse::<f64>(), z.parse::<f64>()) {
|
||||||
state.pos = Vec3::new(x_float, y_float, z_float);
|
state.pos = DVec3::new(x_float, y_float, z_float);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error!("Can't parse coordinates as floats in def: {line}");
|
error!("Can't parse coordinates as floats in def: {line}");
|
||||||
|
@ -506,6 +506,8 @@ fn spawn_entities(
|
||||||
camdistance: state.camdistance,
|
camdistance: state.camdistance,
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
|
actor.insert(Position::from(state.pos));
|
||||||
|
actor.insert(Rotation::from(state.rotation));
|
||||||
if state.is_sphere {
|
if state.is_sphere {
|
||||||
let sphere_texture_handle: Handle<Image> = asset_server.load(format!("textures/{}.jpg", state.model));
|
let sphere_texture_handle: Handle<Image> = asset_server.load(format!("textures/{}.jpg", state.model));
|
||||||
let sphere_handle = meshes.add(Sphere::default().mesh().uv(128, 128));
|
let sphere_handle = meshes.add(Sphere::default().mesh().uv(128, 128));
|
||||||
|
@ -519,18 +521,16 @@ fn spawn_entities(
|
||||||
mesh: sphere_handle,
|
mesh: sphere_handle,
|
||||||
material: sphere_material_handle,
|
material: sphere_material_handle,
|
||||||
transform: Transform {
|
transform: Transform {
|
||||||
translation: state.pos,
|
|
||||||
scale: Vec3::splat(state.model_scale),
|
scale: Vec3::splat(state.model_scale),
|
||||||
rotation: state.rotation,
|
..default()
|
||||||
},
|
},
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
actor.insert(SceneBundle {
|
actor.insert(SceneBundle {
|
||||||
transform: Transform {
|
transform: Transform {
|
||||||
translation: state.pos,
|
|
||||||
scale: Vec3::splat(state.model_scale),
|
scale: Vec3::splat(state.model_scale),
|
||||||
rotation: state.rotation,
|
..default()
|
||||||
},
|
},
|
||||||
scene: asset_server.load(world::asset_name_to_path(state.model.as_str())),
|
scene: asset_server.load(world::asset_name_to_path(state.model.as_str())),
|
||||||
..default()
|
..default()
|
||||||
|
@ -582,11 +582,6 @@ fn spawn_entities(
|
||||||
radius: 100.0,
|
radius: 100.0,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
transform: Transform {
|
|
||||||
translation: state.pos,
|
|
||||||
scale: Vec3::splat(state.model_scale),
|
|
||||||
rotation: state.rotation,
|
|
||||||
},
|
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
48
src/world.rs
48
src/world.rs
|
@ -4,6 +4,7 @@ use bevy::pbr::CascadeShadowConfigBuilder;
|
||||||
use bevy::render::render_resource::{AsBindGroup, ShaderRef};
|
use bevy::render::render_resource::{AsBindGroup, ShaderRef};
|
||||||
use bevy::math::DVec3;
|
use bevy::math::DVec3;
|
||||||
use bevy_xpbd_3d::prelude::*;
|
use bevy_xpbd_3d::prelude::*;
|
||||||
|
use bevy_xpbd_3d::plugins::sync::SyncConfig;
|
||||||
use std::f32::consts::PI;
|
use std::f32::consts::PI;
|
||||||
|
|
||||||
const ASTEROID_SIZE: f32 = 100.0;
|
const ASTEROID_SIZE: f32 = 100.0;
|
||||||
|
@ -35,6 +36,14 @@ impl Plugin for WorldPlugin {
|
||||||
app.add_plugins(MaterialPlugin::<RingMaterial>::default());
|
app.add_plugins(MaterialPlugin::<RingMaterial>::default());
|
||||||
//app.add_plugins(PhysicsDebugPlugin::default());
|
//app.add_plugins(PhysicsDebugPlugin::default());
|
||||||
app.insert_resource(Gravity(DVec3::splat(0.0)));
|
app.insert_resource(Gravity(DVec3::splat(0.0)));
|
||||||
|
|
||||||
|
// Disable bevy_xpbd's position->transform sync because we have a
|
||||||
|
// custom syncing function.
|
||||||
|
app.insert_resource(SyncConfig {
|
||||||
|
position_to_transform: false,
|
||||||
|
transform_to_position: false,
|
||||||
|
});
|
||||||
|
app.add_systems(PreUpdate, position_to_transform);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,17 +162,19 @@ pub fn setup(
|
||||||
// Add shaded ring
|
// Add shaded ring
|
||||||
let ring_radius = 640000.0;
|
let ring_radius = 640000.0;
|
||||||
let jupiter_radius = 200000.0;
|
let jupiter_radius = 200000.0;
|
||||||
commands.spawn(MaterialMeshBundle {
|
commands.spawn((
|
||||||
|
MaterialMeshBundle {
|
||||||
mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))),
|
mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))),
|
||||||
transform: Transform::from_xyz(300000.0, -1000.0, 500000.0)
|
|
||||||
.with_rotation(Quat::from_rotation_z(1f32.to_radians())),
|
|
||||||
material: materials_custom.add(RingMaterial {
|
material: materials_custom.add(RingMaterial {
|
||||||
alpha_mode: AlphaMode::Blend,
|
alpha_mode: AlphaMode::Blend,
|
||||||
ring_radius: ring_radius,
|
ring_radius: ring_radius,
|
||||||
jupiter_radius: jupiter_radius,
|
jupiter_radius: jupiter_radius,
|
||||||
}),
|
}),
|
||||||
..default()
|
..default()
|
||||||
});
|
},
|
||||||
|
Position::from_xyz(300000.0, -1000.0, 500000.0),
|
||||||
|
Rotation::from(Quat::from_rotation_z(1f32.to_radians())),
|
||||||
|
));
|
||||||
|
|
||||||
// Add Light from the Sun
|
// Add Light from the Sun
|
||||||
commands.spawn(DirectionalLightBundle {
|
commands.spawn(DirectionalLightBundle {
|
||||||
|
@ -185,23 +196,23 @@ pub fn setup(
|
||||||
|
|
||||||
fn handle_cheats(
|
fn handle_cheats(
|
||||||
key_input: Res<ButtonInput<KeyCode>>,
|
key_input: Res<ButtonInput<KeyCode>>,
|
||||||
mut q_player: Query<(&mut Transform, &mut LinearVelocity), With<actor::PlayerCamera>>,
|
mut q_player: Query<(&Transform, &mut Position, &mut LinearVelocity), With<actor::PlayerCamera>>,
|
||||||
mut q_life: Query<(&mut actor::LifeForm, ), With<actor::Player>>,
|
mut q_life: Query<(&mut actor::LifeForm, ), With<actor::Player>>,
|
||||||
settings: ResMut<settings::Settings>,
|
settings: ResMut<settings::Settings>,
|
||||||
) {
|
) {
|
||||||
if !settings.dev_mode || q_player.is_empty() || q_life.is_empty() {
|
if !settings.dev_mode || q_player.is_empty() || q_life.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (mut trans, mut v) = q_player.get_single_mut().unwrap();
|
let (trans, mut pos, mut v) = q_player.get_single_mut().unwrap();
|
||||||
let (mut lifeform, ) = q_life.get_single_mut().unwrap();
|
let (mut lifeform, ) = q_life.get_single_mut().unwrap();
|
||||||
if key_input.just_pressed(settings.key_cheat_pizza) {
|
if key_input.just_pressed(settings.key_cheat_pizza) {
|
||||||
trans.translation = Vec3::new(-3370.0, 0.0, 0.0);
|
pos.0 = DVec3::new(-3370.0, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
if key_input.just_pressed(settings.key_cheat_farview1) {
|
if key_input.just_pressed(settings.key_cheat_farview1) {
|
||||||
trans.translation = Vec3::new(-800000.0, 800000.0, 0.0);
|
pos.0 = DVec3::new(-800000.0, 800000.0, 0.0);
|
||||||
}
|
}
|
||||||
if key_input.just_pressed(settings.key_cheat_farview2) {
|
if key_input.just_pressed(settings.key_cheat_farview2) {
|
||||||
trans.translation = Vec3::new(800000.0, 400000.0, 0.0);
|
pos.0 = DVec3::new(800000.0, 400000.0, 0.0);
|
||||||
}
|
}
|
||||||
if key_input.just_pressed(settings.key_cheat_stop) {
|
if key_input.just_pressed(settings.key_cheat_stop) {
|
||||||
v.0 = DVec3::ZERO;
|
v.0 = DVec3::ZERO;
|
||||||
|
@ -219,3 +230,22 @@ fn handle_cheats(
|
||||||
lifeform.adrenaline = 1.0;
|
lifeform.adrenaline = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A variant of bevy_xpbd_3d::plugins::position_to_transform that adjusts
|
||||||
|
// the rendering position to center entities at the player camera.
|
||||||
|
// This avoids rendering glitches when very far away from the origin.
|
||||||
|
pub fn position_to_transform(
|
||||||
|
q_player: Query<&Position, With<actor::PlayerCamera>>,
|
||||||
|
mut q_trans: Query<(&mut Transform, &Position, &Rotation)>,
|
||||||
|
) {
|
||||||
|
if let Ok(player_pos) = q_player.get_single() {
|
||||||
|
for (mut transform, pos, rot) in &mut q_trans {
|
||||||
|
transform.translation = Vec3::new(
|
||||||
|
(pos.x - player_pos.x) as f32,
|
||||||
|
(pos.y - player_pos.y) as f32,
|
||||||
|
(pos.z - player_pos.z) as f32,
|
||||||
|
);
|
||||||
|
transform.rotation = rot.as_quat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue