Skip to content

Instantly share code, notes, and snippets.

@trusktr
Last active May 27, 2019
Embed
What would you like to do?
import * as THREE from 'three'
export function isRenderItem(obj: THREE.Object3D): obj is THREE.RenderItem & THREE.Object3D {
return 'geometry' in obj && 'material' in obj
}
export function disposeMaterial(obj: THREE.Object3D): void {
if (!isRenderItem(obj)) return
// because obj.material can be a material or an array of materials
const materials = ([] as THREE.Material[]).concat(obj.material)
for (const material of materials) {
material.dispose()
}
}
export function disposeObject(
obj: THREE.Object3D,
removeFromParent: boolean = true,
destroyGeometry: boolean = true,
destroyMaterial: boolean = true
): void {
if (isRenderItem(obj)) {
if (destroyGeometry) obj.geometry.dispose()
if (destroyMaterial) disposeMaterial(obj)
}
removeFromParent && Promise.resolve().then(() => {
// if we remove children in the same tick then we can't continue traversing,
// so we defer to the next microtask
obj.parent && obj.parent.remove(obj)
})
}
export type DisposeOptions = {
removeFromParent?: boolean
destroyGeometry?: boolean
destroyMaterial?: boolean
}
export function disposeObjectTree(obj: THREE.Object3D, disposeOptions: DisposeOptions = {}): void {
obj.traverse(node => {
disposeObject(
node,
disposeOptions.removeFromParent,
disposeOptions.destroyGeometry,
disposeOptions.destroyMaterial
)
})
}
export function quaternionApproximateEquals(a: THREE.Quaternion, b: THREE.Quaternion, epsilon: number): boolean {
return Math.abs(a.x - b.x) < epsilon
&& Math.abs(a.y - b.y) < epsilon
&& Math.abs(a.z - b.z) < epsilon
&& Math.abs(a.w - b.w) < epsilon
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment