Skip to content

Commit

Permalink
gltf bugfixes (#117)
Browse files Browse the repository at this point in the history
bugfixes
- fix crash on inverted range for camera zoom level
- preview reloading: don't use cached b64 entity definitions
- remove existing skin when gltflinked nodes with skinned meshes have a new mesh assigned
- fix moving platform collision base position
- reorder transform sync systems to remove lag frames from gltf-linked or avatar-attached entities to player and camera
  • Loading branch information
robtfm authored Aug 3, 2024
1 parent e7df3cc commit 939228c
Show file tree
Hide file tree
Showing 26 changed files with 352 additions and 228 deletions.
15 changes: 10 additions & 5 deletions crates/avatar/src/animate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ use scene_runner::{
permissions::Permission,
renderer_context::RendererSceneContext,
update_world::{
avatar_modifier_area::PlayerModifiers, transform_and_parent::ParentPositionSync,
avatar_modifier_area::PlayerModifiers,
transform_and_parent::{ParentPositionSync, SceneProxyStage},
AddCrdtInterfaceExt,
},
ContainerEntity, ContainingScene,
Expand Down Expand Up @@ -105,13 +106,14 @@ impl Plugin for AvatarAnimationPlugin {
}

// copy emotes from scene-player entities onto main player entity
#[allow(clippy::type_complexity)]
fn read_player_emotes(
mut commands: Commands,
scene_player_emotes: Query<
(
Entity,
Ref<EmotesFromScene>,
&ParentPositionSync,
&ParentPositionSync<SceneProxyStage>,
&ContainerEntity,
),
Without<PrimaryUser>,
Expand Down Expand Up @@ -412,9 +414,12 @@ fn animate(
}
} else {
// otherwise play a default emote baesd on motion
if dynamic_state.ground_height > 0.2 {
let time_to_peak = (jump_height * -gravity * 2.0).sqrt() / -gravity;

let time_to_peak = (jump_height * -gravity * 2.0).sqrt() / -gravity;
if dynamic_state.ground_height > 0.2
|| dynamic_state.velocity.y > 0.0
&& dynamic_state.jump_time
> (time.elapsed_seconds() - time_to_peak / 2.0).max(0.0)
{
ActiveEmote {
urn: EmoteUrn::new("jump").unwrap(),
speed: time_to_peak.recip() * 0.75,
Expand Down
13 changes: 8 additions & 5 deletions crates/avatar/src/attach.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use dcl_component::{
SceneComponentId,
};
use scene_runner::update_world::{
mesh_collider::DisableCollisions, transform_and_parent::ParentPositionSync, AddCrdtInterfaceExt,
mesh_collider::DisableCollisions,
transform_and_parent::{AvatarAttachStage, ParentPositionSync},
AddCrdtInterfaceExt,
};

pub struct AttachPlugin;
Expand Down Expand Up @@ -44,7 +46,7 @@ pub fn update_attached(
) {
for removed in removed_attachments.read() {
if let Some(mut commands) = commands.get_entity(removed) {
commands.remove::<(ParentPositionSync, DisableCollisions)>();
commands.remove::<(ParentPositionSync<AvatarAttachStage>, DisableCollisions)>();
}
}

Expand Down Expand Up @@ -90,9 +92,10 @@ pub fn update_attached(
}
};

commands
.entity(ent)
.try_insert((ParentPositionSync(sync_entity), DisableCollisions));
commands.entity(ent).try_insert((
ParentPositionSync::<AvatarAttachStage>::new(sync_entity),
DisableCollisions,
));
debug!("syncing {ent:?} to {sync_entity:?}");
}
}
8 changes: 1 addition & 7 deletions crates/avatar/src/avatar_texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,7 @@ impl<'w, 's> PhotoBooth<'w, 's> {
render_layers: Some(render_layers),
automatic_delete: false,
},
AvatarDynamicState {
force: Vec2::ZERO,
velocity: Vec3::ZERO,
ground_height: 0.0,
tank: false,
rotate: 0.0,
},
AvatarDynamicState::default(),
BoothAvatar,
))
.id();
Expand Down
1 change: 1 addition & 0 deletions crates/avatar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ pub struct AvatarDynamicState {
pub ground_height: f32,
pub tank: bool,
pub rotate: f32,
pub jump_time: f32,
}

// send received avatar info into scenes
Expand Down
4 changes: 2 additions & 2 deletions crates/common/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ pub struct PrimaryCamera {
pub scene_override: Option<CameraOverride>,
}

#[derive(Clone, Debug, Default)]
#[derive(Clone, Debug)]
pub struct CinematicSettings {
pub origin: GlobalTransform,
pub origin: Entity,
pub allow_manual_rotation: bool,
pub yaw_range: Option<f32>,
pub pitch_range: Option<f32>,
Expand Down
99 changes: 97 additions & 2 deletions crates/common/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::collections::VecDeque;
use std::{collections::VecDeque, marker::PhantomData};

use bevy::{
app::Update,
ecs::{
component::Component,
event::{Event, Events},
system::{Command, Commands, EntityCommands, Query},
system::{Command, Commands, EntityCommand, EntityCommands, Query},
},
hierarchy::DespawnRecursiveExt,
prelude::{
Expand Down Expand Up @@ -233,3 +233,98 @@ fn despawn_with(mut commands: Commands, q: Query<(Entity, &DespawnWith)>) {
pub fn project_directories() -> directories::ProjectDirs {
directories::ProjectDirs::from("org", "decentraland", "BevyExplorer").unwrap()
}

// commands to modify components

pub struct ModifyComponent<C: Component, F: FnOnce(&mut C) + Send + Sync + 'static> {
func: F,
_p: PhantomData<fn() -> C>,
}

impl<C: Component, F: FnOnce(&mut C) + Send + Sync + 'static> EntityCommand
for ModifyComponent<C, F>
{
fn apply(self, id: Entity, world: &mut World) {
if let Some(mut c) = world.get_mut::<C>(id) {
(self.func)(&mut *c)
}
}
}

impl<C: Component, F: FnOnce(&mut C) + Send + Sync + 'static> ModifyComponent<C, F> {
fn new(func: F) -> Self {
Self {
func,
_p: PhantomData,
}
}
}

pub trait ModifyComponentExt {
fn modify_component<C: Component, F: FnOnce(&mut C) + Send + Sync + 'static>(
&mut self,
func: F,
) -> &mut Self;
}

impl<'a> ModifyComponentExt for EntityCommands<'a> {
fn modify_component<C: Component, F: FnOnce(&mut C) + Send + Sync + 'static>(
&mut self,
func: F,
) -> &mut Self {
self.add(ModifyComponent::new(func))
}
}

pub struct ModifyDefaultComponent<C: Component + Default, F: FnOnce(&mut C) + Send + Sync + 'static>
{
func: F,
_p: PhantomData<fn() -> C>,
}

impl<C: Component + Default, F: FnOnce(&mut C) + Send + Sync + 'static> EntityCommand
for ModifyDefaultComponent<C, F>
{
fn apply(self, id: Entity, world: &mut World) {
if let Some(mut c) = world.get_mut::<C>(id) {
(self.func)(&mut *c)
} else if let Some(mut entity) = world.get_entity_mut(id) {
let mut v = C::default();
(self.func)(&mut v);
entity.insert(v);
}
}
}

impl<C: Component + Default, F: FnOnce(&mut C) + Send + Sync + 'static>
ModifyDefaultComponent<C, F>
{
fn new(func: F) -> Self {
Self {
func,
_p: PhantomData,
}
}
}

pub trait ModifyDefaultComponentExt {
fn default_and_modify_component<
C: Component + Default,
F: FnOnce(&mut C) + Send + Sync + 'static,
>(
&mut self,
func: F,
) -> &mut Self;
}

impl<'a> ModifyDefaultComponentExt for EntityCommands<'a> {
fn default_and_modify_component<
C: Component + Default,
F: FnOnce(&mut C) + Send + Sync + 'static,
>(
&mut self,
func: F,
) -> &mut Self {
self.add(ModifyDefaultComponent::new(func))
}
}
12 changes: 7 additions & 5 deletions crates/ipfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,11 +939,13 @@ impl AssetReader for IpfsIo {

if let Some(hash) = &hash {
debug!("hash: {}", hash);
if let Ok(mut res) = self.default_io.read(&self.cache_path().join(hash)).await {
let mut daft_buffer = Vec::default();
res.read_to_end(&mut daft_buffer).await?;
let reader: Box<Reader> = Box::new(Cursor::new(daft_buffer));
return Ok(reader);
if !hash.starts_with("b64") {
if let Ok(mut res) = self.default_io.read(&self.cache_path().join(hash)).await {
let mut daft_buffer = Vec::default();
res.read_to_end(&mut daft_buffer).await?;
let reader: Box<Reader> = Box::new(Cursor::new(daft_buffer));
return Ok(reader);
}
}
};

Expand Down
19 changes: 12 additions & 7 deletions crates/scene_runner/src/renderer_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use dcl_component::{DclReader, DclWriter, SceneComponentId, SceneEntityId, ToDcl

use crate::{
primary_entities::PrimaryEntities,
update_world::{mesh_collider::DisableCollisions, transform_and_parent::ParentPositionSync},
update_world::{
mesh_collider::DisableCollisions,
transform_and_parent::{ParentPositionSync, SceneProxyStage},
},
ContainerEntity, SceneEntity, TargetParent,
};

Expand Down Expand Up @@ -212,14 +215,16 @@ impl RendererSceneContext {
});

if id == SceneEntityId::CAMERA {
commands
.entity(spawned)
.try_insert((ParentPositionSync(primaries.camera()), DisableCollisions));
commands.entity(spawned).try_insert((
ParentPositionSync::<SceneProxyStage>::new(primaries.camera()),
DisableCollisions,
));
}
if id == SceneEntityId::PLAYER {
commands
.entity(spawned)
.try_insert((ParentPositionSync(primaries.player()), DisableCollisions));
commands.entity(spawned).try_insert((
ParentPositionSync::<SceneProxyStage>::new(primaries.player()),
DisableCollisions,
));
}

commands.entity(root).add_child(spawned);
Expand Down
7 changes: 1 addition & 6 deletions crates/scene_runner/src/update_world/camera_mode_area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ pub fn update_camera_mode_area(
contexts: Query<&RendererSceneContext>,
mut current_areas: Local<Vec<(Entity, PermissionState)>>,
mut camera: Query<&mut PrimaryCamera>,
gt_helper: TransformHelper,
mut perms: Permission<Entity>,
) {
let Ok(mut camera) = camera.get_single_mut() else {
Expand Down Expand Up @@ -164,12 +163,8 @@ pub fn update_camera_mode_area(
warn!("no scene cam");
return;
};
let Ok(origin) = gt_helper.compute_global_transform(cam) else {
warn!("failed to get gt");
return;
};
camera.scene_override = Some(CameraOverride::Cinematic(CinematicSettings {
origin,
origin: cam,
allow_manual_rotation: cinematic_settings
.allow_manual_rotation
.unwrap_or_default(),
Expand Down
22 changes: 15 additions & 7 deletions crates/scene_runner/src/update_world/gltf_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::{
};

use bevy::{
animation::animation_player,
asset::LoadState,
gltf::{Gltf, GltfExtras, GltfLoaderSettings},
pbr::ExtendedMaterial,
Expand All @@ -17,12 +18,12 @@ use bevy::{
view::NoFrustumCulling,
},
scene::{scene_spawner_system, InstanceId},
transform::TransformSystem,
utils::{HashMap, HashSet},
};
use common::structs::AppConfig;
use common::{structs::AppConfig, util::ModifyComponentExt};
use rapier3d_f64::prelude::*;
use serde::Deserialize;
use ui_core::ModifyComponentExt;

use crate::{
renderer_context::RendererSceneContext,
Expand Down Expand Up @@ -50,6 +51,9 @@ use super::{

pub struct GltfDefinitionPlugin;

#[derive(SystemSet, Debug, PartialEq, Eq, Hash, Clone)]
pub struct GltfLinkSet;

#[derive(Component, Debug)]
pub struct GltfDefinition(PbGltfContainer);

Expand All @@ -76,14 +80,18 @@ impl Plugin for GltfDefinitionPlugin {
app.add_systems(Update, check_gltfs_ready.in_set(SceneSets::PostInit));
app.add_systems(
Update,
(
expose_gltfs,
update_gltf_linked_transforms,
update_gltf_linked_visibility,
)
(expose_gltfs, update_gltf_linked_visibility)
.chain()
.in_set(SceneSets::PostLoop),
);
app.add_systems(
PostUpdate,
(update_gltf_linked_transforms, apply_deferred)
.chain()
.in_set(GltfLinkSet)
.after(animation_player)
.before(TransformSystem::TransformPropagate),
);
}
}

Expand Down
13 changes: 11 additions & 2 deletions crates/scene_runner/src/update_world/mesh_renderer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use std::f32::consts::FRAC_PI_2;

use bevy::{prelude::*, render::mesh::VertexAttributeValues, utils::HashMap};
use bevy::{
prelude::*,
render::mesh::{skinning::SkinnedMesh, VertexAttributeValues},
utils::HashMap,
};

use common::{sets::SceneSets, structs::AppConfig};

Expand Down Expand Up @@ -138,6 +142,7 @@ pub fn update_mesh(
&SceneEntity,
&MeshDefinition,
Option<&Handle<SceneMaterial>>,
Option<&Handle<Mesh>>,
),
Or<(Changed<MeshDefinition>, With<RetryMeshDefinition>)>,
>,
Expand All @@ -150,7 +155,7 @@ pub fn update_mesh(
config: Res<AppConfig>,
mut gltf_mesh_resolver: GltfMeshResolver,
) {
for (ent, scene_ent, prim, maybe_material) in new_primitives.iter() {
for (ent, scene_ent, prim, maybe_material, maybe_existing_mesh) in new_primitives.iter() {
commands.entity(ent).remove::<RetryMeshDefinition>();
let handle = match prim {
MeshDefinition::Box { uvs } => {
Expand Down Expand Up @@ -215,6 +220,10 @@ pub fn update_mesh(
commands.entity(ent).try_insert(RetryMeshDefinition);
continue;
};
// remove skin if mesh changed
if maybe_existing_mesh != Some(&h_mesh) {
commands.entity(ent).remove::<SkinnedMesh>();
}
h_mesh
}
};
Expand Down
Loading

0 comments on commit 939228c

Please sign in to comment.