@@ -35,6 +35,21 @@ const colorMaps = ['map', 'emissiveMap', 'sheenColorMap', 'specularColorMap', 'e
3535
3636type ClassConstructor = { new ( ) : void } ;
3737
38+ const MEMOIZED_PROTOTYPES = new Map ( ) ;
39+
40+ function getMemoizedPrototype ( root : any ) {
41+ let ctor = MEMOIZED_PROTOTYPES . get ( root . constructor ) ;
42+ try {
43+ if ( ! ctor ) {
44+ ctor = new root . constructor ( ) ;
45+ MEMOIZED_PROTOTYPES . set ( root . constructor , ctor ) ;
46+ }
47+ } catch ( e ) {
48+ // ...
49+ }
50+ return ctor ;
51+ }
52+
3853// This function applies a set of changes to the instance
3954export function applyProps < T extends NgtAnyRecord > ( instance : NgtInstanceState < T > [ 'object' ] , props : NgtAnyRecord ) {
4055 // if props is empty
@@ -77,7 +92,21 @@ export function applyProps<T extends NgtAnyRecord>(instance: NgtInstanceState<T>
7792 ( value as ClassConstructor | undefined ) ?. constructor &&
7893 ( targetProp as ClassConstructor ) . constructor === ( value as ClassConstructor ) . constructor
7994 ) {
80- targetProp . copy ( value ) ;
95+ // If both are geometries, we should assign the value directly instead of copying
96+ if (
97+ is . three < THREE . BufferGeometry > ( targetProp , 'isBufferGeometry' ) &&
98+ is . three < THREE . BufferGeometry > ( value , 'isBufferGeometry' )
99+ ) {
100+ Object . assign ( currentInstance , { [ key ] : value } ) ;
101+ } else {
102+ // fetch the default state of the target
103+ const ctor = getMemoizedPrototype ( currentInstance ) ;
104+ // The target key was originally null or undefined, which indicates that the object which
105+ // is now present was externally set by the user, we should therefore assign the value directly
106+ if ( ctor !== undefined && ctor [ key ] == null ) Object . assign ( currentInstance , { [ key ] : value } ) ;
107+ // Otherwise copy is correct
108+ else targetProp . copy ( value ) ;
109+ }
81110 }
82111 // Layers have no copy function, we must therefore copy the mask property
83112 else if ( targetProp instanceof THREE . Layers && value instanceof THREE . Layers ) {
0 commit comments