@@ -13,6 +13,22 @@ import {
1313 eps
1414} from '../math/Constants.tests' ;
1515
16+ const matrixEquals4 = ( a , b ) => {
17+
18+ for ( let i = 0 ; i < 16 ; i ++ ) {
19+
20+ if ( Math . abs ( a . elements [ i ] - b . elements [ i ] ) >= eps ) {
21+
22+ return false ;
23+
24+ }
25+
26+ }
27+
28+ return true ;
29+
30+ } ;
31+
1632export default QUnit . module ( 'Core' , ( ) => {
1733
1834 QUnit . module ( 'Object3D' , ( ) => {
@@ -385,6 +401,63 @@ export default QUnit.module( 'Core', () => {
385401
386402 } ) ;
387403
404+ QUnit . test ( "attach" , ( assert ) => {
405+
406+ const object = new Object3D ( ) ;
407+ const oldParent = new Object3D ( ) ;
408+ const newParent = new Object3D ( ) ;
409+ const expectedMatrixWorld = new Matrix4 ( ) ;
410+
411+ // Attach to a parent
412+
413+ object . position . set ( 1 , 2 , 3 ) ;
414+ object . rotation . set ( Math . PI / 2 , Math . PI / 3 , Math . PI / 4 ) ;
415+ object . scale . set ( 2 , 3 , 4 ) ;
416+ newParent . position . set ( 4 , 5 , 6 ) ;
417+ newParent . rotation . set ( Math . PI / 5 , Math . PI / 6 , Math . PI / 7 ) ;
418+ newParent . scale . set ( 5 , 5 , 5 ) ;
419+
420+ object . updateMatrixWorld ( ) ;
421+ newParent . updateMatrixWorld ( ) ;
422+ expectedMatrixWorld . copy ( object . matrixWorld ) ;
423+
424+ newParent . attach ( object ) ;
425+
426+ assert . ok ( object . parent && object . parent == newParent &&
427+ oldParent . children . indexOf ( object ) === - 1 ,
428+ "object is a child of a new parent" ) ;
429+
430+ assert . ok ( matrixEquals4 ( expectedMatrixWorld , object . matrixWorld ) , "object's world matrix is maintained" ) ;
431+
432+ // Attach to a new parent from an old parent
433+
434+ object . position . set ( 1 , 2 , 3 ) ;
435+ object . rotation . set ( Math . PI / 2 , Math . PI / 3 , Math . PI / 4 ) ;
436+ object . scale . set ( 2 , 3 , 4 ) ;
437+ oldParent . position . set ( 4 , 5 , 6 ) ;
438+ oldParent . rotation . set ( Math . PI / 5 , Math . PI / 6 , Math . PI / 7 ) ;
439+ oldParent . scale . set ( 5 , 5 , 5 ) ;
440+ newParent . position . set ( 7 , 8 , 9 ) ;
441+ newParent . rotation . set ( Math . PI / 8 , Math . PI / 9 , Math . PI / 10 ) ;
442+ newParent . scale . set ( 6 , 6 , 6 ) ;
443+
444+ oldParent . add ( object ) ;
445+ oldParent . updateMatrixWorld ( ) ;
446+ newParent . updateMatrixWorld ( ) ;
447+ expectedMatrixWorld . copy ( object . matrixWorld ) ;
448+
449+ newParent . attach ( object ) ;
450+
451+ assert . ok ( object . parent && object . parent == newParent &&
452+ newParent . children . indexOf ( object ) !== - 1 &&
453+ oldParent . children . indexOf ( object ) === - 1 ,
454+ "object is no longer a child of an old parent and is a child of a new parent now" ) ;
455+
456+ assert . ok ( matrixEquals4 ( expectedMatrixWorld , object . matrixWorld ) ,
457+ "object's world matrix is maintained even it had a parent" ) ;
458+
459+ } ) ;
460+
388461 QUnit . test ( "getObjectById/getObjectByName/getObjectByProperty" , ( assert ) => {
389462
390463 var parent = new Object3D ( ) ;
0 commit comments