@@ -18,6 +18,13 @@ import { createComponentDefinition } from "../utils/validation.ts";
1818import { useParent } from "../hooks/use-parent.tsx" ;
1919import { useApp } from "../hooks/use-app.tsx" ;
2020
21+ /**
22+ * Extended instancing data with cleanup flag
23+ */
24+ type InstancingDataWithCleanup = NonNullable < PcMeshInstance [ "instancingData" ] > & {
25+ _destroyVertexBuffer ?: boolean ;
26+ } ;
27+
2128/**
2229 * Declarative wrapper for pc.MeshInstance.
2330 * Supports morphs, skins, and hardware instancing.
@@ -84,9 +91,11 @@ const MeshInstanceComponent: FC<MeshInstanceProps> = (props) => {
8491 mi . setInstancing ( vertexBuffer ) ;
8592 } else if ( matrices && count && device ) {
8693 const format = VertexFormat . getDefaultInstancingFormat ( device ) ;
87- const vb = new VertexBuffer ( device , format , count , { data : matrices } ) ;
94+ const vb = new VertexBuffer ( device , format , count , { data : matrices . buffer as ArrayBuffer } ) ;
8895 mi . setInstancing ( vb ) ;
89- ( mi . instancingData as any ) . _destroyVertexBuffer = true ;
96+ if ( mi . instancingData ) {
97+ ( mi . instancingData as InstancingDataWithCleanup ) . _destroyVertexBuffer = true ;
98+ }
9099 }
91100
92101 if ( count ) mi . instancingCount = count ;
@@ -101,8 +110,9 @@ const MeshInstanceComponent: FC<MeshInstanceProps> = (props) => {
101110 if ( idx !== - 1 ) render . meshInstances . splice ( idx , 1 ) ;
102111
103112 // clean up any auto-created instancing buffer
104- if ( mi . instancingData && ( mi . instancingData as any ) . _destroyVertexBuffer ) {
105- mi . instancingData . vertexBuffer ?. destroy ( ) ;
113+ const instancingData = mi . instancingData as InstancingDataWithCleanup | null ;
114+ if ( instancingData ?. _destroyVertexBuffer ) {
115+ instancingData . vertexBuffer ?. destroy ( ) ;
106116 }
107117
108118 instanceRef . current = null ;
@@ -133,7 +143,7 @@ const MeshInstanceComponent: FC<MeshInstanceProps> = (props) => {
133143 const { matrices, count } = props . instancing ;
134144 if ( matrices && mi . instancingData . vertexBuffer ) {
135145 const vb = mi . instancingData . vertexBuffer ;
136- const view = vb . lock ( ) ;
146+ const view = vb . lock ( ) as unknown as Float32Array ;
137147 view . set ( matrices ) ;
138148 vb . unlock ( ) ;
139149 }
@@ -156,8 +166,10 @@ const componentDefinition = createComponentDefinition<MeshInstanceProps, PcMeshI
156166 new Entity ( "mock" , getStaticNullApplication ( ) )
157167 ) ,
158168 ( mi ) => {
159- if ( mi . instancingData && ( mi . instancingData as any ) . _destroyVertexBuffer )
160- mi . instancingData . vertexBuffer ?. destroy ( ) ;
169+ const instancingData = mi . instancingData as InstancingDataWithCleanup | null ;
170+ if ( instancingData ?. _destroyVertexBuffer ) {
171+ instancingData . vertexBuffer ?. destroy ( ) ;
172+ }
161173 } ,
162174 "MeshInstanceComponent"
163175) ;
@@ -187,11 +199,15 @@ componentDefinition.schema = {
187199 default : undefined ,
188200 } ,
189201 instancing : {
190- validate : ( v : unknown ) =>
191- ! v ||
192- ( typeof v === "object" &&
193- ( ( v as any ) . vertexBuffer instanceof VertexBuffer ||
194- ( v as any ) . matrices instanceof Float32Array ) ) ,
202+ validate : ( v : unknown ) => {
203+ if ( ! v ) return true ;
204+ if ( typeof v !== "object" || v === null ) return false ;
205+ const obj = v as Record < string , unknown > ;
206+ return (
207+ ( obj . vertexBuffer instanceof VertexBuffer ) ||
208+ ( obj . matrices instanceof Float32Array )
209+ ) ;
210+ } ,
195211 errorMsg : ( v : unknown ) =>
196212 `Invalid value for prop "instancing": ${ v } . Expected { vertexBuffer?: VertexBuffer, matrices?: Float32Array, count?: number }.` ,
197213 default : undefined ,
0 commit comments