Object3D.js 19 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. import { Quaternion } from '../math/Quaternion.js';
  2. import { Vector3 } from '../math/Vector3.js';
  3. import { Matrix4 } from '../math/Matrix4.js';
  4. import { EventDispatcher } from './EventDispatcher.js';
  5. import { Euler } from '../math/Euler.js';
  6. import { Layers } from './Layers.js';
  7. import { Matrix3 } from '../math/Matrix3.js';
  8. import * as MathUtils from '../math/MathUtils.js';
  9. let _object3DId = 0;
  10. const _v1 = /*@__PURE__*/ new Vector3();
  11. const _q1 = /*@__PURE__*/ new Quaternion();
  12. const _m1 = /*@__PURE__*/ new Matrix4();
  13. const _target = /*@__PURE__*/ new Vector3();
  14. const _position = /*@__PURE__*/ new Vector3();
  15. const _scale = /*@__PURE__*/ new Vector3();
  16. const _quaternion = /*@__PURE__*/ new Quaternion();
  17. const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 );
  18. const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 );
  19. const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 );
  20. const _addedEvent = { type: 'added' };
  21. const _removedEvent = { type: 'removed' };
  22. const _childaddedEvent = { type: 'childadded', child: null };
  23. const _childremovedEvent = { type: 'childremoved', child: null };
  24. class Object3D extends EventDispatcher {
  25. constructor() {
  26. super();
  27. this.isObject3D = true;
  28. Object.defineProperty( this, 'id', { value: _object3DId ++ } );
  29. this.uuid = MathUtils.generateUUID();
  30. this.name = '';
  31. this.type = 'Object3D';
  32. this.parent = null;
  33. this.children = [];
  34. this.up = Object3D.DEFAULT_UP.clone();
  35. const position = new Vector3();
  36. const rotation = new Euler();
  37. const quaternion = new Quaternion();
  38. const scale = new Vector3( 1, 1, 1 );
  39. function onRotationChange() {
  40. quaternion.setFromEuler( rotation, false );
  41. }
  42. function onQuaternionChange() {
  43. rotation.setFromQuaternion( quaternion, undefined, false );
  44. }
  45. rotation._onChange( onRotationChange );
  46. quaternion._onChange( onQuaternionChange );
  47. Object.defineProperties( this, {
  48. position: {
  49. configurable: true,
  50. enumerable: true,
  51. value: position
  52. },
  53. rotation: {
  54. configurable: true,
  55. enumerable: true,
  56. value: rotation
  57. },
  58. quaternion: {
  59. configurable: true,
  60. enumerable: true,
  61. value: quaternion
  62. },
  63. scale: {
  64. configurable: true,
  65. enumerable: true,
  66. value: scale
  67. },
  68. modelViewMatrix: {
  69. value: new Matrix4()
  70. },
  71. normalMatrix: {
  72. value: new Matrix3()
  73. }
  74. } );
  75. this.matrix = new Matrix4();
  76. this.matrixWorld = new Matrix4();
  77. this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE;
  78. this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer
  79. this.matrixWorldNeedsUpdate = false;
  80. this.layers = new Layers();
  81. this.visible = true;
  82. this.castShadow = false;
  83. this.receiveShadow = false;
  84. this.frustumCulled = true;
  85. this.renderOrder = 0;
  86. this.animations = [];
  87. this.userData = {};
  88. }
  89. onBeforeShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {}
  90. onAfterShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {}
  91. onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {}
  92. onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {}
  93. applyMatrix4( matrix ) {
  94. if ( this.matrixAutoUpdate ) this.updateMatrix();
  95. this.matrix.premultiply( matrix );
  96. this.matrix.decompose( this.position, this.quaternion, this.scale );
  97. }
  98. applyQuaternion( q ) {
  99. this.quaternion.premultiply( q );
  100. return this;
  101. }
  102. setRotationFromAxisAngle( axis, angle ) {
  103. // assumes axis is normalized
  104. this.quaternion.setFromAxisAngle( axis, angle );
  105. }
  106. setRotationFromEuler( euler ) {
  107. this.quaternion.setFromEuler( euler, true );
  108. }
  109. setRotationFromMatrix( m ) {
  110. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  111. this.quaternion.setFromRotationMatrix( m );
  112. }
  113. setRotationFromQuaternion( q ) {
  114. // assumes q is normalized
  115. this.quaternion.copy( q );
  116. }
  117. rotateOnAxis( axis, angle ) {
  118. // rotate object on axis in object space
  119. // axis is assumed to be normalized
  120. _q1.setFromAxisAngle( axis, angle );
  121. this.quaternion.multiply( _q1 );
  122. return this;
  123. }
  124. rotateOnWorldAxis( axis, angle ) {
  125. // rotate object on axis in world space
  126. // axis is assumed to be normalized
  127. // method assumes no rotated parent
  128. _q1.setFromAxisAngle( axis, angle );
  129. this.quaternion.premultiply( _q1 );
  130. return this;
  131. }
  132. rotateX( angle ) {
  133. return this.rotateOnAxis( _xAxis, angle );
  134. }
  135. rotateY( angle ) {
  136. return this.rotateOnAxis( _yAxis, angle );
  137. }
  138. rotateZ( angle ) {
  139. return this.rotateOnAxis( _zAxis, angle );
  140. }
  141. translateOnAxis( axis, distance ) {
  142. // translate object by distance along axis in object space
  143. // axis is assumed to be normalized
  144. _v1.copy( axis ).applyQuaternion( this.quaternion );
  145. this.position.add( _v1.multiplyScalar( distance ) );
  146. return this;
  147. }
  148. translateX( distance ) {
  149. return this.translateOnAxis( _xAxis, distance );
  150. }
  151. translateY( distance ) {
  152. return this.translateOnAxis( _yAxis, distance );
  153. }
  154. translateZ( distance ) {
  155. return this.translateOnAxis( _zAxis, distance );
  156. }
  157. localToWorld( vector ) {
  158. this.updateWorldMatrix( true, false );
  159. return vector.applyMatrix4( this.matrixWorld );
  160. }
  161. worldToLocal( vector ) {
  162. this.updateWorldMatrix( true, false );
  163. return vector.applyMatrix4( _m1.copy( this.matrixWorld ).invert() );
  164. }
  165. lookAt( x, y, z ) {
  166. // This method does not support objects having non-uniformly-scaled parent(s)
  167. if ( x.isVector3 ) {
  168. _target.copy( x );
  169. } else {
  170. _target.set( x, y, z );
  171. }
  172. const parent = this.parent;
  173. this.updateWorldMatrix( true, false );
  174. _position.setFromMatrixPosition( this.matrixWorld );
  175. if ( this.isCamera || this.isLight ) {
  176. _m1.lookAt( _position, _target, this.up );
  177. } else {
  178. _m1.lookAt( _target, _position, this.up );
  179. }
  180. this.quaternion.setFromRotationMatrix( _m1 );
  181. if ( parent ) {
  182. _m1.extractRotation( parent.matrixWorld );
  183. _q1.setFromRotationMatrix( _m1 );
  184. this.quaternion.premultiply( _q1.invert() );
  185. }
  186. }
  187. add( object ) {
  188. if ( arguments.length > 1 ) {
  189. for ( let i = 0; i < arguments.length; i ++ ) {
  190. this.add( arguments[ i ] );
  191. }
  192. return this;
  193. }
  194. if ( object === this ) {
  195. console.error( 'THREE.Object3D.add: object can\'t be added as a child of itself.', object );
  196. return this;
  197. }
  198. if ( object && object.isObject3D ) {
  199. object.removeFromParent();
  200. object.parent = this;
  201. this.children.push( object );
  202. object.dispatchEvent( _addedEvent );
  203. _childaddedEvent.child = object;
  204. this.dispatchEvent( _childaddedEvent );
  205. _childaddedEvent.child = null;
  206. } else {
  207. console.error( 'THREE.Object3D.add: object not an instance of THREE.Object3D.', object );
  208. }
  209. return this;
  210. }
  211. remove( object ) {
  212. if ( arguments.length > 1 ) {
  213. for ( let i = 0; i < arguments.length; i ++ ) {
  214. this.remove( arguments[ i ] );
  215. }
  216. return this;
  217. }
  218. const index = this.children.indexOf( object );
  219. if ( index !== - 1 ) {
  220. object.parent = null;
  221. this.children.splice( index, 1 );
  222. object.dispatchEvent( _removedEvent );
  223. _childremovedEvent.child = object;
  224. this.dispatchEvent( _childremovedEvent );
  225. _childremovedEvent.child = null;
  226. }
  227. return this;
  228. }
  229. removeFromParent() {
  230. const parent = this.parent;
  231. if ( parent !== null ) {
  232. parent.remove( this );
  233. }
  234. return this;
  235. }
  236. clear() {
  237. return this.remove( ... this.children );
  238. }
  239. attach( object ) {
  240. // adds object as a child of this, while maintaining the object's world transform
  241. // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s)
  242. this.updateWorldMatrix( true, false );
  243. _m1.copy( this.matrixWorld ).invert();
  244. if ( object.parent !== null ) {
  245. object.parent.updateWorldMatrix( true, false );
  246. _m1.multiply( object.parent.matrixWorld );
  247. }
  248. object.applyMatrix4( _m1 );
  249. object.removeFromParent();
  250. object.parent = this;
  251. this.children.push( object );
  252. object.updateWorldMatrix( false, true );
  253. object.dispatchEvent( _addedEvent );
  254. _childaddedEvent.child = object;
  255. this.dispatchEvent( _childaddedEvent );
  256. _childaddedEvent.child = null;
  257. return this;
  258. }
  259. getObjectById( id ) {
  260. return this.getObjectByProperty( 'id', id );
  261. }
  262. getObjectByName( name ) {
  263. return this.getObjectByProperty( 'name', name );
  264. }
  265. getObjectByProperty( name, value ) {
  266. if ( this[ name ] === value ) return this;
  267. for ( let i = 0, l = this.children.length; i < l; i ++ ) {
  268. const child = this.children[ i ];
  269. const object = child.getObjectByProperty( name, value );
  270. if ( object !== undefined ) {
  271. return object;
  272. }
  273. }
  274. return undefined;
  275. }
  276. getObjectsByProperty( name, value, result = [] ) {
  277. if ( this[ name ] === value ) result.push( this );
  278. const children = this.children;
  279. for ( let i = 0, l = children.length; i < l; i ++ ) {
  280. children[ i ].getObjectsByProperty( name, value, result );
  281. }
  282. return result;
  283. }
  284. getWorldPosition( target ) {
  285. this.updateWorldMatrix( true, false );
  286. return target.setFromMatrixPosition( this.matrixWorld );
  287. }
  288. getWorldQuaternion( target ) {
  289. this.updateWorldMatrix( true, false );
  290. this.matrixWorld.decompose( _position, target, _scale );
  291. return target;
  292. }
  293. getWorldScale( target ) {
  294. this.updateWorldMatrix( true, false );
  295. this.matrixWorld.decompose( _position, _quaternion, target );
  296. return target;
  297. }
  298. getWorldDirection( target ) {
  299. this.updateWorldMatrix( true, false );
  300. const e = this.matrixWorld.elements;
  301. return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize();
  302. }
  303. raycast( /* raycaster, intersects */ ) {}
  304. traverse( callback ) {
  305. callback( this );
  306. const children = this.children;
  307. for ( let i = 0, l = children.length; i < l; i ++ ) {
  308. children[ i ].traverse( callback );
  309. }
  310. }
  311. traverseVisible( callback ) {
  312. if ( this.visible === false ) return;
  313. callback( this );
  314. const children = this.children;
  315. for ( let i = 0, l = children.length; i < l; i ++ ) {
  316. children[ i ].traverseVisible( callback );
  317. }
  318. }
  319. traverseAncestors( callback ) {
  320. const parent = this.parent;
  321. if ( parent !== null ) {
  322. callback( parent );
  323. parent.traverseAncestors( callback );
  324. }
  325. }
  326. updateMatrix() {
  327. this.matrix.compose( this.position, this.quaternion, this.scale );
  328. this.matrixWorldNeedsUpdate = true;
  329. }
  330. updateMatrixWorld( force ) {
  331. if ( this.matrixAutoUpdate ) this.updateMatrix();
  332. if ( this.matrixWorldNeedsUpdate || force ) {
  333. if ( this.matrixWorldAutoUpdate === true ) {
  334. if ( this.parent === null ) {
  335. this.matrixWorld.copy( this.matrix );
  336. } else {
  337. this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
  338. }
  339. }
  340. this.matrixWorldNeedsUpdate = false;
  341. force = true;
  342. }
  343. // make sure descendants are updated if required
  344. const children = this.children;
  345. for ( let i = 0, l = children.length; i < l; i ++ ) {
  346. const child = children[ i ];
  347. child.updateMatrixWorld( force );
  348. }
  349. }
  350. updateWorldMatrix( updateParents, updateChildren ) {
  351. const parent = this.parent;
  352. if ( updateParents === true && parent !== null ) {
  353. parent.updateWorldMatrix( true, false );
  354. }
  355. if ( this.matrixAutoUpdate ) this.updateMatrix();
  356. if ( this.matrixWorldAutoUpdate === true ) {
  357. if ( this.parent === null ) {
  358. this.matrixWorld.copy( this.matrix );
  359. } else {
  360. this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix );
  361. }
  362. }
  363. // make sure descendants are updated
  364. if ( updateChildren === true ) {
  365. const children = this.children;
  366. for ( let i = 0, l = children.length; i < l; i ++ ) {
  367. const child = children[ i ];
  368. child.updateWorldMatrix( false, true );
  369. }
  370. }
  371. }
  372. toJSON( meta ) {
  373. // meta is a string when called from JSON.stringify
  374. const isRootObject = ( meta === undefined || typeof meta === 'string' );
  375. const output = {};
  376. // meta is a hash used to collect geometries, materials.
  377. // not providing it implies that this is the root object
  378. // being serialized.
  379. if ( isRootObject ) {
  380. // initialize meta obj
  381. meta = {
  382. geometries: {},
  383. materials: {},
  384. textures: {},
  385. images: {},
  386. shapes: {},
  387. skeletons: {},
  388. animations: {},
  389. nodes: {}
  390. };
  391. output.metadata = {
  392. version: 4.6,
  393. type: 'Object',
  394. generator: 'Object3D.toJSON'
  395. };
  396. }
  397. // standard Object3D serialization
  398. const object = {};
  399. object.uuid = this.uuid;
  400. object.type = this.type;
  401. if ( this.name !== '' ) object.name = this.name;
  402. if ( this.castShadow === true ) object.castShadow = true;
  403. if ( this.receiveShadow === true ) object.receiveShadow = true;
  404. if ( this.visible === false ) object.visible = false;
  405. if ( this.frustumCulled === false ) object.frustumCulled = false;
  406. if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder;
  407. if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData;
  408. object.layers = this.layers.mask;
  409. object.matrix = this.matrix.toArray();
  410. object.up = this.up.toArray();
  411. if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;
  412. // object specific properties
  413. if ( this.isInstancedMesh ) {
  414. object.type = 'InstancedMesh';
  415. object.count = this.count;
  416. object.instanceMatrix = this.instanceMatrix.toJSON();
  417. if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON();
  418. }
  419. if ( this.isBatchedMesh ) {
  420. object.type = 'BatchedMesh';
  421. object.perObjectFrustumCulled = this.perObjectFrustumCulled;
  422. object.sortObjects = this.sortObjects;
  423. object.drawRanges = this._drawRanges;
  424. object.reservedRanges = this._reservedRanges;
  425. object.visibility = this._visibility;
  426. object.active = this._active;
  427. object.bounds = this._bounds.map( bound => ( {
  428. boxInitialized: bound.boxInitialized,
  429. boxMin: bound.box.min.toArray(),
  430. boxMax: bound.box.max.toArray(),
  431. sphereInitialized: bound.sphereInitialized,
  432. sphereRadius: bound.sphere.radius,
  433. sphereCenter: bound.sphere.center.toArray()
  434. } ) );
  435. object.maxGeometryCount = this._maxGeometryCount;
  436. object.maxVertexCount = this._maxVertexCount;
  437. object.maxIndexCount = this._maxIndexCount;
  438. object.geometryInitialized = this._geometryInitialized;
  439. object.geometryCount = this._geometryCount;
  440. object.matricesTexture = this._matricesTexture.toJSON( meta );
  441. if ( this._colorsTexture !== null ) object.colorsTexture = this._colorsTexture.toJSON( meta );
  442. if ( this.boundingSphere !== null ) {
  443. object.boundingSphere = {
  444. center: object.boundingSphere.center.toArray(),
  445. radius: object.boundingSphere.radius
  446. };
  447. }
  448. if ( this.boundingBox !== null ) {
  449. object.boundingBox = {
  450. min: object.boundingBox.min.toArray(),
  451. max: object.boundingBox.max.toArray()
  452. };
  453. }
  454. }
  455. //
  456. function serialize( library, element ) {
  457. if ( library[ element.uuid ] === undefined ) {
  458. library[ element.uuid ] = element.toJSON( meta );
  459. }
  460. return element.uuid;
  461. }
  462. if ( this.isScene ) {
  463. if ( this.background ) {
  464. if ( this.background.isColor ) {
  465. object.background = this.background.toJSON();
  466. } else if ( this.background.isTexture ) {
  467. object.background = this.background.toJSON( meta ).uuid;
  468. }
  469. }
  470. if ( this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true ) {
  471. object.environment = this.environment.toJSON( meta ).uuid;
  472. }
  473. } else if ( this.isMesh || this.isLine || this.isPoints ) {
  474. object.geometry = serialize( meta.geometries, this.geometry );
  475. const parameters = this.geometry.parameters;
  476. if ( parameters !== undefined && parameters.shapes !== undefined ) {
  477. const shapes = parameters.shapes;
  478. if ( Array.isArray( shapes ) ) {
  479. for ( let i = 0, l = shapes.length; i < l; i ++ ) {
  480. const shape = shapes[ i ];
  481. serialize( meta.shapes, shape );
  482. }
  483. } else {
  484. serialize( meta.shapes, shapes );
  485. }
  486. }
  487. }
  488. if ( this.isSkinnedMesh ) {
  489. object.bindMode = this.bindMode;
  490. object.bindMatrix = this.bindMatrix.toArray();
  491. if ( this.skeleton !== undefined ) {
  492. serialize( meta.skeletons, this.skeleton );
  493. object.skeleton = this.skeleton.uuid;
  494. }
  495. }
  496. if ( this.material !== undefined ) {
  497. if ( Array.isArray( this.material ) ) {
  498. const uuids = [];
  499. for ( let i = 0, l = this.material.length; i < l; i ++ ) {
  500. uuids.push( serialize( meta.materials, this.material[ i ] ) );
  501. }
  502. object.material = uuids;
  503. } else {
  504. object.material = serialize( meta.materials, this.material );
  505. }
  506. }
  507. //
  508. if ( this.children.length > 0 ) {
  509. object.children = [];
  510. for ( let i = 0; i < this.children.length; i ++ ) {
  511. object.children.push( this.children[ i ].toJSON( meta ).object );
  512. }
  513. }
  514. //
  515. if ( this.animations.length > 0 ) {
  516. object.animations = [];
  517. for ( let i = 0; i < this.animations.length; i ++ ) {
  518. const animation = this.animations[ i ];
  519. object.animations.push( serialize( meta.animations, animation ) );
  520. }
  521. }
  522. if ( isRootObject ) {
  523. const geometries = extractFromCache( meta.geometries );
  524. const materials = extractFromCache( meta.materials );
  525. const textures = extractFromCache( meta.textures );
  526. const images = extractFromCache( meta.images );
  527. const shapes = extractFromCache( meta.shapes );
  528. const skeletons = extractFromCache( meta.skeletons );
  529. const animations = extractFromCache( meta.animations );
  530. const nodes = extractFromCache( meta.nodes );
  531. if ( geometries.length > 0 ) output.geometries = geometries;
  532. if ( materials.length > 0 ) output.materials = materials;
  533. if ( textures.length > 0 ) output.textures = textures;
  534. if ( images.length > 0 ) output.images = images;
  535. if ( shapes.length > 0 ) output.shapes = shapes;
  536. if ( skeletons.length > 0 ) output.skeletons = skeletons;
  537. if ( animations.length > 0 ) output.animations = animations;
  538. if ( nodes.length > 0 ) output.nodes = nodes;
  539. }
  540. output.object = object;
  541. return output;
  542. // extract data from the cache hash
  543. // remove metadata on each item
  544. // and return as array
  545. function extractFromCache( cache ) {
  546. const values = [];
  547. for ( const key in cache ) {
  548. const data = cache[ key ];
  549. delete data.metadata;
  550. values.push( data );
  551. }
  552. return values;
  553. }
  554. }
  555. clone( recursive ) {
  556. return new this.constructor().copy( this, recursive );
  557. }
  558. copy( source, recursive = true ) {
  559. this.name = source.name;
  560. this.up.copy( source.up );
  561. this.position.copy( source.position );
  562. this.rotation.order = source.rotation.order;
  563. this.quaternion.copy( source.quaternion );
  564. this.scale.copy( source.scale );
  565. this.matrix.copy( source.matrix );
  566. this.matrixWorld.copy( source.matrixWorld );
  567. this.matrixAutoUpdate = source.matrixAutoUpdate;
  568. this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate;
  569. this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
  570. this.layers.mask = source.layers.mask;
  571. this.visible = source.visible;
  572. this.castShadow = source.castShadow;
  573. this.receiveShadow = source.receiveShadow;
  574. this.frustumCulled = source.frustumCulled;
  575. this.renderOrder = source.renderOrder;
  576. this.animations = source.animations.slice();
  577. this.userData = JSON.parse( JSON.stringify( source.userData ) );
  578. if ( recursive === true ) {
  579. for ( let i = 0; i < source.children.length; i ++ ) {
  580. const child = source.children[ i ];
  581. this.add( child.clone() );
  582. }
  583. }
  584. return this;
  585. }
  586. }
  587. Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 );
  588. Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true;
  589. Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true;
  590. export { Object3D };