threepipe
Version:
A modern 3D viewer framework built on top of three.js, written in TypeScript, designed to make creating high-quality, modular, and extensible 3D experiences on the web simple and enjoyable.
102 lines • 3.99 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { AViewerPluginSync } from '../../viewer';
import { onChange } from 'ts-browser-helpers';
import { Object3D } from 'three';
import { CameraHelper2, DirectionalLightHelper2, PointLightHelper2, SpotLightHelper2 } from '../../three';
/**
* Adds light and camera helpers/gizmos in the viewer.
* A helper is automatically created when any supported light or camera is added to the scene.
* @category Plugins
*/
export class Object3DWidgetsPlugin extends AViewerPluginSync {
setDirty() {
this.widgets?.forEach(w => w.visible = !this.isDisabled());
this._viewer?.setDirty();
}
constructor(enabled = true) {
super();
this.enabled = true;
this.helpers = [
DirectionalLightHelper2,
SpotLightHelper2,
PointLightHelper2,
CameraHelper2,
];
this.toJSON = null;
this._widgetRoot = new Object3D();
this._addSceneObject = (e) => {
this._createWidgets(e.object);
};
this.widgets = [];
this._widgetDisposed = (e) => this._unregisterWidget(e.target);
this.uiConfig = {
type: 'folder',
label: 'Widgets',
children: [
{
type: 'checkbox',
label: 'Enabled',
property: [this, 'enabled'],
},
{
type: 'button',
label: 'Refresh',
value: () => this.refresh(),
},
],
};
this.enabled = enabled;
}
onAdded(viewer) {
super.onAdded(viewer);
viewer.scene.addObject(this._widgetRoot, { addToRoot: true, autoScale: false, autoCenter: false });
viewer.scene.addEventListener('addSceneObject', this._addSceneObject);
}
onRemove(viewer) {
viewer.scene.removeEventListener('addSceneObject', this._addSceneObject);
this.widgets.forEach(w => w.dispose && w.dispose());
this.widgets = [];
this._widgetRoot.removeFromParent();
this._widgetRoot.clear();
super.onRemove(viewer);
}
refresh() {
this._createWidgets(this._viewer?.scene.modelRoot);
}
_registerWidget(w) {
this.widgets.push(w);
w.addEventListener('dispose', this._widgetDisposed); // todo: maybe unregister when removed from parent, dispose makes little sense.
}
_unregisterWidget(w) {
w.removeEventListener('dispose', this._widgetDisposed);
const i = this.widgets.indexOf(w);
if (i >= 0)
this.widgets.splice(i, 1);
}
_createWidgets(o) {
o?.traverse((l) => {
const widget = this.widgets.find(w => w.object === l);
if (widget) {
widget.update && widget.update();
return;
}
const helpers = this.helpers.filter(h => h.Check(l));
helpers.forEach(h => {
const w = h.Create(l);
w.visible = !this.isDisabled();
this._widgetRoot.add(w);
this._registerWidget(w);
});
});
}
}
Object3DWidgetsPlugin.PluginType = 'Object3DWidgetsPlugin';
__decorate([
onChange(Object3DWidgetsPlugin.prototype.setDirty)
], Object3DWidgetsPlugin.prototype, "enabled", void 0);
//# sourceMappingURL=Object3DWidgetsPlugin.js.map