| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- import { Parameters } from './Parameters.js';
- import { WebGPURenderer, WebGLBackend, Node } from 'three/webgpu';
- import { getItem, setItem } from '../Inspector.js';
- const _EXTENSIONS_PATH = '../extensions/extensions.json';
- const _init = WebGPURenderer.prototype.init;
- function forceWebGL( enable ) {
- if ( enable ) {
- WebGPURenderer.prototype.init = async function () {
- if ( this.backend.isWebGLBackend !== true ) {
- const parameters = this.backend.parameters;
- this.backend = new WebGLBackend( parameters );
- }
- return _init.call( this );
- };
- } else {
- WebGPURenderer.prototype.init = _init;
- }
- }
- let _state = null;
- function _loadState() {
- if ( _state !== null ) return _state;
- const settings = getItem( 'settings' );
- _state = {
- forceWebGL: settings.forceWebGL !== undefined ? settings.forceWebGL : false,
- captureStackTrace: settings.captureStackTrace !== undefined ? settings.captureStackTrace : false,
- activeExtensions: settings.activeExtensions !== undefined ? settings.activeExtensions : {}
- };
- if ( _state.forceWebGL ) {
- forceWebGL( true );
- }
- if ( _state.captureStackTrace ) {
- Node.captureStackTrace = true;
- }
- return _state;
- }
- function _saveState() {
- setItem( 'settings', {
- forceWebGL: _state.forceWebGL,
- captureStackTrace: _state.captureStackTrace,
- activeExtensions: _state.activeExtensions
- } );
- }
- _loadState();
- //
- class Settings extends Parameters {
- constructor() {
- super( { name: 'Settings' } );
- this.extensions = {};
- const currentState = _loadState();
- // UI
- const rendererGroup = this.createGroup( 'Renderer' );
- rendererGroup.add( currentState, 'forceWebGL' ).name( 'Force WebGL' ).onChange( ( enable ) => {
- forceWebGL( enable );
- _saveState();
- location.reload();
- } );
- rendererGroup.add( currentState, 'captureStackTrace' ).name( 'Capture Stack Trace' ).onChange( ( enable ) => {
- Node.captureStackTrace = enable;
- _saveState();
- location.reload();
- } );
- }
- init() {
- const extensionsGroup = this.createGroup( 'Extensions' );
- this._getExtensions().then( extensions => {
- for ( const extension of extensions ) {
- extension.active = false;
- extension.loaded = false;
- extension.tab = null;
- this.extensions[ extension.name ] = extension;
- extension.ui = extensionsGroup.add( { [ extension.name ]: false }, extension.name ).onChange( async ( value ) => {
- this.setActiveExtension( extension.name, value );
- // User preference
- if ( value ) {
- _state.activeExtensions[ extension.name ] = {
- name: extension.name,
- url: extension.url
- };
- } else {
- delete _state.activeExtensions[ extension.name ];
- }
- //
- this._updateExtensionUI( extension );
- _saveState();
- } );
- // Set user-defined state
- if ( _state.activeExtensions[ extension.name ] !== undefined ) {
- extension.ui.setValue( true );
- }
- }
- } );
- }
- async setActiveExtension( name, value ) {
- const extension = this.extensions[ name ];
- const inspector = this.inspector;
- if ( extension ) {
- if ( value ) {
- await this._loadExtension( inspector, extension );
- } else {
- await this._unloadExtension( inspector, extension );
- }
- }
- }
- _updateExtensionUI( extension ) {
- const forceActive = extension.active && _state.activeExtensions[ extension.name ] === undefined;
- if ( forceActive ) {
- extension.ui.checkbox.checked = true;
- extension.ui.domElement.style.setProperty( '--accent-color', 'var(--color-green)' );
- } else {
- extension.ui.domElement.style.removeProperty( '--accent-color' );
- }
- }
- async _unloadExtension( inspector, extension ) {
- if ( extension.active === false ) return;
- //
- inspector.removeTab( extension.tab );
- extension.active = false;
- extension.loaded = false;
- extension.tab = null;
- this._updateExtensionUI( extension );
- this.dispatchEvent( { type: 'extensionremoved', name: extension.name } );
- }
- async _loadExtension( inspector, extension ) {
- if ( extension.active === true ) return;
- //
- extension.active = true;
- const extUrl = new URL( extension.url, new URL( _EXTENSIONS_PATH, import.meta.url ) ).href;
- const module = await import( extUrl );
- const keys = Object.keys( module );
- const ExtensionClass = module[ keys[ 0 ] ];
- const extensionTab = new ExtensionClass();
- inspector.addTab( extensionTab );
- extension.loaded = true;
- extension.tab = extensionTab;
- this._updateExtensionUI( extension );
- this.dispatchEvent( { type: 'extensionadded', name: extension.name, tab: extensionTab } );
- }
- async _getExtensions() {
- const url = new URL( _EXTENSIONS_PATH, import.meta.url );
- const extensions = await fetch( url ).then( res => res.json() );
- return extensions;
- }
- }
- export { Settings };
|