load jupiter from a texture rather than scene
This commit is contained in:
parent
1f046fe8c3
commit
ccd993a4fe
Binary file not shown.
Before Width: | Height: | Size: 495 KiB After Width: | Height: | Size: 403 KiB |
|
@ -11,10 +11,12 @@ actor 0 0 0 suit
|
|||
engine monopropellant
|
||||
|
||||
actor 300000 0 500000 jupiter
|
||||
scale 200000
|
||||
scale 400000
|
||||
sphere yes
|
||||
physics off
|
||||
rotationy -1.40
|
||||
angularmomentum 0 0.0001 0
|
||||
rotationx -0.50
|
||||
rotationz -0.28
|
||||
angularmomentum 30 30 30
|
||||
|
||||
actor 3000 0 0 moonlet
|
||||
scale 500
|
||||
|
|
239
src/world.rs
239
src/world.rs
|
@ -22,7 +22,6 @@ const ASSET_ASTEROID2: &str = "models/asteroid2.glb#Scene0";
|
|||
fn asset_name_to_path(name: &str) -> &'static str {
|
||||
match name {
|
||||
"suit" => "models/suit.glb#Scene0",
|
||||
"jupiter" => "models/jupiter.glb#Scene0",
|
||||
"asteroid1" => ASSET_ASTEROID1,
|
||||
"asteroid2" => ASSET_ASTEROID2,
|
||||
"moonlet" => "models/moonlet.glb#Scene0",
|
||||
|
@ -38,15 +37,19 @@ pub struct WorldPlugin;
|
|||
impl Plugin for WorldPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, (setup, load_defs));
|
||||
app.add_systems(Update, spawn_entities);
|
||||
//app.add_systems(Update, asset_loaded.after(load_cubemap_asset));
|
||||
//app.add_systems(Update, swap_world_on_ar_toggle);
|
||||
app.add_plugins(PhysicsPlugins::default());
|
||||
//app.add_plugins(PhysicsDebugPlugin::default());
|
||||
app.insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0)));
|
||||
app.insert_resource(Gravity(Vec3::splat(0.0)));
|
||||
app.add_event::<SpawnEvent>();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Event)] pub struct SpawnEvent(ParserState);
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Star;
|
||||
|
||||
|
@ -183,12 +186,14 @@ pub fn setup(
|
|||
});
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone)]
|
||||
enum DefClass {
|
||||
Actor,
|
||||
Chat,
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ParserState {
|
||||
class: DefClass,
|
||||
|
||||
|
@ -204,6 +209,7 @@ struct ParserState {
|
|||
rotation: Quat,
|
||||
angular_momentum: Vec3,
|
||||
pronoun: String,
|
||||
is_sphere: bool,
|
||||
is_player: bool,
|
||||
is_lifeform: bool,
|
||||
is_alive: bool,
|
||||
|
@ -250,6 +256,7 @@ impl Default for ParserState {
|
|||
rotation: Quat::IDENTITY,
|
||||
angular_momentum: Vec3::new(0.03, 0.3, 0.09),
|
||||
pronoun: "they/them".to_string(),
|
||||
is_sphere: false,
|
||||
is_player: false,
|
||||
is_lifeform: false,
|
||||
is_alive: false,
|
||||
|
@ -291,14 +298,6 @@ impl ParserState {
|
|||
self.text = default.text;
|
||||
self.is_choice = default.is_choice;
|
||||
}
|
||||
fn reset_chat(&mut self) {
|
||||
let default = ParserState::default();
|
||||
self.reset_message();
|
||||
self.stores_item = default.stores_item;
|
||||
}
|
||||
fn reset(&mut self) {
|
||||
*self = Self::default();
|
||||
}
|
||||
fn as_chatbranch(&self) -> actor::ChatBranch {
|
||||
return actor::ChatBranch {
|
||||
id: self.chat.clone(),
|
||||
|
@ -315,91 +314,10 @@ impl ParserState {
|
|||
script_parameter2: self.script_parameter2.clone(),
|
||||
}
|
||||
}
|
||||
fn spawn_chat(&mut self, commands: &mut Commands) {
|
||||
if self.stores_item {
|
||||
debug!("{:#?}", self.as_chatbranch());
|
||||
commands.spawn(self.as_chatbranch());
|
||||
}
|
||||
self.reset_message();
|
||||
}
|
||||
fn spawn_actor(&mut self, commands: &mut Commands, asset_server: &Res<AssetServer>) {
|
||||
let mut actor = commands.spawn_empty();
|
||||
actor.insert(actor::Actor {
|
||||
id: self.id.clone(),
|
||||
camdistance: self.camdistance,
|
||||
..default()
|
||||
});
|
||||
actor.insert(SceneBundle {
|
||||
transform: Transform {
|
||||
translation: self.pos,
|
||||
scale: Vec3::splat(self.model_scale),
|
||||
rotation: self.rotation,
|
||||
},
|
||||
scene: asset_server.load(asset_name_to_path(self.model.as_str())),
|
||||
..default()
|
||||
});
|
||||
|
||||
// Physics Parameters
|
||||
if self.has_physics {
|
||||
let fix_scale = 1.0 / self.model_scale.powf(3.0);
|
||||
actor.insert(RigidBody::Dynamic);
|
||||
actor.insert(AngularVelocity(self.angular_momentum));
|
||||
actor.insert(self.collider.clone());
|
||||
actor.insert(ColliderDensity(self.mass * fix_scale));
|
||||
}
|
||||
// TODO: angular velocity for objects without collisions, static objects
|
||||
|
||||
// Optional Components
|
||||
if self.is_player {
|
||||
actor.insert(actor::Player);
|
||||
actor.insert(actor::PlayerCamera);
|
||||
}
|
||||
if self.is_lifeform {
|
||||
actor.insert(actor::LifeForm::default());
|
||||
actor.insert(actor::Suit {
|
||||
oxygen: self.oxygen,
|
||||
oxygen_max: nature::OXY_D,
|
||||
integrity: self.suit_integrity,
|
||||
..default()
|
||||
});
|
||||
}
|
||||
if !self.chat.is_empty() {
|
||||
actor.insert(actor::Talker {
|
||||
conv_id: self.chat.clone(),
|
||||
..default()
|
||||
});
|
||||
}
|
||||
if self.is_vehicle {
|
||||
actor.insert(actor::Vehicle::default());
|
||||
}
|
||||
if self.is_vehicle || self.is_suited {
|
||||
actor.insert(actor::Engine {
|
||||
thrust_forward: self.thrust_forward,
|
||||
thrust_back: self.thrust_back,
|
||||
thrust_sideways: self.thrust_sideways,
|
||||
reaction_wheels: self.reaction_wheels,
|
||||
warmup_seconds: self.warmup_seconds,
|
||||
engine_type: self.engine_type,
|
||||
..default()
|
||||
});
|
||||
}
|
||||
|
||||
//info!("Spawning actor {} with model {} at {}/{}/{}",
|
||||
// self.name, self.model, self.pos.x, self.pos.y, self.pos.z);
|
||||
self.reset();
|
||||
}
|
||||
fn spawn_entities(&mut self, commands: &mut Commands, asset_server: &Res<AssetServer>) {
|
||||
match self.class {
|
||||
DefClass::Actor => { self.spawn_actor(commands, asset_server); }
|
||||
DefClass::Chat => { self.spawn_chat(commands); }
|
||||
DefClass::None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_defs(
|
||||
mut commands: Commands,
|
||||
asset_server: Res<AssetServer>,
|
||||
mut ew_spawn: EventWriter<SpawnEvent>,
|
||||
) {
|
||||
let re1 = Regex::new(r"^\s*([a-z_-]+)\s+(.*)$").unwrap();
|
||||
let re2 = Regex::new("\"([^\"]*)\"|(-?[0-9]+(?:\\.[0-9]+)?)|([a-zA-Z_-][a-zA-Z0-9_-]*)").unwrap();
|
||||
|
@ -445,8 +363,8 @@ pub fn load_defs(
|
|||
match parts.as_slice() {
|
||||
// Parsing actors
|
||||
["actor", x, y, z, model] => {
|
||||
state.spawn_entities(&mut commands, &asset_server);
|
||||
state.reset();
|
||||
ew_spawn.send(SpawnEvent(state));
|
||||
state = ParserState::default();
|
||||
state.class = DefClass::Actor;
|
||||
state.model = model.to_string();
|
||||
if let (Ok(x_float), Ok(y_float), Ok(z_float)) =
|
||||
|
@ -455,10 +373,13 @@ pub fn load_defs(
|
|||
}
|
||||
else {
|
||||
error!("Can't parse coordinates as floats in def: {line}");
|
||||
state.reset();
|
||||
state = ParserState::default();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
["sphere", "yes"] => {
|
||||
state.is_sphere = true;
|
||||
}
|
||||
["id", id] => {
|
||||
state.id = id.to_string();
|
||||
}
|
||||
|
@ -498,7 +419,7 @@ pub fn load_defs(
|
|||
}
|
||||
["rotationx", rotation_x] => {
|
||||
if let Ok(rotation_x_float) = rotation_x.parse::<f32>() {
|
||||
state.rotation = Quat::from_rotation_x(PI * rotation_x_float);
|
||||
state.rotation *= Quat::from_rotation_x(PI * rotation_x_float);
|
||||
}
|
||||
else {
|
||||
error!("Can't parse float: {line}");
|
||||
|
@ -507,7 +428,16 @@ pub fn load_defs(
|
|||
}
|
||||
["rotationy", rotation_y] => {
|
||||
if let Ok(rotation_y_float) = rotation_y.parse::<f32>() {
|
||||
state.rotation = Quat::from_rotation_y(PI * rotation_y_float);
|
||||
state.rotation *= Quat::from_rotation_y(PI * rotation_y_float);
|
||||
}
|
||||
else {
|
||||
error!("Can't parse float: {line}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
["rotationz", rotation_z] => {
|
||||
if let Ok(rotation_z_float) = rotation_z.parse::<f32>() {
|
||||
state.rotation *= Quat::from_rotation_z(PI * rotation_z_float);
|
||||
}
|
||||
else {
|
||||
error!("Can't parse float: {line}");
|
||||
|
@ -598,8 +528,8 @@ pub fn load_defs(
|
|||
// Parsing chats
|
||||
["chat", chat_name] => {
|
||||
debug!("Registering chat: {}", chat_name);
|
||||
state.spawn_entities(&mut commands, &asset_server);
|
||||
state.reset_chat();
|
||||
ew_spawn.send(SpawnEvent(state));
|
||||
state = ParserState::default();
|
||||
state.class = DefClass::Chat;
|
||||
state.chat = chat_name.to_string();
|
||||
}
|
||||
|
@ -609,7 +539,7 @@ pub fn load_defs(
|
|||
}
|
||||
["msg", sleep, text] => {
|
||||
debug!("Registering message (sleep={}): {}", sleep, text);
|
||||
state.spawn_entities(&mut commands, &asset_server);
|
||||
ew_spawn.send(SpawnEvent(state.clone()));
|
||||
if let Ok(sleep_float) = sleep.parse::<f64>() {
|
||||
state.delay = sleep_float;
|
||||
state.text = text.to_string();
|
||||
|
@ -622,7 +552,8 @@ pub fn load_defs(
|
|||
}
|
||||
["msg", sleep, label, goto, text] => {
|
||||
debug!("Registering message (sleep={}): {}", sleep, text);
|
||||
state.spawn_entities(&mut commands, &asset_server);
|
||||
ew_spawn.send(SpawnEvent(state.clone()));
|
||||
state.reset_message();
|
||||
if let Ok(sleep_float) = sleep.parse::<f64>() {
|
||||
state.delay = sleep_float;
|
||||
state.text = text.to_string();
|
||||
|
@ -637,7 +568,8 @@ pub fn load_defs(
|
|||
}
|
||||
["choice", sleep, text] => {
|
||||
debug!("Registering choice (sleep={}): {}", sleep, text);
|
||||
state.spawn_entities(&mut commands, &asset_server);
|
||||
ew_spawn.send(SpawnEvent(state.clone()));
|
||||
state.reset_message();
|
||||
if let Ok(sleep_float) = sleep.parse::<f64>() {
|
||||
state.delay = sleep_float;
|
||||
state.text = text.to_string();
|
||||
|
@ -650,7 +582,8 @@ pub fn load_defs(
|
|||
}
|
||||
["choice", sleep, label, goto, text] => {
|
||||
debug!("Registering choice (sleep={}): {}", sleep, text);
|
||||
state.spawn_entities(&mut commands, &asset_server);
|
||||
ew_spawn.send(SpawnEvent(state.clone()));
|
||||
state.reset_message();
|
||||
if let Ok(sleep_float) = sleep.parse::<f64>() {
|
||||
state.delay = sleep_float;
|
||||
state.text = text.to_string();
|
||||
|
@ -690,7 +623,107 @@ pub fn load_defs(
|
|||
}
|
||||
}
|
||||
}
|
||||
state.spawn_entities(&mut commands, &asset_server);
|
||||
ew_spawn.send(SpawnEvent(state));
|
||||
}
|
||||
|
||||
fn spawn_entities(
|
||||
mut er_spawn: EventReader<SpawnEvent>,
|
||||
mut commands: Commands,
|
||||
asset_server: Res<AssetServer>,
|
||||
mut meshes: ResMut<Assets<Mesh>>,
|
||||
mut materials: ResMut<Assets<StandardMaterial>>,
|
||||
) {
|
||||
for state_wrapper in er_spawn.read() {
|
||||
let state = &state_wrapper.0;
|
||||
if state.class == DefClass::Chat {
|
||||
if state.stores_item {
|
||||
commands.spawn(state.as_chatbranch());
|
||||
}
|
||||
}
|
||||
else if state.class == DefClass::Actor {
|
||||
let mut actor = commands.spawn_empty();
|
||||
actor.insert(actor::Actor {
|
||||
id: state.id.clone(),
|
||||
camdistance: state.camdistance,
|
||||
..default()
|
||||
});
|
||||
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));
|
||||
let sphere_material_handle = materials.add(StandardMaterial {
|
||||
base_color_texture: Some(sphere_texture_handle.clone()),
|
||||
perceptual_roughness: 1.0,
|
||||
metallic: 0.0,
|
||||
..default()
|
||||
});
|
||||
actor.insert(PbrBundle {
|
||||
mesh: sphere_handle,
|
||||
material: sphere_material_handle,
|
||||
transform: Transform {
|
||||
translation: state.pos,
|
||||
scale: Vec3::splat(state.model_scale),
|
||||
rotation: state.rotation,
|
||||
},
|
||||
..default()
|
||||
});
|
||||
} else {
|
||||
actor.insert(SceneBundle {
|
||||
transform: Transform {
|
||||
translation: state.pos,
|
||||
scale: Vec3::splat(state.model_scale),
|
||||
rotation: state.rotation,
|
||||
},
|
||||
scene: asset_server.load(asset_name_to_path(state.model.as_str())),
|
||||
..default()
|
||||
});
|
||||
}
|
||||
|
||||
// Physics Parameters
|
||||
if state.has_physics {
|
||||
let fix_scale = 1.0 / state.model_scale.powf(3.0);
|
||||
actor.insert(RigidBody::Dynamic);
|
||||
actor.insert(AngularVelocity(state.angular_momentum));
|
||||
actor.insert(state.collider.clone());
|
||||
actor.insert(ColliderDensity(state.mass * fix_scale));
|
||||
}
|
||||
// TODO: angular velocity for objects without collisions, static objects
|
||||
|
||||
// Optional Components
|
||||
if state.is_player {
|
||||
actor.insert(actor::Player);
|
||||
actor.insert(actor::PlayerCamera);
|
||||
}
|
||||
if state.is_lifeform {
|
||||
actor.insert(actor::LifeForm::default());
|
||||
actor.insert(actor::Suit {
|
||||
oxygen: state.oxygen,
|
||||
oxygen_max: nature::OXY_D,
|
||||
integrity: state.suit_integrity,
|
||||
..default()
|
||||
});
|
||||
}
|
||||
if !state.chat.is_empty() {
|
||||
actor.insert(actor::Talker {
|
||||
conv_id: state.chat.clone(),
|
||||
..default()
|
||||
});
|
||||
}
|
||||
if state.is_vehicle {
|
||||
actor.insert(actor::Vehicle::default());
|
||||
}
|
||||
if state.is_vehicle || state.is_suited {
|
||||
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()
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//pub fn swap_world_on_ar_toggle(
|
||||
|
|
Loading…
Reference in a new issue