Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a114ab1
feat: implement trigger area component
kuruk-mm Dec 14, 2025
0767d86
add CL_PLAYER collision layer
kuruk-mm Dec 14, 2025
3f56ce6
detect any entity also
kuruk-mm Dec 14, 2025
6920cca
optimizations, and implement pooling
kuruk-mm Dec 14, 2025
e5eaaa0
add global object pool manager
kuruk-mm Dec 14, 2025
533ed0d
refactor: apply clippy fixes and reduce log verbosity
kuruk-mm Dec 14, 2025
74b2f01
refactor: use callback monitor
kuruk-mm Dec 14, 2025
80ba58b
fix crash, check object is valid
kuruk-mm Dec 14, 2025
5a533f5
fix panic
kuruk-mm Dec 14, 2025
f8ec6b3
feat: implement tween continuous modes (RotateContinuous, MoveContinu…
kuruk-mm Dec 14, 2025
b3dcdde
fix: normalize quaternions in RotateContinuous to prevent assertion f…
kuruk-mm Dec 15, 2025
c54c723
fix: use axis-angle extraction for RotateContinuous instead of euler …
kuruk-mm Dec 15, 2025
6c8cee6
fix: correct RotateContinuous to extract axis from quaternion xyz
kuruk-mm Dec 15, 2025
9ee2112
fixes
kuruk-mm Dec 15, 2025
8107677
fixes on material
kuruk-mm Dec 15, 2025
7a73e4c
feat: add remote avatar detection and scene-aware trigger areas
kuruk-mm Dec 17, 2025
cdb0f48
perf: optimize trigger area avatar scene detection
kuruk-mm Dec 17, 2025
59dc0c3
refactor: simplify trigger area scene-awareness with physics enable/d…
kuruk-mm Dec 17, 2025
d5bc330
Merge remote-tracking branch 'origin/main' into feat/trigger-area
kuruk-mm Dec 17, 2025
8fd54e4
fix: apply clippy match_ref_pats lint fix
kuruk-mm Dec 17, 2025
45d0119
Merge branch 'feat/trigger-area' into feat/tween-continuous-modes
kuruk-mm Dec 17, 2025
17d5b30
Merge branch 'main' into feat/tween-continuous-modes
kuruk-mm Dec 19, 2025
6cb3042
format
kuruk-mm Dec 20, 2025
fb4f251
Merge branch 'main' into feat/tween-continuous-modes
kuruk-mm Dec 21, 2025
b0a035b
revert: remove unrelated bug fixes (moved to separate PR #1004)
kuruk-mm Dec 22, 2025
4c3a82a
Merge branch 'main' into feat/tween-continuous-modes
kuruk-mm Dec 23, 2025
9f679a2
Merge branch 'main' into feat/tween-continuous-modes
kuruk-mm Dec 24, 2025
778dfed
fix: remove duplicate trigger area cleanup block
kuruk-mm Dec 24, 2025
d92320d
Merge branch 'main' into feat/tween-continuous-modes
kuruk-mm Dec 29, 2025
4394037
Merge branch 'main' into feat/tween-continuous-modes
kuruk-mm Dec 29, 2025
0584237
fix: update gdext import from engine to classes module
kuruk-mm Dec 29, 2025
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
66 changes: 64 additions & 2 deletions lib/src/dcl/components/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use super::{
proto_components::{
common::{
texture_union::Tex, Color3, Color4, TextureFilterMode, TextureUnion, TextureWrapMode,
Vector2,
},
sdk::components::{pb_material, MaterialTransparencyMode},
},
Expand Down Expand Up @@ -92,6 +93,33 @@ impl Eq for RoundedColor3 {
fn assert_receiver_is_total_eq(&self) {}
}

#[derive(Clone)]
pub struct RoundedVector2(pub Vector2);

impl std::hash::Hash for RoundedVector2 {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
RoundedFloat(self.0.x).hash(state);
RoundedFloat(self.0.y).hash(state);
}
}

impl PartialEq for RoundedVector2 {
fn eq(&self, other: &Self) -> bool {
RoundedFloat(self.0.x) == RoundedFloat(other.0.x)
&& RoundedFloat(self.0.y) == RoundedFloat(other.0.y)
}
}

impl Eq for RoundedVector2 {
fn assert_receiver_is_total_eq(&self) {}
}

impl Default for RoundedVector2 {
fn default() -> Self {
Self(Vector2 { x: 0.0, y: 0.0 })
}
}

#[derive(Clone, Hash, PartialEq, Eq)]
pub enum DclSourceTex {
Texture(String),
Expand All @@ -105,11 +133,27 @@ impl Default for DclSourceTex {
}
}

#[derive(Clone, Hash, PartialEq, Eq, Default)]
#[derive(Clone, Hash, PartialEq, Eq)]
pub struct DclTexture {
pub wrap_mode: TextureWrapMode,
pub filter_mode: TextureFilterMode,
pub source: DclSourceTex,
/// UV offset, default = (0, 0). Only applies to main texture in PbrMaterial/UnlitMaterial.
pub offset: RoundedVector2,
/// UV tiling/scale, default = (1, 1). Only applies to main texture in PbrMaterial/UnlitMaterial.
pub tiling: RoundedVector2,
}

impl Default for DclTexture {
fn default() -> Self {
Self {
wrap_mode: TextureWrapMode::TwmClamp,
filter_mode: TextureFilterMode::TfmBilinear,
source: DclSourceTex::default(),
offset: RoundedVector2(Vector2 { x: 0.0, y: 0.0 }),
tiling: RoundedVector2(Vector2 { x: 1.0, y: 1.0 }),
}
}
}

impl From<&TextureUnion> for Option<DclTexture> {
Expand Down Expand Up @@ -152,24 +196,41 @@ impl From<&TextureUnion> for Option<DclTexture> {

match value.tex.as_ref()? {
Tex::Texture(texture) => {
//some
// Only Texture type has offset and tiling fields
let offset = texture
.offset
.as_ref()
.map(|v| RoundedVector2(v.clone()))
.unwrap_or_else(|| RoundedVector2(Vector2 { x: 0.0, y: 0.0 }));
let tiling = texture
.tiling
.as_ref()
.map(|v| RoundedVector2(v.clone()))
.unwrap_or_else(|| RoundedVector2(Vector2 { x: 1.0, y: 1.0 }));

Some(DclTexture {
wrap_mode,
filter_mode,
source: DclSourceTex::Texture(texture.src.clone()),
offset,
tiling,
})
}
Tex::AvatarTexture(avatar_texture) => Some(DclTexture {
wrap_mode,
filter_mode,
source: DclSourceTex::AvatarTexture(avatar_texture.user_id.clone()),
offset: RoundedVector2(Vector2 { x: 0.0, y: 0.0 }),
tiling: RoundedVector2(Vector2 { x: 1.0, y: 1.0 }),
}),
Tex::VideoTexture(video_texture) => Some(DclTexture {
wrap_mode,
filter_mode,
source: DclSourceTex::VideoTexture(SceneEntityId::from_i32(
video_texture.video_player_entity as i32,
)),
offset: RoundedVector2(Vector2 { x: 0.0, y: 0.0 }),
tiling: RoundedVector2(Vector2 { x: 1.0, y: 1.0 }),
}),
Tex::UiTexture(_) => todo!("UI Texture not implemented"),
}
Expand Down Expand Up @@ -233,6 +294,7 @@ pub struct DclPbrMaterial {
}

#[derive(Clone, Hash, PartialEq, Eq)]
#[allow(clippy::large_enum_variant)]
pub enum DclMaterial {
Unlit(DclUnlitMaterial),
Pbr(DclPbrMaterial),
Expand Down
28 changes: 28 additions & 0 deletions lib/src/scene_runner/components/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,20 @@ pub fn update_material(scene: &mut Scene, crdt_state: &mut SceneCrdtState) {
godot_material
.set_albedo(unlit.diffuse_color.0.to_godot().linear_to_srgb());

// Apply UV offset/tiling from main texture (only main texture supports this)
if let Some(texture) = &unlit.texture {
godot_material.set_uv1_offset(godot::builtin::Vector3::new(
texture.offset.0.x,
texture.offset.0.y,
0.0,
));
godot_material.set_uv1_scale(godot::builtin::Vector3::new(
texture.tiling.0.x,
texture.tiling.0.y,
1.0,
));
}

// Handle transparency for unlit materials (auto-detect)
if unlit.diffuse_color.0.a < 1.0 || unlit.texture.is_some() {
godot_material.set_transparency(Transparency::ALPHA_DEPTH_PRE_PASS);
Expand All @@ -152,6 +166,20 @@ pub fn update_material(scene: &mut Scene, crdt_state: &mut SceneCrdtState) {
godot_material.set_flag(Flags::ALBEDO_TEXTURE_FORCE_SRGB, true);
godot_material.set_albedo(pbr.albedo_color.0.to_godot());

// Apply UV offset/tiling from main texture (only main texture supports this)
if let Some(texture) = &pbr.texture {
godot_material.set_uv1_offset(godot::builtin::Vector3::new(
texture.offset.0.x,
texture.offset.0.y,
0.0,
));
godot_material.set_uv1_scale(godot::builtin::Vector3::new(
texture.tiling.0.x,
texture.tiling.0.y,
1.0,
));
}

// Handle transparency mode
match pbr.transparency_mode {
MaterialTransparencyMode::MtmOpaque => {
Expand Down
Loading
Loading