Skip to content

Commit c1106f7

Browse files
authored
fix(GSplat): Do not apply instance and material again if no changes. (#304)
1 parent 31b5dc6 commit c1106f7

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

.changeset/gsplat-props-guard.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@playcanvas/react": patch
3+
---
4+
5+
Fixed GSplat component props re-application causing splat to disappear during React re-renders. Added equality guards for `instance` and `material` properties to prevent destructive setter calls when the value hasn't changed.
6+

packages/lib/src/components/GSplat.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { FC } from "react";
44
import { useComponent } from "../hooks/index.ts";
5-
import { Asset, Entity, GSplatComponent } from "playcanvas";
5+
import { Asset, Entity, GSplatComponent, GSplatInstance, ShaderMaterial } from "playcanvas";
66
import { PublicProps } from "../utils/types-utils.ts";
77
import { validatePropsWithDefaults, createComponentDefinition, getStaticNullApplication } from "../utils/validation.ts";
88
/**
@@ -60,5 +60,31 @@ componentDefinition.schema = {
6060
instance.unified = value;
6161
instance.enabled = true;
6262
}
63+
},
64+
material: {
65+
validate: (val: unknown) => val === null || val instanceof ShaderMaterial,
66+
errorMsg: (val: unknown) => `Invalid value for prop "material": "${val}". Expected a ShaderMaterial or null.`,
67+
default: null,
68+
apply: (instance: GSplatComponent, props: Record<string, unknown>, key: string) => {
69+
const value = props[key] as ShaderMaterial | null;
70+
if (instance.material === value) {
71+
return;
72+
}
73+
if (value) {
74+
instance.material = value;
75+
}
76+
}
77+
},
78+
instance: {
79+
validate: (val: unknown) => val === null || val instanceof GSplatInstance,
80+
errorMsg: (val: unknown) => `Invalid value for prop "instance": "${val}". Expected a GSplatInstance or null.`,
81+
default: null,
82+
apply: (instance: GSplatComponent, props: Record<string, unknown>, key: string) => {
83+
const value = props[key] as GSplatInstance | null;
84+
if (instance.instance === value) {
85+
return;
86+
}
87+
instance.instance = value;
88+
}
6389
}
6490
}

0 commit comments

Comments
 (0)