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
|
||||
id: String,
|
||||
pos: Vec3,
|
||||
pos: DVec3,
|
||||
model: String,
|
||||
model_scale: f32,
|
||||
rotation: Quat,
|
||||
|
@ -84,7 +84,7 @@ impl Default for ParserState {
|
|||
chat: "".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_scale: 1.0,
|
||||
rotation: Quat::IDENTITY,
|
||||
|
@ -205,8 +205,8 @@ pub fn load_defs(
|
|||
state.class = DefClass::Actor;
|
||||
state.model = model.to_string();
|
||||
if let (Ok(x_float), Ok(y_float), Ok(z_float)) =
|
||||
(x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>()) {
|
||||
state.pos = Vec3::new(x_float, y_float, z_float);
|
||||
(x.parse::<f64>(), y.parse::<f64>(), z.parse::<f64>()) {
|
||||
state.pos = DVec3::new(x_float, y_float, z_float);
|
||||
}
|
||||
else {
|
||||
error!("Can't parse coordinates as floats in def: {line}");
|
||||
|
@ -506,6 +506,8 @@ fn spawn_entities(
|
|||
camdistance: state.camdistance,
|
||||
..default()
|
||||
});
|
||||
actor.insert(Position::from(state.pos));
|
||||
actor.insert(Rotation::from(state.rotation));
|
||||
if state.is_sphere {
|
||||
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));
|
||||
|
@ -519,18 +521,16 @@ fn spawn_entities(
|
|||
mesh: sphere_handle,
|
||||
material: sphere_material_handle,
|
||||
transform: Transform {
|
||||
translation: state.pos,
|
||||
scale: Vec3::splat(state.model_scale),
|
||||
rotation: state.rotation,
|
||||
..default()
|
||||
},
|
||||
..default()
|
||||
});
|
||||
} else {
|
||||
actor.insert(SceneBundle {
|
||||
transform: Transform {
|
||||
translation: state.pos,
|
||||
scale: Vec3::splat(state.model_scale),
|
||||
rotation: state.rotation,
|
||||
..default()
|
||||
},
|
||||
scene: asset_server.load(world::asset_name_to_path(state.model.as_str())),
|
||||
..default()
|
||||
|
@ -582,11 +582,6 @@ fn spawn_entities(
|
|||
radius: 100.0,
|
||||
..default()
|
||||
},
|
||||
transform: Transform {
|
||||
translation: state.pos,
|
||||
scale: Vec3::splat(state.model_scale),
|
||||
rotation: state.rotation,
|
||||
},
|
||||
..default()
|
||||
});
|
||||
}
|
||||
|
|
62
src/world.rs
62
src/world.rs
|
@ -4,6 +4,7 @@ use bevy::pbr::CascadeShadowConfigBuilder;
|
|||
use bevy::render::render_resource::{AsBindGroup, ShaderRef};
|
||||
use bevy::math::DVec3;
|
||||
use bevy_xpbd_3d::prelude::*;
|
||||
use bevy_xpbd_3d::plugins::sync::SyncConfig;
|
||||
use std::f32::consts::PI;
|
||||
|
||||
const ASTEROID_SIZE: f32 = 100.0;
|
||||
|
@ -35,6 +36,14 @@ impl Plugin for WorldPlugin {
|
|||
app.add_plugins(MaterialPlugin::<RingMaterial>::default());
|
||||
//app.add_plugins(PhysicsDebugPlugin::default());
|
||||
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
|
||||
let ring_radius = 640000.0;
|
||||
let jupiter_radius = 200000.0;
|
||||
commands.spawn(MaterialMeshBundle {
|
||||
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 {
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
ring_radius: ring_radius,
|
||||
jupiter_radius: jupiter_radius,
|
||||
}),
|
||||
..default()
|
||||
});
|
||||
commands.spawn((
|
||||
MaterialMeshBundle {
|
||||
mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))),
|
||||
material: materials_custom.add(RingMaterial {
|
||||
alpha_mode: AlphaMode::Blend,
|
||||
ring_radius: ring_radius,
|
||||
jupiter_radius: jupiter_radius,
|
||||
}),
|
||||
..default()
|
||||
},
|
||||
Position::from_xyz(300000.0, -1000.0, 500000.0),
|
||||
Rotation::from(Quat::from_rotation_z(1f32.to_radians())),
|
||||
));
|
||||
|
||||
// Add Light from the Sun
|
||||
commands.spawn(DirectionalLightBundle {
|
||||
|
@ -185,23 +196,23 @@ pub fn setup(
|
|||
|
||||
fn handle_cheats(
|
||||
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>>,
|
||||
settings: ResMut<settings::Settings>,
|
||||
) {
|
||||
if !settings.dev_mode || q_player.is_empty() || q_life.is_empty() {
|
||||
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();
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
v.0 = DVec3::ZERO;
|
||||
|
@ -219,3 +230,22 @@ fn handle_cheats(
|
|||
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