@gnsx/three 0.184.17 → 0.184.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/three.cjs CHANGED
@@ -11958,6 +11958,17 @@ class Object3D extends EventDispatcher {
11958
11958
  */
11959
11959
  this.visible = true;
11960
11960
 
11961
+ // WITH_GENESYS
11962
+ /**
11963
+ * When set to `true`, this object itself is hidden.
11964
+ * Doesn't affect the visibility of the children.
11965
+ *
11966
+ * @type {boolean}
11967
+ * @default false
11968
+ */
11969
+ this.selfHidden = false;
11970
+ // !WITH_GENESYS
11971
+
11961
11972
  /**
11962
11973
  * When set to `true`, the 3D object gets rendered into shadow maps.
11963
11974
  *
@@ -12971,6 +12982,9 @@ class Object3D extends EventDispatcher {
12971
12982
  if ( this.castShadow === true ) object.castShadow = true;
12972
12983
  if ( this.receiveShadow === true ) object.receiveShadow = true;
12973
12984
  if ( this.visible === false ) object.visible = false;
12985
+ // WITH_GENESYS
12986
+ if ( this.selfHidden === true ) object.selfHidden = true;
12987
+ // !WITH_GENESYS
12974
12988
  if ( this.frustumCulled === false ) object.frustumCulled = false;
12975
12989
  if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
12976
12990
  if ( this.static !== false ) object.static = this.static;
@@ -13272,6 +13286,9 @@ class Object3D extends EventDispatcher {
13272
13286
 
13273
13287
  this.layers.mask = source.layers.mask;
13274
13288
  this.visible = source.visible;
13289
+ // WITH_GENESYS
13290
+ this.selfHidden = source.selfHidden;
13291
+ // !WITH_GENESYS
13275
13292
 
13276
13293
  this.castShadow = source.castShadow;
13277
13294
  this.receiveShadow = source.receiveShadow;
@@ -49328,6 +49345,9 @@ class ObjectLoader extends Loader {
49328
49345
  }
49329
49346
 
49330
49347
  if ( data.visible !== undefined ) object.visible = data.visible;
49348
+ // WITH_GENESYS
49349
+ if ( data.selfHidden !== undefined ) object.selfHidden = data.selfHidden;
49350
+ // !WITH_GENESYS
49331
49351
  if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled;
49332
49352
  if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder;
49333
49353
  if ( data.static !== undefined ) object.static = data.static;
@@ -59713,7 +59733,7 @@ class ProfilerServiceClass {
59713
59733
  this._profile = 'full';
59714
59734
  this._enabled = false;
59715
59735
 
59716
- /** @type {Map<string, Float64Array>} */
59736
+ /** @type {Map<string, Float64Array>} Inclusive time ring buffers (one per label). */
59717
59737
  this.buffers = new Map();
59718
59738
  /** @type {Map<string, number>} */
59719
59739
  this.cursors = new Map();
@@ -59726,6 +59746,20 @@ class ProfilerServiceClass {
59726
59746
  this.traceStartTime = 0;
59727
59747
  this._markId = 0;
59728
59748
 
59749
+ /** @type {Map<string, Float64Array>} Exclusive (self) time ring buffers (one per label). */
59750
+ this.selfBuffers = new Map();
59751
+ /** @type {Map<string, number>} */
59752
+ this.selfCursors = new Map();
59753
+ /** @type {Map<string, number>} */
59754
+ this.selfCounts = new Map();
59755
+ /**
59756
+ * Global call stack tracking nesting across all labels for exclusive-time computation.
59757
+ * @type {Array<{ label: string, childTime: number }>}
59758
+ */
59759
+ this.callStack = [];
59760
+ /** @type {Map<string, number>} Total (uncapped) invocation count since last reset, for calls-per-frame. */
59761
+ this.invocations = new Map();
59762
+
59729
59763
  if ( this._enabled ) {
59730
59764
 
59731
59765
  this.traceStartTime = performance.now();
@@ -59832,6 +59866,9 @@ class ProfilerServiceClass {
59832
59866
  performance.mark( startMark );
59833
59867
  stack.push( { startTime, startMark, traced } );
59834
59868
 
59869
+ // Push onto the global call stack for exclusive-time tracking.
59870
+ this.callStack.push( { label, childTime: 0 } );
59871
+
59835
59872
  }
59836
59873
 
59837
59874
  /**
@@ -59867,6 +59904,42 @@ class ProfilerServiceClass {
59867
59904
  this.cursors.set( label, ( cursor + 1 ) % RING_SIZE );
59868
59905
  this.counts.set( label, Math.min( ( this.counts.get( label ) + 1 ), RING_SIZE ) );
59869
59906
 
59907
+ // Track total invocations (uncapped) for calls-per-frame computation.
59908
+ this.invocations.set( label, ( this.invocations.get( label ) ?? 0 ) + 1 );
59909
+
59910
+ // Exclusive (self) time via the global call stack.
59911
+ const top = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59912
+ if ( top !== undefined && top.label === label ) {
59913
+
59914
+ this.callStack.pop();
59915
+ const selfTime = Math.max( 0, duration - top.childTime );
59916
+
59917
+ let selfBuffer = this.selfBuffers.get( label );
59918
+ if ( ! selfBuffer ) {
59919
+
59920
+ selfBuffer = new Float64Array( RING_SIZE );
59921
+ this.selfBuffers.set( label, selfBuffer );
59922
+ this.selfCursors.set( label, 0 );
59923
+ this.selfCounts.set( label, 0 );
59924
+
59925
+ }
59926
+
59927
+ const selfCursor = this.selfCursors.get( label );
59928
+ selfBuffer[ selfCursor ] = selfTime;
59929
+ this.selfCursors.set( label, ( selfCursor + 1 ) % RING_SIZE );
59930
+ this.selfCounts.set( label, Math.min( ( this.selfCounts.get( label ) + 1 ), RING_SIZE ) );
59931
+
59932
+ // Propagate inclusive duration to the parent scope's child accumulator.
59933
+ const parent = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59934
+ if ( parent !== undefined ) parent.childTime += duration;
59935
+
59936
+ } else {
59937
+
59938
+ // Label mismatch — likely async interleaving. Reset to avoid corruption.
59939
+ this.callStack.length = 0;
59940
+
59941
+ }
59942
+
59870
59943
  if ( traced ) {
59871
59944
 
59872
59945
  this.traceEvents.push( {
@@ -59909,6 +59982,23 @@ class ProfilerServiceClass {
59909
59982
  const sorted = [ ...samples ].sort( ( a, b ) => a - b );
59910
59983
  const avg = sorted.reduce( ( a, b ) => a + b, 0 ) / sorted.length;
59911
59984
 
59985
+ // Exclusive (self) time stats.
59986
+ const selfCount = this.selfCounts.get( label ) ?? 0;
59987
+ let selfAvg, selfMin, selfMax, selfP95, selfFrameBudget;
59988
+ if ( selfCount > 0 ) {
59989
+
59990
+ const selfBuffer = this.selfBuffers.get( label );
59991
+ const selfSamples = [ ...( selfCount < RING_SIZE
59992
+ ? selfBuffer.subarray( 0, selfCount )
59993
+ : selfBuffer ) ].sort( ( a, b ) => a - b );
59994
+ selfAvg = selfSamples.reduce( ( a, b ) => a + b, 0 ) / selfSamples.length;
59995
+ selfMin = selfSamples[ 0 ];
59996
+ selfMax = selfSamples[ selfSamples.length - 1 ];
59997
+ selfP95 = selfSamples[ Math.floor( selfSamples.length * 0.95 ) ];
59998
+ selfFrameBudget = ( selfAvg / FRAME_BUDGET_MS ) * 100;
59999
+
60000
+ }
60001
+
59912
60002
  return {
59913
60003
  label,
59914
60004
  samples: samples.length,
@@ -59917,6 +60007,12 @@ class ProfilerServiceClass {
59917
60007
  max: sorted[ sorted.length - 1 ],
59918
60008
  p95: sorted[ Math.floor( sorted.length * 0.95 ) ],
59919
60009
  frameBudget: ( avg / FRAME_BUDGET_MS ) * 100,
60010
+ totalInvocations: this.invocations.get( label ) ?? 0,
60011
+ selfAvg,
60012
+ selfMin,
60013
+ selfMax,
60014
+ selfP95,
60015
+ selfFrameBudget,
59920
60016
  };
59921
60017
 
59922
60018
  }
@@ -60039,6 +60135,11 @@ class ProfilerServiceClass {
60039
60135
  this.traceEvents = [];
60040
60136
  this.traceStartTime = performance.now();
60041
60137
  this._markId = 0;
60138
+ this.selfBuffers.clear();
60139
+ this.selfCursors.clear();
60140
+ this.selfCounts.clear();
60141
+ this.callStack.length = 0;
60142
+ this.invocations.clear();
60042
60143
 
60043
60144
  }
60044
60145
 
@@ -60060,6 +60161,12 @@ class ProfilerServiceClass {
60060
60161
  * @property {number} max
60061
60162
  * @property {number} p95
60062
60163
  * @property {number} frameBudget Percentage of a 60 fps frame budget (16.67 ms)
60164
+ * @property {number} totalInvocations Total (uncapped) call count since last reset, for calls-per-frame computation.
60165
+ * @property {number|undefined} selfAvg Exclusive (self) avg ms — inclusive time minus child scope time.
60166
+ * @property {number|undefined} selfMin
60167
+ * @property {number|undefined} selfMax
60168
+ * @property {number|undefined} selfP95
60169
+ * @property {number|undefined} selfFrameBudget Exclusive time as percentage of a 60 fps frame budget.
60063
60170
  */
60064
60171
 
60065
60172
  /**
@@ -78100,7 +78207,7 @@ class WebGLRenderer {
78100
78207
 
78101
78208
  const visible = object.layers.test( camera.layers );
78102
78209
 
78103
- if ( visible ) {
78210
+ if ( visible && ! object.selfHidden /* WITH_GENESYS */ ) {
78104
78211
 
78105
78212
  if ( object.isGroup ) {
78106
78213
 
@@ -11978,6 +11978,17 @@ class Object3D extends EventDispatcher {
11978
11978
  */
11979
11979
  this.visible = true;
11980
11980
 
11981
+ // WITH_GENESYS
11982
+ /**
11983
+ * When set to `true`, this object itself is hidden.
11984
+ * Doesn't affect the visibility of the children.
11985
+ *
11986
+ * @type {boolean}
11987
+ * @default false
11988
+ */
11989
+ this.selfHidden = false;
11990
+ // !WITH_GENESYS
11991
+
11981
11992
  /**
11982
11993
  * When set to `true`, the 3D object gets rendered into shadow maps.
11983
11994
  *
@@ -12991,6 +13002,9 @@ class Object3D extends EventDispatcher {
12991
13002
  if ( this.castShadow === true ) object.castShadow = true;
12992
13003
  if ( this.receiveShadow === true ) object.receiveShadow = true;
12993
13004
  if ( this.visible === false ) object.visible = false;
13005
+ // WITH_GENESYS
13006
+ if ( this.selfHidden === true ) object.selfHidden = true;
13007
+ // !WITH_GENESYS
12994
13008
  if ( this.frustumCulled === false ) object.frustumCulled = false;
12995
13009
  if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
12996
13010
  if ( this.static !== false ) object.static = this.static;
@@ -13292,6 +13306,9 @@ class Object3D extends EventDispatcher {
13292
13306
 
13293
13307
  this.layers.mask = source.layers.mask;
13294
13308
  this.visible = source.visible;
13309
+ // WITH_GENESYS
13310
+ this.selfHidden = source.selfHidden;
13311
+ // !WITH_GENESYS
13295
13312
 
13296
13313
  this.castShadow = source.castShadow;
13297
13314
  this.receiveShadow = source.receiveShadow;
@@ -49348,6 +49365,9 @@ class ObjectLoader extends Loader {
49348
49365
  }
49349
49366
 
49350
49367
  if ( data.visible !== undefined ) object.visible = data.visible;
49368
+ // WITH_GENESYS
49369
+ if ( data.selfHidden !== undefined ) object.selfHidden = data.selfHidden;
49370
+ // !WITH_GENESYS
49351
49371
  if ( data.frustumCulled !== undefined ) object.frustumCulled = data.frustumCulled;
49352
49372
  if ( data.renderOrder !== undefined ) object.renderOrder = data.renderOrder;
49353
49373
  if ( data.static !== undefined ) object.static = data.static;
@@ -59733,7 +59753,7 @@ class ProfilerServiceClass {
59733
59753
  this._profile = 'full';
59734
59754
  this._enabled = false;
59735
59755
 
59736
- /** @type {Map<string, Float64Array>} */
59756
+ /** @type {Map<string, Float64Array>} Inclusive time ring buffers (one per label). */
59737
59757
  this.buffers = new Map();
59738
59758
  /** @type {Map<string, number>} */
59739
59759
  this.cursors = new Map();
@@ -59746,6 +59766,20 @@ class ProfilerServiceClass {
59746
59766
  this.traceStartTime = 0;
59747
59767
  this._markId = 0;
59748
59768
 
59769
+ /** @type {Map<string, Float64Array>} Exclusive (self) time ring buffers (one per label). */
59770
+ this.selfBuffers = new Map();
59771
+ /** @type {Map<string, number>} */
59772
+ this.selfCursors = new Map();
59773
+ /** @type {Map<string, number>} */
59774
+ this.selfCounts = new Map();
59775
+ /**
59776
+ * Global call stack tracking nesting across all labels for exclusive-time computation.
59777
+ * @type {Array<{ label: string, childTime: number }>}
59778
+ */
59779
+ this.callStack = [];
59780
+ /** @type {Map<string, number>} Total (uncapped) invocation count since last reset, for calls-per-frame. */
59781
+ this.invocations = new Map();
59782
+
59749
59783
  if ( this._enabled ) {
59750
59784
 
59751
59785
  this.traceStartTime = performance.now();
@@ -59852,6 +59886,9 @@ class ProfilerServiceClass {
59852
59886
  performance.mark( startMark );
59853
59887
  stack.push( { startTime, startMark, traced } );
59854
59888
 
59889
+ // Push onto the global call stack for exclusive-time tracking.
59890
+ this.callStack.push( { label, childTime: 0 } );
59891
+
59855
59892
  }
59856
59893
 
59857
59894
  /**
@@ -59887,6 +59924,42 @@ class ProfilerServiceClass {
59887
59924
  this.cursors.set( label, ( cursor + 1 ) % RING_SIZE );
59888
59925
  this.counts.set( label, Math.min( ( this.counts.get( label ) + 1 ), RING_SIZE ) );
59889
59926
 
59927
+ // Track total invocations (uncapped) for calls-per-frame computation.
59928
+ this.invocations.set( label, ( this.invocations.get( label ) ?? 0 ) + 1 );
59929
+
59930
+ // Exclusive (self) time via the global call stack.
59931
+ const top = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59932
+ if ( top !== undefined && top.label === label ) {
59933
+
59934
+ this.callStack.pop();
59935
+ const selfTime = Math.max( 0, duration - top.childTime );
59936
+
59937
+ let selfBuffer = this.selfBuffers.get( label );
59938
+ if ( ! selfBuffer ) {
59939
+
59940
+ selfBuffer = new Float64Array( RING_SIZE );
59941
+ this.selfBuffers.set( label, selfBuffer );
59942
+ this.selfCursors.set( label, 0 );
59943
+ this.selfCounts.set( label, 0 );
59944
+
59945
+ }
59946
+
59947
+ const selfCursor = this.selfCursors.get( label );
59948
+ selfBuffer[ selfCursor ] = selfTime;
59949
+ this.selfCursors.set( label, ( selfCursor + 1 ) % RING_SIZE );
59950
+ this.selfCounts.set( label, Math.min( ( this.selfCounts.get( label ) + 1 ), RING_SIZE ) );
59951
+
59952
+ // Propagate inclusive duration to the parent scope's child accumulator.
59953
+ const parent = this.callStack.length > 0 ? this.callStack[ this.callStack.length - 1 ] : undefined;
59954
+ if ( parent !== undefined ) parent.childTime += duration;
59955
+
59956
+ } else {
59957
+
59958
+ // Label mismatch — likely async interleaving. Reset to avoid corruption.
59959
+ this.callStack.length = 0;
59960
+
59961
+ }
59962
+
59890
59963
  if ( traced ) {
59891
59964
 
59892
59965
  this.traceEvents.push( {
@@ -59929,6 +60002,23 @@ class ProfilerServiceClass {
59929
60002
  const sorted = [ ...samples ].sort( ( a, b ) => a - b );
59930
60003
  const avg = sorted.reduce( ( a, b ) => a + b, 0 ) / sorted.length;
59931
60004
 
60005
+ // Exclusive (self) time stats.
60006
+ const selfCount = this.selfCounts.get( label ) ?? 0;
60007
+ let selfAvg, selfMin, selfMax, selfP95, selfFrameBudget;
60008
+ if ( selfCount > 0 ) {
60009
+
60010
+ const selfBuffer = this.selfBuffers.get( label );
60011
+ const selfSamples = [ ...( selfCount < RING_SIZE
60012
+ ? selfBuffer.subarray( 0, selfCount )
60013
+ : selfBuffer ) ].sort( ( a, b ) => a - b );
60014
+ selfAvg = selfSamples.reduce( ( a, b ) => a + b, 0 ) / selfSamples.length;
60015
+ selfMin = selfSamples[ 0 ];
60016
+ selfMax = selfSamples[ selfSamples.length - 1 ];
60017
+ selfP95 = selfSamples[ Math.floor( selfSamples.length * 0.95 ) ];
60018
+ selfFrameBudget = ( selfAvg / FRAME_BUDGET_MS ) * 100;
60019
+
60020
+ }
60021
+
59932
60022
  return {
59933
60023
  label,
59934
60024
  samples: samples.length,
@@ -59937,6 +60027,12 @@ class ProfilerServiceClass {
59937
60027
  max: sorted[ sorted.length - 1 ],
59938
60028
  p95: sorted[ Math.floor( sorted.length * 0.95 ) ],
59939
60029
  frameBudget: ( avg / FRAME_BUDGET_MS ) * 100,
60030
+ totalInvocations: this.invocations.get( label ) ?? 0,
60031
+ selfAvg,
60032
+ selfMin,
60033
+ selfMax,
60034
+ selfP95,
60035
+ selfFrameBudget,
59940
60036
  };
59941
60037
 
59942
60038
  }
@@ -60059,6 +60155,11 @@ class ProfilerServiceClass {
60059
60155
  this.traceEvents = [];
60060
60156
  this.traceStartTime = performance.now();
60061
60157
  this._markId = 0;
60158
+ this.selfBuffers.clear();
60159
+ this.selfCursors.clear();
60160
+ this.selfCounts.clear();
60161
+ this.callStack.length = 0;
60162
+ this.invocations.clear();
60062
60163
 
60063
60164
  }
60064
60165
 
@@ -60080,6 +60181,12 @@ class ProfilerServiceClass {
60080
60181
  * @property {number} max
60081
60182
  * @property {number} p95
60082
60183
  * @property {number} frameBudget Percentage of a 60 fps frame budget (16.67 ms)
60184
+ * @property {number} totalInvocations Total (uncapped) call count since last reset, for calls-per-frame computation.
60185
+ * @property {number|undefined} selfAvg Exclusive (self) avg ms — inclusive time minus child scope time.
60186
+ * @property {number|undefined} selfMin
60187
+ * @property {number|undefined} selfMax
60188
+ * @property {number|undefined} selfP95
60189
+ * @property {number|undefined} selfFrameBudget Exclusive time as percentage of a 60 fps frame budget.
60083
60190
  */
60084
60191
 
60085
60192
  /**