Skip to content

Commit

Permalink
creates setup function for three helpers, and various small improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
dpwoert committed Jan 17, 2024
1 parent c69307e commit 4f6ee8a
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 37 deletions.
55 changes: 43 additions & 12 deletions examples/three-gltf-editor/src/Viewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {
WebGLRenderer,
Color,
AnimationMixer,
Vector3,
Mesh,
Object3D,
} from 'three';

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
Expand All @@ -18,6 +19,27 @@ import { MagicCircle } from '@magic-circle/client';
import * as GUI from '@magic-circle/three';
import { COLORS } from '@magic-circle/styles';

const dispose = (object: Object3D) => {
if ('geometry' in object) {
(object.geometry as Mesh['geometry']).dispose();
}

if ('material' in object) {
const mat = object.material as Mesh['material'];
const materials = Array.isArray(mat) ? mat : [mat];
materials.forEach((material) => {
// eslint-disable-next-line
for (const key in material) {
if (key !== 'envMap' && material[key] && material[key].isTexture) {
material[key].dispose();
}
}

material.dispose();
});
}
};

export default class Viewer {
renderer: WebGLRenderer;
loader: GLTFLoader;
Expand Down Expand Up @@ -105,17 +127,18 @@ export default class Viewer {
}

// Create UI
GUI.webglRenderer(this.renderer).addTo(this.magicCircle.layer);
GUI.scene(this.scene, {
watch: () => true,
camera: this.camera,
onTransformStart: () => {
this.controls.enabled = false;
},
onTransformEnd: () => {
this.controls.enabled = true;
},
}).addTo(this.magicCircle.layer);
this.magicCircle.layer.add(
GUI.setup(this.renderer, this.camera, this.scene, {
watch: () => true,
camera: this.camera,
onTransformStart: () => {
this.controls.enabled = false;
},
onTransformEnd: () => {
this.controls.enabled = true;
},
})
);

// Trigger sync of UI
this.magicCircle.sync();
Expand All @@ -135,6 +158,14 @@ export default class Viewer {
this.magicCircle.layer.forEach((c) => c.destroy(true));
this.magicCircle.layer.children = [];
}

this.scene.traverse((child) => {
dispose(child);
});

this.scene.children.forEach((child) => {
child.removeFromParent();
});
}

tick(delta: number) {
Expand Down
2 changes: 0 additions & 2 deletions plugins/three/src/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export function perspectiveCamera(
): Layer {
const layer = new Layer(camera.name || 'Camera');

console.log({ settings });

// Add matrix controls and helpers
layer.add(cameraHelpers(camera, settings));
layer.add(cameraMatrix(camera, settings));
Expand Down
1 change: 1 addition & 0 deletions plugins/three/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export { webglRenderer } from './renderer';
export { TransformControl } from './TransformControl';
export { CameraHelperControl } from './CameraHelperControl';
export { LightHelperControl } from './LightHelperControl';
export { setup } from './setup';
44 changes: 39 additions & 5 deletions plugins/three/src/light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,67 @@ import {
AmbientLight,
HemisphereLight,
RectAreaLight,
Camera,
} from 'three';
import {
VectorControl,
NumberControl,
RotationControl,
TextControl,
Layer,
Folder,
BooleanControl,
ColorControl,
} from '@magic-circle/client';

import { TransformControl } from './TransformControl';
import { LightHelperControl } from './LightHelperControl';
import { CameraHelperControl } from './CameraHelperControl';
import { getParentScene } from './utils';

type LightSettings = {
type LightHelperSettings = {
camera?: Camera;
onTransformStart?: () => void;
onTransformEnd?: () => void;
};

type LightSettings = LightHelperSettings & {
range: Vector3;
precision?: number;
};

function lightHelpers(light: Light): Folder[] {
function lightHelpers(
light: Light,
settings: LightHelperSettings = {}
): Folder[] {
const scene = getParentScene(light);

if (scene) {
// Add camera specific options
const folder = new Folder('Helper').add(new LightHelperControl(light));

// Add transform
if (settings.camera) {
const transformSettings = { mode: 'translate' };
const transformControl = new TransformControl(
settings.camera,
light
).onUpdate((newVal) => {
if (newVal && settings.onTransformStart) {
settings.onTransformStart();
}
if (!newVal && settings.onTransformEnd) {
settings.onTransformEnd();
}
});
const transformMode = new TextControl(transformSettings, 'mode')
.selection(['translate', 'rotate', 'scale'])
.onUpdate(() => {
transformControl.mode(transformSettings.mode as any);
});
folder.add([transformControl, transformMode]);
}

if (light.shadow) {
folder.add(
new CameraHelperControl(light.shadow?.camera, scene).label(
Expand Down Expand Up @@ -108,7 +142,7 @@ export function pointLight(light: PointLight, settings: LightSettings): Layer {
const layer = new Layer(light.name || 'Point Liight');

// Add matrix controls
layer.add(lightHelpers(light));
layer.add(lightHelpers(light, settings));
layer.add(lightMatrix(light, settings));
layer.add(lightShadow(light));

Expand All @@ -131,7 +165,7 @@ export function spotLight(light: SpotLight, settings: LightSettings): Layer {
const layer = new Layer(light.name || 'Point Liight');

// Add matrix controls
layer.add(lightHelpers(light));
layer.add(lightHelpers(light, settings));
layer.add(lightMatrix(light, settings));
layer.add(lightShadow(light));

Expand Down Expand Up @@ -191,7 +225,7 @@ export function directionalLight(
const layer = new Layer(light.name || 'Directional light');

// Add matrix controls
layer.add(lightHelpers(light));
layer.add(lightHelpers(light, settings));
layer.add(lightMatrix(light, settings));
layer.add(lightShadow(light));

Expand Down
30 changes: 14 additions & 16 deletions plugins/three/src/object3d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,25 @@ export function matrixFolders(
object.position.x - settings.range.x,
object.position.x + settings.range.x
)
.precision(settings.precision),
.precision(settings.precision)
.watch(!!settings.camera),
]),
new Folder('Scale').add([
new NumberControl(object.scale, 'x').range(
settings.scale.x,
settings.scale.y
),
new NumberControl(object.scale, 'y').range(
settings.scale.x,
settings.scale.y
),
new NumberControl(object.scale, 'z').range(
settings.scale.x,
settings.scale.y
),
new NumberControl(object.scale, 'x')
.range(settings.scale.x, settings.scale.y)
.watch(!!settings.camera),
new NumberControl(object.scale, 'y')
.range(settings.scale.x, settings.scale.y)
.watch(!!settings.camera),
new NumberControl(object.scale, 'z')
.range(settings.scale.x, settings.scale.y)
.watch(!!settings.camera),
]),

new Folder('Rotation').add([
new RotationControl(object.rotation, 'x'),
new RotationControl(object.rotation, 'y'),
new RotationControl(object.rotation, 'z'),
new RotationControl(object.rotation, 'x').watch(!!settings.camera),
new RotationControl(object.rotation, 'y').watch(!!settings.camera),
new RotationControl(object.rotation, 'z').watch(!!settings.camera),
])
);

Expand Down
1 change: 1 addition & 0 deletions plugins/three/src/recursive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export function recursive(
}).addTo(parentLayer);
} else if (object instanceof Light) {
gui = light(object, {
...settings,
range: settings.range
? settings.range(object)
: new Vector3(10, 10, 10),
Expand Down
3 changes: 1 addition & 2 deletions plugins/three/src/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import {

import { RecursiveSettings, recursive } from './recursive';

type SceneSettings = RecursiveSettings & {
export type SceneSettings = RecursiveSettings & {
noRecursive?: boolean;
sync?: boolean;
};

export function scene(scene: Scene, opts: SceneSettings = {}): Layer {
Expand Down
22 changes: 22 additions & 0 deletions plugins/three/src/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Scene, Camera, WebGLRenderer, Box3, Vector3 } from 'three';
import { Layer } from '@magic-circle/client';

import { SceneSettings, scene as createScene } from './scene';
import { camera as createCamera } from './camera';
import { webglRenderer as createRenderer } from './renderer';

export function setup(
renderer: WebGLRenderer,
camera: Camera,
scene: Scene,
settings: SceneSettings = {}
): Layer[] {
const bbox = new Box3().setFromObject(scene);
const range = bbox.getSize(new Vector3()).multiplyScalar(3);

return [
createRenderer(renderer),
createCamera(camera, { scene, range }),
createScene(scene, settings),
];
}

0 comments on commit 4f6ee8a

Please sign in to comment.