Skip to content

Commit 30776bb

Browse files
authored
Object3D: Added pivot property. (#32745)
1 parent 3cd3e5b commit 30776bb

File tree

4 files changed

+49
-39
lines changed

4 files changed

+49
-39
lines changed

examples/jsm/loaders/LWOLoader.js

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ import {
2323
RepeatWrapping,
2424
SRGBColorSpace,
2525
TextureLoader,
26-
Vector2
26+
Vector2,
27+
Vector3
2728
} from 'three';
2829

2930
import { IFFParser } from './lwo/IFFParser.js';
@@ -185,8 +186,6 @@ class LWOTreeParser {
185186

186187
} );
187188

188-
this.applyPivots( finalMeshes );
189-
190189
return finalMeshes;
191190

192191
}
@@ -204,38 +203,14 @@ class LWOTreeParser {
204203
if ( layer.name ) mesh.name = layer.name;
205204
else mesh.name = this.defaultLayerName + '_layer_' + layer.number;
206205

207-
mesh.userData.pivot = layer.pivot;
208-
209-
return mesh;
210-
211-
}
212-
213-
// TODO: may need to be reversed in z to convert LWO to three.js coordinates
214-
applyPivots( meshes ) {
215-
216-
meshes.forEach( function ( mesh ) {
217-
218-
mesh.traverse( function ( child ) {
219-
220-
const pivot = child.userData.pivot;
221-
222-
child.position.x += pivot[ 0 ];
223-
child.position.y += pivot[ 1 ];
224-
child.position.z += pivot[ 2 ];
206+
const pivot = layer.pivot;
207+
if ( pivot[ 0 ] !== 0 || pivot[ 1 ] !== 0 || pivot[ 2 ] !== 0 ) {
225208

226-
if ( child.parent ) {
209+
mesh.pivot = new Vector3( pivot[ 0 ], pivot[ 1 ], pivot[ 2 ] );
227210

228-
const parentPivot = child.parent.userData.pivot;
229-
230-
child.position.x -= parentPivot[ 0 ];
231-
child.position.y -= parentPivot[ 1 ];
232-
child.position.z -= parentPivot[ 2 ];
233-
234-
}
235-
236-
} );
211+
}
237212

238-
} );
213+
return mesh;
239214

240215
}
241216

@@ -813,13 +788,6 @@ class GeometryParser {
813788
this.parseUVs( geometry, layer );
814789
this.parseMorphTargets( geometry, layer );
815790

816-
// TODO: z may need to be reversed to account for coordinate system change
817-
geometry.translate( - layer.pivot[ 0 ], - layer.pivot[ 1 ], - layer.pivot[ 2 ] );
818-
819-
// let userData = geometry.userData;
820-
// geometry = geometry.toNonIndexed()
821-
// geometry.userData = userData;
822-
823791
return geometry;
824792

825793
}

examples/jsm/loaders/usd/USDComposer.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
Bone,
2020
SRGBColorSpace,
2121
Texture,
22+
Vector3,
2223
VectorKeyframeTrack
2324
} from 'three';
2425

@@ -256,6 +257,13 @@ class USDComposer {
256257

257258
}
258259

260+
if ( data[ 'xformOp:translate:pivot' ] ) {
261+
262+
const p = data[ 'xformOp:translate:pivot' ];
263+
obj.pivot = new Vector3( p[ 0 ], p[ 1 ], p[ 2 ] );
264+
265+
}
266+
259267
if ( data[ 'xformOp:scale' ] ) {
260268

261269
const s = data[ 'xformOp:scale' ];

src/core/Object3D.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,16 @@ class Object3D extends EventDispatcher {
375375
*/
376376
this.userData = {};
377377

378+
/**
379+
* The pivot point for rotation and scale transformations.
380+
* When set, rotation and scale are applied around this point
381+
* instead of the object's origin.
382+
*
383+
* @type {?Vector3}
384+
* @default null
385+
*/
386+
this.pivot = null;
387+
378388
}
379389

380390
/**
@@ -1122,6 +1132,19 @@ class Object3D extends EventDispatcher {
11221132

11231133
this.matrix.compose( this.position, this.quaternion, this.scale );
11241134

1135+
const pivot = this.pivot;
1136+
1137+
if ( pivot !== null ) {
1138+
1139+
const px = pivot.x, py = pivot.y, pz = pivot.z;
1140+
const te = this.matrix.elements;
1141+
1142+
te[ 12 ] += px - te[ 0 ] * px - te[ 4 ] * py - te[ 8 ] * pz;
1143+
te[ 13 ] += py - te[ 1 ] * px - te[ 5 ] * py - te[ 9 ] * pz;
1144+
te[ 14 ] += pz - te[ 2 ] * px - te[ 6 ] * py - te[ 10 ] * pz;
1145+
1146+
}
1147+
11251148
this.matrixWorldNeedsUpdate = true;
11261149

11271150
}
@@ -1287,6 +1310,8 @@ class Object3D extends EventDispatcher {
12871310
object.matrix = this.matrix.toArray();
12881311
object.up = this.up.toArray();
12891312

1313+
if ( this.pivot !== null ) object.pivot = this.pivot.toArray();
1314+
12901315
if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false;
12911316

12921317
// object specific properties
@@ -1562,6 +1587,12 @@ class Object3D extends EventDispatcher {
15621587
this.quaternion.copy( source.quaternion );
15631588
this.scale.copy( source.scale );
15641589

1590+
if ( source.pivot !== null ) {
1591+
1592+
this.pivot = source.pivot.clone();
1593+
1594+
}
1595+
15651596
this.matrix.copy( source.matrix );
15661597
this.matrixWorld.copy( source.matrixWorld );
15671598

src/loaders/ObjectLoader.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
} from '../constants.js';
2020
import { InstancedBufferAttribute } from '../core/InstancedBufferAttribute.js';
2121
import { Color } from '../math/Color.js';
22+
import { Vector3 } from '../math/Vector3.js';
2223
import { Object3D } from '../core/Object3D.js';
2324
import { Group } from '../objects/Group.js';
2425
import { InstancedMesh } from '../objects/InstancedMesh.js';
@@ -1114,6 +1115,8 @@ class ObjectLoader extends Loader {
11141115

11151116
if ( data.up !== undefined ) object.up.fromArray( data.up );
11161117

1118+
if ( data.pivot !== undefined ) object.pivot = new Vector3().fromArray( data.pivot );
1119+
11171120
if ( data.castShadow !== undefined ) object.castShadow = data.castShadow;
11181121
if ( data.receiveShadow !== undefined ) object.receiveShadow = data.receiveShadow;
11191122

0 commit comments

Comments
 (0)