|
import { Vector3 } from './vector.js'; |
|
import { Quaternion } from './quaternion.js'; |
|
import { Matrix } from './matrix.js'; |
|
|
|
export class Transform { |
|
constructor() { |
|
this.position = new Vector3(); |
|
this.rotation = new Quaternion(); |
|
this.scale = new Vector3(1, 1, 1); |
|
this.parent = null; |
|
this.children = new Set(); |
|
this.isDirty = true; |
|
} |
|
|
|
setPosition(x, y, z) { |
|
this.position = new Vector3(x, y, z); |
|
this.markDirty(); |
|
} |
|
|
|
setRotation(x, y, z) { |
|
this.rotation = Quaternion.fromEuler(x, y, z); |
|
this.markDirty(); |
|
} |
|
|
|
setScale(x, y, z) { |
|
this.scale = new Vector3(x, y, z); |
|
this.markDirty(); |
|
} |
|
|
|
addChild(child) { |
|
if (child.parent) { |
|
child.parent.children.delete(child); |
|
} |
|
child.parent = this; |
|
this.children.add(child); |
|
child.markDirty(); |
|
} |
|
|
|
markDirty() { |
|
this.isDirty = true; |
|
this.children.forEach(child => child.markDirty()); |
|
} |
|
|
|
getWorldMatrix() { |
|
|
|
let matrix = Matrix.translation( |
|
this.position.x, |
|
this.position.y, |
|
this.position.z |
|
); |
|
|
|
|
|
matrix = Matrix.multiply( |
|
matrix, |
|
Matrix.fromQuaternion(this.rotation) |
|
); |
|
|
|
|
|
matrix = Matrix.multiply( |
|
matrix, |
|
Matrix.scaling(this.scale.x, this.scale.y, this.scale.z) |
|
); |
|
|
|
|
|
if (this.parent) { |
|
matrix = Matrix.multiply( |
|
this.parent.getWorldMatrix(), |
|
matrix |
|
); |
|
} |
|
|
|
return matrix; |
|
} |
|
|
|
translate(x, y, z) { |
|
this.position = this.position.add(new Vector3(x, y, z)); |
|
this.markDirty(); |
|
} |
|
|
|
rotate(x, y, z) { |
|
const rotation = Quaternion.fromEuler(x, y, z); |
|
this.rotation = Quaternion.multiply(this.rotation, rotation); |
|
this.markDirty(); |
|
} |
|
|
|
scaleBy(x, y, z) { |
|
this.scale = new Vector3( |
|
this.scale.x * x, |
|
this.scale.y * y, |
|
this.scale.z * z |
|
); |
|
this.markDirty(); |
|
} |
|
|
|
setLocalPosition(x, y, z) { |
|
this.position = new Vector3(x, y, z); |
|
this.markDirty(); |
|
} |
|
|
|
setLocalRotation(x, y, z) { |
|
this.rotation = Quaternion.fromEuler(x, y, z); |
|
this.markDirty(); |
|
} |
|
|
|
setLocalScale(x, y, z) { |
|
this.scale = new Vector3(x, y, z); |
|
this.markDirty(); |
|
} |
|
|
|
getLocalPosition() { |
|
return this.position.clone(); |
|
} |
|
|
|
getLocalRotation() { |
|
return this.rotation.clone(); |
|
} |
|
|
|
getLocalScale() { |
|
return this.scale.clone(); |
|
} |
|
} |
|
|