Initial project import
This commit is contained in:
268
node_modules/three/examples/jsm/inspector/tabs/Viewer.js
generated
vendored
Normal file
268
node_modules/three/examples/jsm/inspector/tabs/Viewer.js
generated
vendored
Normal file
@@ -0,0 +1,268 @@
|
||||
import { Tab } from '../ui/Tab.js';
|
||||
import { List } from '../ui/List.js';
|
||||
import { Item } from '../ui/Item.js';
|
||||
import { splitPath, splitCamelCase } from '../ui/utils.js';
|
||||
|
||||
import { RendererUtils, NoToneMapping, LinearSRGBColorSpace, QuadMesh, NodeMaterial, CanvasTarget } from 'three/webgpu';
|
||||
import { renderOutput, vec2, vec3, vec4, Fn, screenUV, step, OnMaterialUpdate, uniform } from 'three/tsl';
|
||||
|
||||
const aspectRatioUV = /*@__PURE__*/ Fn( ( [ uv, textureNode ] ) => {
|
||||
|
||||
const aspect = uniform( 0 );
|
||||
|
||||
OnMaterialUpdate( () => {
|
||||
|
||||
const { width, height } = textureNode.value;
|
||||
|
||||
aspect.value = width / height;
|
||||
|
||||
} );
|
||||
|
||||
const centered = uv.sub( 0.5 );
|
||||
const corrected = vec2( centered.x.div( aspect ), centered.y );
|
||||
const finalUV = corrected.add( 0.5 );
|
||||
|
||||
const inBounds = step( 0.0, finalUV.x ).mul( step( finalUV.x, 1.0 ) ).mul( step( 0.0, finalUV.y ) ).mul( step( finalUV.y, 1.0 ) );
|
||||
|
||||
return vec3( finalUV, inBounds );
|
||||
|
||||
} );
|
||||
|
||||
class Viewer extends Tab {
|
||||
|
||||
constructor( options = {} ) {
|
||||
|
||||
super( 'Viewer', options );
|
||||
|
||||
const nodeList = new List( 'Viewer', 'Name' );
|
||||
nodeList.setGridStyle( '150px minmax(200px, 2fr)' );
|
||||
nodeList.domElement.style.minWidth = '400px';
|
||||
|
||||
const scrollWrapper = document.createElement( 'div' );
|
||||
scrollWrapper.className = 'list-scroll-wrapper';
|
||||
scrollWrapper.appendChild( nodeList.domElement );
|
||||
this.content.appendChild( scrollWrapper );
|
||||
|
||||
const nodes = new Item( 'Nodes' );
|
||||
nodeList.add( nodes );
|
||||
|
||||
//
|
||||
|
||||
this.itemLibrary = new Map();
|
||||
this.folderLibrary = new Map();
|
||||
this.canvasNodes = new Map();
|
||||
this.currentDataList = [];
|
||||
this.nodeList = nodeList;
|
||||
this.nodes = nodes;
|
||||
|
||||
}
|
||||
|
||||
getFolder( name ) {
|
||||
|
||||
let folder = this.folderLibrary.get( name );
|
||||
|
||||
if ( folder === undefined ) {
|
||||
|
||||
folder = new Item( name );
|
||||
|
||||
this.folderLibrary.set( name, folder );
|
||||
this.nodeList.add( folder );
|
||||
|
||||
}
|
||||
|
||||
return folder;
|
||||
|
||||
}
|
||||
|
||||
addNodeItem( canvasData ) {
|
||||
|
||||
let item = this.itemLibrary.get( canvasData.id );
|
||||
|
||||
if ( item === undefined ) {
|
||||
|
||||
const name = canvasData.name;
|
||||
const domElement = canvasData.canvasTarget.domElement;
|
||||
|
||||
item = new Item( domElement, name );
|
||||
item.itemRow.children[ 1 ].style[ 'justify-content' ] = 'flex-start';
|
||||
this.itemLibrary.set( canvasData.id, item );
|
||||
|
||||
}
|
||||
|
||||
return item;
|
||||
|
||||
}
|
||||
|
||||
getCanvasDataByNode( renderer, node ) {
|
||||
|
||||
let canvasData = this.canvasNodes.get( node );
|
||||
|
||||
if ( canvasData === undefined ) {
|
||||
|
||||
const canvas = document.createElement( 'canvas' );
|
||||
|
||||
const canvasTarget = new CanvasTarget( canvas );
|
||||
canvasTarget.setPixelRatio( window.devicePixelRatio );
|
||||
canvasTarget.setSize( 140, 140 );
|
||||
|
||||
const id = node.id;
|
||||
|
||||
const { path, name } = splitPath( splitCamelCase( node.getName() || '(unnamed)' ) );
|
||||
|
||||
const target = node.context( { getUV: ( textureNode ) => {
|
||||
|
||||
const uvData = aspectRatioUV( screenUV, textureNode );
|
||||
const correctedUV = uvData.xy;
|
||||
const mask = uvData.z;
|
||||
|
||||
return correctedUV.mul( mask );
|
||||
|
||||
} } );
|
||||
|
||||
let output = vec4( vec3( target ), 1 );
|
||||
output = renderOutput( output, NoToneMapping, renderer.outputColorSpace );
|
||||
output = output.context( { inspector: true } );
|
||||
|
||||
const material = new NodeMaterial();
|
||||
material.outputNode = output;
|
||||
|
||||
const quad = new QuadMesh( material );
|
||||
quad.name = 'Viewer - ' + name;
|
||||
|
||||
canvasData = {
|
||||
id,
|
||||
name,
|
||||
path,
|
||||
node,
|
||||
quad,
|
||||
canvasTarget,
|
||||
material
|
||||
};
|
||||
|
||||
this.canvasNodes.set( node, canvasData );
|
||||
|
||||
}
|
||||
|
||||
return canvasData;
|
||||
|
||||
}
|
||||
|
||||
update( inspector ) {
|
||||
|
||||
const renderer = inspector.getRenderer();
|
||||
const nodes = inspector.getNodes();
|
||||
|
||||
if ( nodes.length > 0 ) {
|
||||
|
||||
if ( ! renderer.backend.isWebGPUBackend ) {
|
||||
|
||||
inspector.resolveConsoleOnce( 'warn', 'Inspector: Viewer is only available with WebGPU.' );
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( ! this.isVisible ) {
|
||||
|
||||
this.show();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( ! this.isActive ) return;
|
||||
|
||||
const canvasDataList = nodes.map( node => this.getCanvasDataByNode( renderer, node ) );
|
||||
|
||||
//
|
||||
|
||||
const previousDataList = [ ...this.currentDataList ];
|
||||
|
||||
// remove old
|
||||
|
||||
for ( const canvasData of previousDataList ) {
|
||||
|
||||
if ( this.itemLibrary.has( canvasData.id ) && canvasDataList.indexOf( canvasData ) === - 1 ) {
|
||||
|
||||
const item = this.itemLibrary.get( canvasData.id );
|
||||
const parent = item.parent;
|
||||
|
||||
parent.remove( item );
|
||||
|
||||
if ( this.folderLibrary.has( parent.data[ 0 ] ) && parent.children.length === 0 ) {
|
||||
|
||||
parent.parent.remove( parent );
|
||||
|
||||
this.folderLibrary.delete( parent.data[ 0 ] );
|
||||
|
||||
}
|
||||
|
||||
this.itemLibrary.delete( canvasData.id );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const indexes = {};
|
||||
|
||||
for ( const canvasData of canvasDataList ) {
|
||||
|
||||
const item = this.addNodeItem( canvasData );
|
||||
const previousCanvasTarget = renderer.getCanvasTarget();
|
||||
|
||||
const path = canvasData.path;
|
||||
|
||||
if ( path ) {
|
||||
|
||||
const folder = this.getFolder( path );
|
||||
|
||||
if ( indexes[ path ] === undefined ) {
|
||||
|
||||
indexes[ path ] = 0;
|
||||
|
||||
}
|
||||
|
||||
if ( folder.parent === null || item.parent !== folder || folder.children.indexOf( item ) !== indexes[ path ] ) {
|
||||
|
||||
folder.add( item );
|
||||
|
||||
}
|
||||
|
||||
indexes[ path ] ++;
|
||||
|
||||
} else {
|
||||
|
||||
if ( ! item.parent ) {
|
||||
|
||||
this.nodes.add( item );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.currentDataList = canvasDataList;
|
||||
|
||||
//
|
||||
|
||||
const state = RendererUtils.resetRendererState( renderer );
|
||||
|
||||
renderer.toneMapping = NoToneMapping;
|
||||
renderer.outputColorSpace = LinearSRGBColorSpace;
|
||||
|
||||
renderer.setCanvasTarget( canvasData.canvasTarget );
|
||||
|
||||
canvasData.quad.render( renderer );
|
||||
|
||||
renderer.setCanvasTarget( previousCanvasTarget );
|
||||
|
||||
RendererUtils.restoreRendererState( renderer, state );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { Viewer };
|
||||
Reference in New Issue
Block a user