From f2246a247f1d4fbe94d547bb4832339c4645b134 Mon Sep 17 00:00:00 2001 From: yuni Date: Tue, 11 Jun 2024 05:49:23 +0200 Subject: [PATCH] implement scene loader (transformations are still a bit wonky) --- src/cmd.rs | 735 ++++++++++++++++++++++++++-------------------- src/data/defs.txt | 12 +- 2 files changed, 423 insertions(+), 324 deletions(-) diff --git a/src/cmd.rs b/src/cmd.rs index 14b4ab1..bd37443 100644 --- a/src/cmd.rs +++ b/src/cmd.rs @@ -27,13 +27,22 @@ pub struct CmdPlugin; impl Plugin for CmdPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, load_defs); + app.add_systems( + Update, + handle_spawn_events + .before(spawn_entities) + .before(spawn_scenes), + ); app.add_systems(Update, spawn_entities); + app.add_systems(Update, spawn_scenes.after(spawn_entities)); app.add_systems(Update, process_mesh); app.add_systems( PreUpdate, hide_colliders.run_if(any_with_component::), ); app.add_event::(); + app.add_event::(); + app.add_event::(); } } @@ -41,9 +50,14 @@ impl Plugin for CmdPlugin { pub struct NeedsSceneColliderRemoved; #[derive(Event)] pub struct SpawnEvent(ParserState); +#[derive(Event)] +pub struct SpawnActorEvent(ParserState); +#[derive(Event)] +pub struct SpawnSceneEvent(ParserState); #[derive(PartialEq, Clone)] enum DefClass { Actor, + Scene, None, } @@ -347,6 +361,21 @@ pub fn load_defs(mut ew_spawn: EventWriter) { continue; } } + ["scene", x, y, z, name] => { + ew_spawn.send(SpawnEvent(state)); + state = ParserState::default(); + state.class = DefClass::Scene; + state.name = Some(name.to_string()); + if let (Ok(x_float), Ok(y_float), Ok(z_float)) = + (x.parse::(), y.parse::(), z.parse::()) + { + state.pos = DVec3::new(x_float, y_float, z_float); + } else { + error!("Can't parse coordinates as floats in def: {line}"); + state = ParserState::default(); + continue; + } + } ["relativeto", id] => { state.relative_to = Some(id.to_string()); } @@ -646,8 +675,90 @@ pub fn load_defs(mut ew_spawn: EventWriter) { ew_spawn.send(SpawnEvent(state)); } -fn spawn_entities( +fn handle_spawn_events( mut er_spawn: EventReader, + mut ew_spawnscene: EventWriter, + mut ew_spawnactor: EventWriter, +) { + for state in er_spawn.read() { + match state.0.class { + DefClass::Actor => { + ew_spawnactor.send(SpawnActorEvent(state.0.clone())); + } + DefClass::Scene => { + ew_spawnscene.send(SpawnSceneEvent(state.0.clone())); + } + DefClass::None => {} + } + } +} + +fn spawn_scenes( + mut er_spawnscene: EventReader, + mut ew_spawn: EventWriter, +) { + for state_wrapper in er_spawnscene.read() { + let root_state = &state_wrapper.0; + + let scene_defs = include!("data/scenes.in"); + for (name, template, pos, rot) in scene_defs { + if Some(name.to_string()) == root_state.name { + match template { + "cruiser" => { + let mut state = ParserState::default(); + state.class = DefClass::Actor; + state.pos = DVec3::new(pos[0], -pos[2], pos[1]); + state.model = Some("cruiser".to_string()); + + state.rotation = Quat::from_euler(EulerRot::XYZ, rot[0], rot[1], rot[2]); + + // command: relativeto ? + state.relative_to = root_state.relative_to.clone(); + + // command: name Cruiser + state.name = Some("Cruiser".to_string()); + + // command: scale 5 + state.model_scale = 5.0; + + // command: vehicle yes + state.is_vehicle = true; + + // command: angularmomentum 0 0 0 + state.angular_momentum = DVec3::ZERO; + + // command: collider handcrafted + state.collider_is_one_mesh_of_scene = true; + + // command: thrust 16 16 8 100000 3 + state.thrust_forward = 16.0; + state.thrust_back = 16.0; + state.thrust_sideways = 8.0; + state.reaction_wheels = 100000.0; + state.warmup_seconds = 3.0; + + // command: engine ion + state.engine_type = actor::EngineType::Ion; + + // command: camdistance 50 + state.camdistance = 50.0; + + // command: density 500 + state.density = 500.0; + + // command: pointofinterest yes + state.is_point_of_interest = true; + ew_spawn.send(SpawnEvent(state)); + } + _ => {} + } + } + } + } +} + +fn spawn_entities( + mut er_spawn: EventReader, mut commands: Commands, asset_server: Res, mut meshes: ResMut>, @@ -667,343 +778,341 @@ fn spawn_entities( }; let state = &state_wrapper.0; let mut rotation = state.rotation; - if state.class == DefClass::Actor { - // Preprocessing - let mut absolute_pos = if let Some(id) = &state.relative_to { - match id2pos.0.get(&id.to_string()) { - Some(pos) => state.pos + *pos, - None => { - error!("Specified `relativeto` command but could not find id `{id}`"); + + // Preprocessing + let mut absolute_pos = if let Some(id) = &state.relative_to { + match id2pos.0.get(&id.to_string()) { + Some(pos) => state.pos + *pos, + None => { + error!("Specified `relativeto` command but could not find id `{id}`"); + continue; + } + } + } else { + state.pos + }; + if let Some(r) = state.orbit_distance { + let mut phase_radians = 0.0f64; + if let Some(phase) = state.orbit_phase { + phase_radians += phase; + } + if let Some(id) = &state.orbit_object_id { + let mass = match id.as_str() { + "jupiter" => nature::JUPITER_MASS, + "sol" => nature::JUPITER_MASS, + _ => { + error!("Found no mass for object `{id}`"); continue; } - } - } else { - state.pos - }; - if let Some(r) = state.orbit_distance { - let mut phase_radians = 0.0f64; - if let Some(phase) = state.orbit_phase { - phase_radians += phase; - } - if let Some(id) = &state.orbit_object_id { - let mass = match id.as_str() { - "jupiter" => nature::JUPITER_MASS, - "sol" => nature::JUPITER_MASS, - _ => { - error!("Found no mass for object `{id}`"); - continue; - } - }; - let orbital_period = nature::simple_orbital_period(mass, r); - phase_radians += if let Ok(epoch) = - SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) - { + }; + let orbital_period = nature::simple_orbital_period(mass, r); + phase_radians += + if let Ok(epoch) = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { let now = epoch.as_secs_f64() + 614533234154.0; // random PI * 2.0 * (now % orbital_period) / orbital_period } else { error!("Can't determine current time `{id}`"); 0.0 }; - } - absolute_pos += nature::phase_dist_to_coords(-phase_radians, r); } - let scale = Vec3::splat( - if state.is_sun { - 5.0 - } else if state.is_moon && settings.large_moons { - 3.0 - } else { - 1.0 - } * state.model_scale, - ); - let orbits_jupiter = state.id != ID_JUPITER; - let velocity = if orbits_jupiter { - let coords = absolute_pos - jupiter_pos; - state.velocity + nature::orbital_velocity(coords, nature::JUPITER_MASS) + absolute_pos += nature::phase_dist_to_coords(-phase_radians, r); + } + let scale = Vec3::splat( + if state.is_sun { + 5.0 + } else if state.is_moon && settings.large_moons { + 3.0 } else { - state.velocity - }; + 1.0 + } * state.model_scale, + ); + let orbits_jupiter = state.id != ID_JUPITER; + let velocity = if orbits_jupiter { + let coords = absolute_pos - jupiter_pos; + state.velocity + nature::orbital_velocity(coords, nature::JUPITER_MASS) + } else { + state.velocity + }; - // Spawn the actor - let actor_entity; - { - let mut actor = commands.spawn_empty(); - actor.insert(actor::Actor { - id: state.id.clone(), - name: state.name.clone(), - camdistance: state.camdistance, + // Spawn the actor + let actor_entity; + { + let mut actor = commands.spawn_empty(); + actor.insert(actor::Actor { + id: state.id.clone(), + name: state.name.clone(), + camdistance: state.camdistance, + ..default() + }); + actor.insert(SleepingDisabled); + if orbits_jupiter { + actor.insert(actor::OrbitsJupiter); + } + actor.insert(world::DespawnOnPlayerDeath); + actor.insert(actor::HitPoints::default()); + actor.insert(Position::from(absolute_pos)); + if state.is_sphere { + let sphere_texture_handle = if let Some(model) = &state.model { + Some(asset_server.load(format!("textures/{}.jpg", model))) + } else { + None + }; + rotation = Quat::from_rotation_x(-90f32.to_radians()) * rotation; + let sphere_handle = meshes.add(Sphere::new(1.0).mesh().uv(128, 128)); + let sphere_material_handle = materials.add(StandardMaterial { + base_color_texture: sphere_texture_handle, + perceptual_roughness: 1.0, + metallic: 0.0, ..default() }); - actor.insert(SleepingDisabled); - if orbits_jupiter { - actor.insert(actor::OrbitsJupiter); - } - actor.insert(world::DespawnOnPlayerDeath); - actor.insert(actor::HitPoints::default()); - actor.insert(Position::from(absolute_pos)); - if state.is_sphere { - let sphere_texture_handle = if let Some(model) = &state.model { - Some(asset_server.load(format!("textures/{}.jpg", model))) - } else { - None - }; - rotation = Quat::from_rotation_x(-90f32.to_radians()) * rotation; - let sphere_handle = meshes.add(Sphere::new(1.0).mesh().uv(128, 128)); - let sphere_material_handle = materials.add(StandardMaterial { - base_color_texture: sphere_texture_handle, - perceptual_roughness: 1.0, - metallic: 0.0, - ..default() - }); - actor.insert(PbrBundle { - mesh: sphere_handle, - material: sphere_material_handle, - transform: Transform::from_scale(scale), - ..default() - }); - } else if let Some(model) = &state.model { - actor.insert(SpatialBundle { - transform: Transform::from_scale(scale), - ..default() - }); - load_asset(model.as_str(), &mut actor, &*asset_server); - } - actor.insert(Rotation::from(rotation)); + actor.insert(PbrBundle { + mesh: sphere_handle, + material: sphere_material_handle, + transform: Transform::from_scale(scale), + ..default() + }); + } else if let Some(model) = &state.model { + actor.insert(SpatialBundle { + transform: Transform::from_scale(scale), + ..default() + }); + load_asset(model.as_str(), &mut actor, &*asset_server); + } + actor.insert(Rotation::from(rotation)); - // Physics Parameters - if state.has_physics { - actor.insert(RigidBody::Dynamic); - actor.insert(LinearVelocity(velocity)); - actor.insert(AngularVelocity(state.angular_momentum)); - actor.insert(ColliderDensity(state.density)); - if state.collider_is_mesh { - actor.insert(MassPropertiesBundle::new_computed( - &Collider::sphere(0.5 * state.model_scale as f64), - state.density, - )); - actor.insert(AsyncSceneCollider::new(Some( - ComputedCollider::TriMesh, //ComputedCollider::ConvexDecomposition(VHACDParameters::default()) - ))); - } else if state.collider_is_one_mesh_of_scene { - actor.insert(MassPropertiesBundle::new_computed( - &Collider::sphere(0.5 * state.model_scale as f64), - state.density, - )); - actor.insert( - AsyncSceneCollider::new(None) - .with_shape_for_name("Collider", ComputedCollider::TriMesh) - .with_layers_for_name("Collider", CollisionLayers::ALL), //.with_density_for_name("Collider", state.density) - ); - actor.insert(NeedsSceneColliderRemoved); - } else { - actor.insert(state.collider.clone()); - } - } - // TODO: angular velocity for objects without collisions, static objects - - // Optional Components - if state.is_player { - actor.insert(actor::Player); - actor.insert(actor::PlayerCamera); - actor.insert(hud::AugmentedRealityOverlayBroadcaster); - ew_updateavatar.send(hud::UpdateAvatarEvent); - } - if state.is_sun { - let (r, g, b) = nature::star_color_index_to_rgb(0.656); - actor.insert(materials.add(StandardMaterial { - base_color: Color::rgb(r, g, b) * 13.0, - unlit: true, - ..default() - })); - actor.insert((NotShadowCaster, NotShadowReceiver)); - } - if state.is_targeted_on_startup { - actor.insert(hud::IsTargeted); - } - if let Some((mindist, id)) = &state.show_only_in_map_at_distance { - actor.insert(camera::ShowOnlyInMap { - min_distance: *mindist, - distance_to_id: id.clone(), - }); - } - if state.is_player || state.is_vehicle { - // used to apply mouse movement to actor rotation - actor.insert(ExternalTorque::ZERO.with_persistence(false)); - } - if state.is_lifeform { - actor.insert(actor::LifeForm::default()); - actor.insert(actor::ExperiencesGForce::default()); - actor.insert(actor::Suit { - oxygen: state.oxygen, - oxygen_max: nature::OXY_D, - integrity: state.suit_integrity, - ..default() - }); - actor.insert(actor::Battery::default()); - } - if state.is_clickable { - actor.insert(hud::IsClickable { - name: state.name.clone(), - pronoun: state.pronoun.clone(), - ..default() - }); - } - if let Some(value) = state.wants_maxrotation { - actor.insert(actor::WantsMaxRotation(value)); - } - if let Some(value) = state.wants_maxvelocity { - actor.insert(actor::WantsMaxVelocity(value)); - } - if let Some(value) = &state.wants_tolookat_id { - actor.insert(actor::WantsToLookAt(value.clone())); - } - if let Some(value) = &state.wants_matchvelocity_id { - actor.insert(actor::WantsMatchVelocityWith(value.clone())); - } - if let Some(color) = state.light_color { - actor.insert(( - PointLight { - intensity: state.light_brightness, - color, - range: 2000.0, - shadows_enabled: settings.shadows_pointlights, - ..default() - }, - bevy::pbr::CubemapVisibleEntities::default(), - bevy::render::primitives::CubemapFrusta::default(), + // Physics Parameters + if state.has_physics { + actor.insert(RigidBody::Dynamic); + actor.insert(LinearVelocity(velocity)); + actor.insert(AngularVelocity(state.angular_momentum)); + actor.insert(ColliderDensity(state.density)); + if state.collider_is_mesh { + actor.insert(MassPropertiesBundle::new_computed( + &Collider::sphere(0.5 * state.model_scale as f64), + state.density, )); + actor.insert(AsyncSceneCollider::new(Some( + ComputedCollider::TriMesh, //ComputedCollider::ConvexDecomposition(VHACDParameters::default()) + ))); + } else if state.collider_is_one_mesh_of_scene { + actor.insert(MassPropertiesBundle::new_computed( + &Collider::sphere(0.5 * state.model_scale as f64), + state.density, + )); + actor.insert( + AsyncSceneCollider::new(None) + .with_shape_for_name("Collider", ComputedCollider::TriMesh) + .with_layers_for_name("Collider", CollisionLayers::ALL), //.with_density_for_name("Collider", state.density) + ); + actor.insert(NeedsSceneColliderRemoved); + } else { + actor.insert(state.collider.clone()); } - if !state.id.is_empty() { - actor.insert(actor::Identifier(state.id.clone())); - id2pos.0.insert(state.id.clone(), absolute_pos); - } - if !state.chat.is_empty() { - actor.insert(chat::Talker { - actor_id: state.id.clone(), - chat_name: state.chat.clone(), - name: state.name.clone(), - pronoun: state.pronoun.clone(), - talking_speed: 1.0, - }); - if let Some(name) = &state.name { - achievement_tracker.all_people.insert(name.clone()); - } - } - if state.is_vehicle { - actor.insert(actor::Vehicle::default()); - if let Some(name) = &state.name { - achievement_tracker.all_vehicles.insert(name.clone()); - } - } - if state.is_vehicle - || state.is_suited - || state.thrust_forward > 0.0 - || state.thrust_sideways > 0.0 - || state.thrust_back > 0.0 - || state.reaction_wheels > 0.0 - { - actor.insert(actor::Engine { - thrust_forward: state.thrust_forward, - thrust_back: state.thrust_back, - thrust_sideways: state.thrust_sideways, - reaction_wheels: state.reaction_wheels, - warmup_seconds: state.warmup_seconds, - engine_type: state.engine_type, + } + // TODO: angular velocity for objects without collisions, static objects + + // Optional Components + if state.is_player { + actor.insert(actor::Player); + actor.insert(actor::PlayerCamera); + actor.insert(hud::AugmentedRealityOverlayBroadcaster); + ew_updateavatar.send(hud::UpdateAvatarEvent); + } + if state.is_sun { + let (r, g, b) = nature::star_color_index_to_rgb(0.656); + actor.insert(materials.add(StandardMaterial { + base_color: Color::rgb(r, g, b) * 13.0, + unlit: true, + ..default() + })); + actor.insert((NotShadowCaster, NotShadowReceiver)); + } + if state.is_targeted_on_startup { + actor.insert(hud::IsTargeted); + } + if let Some((mindist, id)) = &state.show_only_in_map_at_distance { + actor.insert(camera::ShowOnlyInMap { + min_distance: *mindist, + distance_to_id: id.clone(), + }); + } + if state.is_player || state.is_vehicle { + // used to apply mouse movement to actor rotation + actor.insert(ExternalTorque::ZERO.with_persistence(false)); + } + if state.is_lifeform { + actor.insert(actor::LifeForm::default()); + actor.insert(actor::ExperiencesGForce::default()); + actor.insert(actor::Suit { + oxygen: state.oxygen, + oxygen_max: nature::OXY_D, + integrity: state.suit_integrity, + ..default() + }); + actor.insert(actor::Battery::default()); + } + if state.is_clickable { + actor.insert(hud::IsClickable { + name: state.name.clone(), + pronoun: state.pronoun.clone(), + ..default() + }); + } + if let Some(value) = state.wants_maxrotation { + actor.insert(actor::WantsMaxRotation(value)); + } + if let Some(value) = state.wants_maxvelocity { + actor.insert(actor::WantsMaxVelocity(value)); + } + if let Some(value) = &state.wants_tolookat_id { + actor.insert(actor::WantsToLookAt(value.clone())); + } + if let Some(value) = &state.wants_matchvelocity_id { + actor.insert(actor::WantsMatchVelocityWith(value.clone())); + } + if let Some(color) = state.light_color { + actor.insert(( + PointLight { + intensity: state.light_brightness, + color, + range: 2000.0, + shadows_enabled: settings.shadows_pointlights, ..default() - }); + }, + bevy::pbr::CubemapVisibleEntities::default(), + bevy::render::primitives::CubemapFrusta::default(), + )); + } + if !state.id.is_empty() { + actor.insert(actor::Identifier(state.id.clone())); + id2pos.0.insert(state.id.clone(), absolute_pos); + } + if !state.chat.is_empty() { + actor.insert(chat::Talker { + actor_id: state.id.clone(), + chat_name: state.chat.clone(), + name: state.name.clone(), + pronoun: state.pronoun.clone(), + talking_speed: 1.0, + }); + if let Some(name) = &state.name { + achievement_tracker.all_people.insert(name.clone()); } - if let Some(_) = state.ar_model { - actor.insert(hud::AugmentedRealityOverlayBroadcaster); + } + if state.is_vehicle { + actor.insert(actor::Vehicle::default()); + if let Some(name) = &state.name { + achievement_tracker.all_vehicles.insert(name.clone()); } - if state.is_player { - actor.with_children(|builder| { - builder.spawn(( - world::DespawnOnPlayerDeath, - actor::PlayersFlashLight, - SpotLightBundle { - transform: Transform { - translation: Vec3::new(0.0, 0.0, 1.0), - rotation: Quat::from_rotation_y(180f32.to_radians()), - ..default() - }, - spot_light: SpotLight { - intensity: 40_000_000.0, // lumens - color: Color::WHITE, - shadows_enabled: true, - inner_angle: PI32 / 8.0 * 0.85, - outer_angle: PI32 / 4.0, - range: 2000.0, - ..default() - }, - visibility: Visibility::Hidden, + } + if state.is_vehicle + || state.is_suited + || state.thrust_forward > 0.0 + || state.thrust_sideways > 0.0 + || state.thrust_back > 0.0 + || state.reaction_wheels > 0.0 + { + actor.insert(actor::Engine { + thrust_forward: state.thrust_forward, + thrust_back: state.thrust_back, + thrust_sideways: state.thrust_sideways, + reaction_wheels: state.reaction_wheels, + warmup_seconds: state.warmup_seconds, + engine_type: state.engine_type, + ..default() + }); + } + if let Some(_) = state.ar_model { + actor.insert(hud::AugmentedRealityOverlayBroadcaster); + } + if state.is_player { + actor.with_children(|builder| { + builder.spawn(( + world::DespawnOnPlayerDeath, + actor::PlayersFlashLight, + SpotLightBundle { + transform: Transform { + translation: Vec3::new(0.0, 0.0, 1.0), + rotation: Quat::from_rotation_y(180f32.to_radians()), ..default() }, - )); - }); - } - actor_entity = actor.id(); + spot_light: SpotLight { + intensity: 40_000_000.0, // lumens + color: Color::WHITE, + shadows_enabled: true, + inner_angle: PI32 / 8.0 * 0.85, + outer_angle: PI32 / 4.0, + range: 2000.0, + ..default() + }, + visibility: Visibility::Hidden, + ..default() + }, + )); + }); } + actor_entity = actor.id(); + } - if let Some(ar_asset_name) = &state.ar_model { - let mut entitycmd = commands.spawn(( - hud::AugmentedRealityOverlay { - owner: actor_entity, - scale: 1.0, - }, - world::DespawnOnPlayerDeath, - SpatialBundle { - visibility: Visibility::Hidden, - ..default() - }, - NotShadowCaster, - NotShadowReceiver, - )); - load_asset(ar_asset_name, &mut entitycmd, &*asset_server); - } + if let Some(ar_asset_name) = &state.ar_model { + let mut entitycmd = commands.spawn(( + hud::AugmentedRealityOverlay { + owner: actor_entity, + scale: 1.0, + }, + world::DespawnOnPlayerDeath, + SpatialBundle { + visibility: Visibility::Hidden, + ..default() + }, + NotShadowCaster, + NotShadowReceiver, + )); + load_asset(ar_asset_name, &mut entitycmd, &*asset_server); + } - if state.is_point_of_interest || state.is_moon || state.is_planet { - let mut entitycmd = commands.spawn(( - hud::PointOfInterestMarker(actor_entity), - world::DespawnOnPlayerDeath, - hud::ToggleableHudElement, - SpatialBundle { - visibility: Visibility::Hidden, - ..default() - }, - NotShadowCaster, - NotShadowReceiver, - )); - let model = if state.is_point_of_interest { - "point_of_interest" - } else if state.is_planet { - "marker_planets" - } else { - "marker_satellites" - }; - load_asset(model, &mut entitycmd, &*asset_server); - } + if state.is_point_of_interest || state.is_moon || state.is_planet { + let mut entitycmd = commands.spawn(( + hud::PointOfInterestMarker(actor_entity), + world::DespawnOnPlayerDeath, + hud::ToggleableHudElement, + SpatialBundle { + visibility: Visibility::Hidden, + ..default() + }, + NotShadowCaster, + NotShadowReceiver, + )); + let model = if state.is_point_of_interest { + "point_of_interest" + } else if state.is_planet { + "marker_planets" + } else { + "marker_satellites" + }; + load_asset(model, &mut entitycmd, &*asset_server); + } - if state.has_ring { - let ring_radius = state.model_scale - * (nature::JUPITER_RING_RADIUS / nature::JUPITER_RADIUS) as f32; - commands.spawn(( - world::DespawnOnPlayerDeath, - MaterialMeshBundle { - mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))), - material: materials_jupiter.add(load::JupitersRing { - alpha_mode: AlphaMode::Blend, - ring_radius: nature::JUPITER_RING_RADIUS as f32, - jupiter_radius: nature::JUPITER_RADIUS as f32, - }), - transform: Transform::from_translation(absolute_pos.as_vec3()), - ..default() - }, - Position::new(absolute_pos), - Rotation::from(Quat::from_rotation_z(-state.axialtilt.to_radians())), - NotShadowCaster, - NotShadowReceiver, - )); - } + if state.has_ring { + let ring_radius = + state.model_scale * (nature::JUPITER_RING_RADIUS / nature::JUPITER_RADIUS) as f32; + commands.spawn(( + world::DespawnOnPlayerDeath, + MaterialMeshBundle { + mesh: meshes.add(Mesh::from(Cylinder::new(ring_radius, 1.0))), + material: materials_jupiter.add(load::JupitersRing { + alpha_mode: AlphaMode::Blend, + ring_radius: nature::JUPITER_RING_RADIUS as f32, + jupiter_radius: nature::JUPITER_RADIUS as f32, + }), + transform: Transform::from_translation(absolute_pos.as_vec3()), + ..default() + }, + Position::new(absolute_pos), + Rotation::from(Quat::from_rotation_z(-state.axialtilt.to_radians())), + NotShadowCaster, + NotShadowReceiver, + )); } } } diff --git a/src/data/defs.txt b/src/data/defs.txt index 505db58..0063ba7 100644 --- a/src/data/defs.txt +++ b/src/data/defs.txt @@ -268,18 +268,8 @@ actor 0 59305 0 suitv2 health 0.3 rotationy 135 -actor 10 -30 20 cruiser - name "Cruiser" +scene 10 -30 20 test relativeto player - scale 5 - vehicle yes - collider handcrafted - thrust 16 16 8 100000 3 - engine ion - camdistance 50 - density 500 - angularmomentum 0.1 0.1 0.3 - pointofinterest yes actor -55e3 44e3 0 suitv2 template person