Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/common/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,10 +1202,11 @@ pub struct MicState {
pub enabled: bool,
}

#[derive(Resource, Default)]
#[derive(Debug, Resource, Default)]
pub struct PreviewMode {
pub server: Option<String>,
pub is_preview: bool,
pub preview_parcel: Option<IVec2>,
}

// resource into which systems can add debug info
Expand Down
30 changes: 19 additions & 11 deletions crates/ipfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use bevy::asset::io::wasm::HttpWasmAssetReader;
use bevy_console::{ConsoleCommand, PrintConsoleLine};
use common::{
sets::RealmLifecycle,
structs::{AppConfig, CommsConfig, CurrentRealm, ServerConfiguration},
structs::{AppConfig, CommsConfig, CurrentRealm, PreviewMode, ServerConfiguration},
util::TaskCompat,
};
use ipfs_path::IpfsAsset;
Expand Down Expand Up @@ -574,6 +574,7 @@ pub fn change_realm(
>,
mut current_realm: ResMut<CurrentRealm>,
mut print: EventWriter<PrintConsoleLine>,
preview_mode: Res<PreviewMode>,
) {
match *realm_change {
None => *realm_change = Some(ipfs.realm_config_receiver.clone()),
Expand Down Expand Up @@ -606,16 +607,23 @@ pub fn change_realm(
}

if !change_realm_requests.is_empty() {
let ipfs = ipfs.clone();
let request = change_realm_requests.read().last().unwrap();

let new_realm = map_realm_name(&request.new_realm);
let content_server_override = request.content_server_override.to_owned();
IoTaskPool::get()
.spawn_compat(async move {
ipfs.set_realm(new_realm, content_server_override).await;
})
.detach();
if preview_mode.is_preview {
print.write(PrintConsoleLine {
line: "Changing realm is disabled in preview mode.".to_owned(),
});
change_realm_requests.clear();
} else {
let ipfs = ipfs.clone();
let request = change_realm_requests.read().last().unwrap();

let new_realm = map_realm_name(&request.new_realm);
let content_server_override = request.content_server_override.to_owned();
IoTaskPool::get()
.spawn_compat(async move {
ipfs.set_realm(new_realm, content_server_override).await;
})
.detach();
}
}
}

Expand Down
13 changes: 10 additions & 3 deletions crates/scene_runner/src/initialize_scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use system_bridge::{LiveSceneInfo, SystemApi, SystemBridge};
use super::{update_world::CrdtExtractors, LoadSceneEvent, PrimaryUser, SceneSets, SceneUpdates};
use crate::{
bounds_calc::scene_regions,
parcel_to_vec3,
renderer_context::RendererSceneContext,
update_world::{visibility::VisibilityComponent, ComponentTracker},
vec3_to_parcel, ContainerEntity, DeletedSceneEntities, OutOfWorld, SceneEntity,
Expand Down Expand Up @@ -1366,7 +1367,7 @@ fn load_active_entities(
#[derive(Resource, Default)]
pub struct CurrentImposterScene(pub Option<(PointerResult, bool)>);

#[allow(clippy::type_complexity, clippy::too_many_arguments)]
#[expect(clippy::type_complexity, clippy::too_many_arguments)]
pub fn process_scene_lifecycle(
mut commands: Commands,
current_realm: Res<CurrentRealm>,
Expand All @@ -1381,21 +1382,27 @@ pub fn process_scene_lifecycle(
mut spawn: EventWriter<LoadSceneEvent>,
pointers: Res<ScenePointers>,
imposter_scene: Res<CurrentImposterScene>,
preview_mode: Res<PreviewMode>,
) {
let mut required_scene_ids: HashMap<(String, Option<String>), bool> = HashMap::new();

// add nearby scenes to requirements
let Ok(focus) = focus.single() else {
return;
};
let focus = preview_mode
.preview_parcel
.as_ref()
.map(|p| GlobalTransform::from(Transform::from_translation(parcel_to_vec3(*p))))
.unwrap_or(*focus);

let current_scene = parcels_in_range(focus, 0.0, pointers.min(), pointers.max())
let current_scene = parcels_in_range(&focus, 0.0, pointers.min(), pointers.max())
.first()
.and_then(|(p, _)| pointers.get(p))
.and_then(PointerResult::hash_and_urn);

let pir = parcels_in_range(
focus,
&focus,
range.load + range.unload,
pointers.min(),
pointers.max(),
Expand Down
8 changes: 8 additions & 0 deletions crates/scene_runner/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,14 @@ pub fn vec3_to_parcel(position: Vec3) -> IVec2 {
.as_ivec2()
}

pub fn parcel_to_vec3(parcel: IVec2) -> Vec3 {
Vec3::new(
(parcel.x as f32 + 0.5) * PARCEL_SIZE,
0.,
-(parcel.y as f32 + 0.5) * PARCEL_SIZE,
)
}

impl ContainingScene<'_, '_> {
// just the parcel at the position
pub fn get_parcel_position(&self, position: Vec3) -> Option<Entity> {
Expand Down
21 changes: 14 additions & 7 deletions crates/system_ui/src/sysinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ use console::DoAddConsoleCommand;
use scene_material::{SceneMaterial, SCENE_MATERIAL_OUTLINE};
use scene_runner::{
initialize_scene::{SceneLoading, TestingData, PARCEL_SIZE},
parcel_to_vec3,
renderer_context::RendererSceneContext,
update_world::{
gltf_container::{GltfLoadingCount, SceneResourceLookup},
ComponentTracker, TrackComponents,
},
ContainerEntity, ContainingScene, Toaster,
vec3_to_parcel, ContainerEntity, ContainingScene, Toaster,
};
use ui_core::{
bound_node::BoundedImageMaterial,
Expand Down Expand Up @@ -441,23 +442,25 @@ fn setup_minimap(
fn update_minimap(
q: Query<&DuiEntities, With<Minimap>>,
mut maps: Query<&mut MapTexture>,
player: Query<(Entity, &GlobalTransform), With<PrimaryUser>>,
player: Query<&GlobalTransform, With<PrimaryUser>>,
containing_scene: ContainingScene,
scenes: Query<(&RendererSceneContext, Option<&GltfLoadingCount>)>,
mut text: Query<&mut Text>,
preview: Res<PreviewMode>,
) {
let Ok((player, gt)) = player.single() else {
let Ok(gt) = player.single() else {
return;
};

let player_translation = (gt.translation().xz() * Vec2::new(1.0, -1.0)) / PARCEL_SIZE;
let map_center = player_translation - Vec2::Y;
let parcel = preview
.preview_parcel
.unwrap_or_else(|| player_translation.floor().as_ivec2());

let scene = containing_scene
.get_parcel_oow(player)
.get_parcel_position(parcel_to_vec3(parcel))
.and_then(|scene| scenes.get(scene).ok());
let parcel = player_translation.floor().as_ivec2();
let title = scene
.map(|(context, _)| context.title.clone())
.unwrap_or("???".to_owned());
Expand Down Expand Up @@ -500,7 +503,7 @@ fn update_tracker(
mut q: Query<(Ref<Tracker>, &DuiEntities)>,
stats: Query<&SceneResourceLookup>,
f: Res<FrameCount>,
player: Query<Entity, With<PrimaryUser>>,
player: Query<&GlobalTransform, With<PrimaryUser>>,
containing_scene: ContainingScene,
dui: Res<DuiRegistry>,
mesh_handles: Query<(&Mesh3d, &ContainerEntity, &Visibility)>,
Expand All @@ -514,6 +517,7 @@ fn update_tracker(
materials: Res<Assets<SceneMaterial>>,
diagnostics: Res<DiagnosticsStore>,
images: Res<Assets<Image>>,
preview: Res<PreviewMode>,
) {
let Ok((tracker, entities)) = q.single_mut() else {
return;
Expand All @@ -535,7 +539,10 @@ fn update_tracker(
return;
};

let scenes = containing_scene.get_parcel(player);
let parcel = preview
.preview_parcel
.unwrap_or_else(|| vec3_to_parcel(player.translation()));
let scenes = containing_scene.get_parcel_position(parcel_to_vec3(parcel));
let Some(scene) = scenes.iter().next() else {
return;
};
Expand Down
62 changes: 58 additions & 4 deletions src/lib/actual_web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ use image_processing::ImageProcessingPlugin;
use imposters::DclImposterPlugin;
use restricted_actions::{process_startup_scenes, RestrictedActionsPlugin};
use scene_material::SceneBoundPlugin;
use scene_runner::{initialize_scene::TestingData, vec3_to_parcel, OutOfWorld, SceneRunnerPlugin};
use scene_runner::{
initialize_scene::{parcels_in_range, ScenePointers, TestingData},
vec3_to_parcel, OutOfWorld, SceneRunnerPlugin,
};

use av::AVPlayerPlugin;
use avatar::AvatarPlugin;
Expand Down Expand Up @@ -88,11 +91,13 @@ fn main_inner(
});
let base_graphics = base_config.graphics.clone();

let location = IVec2Arg::from_str(location)
.map(|l| l.0)
.unwrap_or(base_config.location);

let final_config = AppConfig {
server: server.to_owned(),
location: IVec2Arg::from_str(location)
.map(|l| l.0)
.unwrap_or(base_config.location),
location,
graphics: common::structs::GraphicsSettings {
gpu_bytes_per_frame: rabpf,
..base_graphics
Expand Down Expand Up @@ -252,6 +257,7 @@ fn main_inner(
app.insert_resource(PreviewMode {
server: is_preview.then_some(map_realm_name(&final_config.server)),
is_preview,
preview_parcel: None,
});
app.insert_resource(SceneParams::from_query_string(params, true));

Expand Down Expand Up @@ -332,6 +338,8 @@ fn main_inner(
app.add_console_command::<SceneDistanceCommand, _>(scene_distance);
app.add_console_command::<SceneThreadsCommand, _>(scene_threads);
app.add_console_command::<FpsCommand, _>(set_fps);
app.add_console_command::<LockPreviewCommand, _>(lock_preview);
app.add_console_command::<UnlockPreviewCommand, _>(unlock_preview);

app.add_systems(
Update,
Expand Down Expand Up @@ -458,6 +466,52 @@ fn scene_distance(
}
}

/// Locks the preview mode to the current parcel
#[derive(clap::Parser, ConsoleCommand)]
#[command(name = "/lock_preview")]
struct LockPreviewCommand;

fn lock_preview(
mut input: ConsoleCommand<LockPreviewCommand>,
mut preview_mode: ResMut<PreviewMode>,
focus: Single<&GlobalTransform, With<PrimaryUser>>,
pointers: Res<ScenePointers>,
) {
if let Some(Ok(_command)) = input.take() {
let Some((parcel, _)) = parcels_in_range(&focus, 0.0, pointers.min(), pointers.max()).pop()
else {
unreachable!("Player should never be in a invalid parcel.");
};
let Some(_current_scene) = pointers.get(parcel) else {
input.reply_failed(format!("failed to locked preview to parcel {}", parcel));
return;
};
preview_mode.preview_parcel = Some(parcel);

input.reply_ok(format!("locked preview to parcel {}", parcel));
}
}

/// Unlocks the preview mode to the current parcel
#[derive(clap::Parser, ConsoleCommand)]
#[command(name = "/unlock_preview")]
struct UnlockPreviewCommand;

fn unlock_preview(
mut input: ConsoleCommand<UnlockPreviewCommand>,
mut preview_mode: ResMut<PreviewMode>,
) {
if let Some(Ok(_command)) = input.take() {
let parcel = preview_mode.preview_parcel.take();

if let Some(parcel) = parcel {
input.reply_ok(format!("unlocked preview to parcel {}", parcel));
} else {
input.reply("Preview was not locked to a parcel.");
}
}
}

// set thread count
#[derive(clap::Parser, ConsoleCommand)]
#[command(name = "/scene_threads")]
Expand Down
Loading
Loading