@gnsx/three 0.185.13 → 0.185.15
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 +682 -0
- package/build/three.core.js +669 -1
- package/build/three.core.min.js +1 -1
- package/build/three.module.js +1 -1
- package/build/three.module.min.js +1 -1
- package/build/three.webgpu.js +8 -8
- package/build/three.webgpu.min.js +1 -1
- package/build/three.webgpu.nodes.js +8 -8
- package/build/three.webgpu.nodes.min.js +1 -1
- package/package.json +1 -1
- package/src/Three.Core.js +17 -0
- package/src/core/NodePath.js +208 -0
- package/src/core/Object3D.js +191 -0
- package/src/core/nodeId.js +168 -0
- package/src/loaders/ObjectLoader.js +4 -0
- package/src/math/XorShift32.js +119 -0
- package/src/renderers/common/Renderer.js +7 -7
package/build/three.cjs
CHANGED
|
@@ -11723,6 +11723,488 @@ class Layers {
|
|
|
11723
11723
|
|
|
11724
11724
|
}
|
|
11725
11725
|
|
|
11726
|
+
// WITH_GENESYS
|
|
11727
|
+
/**
|
|
11728
|
+
* Shared deterministic PRNG helpers (FNV-1a seed hash + xorshift32).
|
|
11729
|
+
* Used by sibling-local nodeId allocation and other deterministic streams.
|
|
11730
|
+
*/
|
|
11731
|
+
|
|
11732
|
+
/**
|
|
11733
|
+
* Lightweight FNV-1a hash for converting strings into a deterministic 32-bit seed.
|
|
11734
|
+
* @param {string} input
|
|
11735
|
+
* @return {number}
|
|
11736
|
+
*/
|
|
11737
|
+
function hashStringToUint32( input ) {
|
|
11738
|
+
|
|
11739
|
+
let hash = 0x811c9dc5;
|
|
11740
|
+
|
|
11741
|
+
for ( let i = 0; i < input.length; i ++ ) {
|
|
11742
|
+
|
|
11743
|
+
hash ^= input.charCodeAt( i );
|
|
11744
|
+
hash = Math.imul( hash, 0x01000193 );
|
|
11745
|
+
|
|
11746
|
+
}
|
|
11747
|
+
|
|
11748
|
+
return ( hash >>> 0 ) || 0x9e3779b9;
|
|
11749
|
+
|
|
11750
|
+
}
|
|
11751
|
+
|
|
11752
|
+
/**
|
|
11753
|
+
* Xorshift32 step; deterministic and fast for ID generation. Never returns 0.
|
|
11754
|
+
* @param {number} state
|
|
11755
|
+
* @return {number}
|
|
11756
|
+
*/
|
|
11757
|
+
function xorshift32( state ) {
|
|
11758
|
+
|
|
11759
|
+
let next = state | 0;
|
|
11760
|
+
next ^= next << 13;
|
|
11761
|
+
next ^= next >>> 17;
|
|
11762
|
+
next ^= next << 5;
|
|
11763
|
+
return ( next >>> 0 ) || 0x9e3779b9;
|
|
11764
|
+
|
|
11765
|
+
}
|
|
11766
|
+
|
|
11767
|
+
/**
|
|
11768
|
+
* Random non-zero uint32 seed for non-deterministic streams.
|
|
11769
|
+
* @return {number}
|
|
11770
|
+
*/
|
|
11771
|
+
function randomSeedUint32() {
|
|
11772
|
+
|
|
11773
|
+
return ( ( Math.random() * 0x100000000 ) >>> 0 ) || 0x9e3779b9;
|
|
11774
|
+
|
|
11775
|
+
}
|
|
11776
|
+
|
|
11777
|
+
/**
|
|
11778
|
+
* Deterministic xorshift32 stream. Internal state is never 0.
|
|
11779
|
+
*/
|
|
11780
|
+
class XorShift32 {
|
|
11781
|
+
|
|
11782
|
+
/**
|
|
11783
|
+
* @param {number|string} [seed]
|
|
11784
|
+
*/
|
|
11785
|
+
constructor( seed = randomSeedUint32() ) {
|
|
11786
|
+
|
|
11787
|
+
this._state = typeof seed === 'string'
|
|
11788
|
+
? hashStringToUint32( seed )
|
|
11789
|
+
: ( ( seed >>> 0 ) || 0x9e3779b9 );
|
|
11790
|
+
|
|
11791
|
+
}
|
|
11792
|
+
|
|
11793
|
+
/**
|
|
11794
|
+
* Advance and return the next non-zero uint32.
|
|
11795
|
+
* @return {number}
|
|
11796
|
+
*/
|
|
11797
|
+
nextUint32() {
|
|
11798
|
+
|
|
11799
|
+
this._state = xorshift32( this._state );
|
|
11800
|
+
return this._state;
|
|
11801
|
+
|
|
11802
|
+
}
|
|
11803
|
+
|
|
11804
|
+
/**
|
|
11805
|
+
* Advance and return the low 16 bits (0 is allowed).
|
|
11806
|
+
* @return {number}
|
|
11807
|
+
*/
|
|
11808
|
+
nextUint16() {
|
|
11809
|
+
|
|
11810
|
+
return this.nextUint32() & 0xffff;
|
|
11811
|
+
|
|
11812
|
+
}
|
|
11813
|
+
|
|
11814
|
+
/**
|
|
11815
|
+
* @return {number}
|
|
11816
|
+
*/
|
|
11817
|
+
getState() {
|
|
11818
|
+
|
|
11819
|
+
return this._state >>> 0;
|
|
11820
|
+
|
|
11821
|
+
}
|
|
11822
|
+
|
|
11823
|
+
/**
|
|
11824
|
+
* @param {number} state
|
|
11825
|
+
*/
|
|
11826
|
+
setState( state ) {
|
|
11827
|
+
|
|
11828
|
+
this._state = ( state >>> 0 ) || 0x9e3779b9;
|
|
11829
|
+
|
|
11830
|
+
}
|
|
11831
|
+
|
|
11832
|
+
/**
|
|
11833
|
+
* @return {XorShift32}
|
|
11834
|
+
*/
|
|
11835
|
+
clone() {
|
|
11836
|
+
|
|
11837
|
+
return new XorShift32( this._state );
|
|
11838
|
+
|
|
11839
|
+
}
|
|
11840
|
+
|
|
11841
|
+
}
|
|
11842
|
+
// !WITH_GENESYS
|
|
11843
|
+
|
|
11844
|
+
// WITH_GENESYS
|
|
11845
|
+
/**
|
|
11846
|
+
* Sibling-local 16-bit node identities.
|
|
11847
|
+
*
|
|
11848
|
+
* `null` / `undefined` mean unset. `0` is a valid NodeId.
|
|
11849
|
+
*/
|
|
11850
|
+
|
|
11851
|
+
|
|
11852
|
+
/**
|
|
11853
|
+
* True when `id` is a finite integer in the uint16 range (including 0).
|
|
11854
|
+
* @param {unknown} id
|
|
11855
|
+
* @return {boolean}
|
|
11856
|
+
*/
|
|
11857
|
+
function isValidNodeId( id ) {
|
|
11858
|
+
|
|
11859
|
+
return typeof id === 'number' && Number.isInteger( id ) && id >= 0 && id <= 0xffff;
|
|
11860
|
+
|
|
11861
|
+
}
|
|
11862
|
+
|
|
11863
|
+
/**
|
|
11864
|
+
* Canonical display form: 4 lowercase hex characters.
|
|
11865
|
+
* @param {number} id
|
|
11866
|
+
* @return {string}
|
|
11867
|
+
*/
|
|
11868
|
+
function nodeIdToString( id ) {
|
|
11869
|
+
|
|
11870
|
+
return ( id & 0xffff ).toString( 16 ).padStart( 4, '0' );
|
|
11871
|
+
|
|
11872
|
+
}
|
|
11873
|
+
|
|
11874
|
+
/**
|
|
11875
|
+
* Parses a hex node-id segment (1–4 hex digits).
|
|
11876
|
+
* @param {string} value
|
|
11877
|
+
* @return {?number}
|
|
11878
|
+
*/
|
|
11879
|
+
function nodeIdFromString( value ) {
|
|
11880
|
+
|
|
11881
|
+
const trimmed = value.trim();
|
|
11882
|
+
if ( ! /^[0-9a-fA-F]{1,4}$/.test( trimmed ) ) {
|
|
11883
|
+
|
|
11884
|
+
return null;
|
|
11885
|
+
|
|
11886
|
+
}
|
|
11887
|
+
|
|
11888
|
+
return Number.parseInt( trimmed, 16 ) & 0xffff;
|
|
11889
|
+
|
|
11890
|
+
}
|
|
11891
|
+
|
|
11892
|
+
const defaultNodeIdRng = new XorShift32();
|
|
11893
|
+
|
|
11894
|
+
/**
|
|
11895
|
+
* Seeds the process-wide NodeId RNG for deterministic construction.
|
|
11896
|
+
* Pass `undefined` / omit to restore a non-deterministic stream.
|
|
11897
|
+
* @param {string} [seed]
|
|
11898
|
+
*/
|
|
11899
|
+
function configureNodeIdSeed( seed ) {
|
|
11900
|
+
|
|
11901
|
+
if ( seed == null ) {
|
|
11902
|
+
|
|
11903
|
+
defaultNodeIdRng.setState( randomSeedUint32() );
|
|
11904
|
+
return;
|
|
11905
|
+
|
|
11906
|
+
}
|
|
11907
|
+
|
|
11908
|
+
defaultNodeIdRng.setState( hashStringToUint32( seed ) );
|
|
11909
|
+
|
|
11910
|
+
}
|
|
11911
|
+
|
|
11912
|
+
/**
|
|
11913
|
+
* Generates a random NodeId from the process-wide default RNG.
|
|
11914
|
+
* @param {XorShift32} [rng]
|
|
11915
|
+
* @return {number}
|
|
11916
|
+
*/
|
|
11917
|
+
function generateNodeId( rng = defaultNodeIdRng ) {
|
|
11918
|
+
|
|
11919
|
+
return rng.nextUint16();
|
|
11920
|
+
|
|
11921
|
+
}
|
|
11922
|
+
|
|
11923
|
+
/**
|
|
11924
|
+
* Allocates a NodeId not present in `existing`.
|
|
11925
|
+
* @param {Iterable<number>|ReadonlySet<number>} existing
|
|
11926
|
+
* @param {XorShift32} [rng]
|
|
11927
|
+
* @return {number}
|
|
11928
|
+
*/
|
|
11929
|
+
function allocateNodeId( existing, rng = defaultNodeIdRng ) {
|
|
11930
|
+
|
|
11931
|
+
const taken = existing instanceof Set ? existing : new Set( existing );
|
|
11932
|
+
if ( taken.size >= 0x10000 ) {
|
|
11933
|
+
|
|
11934
|
+
throw new Error( '[nodeId] Cannot allocate NodeId: all 65536 sibling ids are in use' );
|
|
11935
|
+
|
|
11936
|
+
}
|
|
11937
|
+
|
|
11938
|
+
let id = rng.nextUint16();
|
|
11939
|
+
while ( taken.has( id ) ) {
|
|
11940
|
+
|
|
11941
|
+
id = rng.nextUint16();
|
|
11942
|
+
|
|
11943
|
+
}
|
|
11944
|
+
|
|
11945
|
+
return id;
|
|
11946
|
+
|
|
11947
|
+
}
|
|
11948
|
+
|
|
11949
|
+
/**
|
|
11950
|
+
* Deterministic NodeId from a stable key (first-try candidate for remints).
|
|
11951
|
+
* @param {string} key
|
|
11952
|
+
* @return {number}
|
|
11953
|
+
*/
|
|
11954
|
+
function nodeIdFromKey( key ) {
|
|
11955
|
+
|
|
11956
|
+
return new XorShift32( key ).nextUint16();
|
|
11957
|
+
|
|
11958
|
+
}
|
|
11959
|
+
|
|
11960
|
+
/**
|
|
11961
|
+
* Collects nodeId values from a sibling set.
|
|
11962
|
+
* @param {Iterable<{nodeId?: ?number}>} nodes
|
|
11963
|
+
* @param {Object} [except]
|
|
11964
|
+
* @return {Set<number>}
|
|
11965
|
+
*/
|
|
11966
|
+
function collectSiblingNodeIds( nodes, except ) {
|
|
11967
|
+
|
|
11968
|
+
const taken = new Set();
|
|
11969
|
+
for ( const node of nodes ) {
|
|
11970
|
+
|
|
11971
|
+
if ( node !== except && isValidNodeId( node.nodeId ) ) {
|
|
11972
|
+
|
|
11973
|
+
taken.add( node.nodeId );
|
|
11974
|
+
|
|
11975
|
+
}
|
|
11976
|
+
|
|
11977
|
+
}
|
|
11978
|
+
|
|
11979
|
+
return taken;
|
|
11980
|
+
|
|
11981
|
+
}
|
|
11982
|
+
|
|
11983
|
+
/**
|
|
11984
|
+
* Ensures `object.nodeId` is unique among `parent.children`.
|
|
11985
|
+
* @param {import('./Object3D.js').Object3D} object
|
|
11986
|
+
* @param {import('./Object3D.js').Object3D} parent
|
|
11987
|
+
*/
|
|
11988
|
+
function ensureUniqueNodeIdAmongParentChildren( object, parent ) {
|
|
11989
|
+
|
|
11990
|
+
const taken = collectSiblingNodeIds( parent.children, object );
|
|
11991
|
+
if ( ! isValidNodeId( object.nodeId ) || taken.has( object.nodeId ) ) {
|
|
11992
|
+
|
|
11993
|
+
object.nodeId = allocateNodeId( taken );
|
|
11994
|
+
|
|
11995
|
+
}
|
|
11996
|
+
|
|
11997
|
+
}
|
|
11998
|
+
// !WITH_GENESYS
|
|
11999
|
+
|
|
12000
|
+
// WITH_GENESYS
|
|
12001
|
+
/**
|
|
12002
|
+
* Path of sibling-local nodeIds identifying a node in the scene tree.
|
|
12003
|
+
* String form: `"a1b2/c3d4"` (4-hex segments separated by `/`).
|
|
12004
|
+
*/
|
|
12005
|
+
|
|
12006
|
+
|
|
12007
|
+
class NodePath {
|
|
12008
|
+
|
|
12009
|
+
/**
|
|
12010
|
+
* @param {readonly number[]} [ids]
|
|
12011
|
+
*/
|
|
12012
|
+
constructor( ids = [] ) {
|
|
12013
|
+
|
|
12014
|
+
const normalized = [];
|
|
12015
|
+
for ( const id of ids ) {
|
|
12016
|
+
|
|
12017
|
+
if ( ! isValidNodeId( id ) ) {
|
|
12018
|
+
|
|
12019
|
+
throw new Error( `[NodePath] Invalid NodeId segment: ${ String( id ) }` );
|
|
12020
|
+
|
|
12021
|
+
}
|
|
12022
|
+
|
|
12023
|
+
normalized.push( id & 0xffff );
|
|
12024
|
+
|
|
12025
|
+
}
|
|
12026
|
+
|
|
12027
|
+
this.ids = normalized;
|
|
12028
|
+
|
|
12029
|
+
}
|
|
12030
|
+
|
|
12031
|
+
/**
|
|
12032
|
+
* @param {...number} ids
|
|
12033
|
+
* @return {NodePath}
|
|
12034
|
+
*/
|
|
12035
|
+
static fromIds( ...ids ) {
|
|
12036
|
+
|
|
12037
|
+
return new NodePath( ids );
|
|
12038
|
+
|
|
12039
|
+
}
|
|
12040
|
+
|
|
12041
|
+
/**
|
|
12042
|
+
* Parses `"a1b2/c3d4"`. Empty / whitespace-only string yields {@link NodePath.empty}.
|
|
12043
|
+
* @param {string} path
|
|
12044
|
+
* @return {NodePath}
|
|
12045
|
+
*/
|
|
12046
|
+
static fromString( path ) {
|
|
12047
|
+
|
|
12048
|
+
const trimmed = path.trim();
|
|
12049
|
+
if ( trimmed.length === 0 ) {
|
|
12050
|
+
|
|
12051
|
+
return NodePath.empty;
|
|
12052
|
+
|
|
12053
|
+
}
|
|
12054
|
+
|
|
12055
|
+
const parts = trimmed.split( '/' );
|
|
12056
|
+
const ids = [];
|
|
12057
|
+
for ( const part of parts ) {
|
|
12058
|
+
|
|
12059
|
+
if ( part.length === 0 ) {
|
|
12060
|
+
|
|
12061
|
+
throw new Error( `[NodePath] Empty segment in path "${ path }"` );
|
|
12062
|
+
|
|
12063
|
+
}
|
|
12064
|
+
|
|
12065
|
+
const id = nodeIdFromString( part );
|
|
12066
|
+
if ( id === null ) {
|
|
12067
|
+
|
|
12068
|
+
throw new Error( `[NodePath] Invalid segment "${ part }" in path "${ path }"` );
|
|
12069
|
+
|
|
12070
|
+
}
|
|
12071
|
+
|
|
12072
|
+
ids.push( id );
|
|
12073
|
+
|
|
12074
|
+
}
|
|
12075
|
+
|
|
12076
|
+
return new NodePath( ids );
|
|
12077
|
+
|
|
12078
|
+
}
|
|
12079
|
+
|
|
12080
|
+
/**
|
|
12081
|
+
* @param {NodePath|string} path
|
|
12082
|
+
* @return {NodePath}
|
|
12083
|
+
*/
|
|
12084
|
+
static coerce( path ) {
|
|
12085
|
+
|
|
12086
|
+
return typeof path === 'string' ? NodePath.fromString( path ) : path;
|
|
12087
|
+
|
|
12088
|
+
}
|
|
12089
|
+
|
|
12090
|
+
/** @return {number} */
|
|
12091
|
+
get length() {
|
|
12092
|
+
|
|
12093
|
+
return this.ids.length;
|
|
12094
|
+
|
|
12095
|
+
}
|
|
12096
|
+
|
|
12097
|
+
/** @return {boolean} */
|
|
12098
|
+
get isEmpty() {
|
|
12099
|
+
|
|
12100
|
+
return this.ids.length === 0;
|
|
12101
|
+
|
|
12102
|
+
}
|
|
12103
|
+
|
|
12104
|
+
/** @return {string} */
|
|
12105
|
+
toString() {
|
|
12106
|
+
|
|
12107
|
+
return this.ids.map( nodeIdToString ).join( '/' );
|
|
12108
|
+
|
|
12109
|
+
}
|
|
12110
|
+
|
|
12111
|
+
/**
|
|
12112
|
+
* @param {NodePath} other
|
|
12113
|
+
* @return {boolean}
|
|
12114
|
+
*/
|
|
12115
|
+
equals( other ) {
|
|
12116
|
+
|
|
12117
|
+
if ( this.ids.length !== other.ids.length ) {
|
|
12118
|
+
|
|
12119
|
+
return false;
|
|
12120
|
+
|
|
12121
|
+
}
|
|
12122
|
+
|
|
12123
|
+
for ( let i = 0; i < this.ids.length; i ++ ) {
|
|
12124
|
+
|
|
12125
|
+
if ( this.ids[ i ] !== other.ids[ i ] ) {
|
|
12126
|
+
|
|
12127
|
+
return false;
|
|
12128
|
+
|
|
12129
|
+
}
|
|
12130
|
+
|
|
12131
|
+
}
|
|
12132
|
+
|
|
12133
|
+
return true;
|
|
12134
|
+
|
|
12135
|
+
}
|
|
12136
|
+
|
|
12137
|
+
/**
|
|
12138
|
+
* @param {NodePath} prefix
|
|
12139
|
+
* @return {boolean}
|
|
12140
|
+
*/
|
|
12141
|
+
startsWith( prefix ) {
|
|
12142
|
+
|
|
12143
|
+
if ( prefix.ids.length > this.ids.length ) {
|
|
12144
|
+
|
|
12145
|
+
return false;
|
|
12146
|
+
|
|
12147
|
+
}
|
|
12148
|
+
|
|
12149
|
+
for ( let i = 0; i < prefix.ids.length; i ++ ) {
|
|
12150
|
+
|
|
12151
|
+
if ( this.ids[ i ] !== prefix.ids[ i ] ) {
|
|
12152
|
+
|
|
12153
|
+
return false;
|
|
12154
|
+
|
|
12155
|
+
}
|
|
12156
|
+
|
|
12157
|
+
}
|
|
12158
|
+
|
|
12159
|
+
return true;
|
|
12160
|
+
|
|
12161
|
+
}
|
|
12162
|
+
|
|
12163
|
+
/**
|
|
12164
|
+
* @param {number} start
|
|
12165
|
+
* @param {number} [end]
|
|
12166
|
+
* @return {NodePath}
|
|
12167
|
+
*/
|
|
12168
|
+
slice( start, end ) {
|
|
12169
|
+
|
|
12170
|
+
return new NodePath( this.ids.slice( start, end ) );
|
|
12171
|
+
|
|
12172
|
+
}
|
|
12173
|
+
|
|
12174
|
+
/**
|
|
12175
|
+
* @param {NodePath} relative
|
|
12176
|
+
* @return {NodePath}
|
|
12177
|
+
*/
|
|
12178
|
+
concat( relative ) {
|
|
12179
|
+
|
|
12180
|
+
return new NodePath( [ ...this.ids, ...relative.ids ] );
|
|
12181
|
+
|
|
12182
|
+
}
|
|
12183
|
+
|
|
12184
|
+
/**
|
|
12185
|
+
* If this path starts with `ancestor`, returns the remainder; otherwise `null`.
|
|
12186
|
+
* @param {NodePath} ancestor
|
|
12187
|
+
* @return {?NodePath}
|
|
12188
|
+
*/
|
|
12189
|
+
relativeFrom( ancestor ) {
|
|
12190
|
+
|
|
12191
|
+
if ( ! this.startsWith( ancestor ) ) {
|
|
12192
|
+
|
|
12193
|
+
return null;
|
|
12194
|
+
|
|
12195
|
+
}
|
|
12196
|
+
|
|
12197
|
+
return this.slice( ancestor.length );
|
|
12198
|
+
|
|
12199
|
+
}
|
|
12200
|
+
|
|
12201
|
+
}
|
|
12202
|
+
|
|
12203
|
+
NodePath.empty = new NodePath( [] );
|
|
12204
|
+
// !WITH_GENESYS
|
|
12205
|
+
|
|
12206
|
+
// !WITH_GENESYS
|
|
12207
|
+
|
|
11726
12208
|
let _object3DId = 0;
|
|
11727
12209
|
|
|
11728
12210
|
const _v1$6 = /*@__PURE__*/ new Vector3();
|
|
@@ -11811,6 +12293,16 @@ class Object3D extends EventDispatcher {
|
|
|
11811
12293
|
*/
|
|
11812
12294
|
this.uuid = generateUUID();
|
|
11813
12295
|
|
|
12296
|
+
// WITH_GENESYS
|
|
12297
|
+
/**
|
|
12298
|
+
* Sibling-local 16-bit identity for scene-graph addressing ({@link NodePath}).
|
|
12299
|
+
* `0` is valid. Reminted on parent attach when colliding with a sibling.
|
|
12300
|
+
*
|
|
12301
|
+
* @type {number}
|
|
12302
|
+
*/
|
|
12303
|
+
this.nodeId = generateNodeId();
|
|
12304
|
+
// !WITH_GENESYS
|
|
12305
|
+
|
|
11814
12306
|
/**
|
|
11815
12307
|
* The name of the 3D object.
|
|
11816
12308
|
*
|
|
@@ -12493,6 +12985,9 @@ class Object3D extends EventDispatcher {
|
|
|
12493
12985
|
if ( object && object.isObject3D ) {
|
|
12494
12986
|
|
|
12495
12987
|
object.removeFromParent();
|
|
12988
|
+
// WITH_GENESYS
|
|
12989
|
+
ensureUniqueNodeIdAmongParentChildren( object, this );
|
|
12990
|
+
// !WITH_GENESYS
|
|
12496
12991
|
object.parent = this;
|
|
12497
12992
|
this.children.push( object );
|
|
12498
12993
|
|
|
@@ -12618,6 +13113,9 @@ class Object3D extends EventDispatcher {
|
|
|
12618
13113
|
object.applyMatrix4( _m1$3 );
|
|
12619
13114
|
|
|
12620
13115
|
object.removeFromParent();
|
|
13116
|
+
// WITH_GENESYS
|
|
13117
|
+
ensureUniqueNodeIdAmongParentChildren( object, this );
|
|
13118
|
+
// !WITH_GENESYS
|
|
12621
13119
|
object.parent = this;
|
|
12622
13120
|
this.children.push( object );
|
|
12623
13121
|
|
|
@@ -12633,6 +13131,166 @@ class Object3D extends EventDispatcher {
|
|
|
12633
13131
|
|
|
12634
13132
|
}
|
|
12635
13133
|
|
|
13134
|
+
// WITH_GENESYS
|
|
13135
|
+
/**
|
|
13136
|
+
* Assigns a {@link nodeId} when unset or outside the uint16 range.
|
|
13137
|
+
* @return {number}
|
|
13138
|
+
*/
|
|
13139
|
+
ensureNodeId() {
|
|
13140
|
+
|
|
13141
|
+
if ( ! isValidNodeId( this.nodeId ) ) {
|
|
13142
|
+
|
|
13143
|
+
this.nodeId = generateNodeId();
|
|
13144
|
+
|
|
13145
|
+
}
|
|
13146
|
+
|
|
13147
|
+
return this.nodeId;
|
|
13148
|
+
|
|
13149
|
+
}
|
|
13150
|
+
|
|
13151
|
+
/**
|
|
13152
|
+
* Replaces {@link nodeId} with a newly generated value (e.g. prefab instance roots).
|
|
13153
|
+
* @param {Iterable<number>} [existingSiblingIds]
|
|
13154
|
+
* @return {number}
|
|
13155
|
+
*/
|
|
13156
|
+
remintNodeId( existingSiblingIds ) {
|
|
13157
|
+
|
|
13158
|
+
this.nodeId = existingSiblingIds !== undefined
|
|
13159
|
+
? allocateNodeId( existingSiblingIds )
|
|
13160
|
+
: generateNodeId();
|
|
13161
|
+
return this.nodeId;
|
|
13162
|
+
|
|
13163
|
+
}
|
|
13164
|
+
|
|
13165
|
+
/**
|
|
13166
|
+
* Direct child with the given {@link nodeId}, or `null`.
|
|
13167
|
+
* @param {number} id
|
|
13168
|
+
* @return {?Object3D}
|
|
13169
|
+
*/
|
|
13170
|
+
findChildByNodeId( id ) {
|
|
13171
|
+
|
|
13172
|
+
for ( let i = 0; i < this.children.length; i ++ ) {
|
|
13173
|
+
|
|
13174
|
+
const child = this.children[ i ];
|
|
13175
|
+
if ( child.nodeId === id ) {
|
|
13176
|
+
|
|
13177
|
+
return child;
|
|
13178
|
+
|
|
13179
|
+
}
|
|
13180
|
+
|
|
13181
|
+
}
|
|
13182
|
+
|
|
13183
|
+
return null;
|
|
13184
|
+
|
|
13185
|
+
}
|
|
13186
|
+
|
|
13187
|
+
/**
|
|
13188
|
+
* Resolves a path relative to this node. An empty path returns `this`.
|
|
13189
|
+
* @param {NodePath|string} path
|
|
13190
|
+
* @return {?Object3D}
|
|
13191
|
+
*/
|
|
13192
|
+
resolvePath( path ) {
|
|
13193
|
+
|
|
13194
|
+
const nodePath = NodePath.coerce( path );
|
|
13195
|
+
if ( nodePath.isEmpty ) {
|
|
13196
|
+
|
|
13197
|
+
return this;
|
|
13198
|
+
|
|
13199
|
+
}
|
|
13200
|
+
|
|
13201
|
+
let current = this;
|
|
13202
|
+
for ( let i = 0; i < nodePath.ids.length; i ++ ) {
|
|
13203
|
+
|
|
13204
|
+
const next = current.findChildByNodeId( nodePath.ids[ i ] );
|
|
13205
|
+
if ( ! next ) {
|
|
13206
|
+
|
|
13207
|
+
return null;
|
|
13208
|
+
|
|
13209
|
+
}
|
|
13210
|
+
|
|
13211
|
+
current = next;
|
|
13212
|
+
|
|
13213
|
+
}
|
|
13214
|
+
|
|
13215
|
+
return current;
|
|
13216
|
+
|
|
13217
|
+
}
|
|
13218
|
+
|
|
13219
|
+
/**
|
|
13220
|
+
* Builds a {@link NodePath} for this node.
|
|
13221
|
+
* - Without `root`: absolute path from the topmost non-Scene ancestor down to this node.
|
|
13222
|
+
* - With `root`: path relative to `root` (empty when `this === root`); `null` when not under `root`.
|
|
13223
|
+
* @param {Object3D} [root]
|
|
13224
|
+
* @return {?NodePath}
|
|
13225
|
+
*/
|
|
13226
|
+
getNodePath( root ) {
|
|
13227
|
+
|
|
13228
|
+
if ( root !== undefined ) {
|
|
13229
|
+
|
|
13230
|
+
if ( this === root ) {
|
|
13231
|
+
|
|
13232
|
+
return NodePath.empty;
|
|
13233
|
+
|
|
13234
|
+
}
|
|
13235
|
+
|
|
13236
|
+
const absolute = this.getNodePath();
|
|
13237
|
+
const rootAbsolute = root.getNodePath();
|
|
13238
|
+
if ( ! absolute || ! rootAbsolute ) {
|
|
13239
|
+
|
|
13240
|
+
return null;
|
|
13241
|
+
|
|
13242
|
+
}
|
|
13243
|
+
|
|
13244
|
+
return absolute.relativeFrom( rootAbsolute );
|
|
13245
|
+
|
|
13246
|
+
}
|
|
13247
|
+
|
|
13248
|
+
const ids = [];
|
|
13249
|
+
let current = this;
|
|
13250
|
+
while ( current ) {
|
|
13251
|
+
|
|
13252
|
+
ids.push( current.ensureNodeId() );
|
|
13253
|
+
const parent = current.parent;
|
|
13254
|
+
// Scene / World containers are not part of authored NodePaths.
|
|
13255
|
+
if ( parent === null || parent.isScene === true ) {
|
|
13256
|
+
|
|
13257
|
+
break;
|
|
13258
|
+
|
|
13259
|
+
}
|
|
13260
|
+
|
|
13261
|
+
current = parent;
|
|
13262
|
+
|
|
13263
|
+
}
|
|
13264
|
+
|
|
13265
|
+
ids.reverse();
|
|
13266
|
+
return new NodePath( ids );
|
|
13267
|
+
|
|
13268
|
+
}
|
|
13269
|
+
|
|
13270
|
+
/**
|
|
13271
|
+
* Ensures every Object3D in this subtree has a valid {@link nodeId}, unique among its siblings.
|
|
13272
|
+
*/
|
|
13273
|
+
ensureNodeIdsInSubtree() {
|
|
13274
|
+
|
|
13275
|
+
this.ensureNodeId();
|
|
13276
|
+
const taken = new Set();
|
|
13277
|
+
for ( let i = 0; i < this.children.length; i ++ ) {
|
|
13278
|
+
|
|
13279
|
+
const child = this.children[ i ];
|
|
13280
|
+
if ( ! isValidNodeId( child.nodeId ) || taken.has( child.nodeId ) ) {
|
|
13281
|
+
|
|
13282
|
+
child.nodeId = allocateNodeId( taken );
|
|
13283
|
+
|
|
13284
|
+
}
|
|
13285
|
+
|
|
13286
|
+
taken.add( child.nodeId );
|
|
13287
|
+
child.ensureNodeIdsInSubtree();
|
|
13288
|
+
|
|
13289
|
+
}
|
|
13290
|
+
|
|
13291
|
+
}
|
|
13292
|
+
// !WITH_GENESYS
|
|
13293
|
+
|
|
12636
13294
|
/**
|
|
12637
13295
|
* Searches through the 3D object and its children, starting with the 3D object
|
|
12638
13296
|
* itself, and returns the first with a matching ID.
|
|
@@ -13035,6 +13693,10 @@ class Object3D extends EventDispatcher {
|
|
|
13035
13693
|
object.uuid = this.uuid;
|
|
13036
13694
|
object.type = this.type;
|
|
13037
13695
|
|
|
13696
|
+
// WITH_GENESYS
|
|
13697
|
+
object.nodeId = this.nodeId;
|
|
13698
|
+
// !WITH_GENESYS
|
|
13699
|
+
|
|
13038
13700
|
if ( this.name !== '' ) object.name = this.name;
|
|
13039
13701
|
if ( this.castShadow === true ) object.castShadow = true;
|
|
13040
13702
|
if ( this.receiveShadow === true ) object.receiveShadow = true;
|
|
@@ -13345,6 +14007,8 @@ class Object3D extends EventDispatcher {
|
|
|
13345
14007
|
this.visible = source.visible;
|
|
13346
14008
|
// WITH_GENESYS
|
|
13347
14009
|
this.selfHidden = source.selfHidden;
|
|
14010
|
+
// Keep nodeId; reminted on attach if it collides with a sibling.
|
|
14011
|
+
this.nodeId = source.nodeId;
|
|
13348
14012
|
// !WITH_GENESYS
|
|
13349
14013
|
|
|
13350
14014
|
this.castShadow = source.castShadow;
|
|
@@ -49581,6 +50245,10 @@ class ObjectLoader extends Loader {
|
|
|
49581
50245
|
|
|
49582
50246
|
object.uuid = data.uuid;
|
|
49583
50247
|
|
|
50248
|
+
// WITH_GENESYS
|
|
50249
|
+
if ( data.nodeId !== undefined ) object.nodeId = data.nodeId;
|
|
50250
|
+
// !WITH_GENESYS
|
|
50251
|
+
|
|
49584
50252
|
if ( data.name !== undefined ) object.name = data.name;
|
|
49585
50253
|
|
|
49586
50254
|
if ( data.matrix !== undefined ) {
|
|
@@ -81720,6 +82388,7 @@ exports.NoBlending = NoBlending;
|
|
|
81720
82388
|
exports.NoColorSpace = NoColorSpace;
|
|
81721
82389
|
exports.NoNormalPacking = NoNormalPacking;
|
|
81722
82390
|
exports.NoToneMapping = NoToneMapping;
|
|
82391
|
+
exports.NodePath = NodePath;
|
|
81723
82392
|
exports.NormalAnimationBlendMode = NormalAnimationBlendMode;
|
|
81724
82393
|
exports.NormalBlending = NormalBlending;
|
|
81725
82394
|
exports.NormalGAPacking = NormalGAPacking;
|
|
@@ -81910,16 +82579,29 @@ exports.WebGPUCoordinateSystem = WebGPUCoordinateSystem;
|
|
|
81910
82579
|
exports.WebXRController = WebXRController;
|
|
81911
82580
|
exports.WireframeGeometry = WireframeGeometry;
|
|
81912
82581
|
exports.WrapAroundEnding = WrapAroundEnding;
|
|
82582
|
+
exports.XorShift32 = XorShift32;
|
|
81913
82583
|
exports.ZeroCurvatureEnding = ZeroCurvatureEnding;
|
|
81914
82584
|
exports.ZeroFactor = ZeroFactor;
|
|
81915
82585
|
exports.ZeroSlopeEnding = ZeroSlopeEnding;
|
|
81916
82586
|
exports.ZeroStencilOp = ZeroStencilOp;
|
|
82587
|
+
exports.allocateNodeId = allocateNodeId;
|
|
82588
|
+
exports.collectSiblingNodeIds = collectSiblingNodeIds;
|
|
82589
|
+
exports.configureNodeIdSeed = configureNodeIdSeed;
|
|
81917
82590
|
exports.createCanvasElement = createCanvasElement;
|
|
82591
|
+
exports.ensureUniqueNodeIdAmongParentChildren = ensureUniqueNodeIdAmongParentChildren;
|
|
81918
82592
|
exports.error = error;
|
|
82593
|
+
exports.generateNodeId = generateNodeId;
|
|
81919
82594
|
exports.getConsoleFunction = getConsoleFunction;
|
|
82595
|
+
exports.hashStringToUint32 = hashStringToUint32;
|
|
82596
|
+
exports.isValidNodeId = isValidNodeId;
|
|
81920
82597
|
exports.log = log;
|
|
82598
|
+
exports.nodeIdFromKey = nodeIdFromKey;
|
|
82599
|
+
exports.nodeIdFromString = nodeIdFromString;
|
|
82600
|
+
exports.nodeIdToString = nodeIdToString;
|
|
81921
82601
|
exports.profile = profile;
|
|
81922
82602
|
exports.profileClass = profileClass;
|
|
82603
|
+
exports.randomSeedUint32 = randomSeedUint32;
|
|
81923
82604
|
exports.setConsoleFunction = setConsoleFunction;
|
|
81924
82605
|
exports.warn = warn;
|
|
81925
82606
|
exports.warnOnce = warnOnce;
|
|
82607
|
+
exports.xorshift32 = xorshift32;
|