clippy: add AR face ^_^
This commit is contained in:
parent
817a5e2a96
commit
d064680d60
|
@ -7,6 +7,8 @@ These cubes are interchangeable, solar panel plated, driven by strong reaction w
|
||||||
|
|
||||||
The shape of a Clippy™ can change quickly to solve a variety of space problems. Off-the-shelf plug-and-play Clippy™ modules further enhance their agency with additional tools, such as propulsion modules, sensors, or manipulators.
|
The shape of a Clippy™ can change quickly to solve a variety of space problems. Off-the-shelf plug-and-play Clippy™ modules further enhance their agency with additional tools, such as propulsion modules, sensors, or manipulators.
|
||||||
|
|
||||||
|
A Clippy™ Convenience Companion will broadcast an Augmented Reality overlay that resembles a face, in the somewhat antiquated "kaomoji" style of the late 1900's, typically a friendly face to instill trust and kindness in viewers. How a unified persona with aligned intentions emerges from the interactions of the individual Clippy™ cubes is, as of writing, still subject to debate.
|
||||||
|
|
||||||
Clippy™ is inspired by [self-assembling cube robots](https://www.youtube.com/watch?v=hI5UDKaWJOo), by the [paperclip maximizer thought experiment](https://en.wikipedia.org/w/index.php?title=Instrumental_convergence&oldid=1210129297#Paperclip_maximizer) (which is also the source of the name), by [Star Gate's Replicators](https://stargate.fandom.com/wiki/Replicator), and finally, by [Fallout New Vegas' "Yes Man" robot](https://fallout.fandom.com/wiki/Yes_Man).
|
Clippy™ is inspired by [self-assembling cube robots](https://www.youtube.com/watch?v=hI5UDKaWJOo), by the [paperclip maximizer thought experiment](https://en.wikipedia.org/w/index.php?title=Instrumental_convergence&oldid=1210129297#Paperclip_maximizer) (which is also the source of the name), by [Star Gate's Replicators](https://stargate.fandom.com/wiki/Replicator), and finally, by [Fallout New Vegas' "Yes Man" robot](https://fallout.fandom.com/wiki/Yes_Man).
|
||||||
|
|
||||||
## MeteorAceGT™ Sports Racing Capsule
|
## MeteorAceGT™ Sports Racing Capsule
|
||||||
|
|
BIN
assets/models/clippy_ar.glb
Normal file
BIN
assets/models/clippy_ar.glb
Normal file
Binary file not shown.
|
@ -67,6 +67,7 @@ struct ParserState {
|
||||||
suit_integrity: f32,
|
suit_integrity: f32,
|
||||||
light_brightness: f32,
|
light_brightness: f32,
|
||||||
light_color: Option<Color>,
|
light_color: Option<Color>,
|
||||||
|
ar_model: Option<String>,
|
||||||
|
|
||||||
// Chat fields
|
// Chat fields
|
||||||
delay: f64,
|
delay: f64,
|
||||||
|
@ -121,6 +122,7 @@ impl Default for ParserState {
|
||||||
suit_integrity: 1.0,
|
suit_integrity: 1.0,
|
||||||
light_brightness: 0.0,
|
light_brightness: 0.0,
|
||||||
light_color: None,
|
light_color: None,
|
||||||
|
ar_model: None,
|
||||||
|
|
||||||
delay: 0.0,
|
delay: 0.0,
|
||||||
text: "".to_string(),
|
text: "".to_string(),
|
||||||
|
@ -453,6 +455,9 @@ pub fn load_defs(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
["armodel", asset_name] => {
|
||||||
|
state.ar_model = Some(asset_name.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
// Parsing chats
|
// Parsing chats
|
||||||
["chat", chat_name] => {
|
["chat", chat_name] => {
|
||||||
|
@ -571,6 +576,8 @@ fn spawn_entities(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if state.class == DefClass::Actor {
|
else if state.class == DefClass::Actor {
|
||||||
|
let actor_entity;
|
||||||
|
{
|
||||||
let mut actor = commands.spawn_empty();
|
let mut actor = commands.spawn_empty();
|
||||||
actor.insert(actor::Actor {
|
actor.insert(actor::Actor {
|
||||||
id: state.id.clone(),
|
id: state.id.clone(),
|
||||||
|
@ -699,6 +706,24 @@ fn spawn_entities(
|
||||||
..default()
|
..default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if let Some(_) = state.ar_model {
|
||||||
|
actor.insert(hud::AugmentedRealityOverlayBroadcaster);
|
||||||
|
}
|
||||||
|
actor_entity = actor.id();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ar_asset_name) = &state.ar_model {
|
||||||
|
commands.spawn((
|
||||||
|
hud::AugmentedRealityOverlay {
|
||||||
|
owner: actor_entity,
|
||||||
|
},
|
||||||
|
SceneBundle {
|
||||||
|
scene: asset_server.load(world::asset_name_to_path(ar_asset_name)),
|
||||||
|
visibility: Visibility::Hidden,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,6 +176,7 @@ actor -3300 10 0 pizzeria
|
||||||
actor -33 0 4 clippy
|
actor -33 0 4 clippy
|
||||||
name "Clippy™ Convenience Companion"
|
name "Clippy™ Convenience Companion"
|
||||||
relativeto pizzeria
|
relativeto pizzeria
|
||||||
|
armodel clippy_ar
|
||||||
angularmomentum 0 0 0
|
angularmomentum 0 0 0
|
||||||
wants maxrotation 0
|
wants maxrotation 0
|
||||||
wants maxvelocity 0
|
wants maxvelocity 0
|
||||||
|
|
51
src/hud.rs
51
src/hud.rs
|
@ -24,6 +24,7 @@ impl Plugin for HudPlugin {
|
||||||
app.add_systems(Startup, setup);
|
app.add_systems(Startup, setup);
|
||||||
app.add_systems(Update, (
|
app.add_systems(Update, (
|
||||||
update_hud,
|
update_hud,
|
||||||
|
update_ar_overlays,
|
||||||
handle_input,
|
handle_input,
|
||||||
handle_target_event,
|
handle_target_event,
|
||||||
));
|
));
|
||||||
|
@ -33,6 +34,9 @@ impl Plugin for HudPlugin {
|
||||||
.after(camera::apply_input_to_player)
|
.after(camera::apply_input_to_player)
|
||||||
.before(TransformSystem::TransformPropagate),
|
.before(TransformSystem::TransformPropagate),
|
||||||
));
|
));
|
||||||
|
app.insert_resource(AugmentedRealityState {
|
||||||
|
overlays_visible: false,
|
||||||
|
});
|
||||||
app.insert_resource(Log {
|
app.insert_resource(Log {
|
||||||
logs: VecDeque::with_capacity(LOG_MAX),
|
logs: VecDeque::with_capacity(LOG_MAX),
|
||||||
needs_rerendering: true,
|
needs_rerendering: true,
|
||||||
|
@ -52,6 +56,17 @@ impl Plugin for HudPlugin {
|
||||||
#[derive(Component)] struct Selectagon;
|
#[derive(Component)] struct Selectagon;
|
||||||
#[derive(Component)] pub struct IsTargeted;
|
#[derive(Component)] pub struct IsTargeted;
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
pub struct AugmentedRealityState {
|
||||||
|
pub overlays_visible: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Component)] pub struct AugmentedRealityOverlayBroadcaster;
|
||||||
|
#[derive(Component)]
|
||||||
|
pub struct AugmentedRealityOverlay {
|
||||||
|
pub owner: Entity,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
struct FPSUpdateTimer(Timer);
|
struct FPSUpdateTimer(Timer);
|
||||||
|
|
||||||
|
@ -645,3 +660,39 @@ fn update_target_selectagon(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_ar_overlays (
|
||||||
|
q_owners: Query<(Entity, &Transform, &Visibility), (With<AugmentedRealityOverlayBroadcaster>, Without<AugmentedRealityOverlay>)>,
|
||||||
|
mut q_overlays: Query<(&mut Transform, &mut Visibility, &mut AugmentedRealityOverlay)>,
|
||||||
|
settings: ResMut<settings::Settings>,
|
||||||
|
mut state: ResMut<AugmentedRealityState>,
|
||||||
|
) {
|
||||||
|
let (need_activate, need_clean, need_update);
|
||||||
|
if settings.hud_active {
|
||||||
|
need_activate = !state.overlays_visible;
|
||||||
|
need_clean = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
need_activate = false;
|
||||||
|
need_clean = state.overlays_visible;
|
||||||
|
}
|
||||||
|
need_update = settings.hud_active;
|
||||||
|
state.overlays_visible = settings.hud_active;
|
||||||
|
|
||||||
|
if need_update || need_clean || need_activate {
|
||||||
|
'outer: for (mut trans, mut vis, ar) in &mut q_overlays {
|
||||||
|
for (owner_id, owner_trans, owner_vis) in &q_owners {
|
||||||
|
if owner_id == ar.owner {
|
||||||
|
*trans = *owner_trans;
|
||||||
|
if need_clean {
|
||||||
|
*vis = Visibility::Hidden;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*vis = *owner_vis;
|
||||||
|
}
|
||||||
|
break 'outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub fn asset_name_to_path(name: &str) -> &'static str {
|
||||||
"pizzasign" => "models/pizzasign.glb#Scene0",
|
"pizzasign" => "models/pizzasign.glb#Scene0",
|
||||||
"selectagon" => "models/selectagon.glb#Scene0",
|
"selectagon" => "models/selectagon.glb#Scene0",
|
||||||
"clippy" => "models/clippy.glb#Scene0",
|
"clippy" => "models/clippy.glb#Scene0",
|
||||||
|
"clippy_ar" => "models/clippy_ar.glb#Scene0",
|
||||||
_ => "models/error.glb#Scene0",
|
_ => "models/error.glb#Scene0",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue