From bd39bd7de3a1f119ca6e0d757bd994a4a8e05b1e Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Fri, 24 May 2024 23:44:29 -0400 Subject: [PATCH] More examples/jsm updates (#983) * Add examples * Add NodeUtils * Update patch * Add examples * Update patch * Add examples * Updates --- examples-jsm/changes.patch | 281 ++++++++++++++++++++++++++++++++++--- examples-jsm/index.js | 1 + 2 files changed, 262 insertions(+), 20 deletions(-) diff --git a/examples-jsm/changes.patch b/examples-jsm/changes.patch index 58948ff73..306168115 100644 --- a/examples-jsm/changes.patch +++ b/examples-jsm/changes.patch @@ -1,15 +1,16 @@ diff --git a/examples-jsm/examples/nodes/core/Node.ts b/examples-jsm/examples/nodes/core/Node.ts -index 438c44d..19ca69c 100644 +index 438c44d..9bf03bb 100644 --- a/examples-jsm/examples/nodes/core/Node.ts +++ b/examples-jsm/examples/nodes/core/Node.ts -@@ -2,12 +2,31 @@ import { EventDispatcher } from 'three'; +@@ -2,12 +2,30 @@ import { EventDispatcher } from 'three'; import { NodeUpdateType } from './constants.js'; import { getNodeChildren, getCacheKey } from './NodeUtils.js'; import { MathUtils } from 'three'; +import NodeBuilder from './NodeBuilder.js'; +import NodeFrame from './NodeFrame.js'; - const NodeClasses = new Map(); +-const NodeClasses = new Map(); ++const NodeClasses = new Map(); let _nodeId = 0; @@ -24,8 +25,7 @@ index 438c44d..19ca69c 100644 + + version: number; + -+ // TODO -+ // _cacheKey?? ++ _cacheKey: string | null; + _cacheKeyVersion: number; + + readonly isNode: true; @@ -35,7 +35,7 @@ index 438c44d..19ca69c 100644 constructor(nodeType = null) { super(); -@@ -28,7 +47,7 @@ class Node extends EventDispatcher { +@@ -28,7 +46,7 @@ class Node extends EventDispatcher { Object.defineProperty(this, 'id', { value: _nodeId++ }); } @@ -44,7 +44,44 @@ index 438c44d..19ca69c 100644 if (value === true) { this.version++; } -@@ -73,7 +92,7 @@ class Node extends EventDispatcher { +@@ -38,26 +56,26 @@ class Node extends EventDispatcher { + return this.constructor.type; + } + +- onUpdate(callback, updateType) { ++ onUpdate(callback: (this: this, frame: NodeFrame) => void, updateType: NodeUpdateType) { + this.updateType = updateType; + this.update = callback.bind(this.getSelf()); + + return this; + } + +- onFrameUpdate(callback) { ++ onFrameUpdate(callback: (this: this, frame: NodeFrame) => void) { + return this.onUpdate(callback, NodeUpdateType.FRAME); + } + +- onRenderUpdate(callback) { ++ onRenderUpdate(callback: (this: this, frame: NodeFrame) => void) { + return this.onUpdate(callback, NodeUpdateType.RENDER); + } + +- onObjectUpdate(callback) { ++ onObjectUpdate(callback: (this: this, frame: NodeFrame) => void) { + return this.onUpdate(callback, NodeUpdateType.OBJECT); + } + +- onReference(callback) { ++ onReference(callback: (this: this, frame: NodeBuilder | NodeFrame) => this) { + this.updateReference = callback.bind(this.getSelf()); + + return this; +@@ -69,11 +87,11 @@ class Node extends EventDispatcher { + return this.self || this; + } + +- updateReference(/*state*/) { ++ updateReference(state: NodeBuilder | NodeFrame) { return this; } @@ -53,7 +90,16 @@ index 438c44d..19ca69c 100644 return false; } -@@ -106,7 +125,7 @@ class Node extends EventDispatcher { +@@ -87,7 +105,7 @@ class Node extends EventDispatcher { + this.dispatchEvent({ type: 'dispose' }); + } + +- traverse(callback) { ++ traverse(callback: (node: Node) => void) { + callback(this); + + for (const childNode of this.getChildren()) { +@@ -106,7 +124,7 @@ class Node extends EventDispatcher { return this._cacheKey; } @@ -62,7 +108,7 @@ index 438c44d..19ca69c 100644 return this.uuid; } -@@ -118,14 +137,14 @@ class Node extends EventDispatcher { +@@ -118,14 +136,14 @@ class Node extends EventDispatcher { return this.updateBeforeType; } @@ -79,7 +125,7 @@ index 438c44d..19ca69c 100644 const nodeProperties = builder.getNodeProperties(this); if (nodeProperties.outputNode) { -@@ -135,14 +154,14 @@ class Node extends EventDispatcher { +@@ -135,14 +153,14 @@ class Node extends EventDispatcher { return this.nodeType; } @@ -96,7 +142,7 @@ index 438c44d..19ca69c 100644 const nodeProperties = builder.getNodeProperties(this); for (const childNode of this.getChildren()) { -@@ -153,7 +172,7 @@ class Node extends EventDispatcher { +@@ -153,7 +171,7 @@ class Node extends EventDispatcher { return null; } @@ -105,7 +151,7 @@ index 438c44d..19ca69c 100644 // @deprecated, r157 console.warn('THREE.Node: construct() is deprecated. Use setup() instead.'); -@@ -161,14 +180,14 @@ class Node extends EventDispatcher { +@@ -161,14 +179,14 @@ class Node extends EventDispatcher { return this.setup(builder); } @@ -122,16 +168,25 @@ index 438c44d..19ca69c 100644 const usageCount = this.increaseUsage(builder); if (usageCount === 1) { -@@ -184,7 +203,7 @@ class Node extends EventDispatcher { +@@ -177,14 +195,14 @@ class Node extends EventDispatcher { + const nodeProperties = builder.getNodeProperties(this); + + for (const childNode of Object.values(nodeProperties)) { +- if (childNode && childNode.isNode === true) { +- childNode.build(builder); ++ if (childNode && (childNode as Node).isNode === true) { ++ (childNode as Node).build(builder); + } + } } } - generate(builder, output) { -+ generate(builder: NodeBuilder, output?: string | null) { ++ generate(builder: NodeBuilder, output?: string | null): string | null | undefined { const { outputNode } = builder.getNodeProperties(this); if (outputNode && outputNode.isNode === true) { -@@ -192,15 +211,15 @@ class Node extends EventDispatcher { +@@ -192,15 +210,15 @@ class Node extends EventDispatcher { } } @@ -146,10 +201,39 @@ index 438c44d..19ca69c 100644 } - build(builder, output = null) { -+ build(builder: NodeBuilder, output: string | null = null) { ++ build(builder: NodeBuilder, output: string | null = null): string | null { const refNode = this.getShared(builder); if (this !== refNode) { +@@ -235,8 +253,8 @@ class Node extends EventDispatcher { + } + + for (const childNode of Object.values(properties)) { +- if (childNode && childNode.isNode === true) { +- childNode.build(builder); ++ if (childNode && (childNode as Node).isNode === true) { ++ (childNode as Node).build(builder); + } + } + } +@@ -391,7 +409,7 @@ class Node extends EventDispatcher { + + export default Node; + +-export function addNodeClass(type, nodeClass) { ++export function addNodeClass(type: string, nodeClass: typeof Node) { + if (typeof nodeClass !== 'function' || !type) throw new Error(`Node class ${type} is not a class`); + if (NodeClasses.has(type)) { + console.warn(`Redefinition of node class ${type}`); +@@ -402,7 +420,7 @@ export function addNodeClass(type, nodeClass) { + nodeClass.type = type; + } + +-export function createNodeFromType(type) { ++export function createNodeFromType(type: string) { + const Class = NodeClasses.get(type); + + if (Class !== undefined) { diff --git a/examples-jsm/examples/nodes/core/NodeAttribute.ts b/examples-jsm/examples/nodes/core/NodeAttribute.ts index 190fe8c..d873bb2 100644 --- a/examples-jsm/examples/nodes/core/NodeAttribute.ts @@ -170,7 +254,7 @@ index 190fe8c..d873bb2 100644 this.name = name; diff --git a/examples-jsm/examples/nodes/core/NodeBuilder.ts b/examples-jsm/examples/nodes/core/NodeBuilder.ts -index ebdc13f..93203f2 100644 +index ebdc13f..5174db4 100644 --- a/examples-jsm/examples/nodes/core/NodeBuilder.ts +++ b/examples-jsm/examples/nodes/core/NodeBuilder.ts @@ -8,7 +8,7 @@ import NodeCache from './NodeCache.js'; @@ -374,6 +458,60 @@ index ebdc13f..93203f2 100644 return false; } +@@ -332,7 +409,7 @@ class NodeBuilder { + throw new Error(`NodeBuilder: Type '${type}' not found in generate constant attempt.`); + } + +- getType(type) { ++ getType(type: string | null) { + if (type === 'color') return 'vec3'; + + return type; +@@ -378,7 +455,7 @@ class NodeBuilder { + return /mat\d/.test(type); + } + +- isReference(type) { ++ isReference(type: string | null) { + return ( + type === 'void' || + type === 'property' || +@@ -405,7 +482,7 @@ class NodeBuilder { + return 'float'; + } + +- getElementType(type) { ++ getElementType(type: string | null) { + if (type === 'mat2') return 'vec2'; + if (type === 'mat3') return 'vec3'; + if (type === 'mat4') return 'vec4'; +@@ -413,7 +490,7 @@ class NodeBuilder { + return this.getComponentType(type); + } + +- getComponentType(type) { ++ getComponentType(type: string | null) { + type = this.getVectorType(type); + + if (type === 'float' || type === 'bool' || type === 'int' || type === 'uint') return type; +@@ -429,7 +506,7 @@ class NodeBuilder { + return 'float'; + } + +- getVectorType(type) { ++ getVectorType(type: string | null) { + if (type === 'color') return 'vec3'; + if (type === 'texture' || type === 'cubeTexture' || type === 'storageTexture' || type === 'texture3D') + return 'vec4'; +@@ -468,7 +545,7 @@ class NodeBuilder { + return this.getTypeFromLength(itemSize, arrayType); + } + +- getTypeLength(type) { ++ getTypeLength(type: string | null) { + const vecType = this.getVectorType(type); + const vecNum = /vec([2-4])/.exec(vecType); + @@ -515,7 +592,11 @@ class NodeBuilder { return lastStack; } @@ -484,11 +622,20 @@ index ebdc13f..93203f2 100644 const output = node.getNodeType(this); const flowData = this.flowChildNode(node, output); +@@ -940,7 +1026,7 @@ class NodeBuilder { + return createNodeMaterialFromType(type); + } + +- format(snippet, fromType, toType) { ++ format(snippet: string, fromType: string | null, toType: string | null): string { + fromType = this.getVectorType(fromType); + toType = this.getVectorType(toType); + diff --git a/examples-jsm/examples/nodes/core/NodeCache.ts b/examples-jsm/examples/nodes/core/NodeCache.ts -index 96a7e0c..2d6219e 100644 +index 96a7e0c..316e946 100644 --- a/examples-jsm/examples/nodes/core/NodeCache.ts +++ b/examples-jsm/examples/nodes/core/NodeCache.ts -@@ -1,16 +1,47 @@ +@@ -1,16 +1,50 @@ +import Node from './Node.js'; +import NodeAttribute from './NodeAttribute.js'; +import NodeUniform from './NodeUniform.js'; @@ -498,10 +645,11 @@ index 96a7e0c..2d6219e 100644 + let id = 0; -+interface ShaderStageNodeData { ++export interface ShaderStageNodeData { + properties?: + | { + outputNode: Node | null; ++ initialized?: boolean | undefined; + } + | undefined; + bufferAttribute?: NodeAttribute | undefined; @@ -510,6 +658,8 @@ index 96a7e0c..2d6219e 100644 + variable?: NodeVar | undefined; + varying?: NodeVarying | undefined; + code?: NodeCode | undefined; ++ usageCount?: number | undefined; ++ snippet?: string | undefined; +} + +interface NodeData { @@ -649,6 +799,97 @@ index 2918e21..c407d0a 100644 this.isNodeUniform = true; this.name = name; +diff --git a/examples-jsm/examples/nodes/core/NodeUtils.ts b/examples-jsm/examples/nodes/core/NodeUtils.ts +index 16a5f32..6adbec5 100644 +--- a/examples-jsm/examples/nodes/core/NodeUtils.ts ++++ b/examples-jsm/examples/nodes/core/NodeUtils.ts +@@ -1,10 +1,11 @@ + import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three'; ++import Node from './Node.js'; + +-export function getCacheKey(object, force = false) { ++export function getCacheKey(object: object, force = false) { + let cacheKey = '{'; + +- if (object.isNode === true) { +- cacheKey += object.id; ++ if ((object as Node).isNode === true) { ++ cacheKey += (object as Node).id; + } + + for (const { property, childNode } of getNodeChildren(object)) { +@@ -16,36 +17,58 @@ export function getCacheKey(object, force = false) { + return cacheKey; + } + +-export function* getNodeChildren(node, toJSON = false) { ++export interface NodeChild { ++ property: string; ++ index?: number | string; ++ childNode: Node; ++} ++ ++export interface NodeChildWithToJSON { ++ property: string; ++ index?: number | string; ++ childNode: Node | { toJSON: () => unknown }; ++} ++ ++export function getNodeChildren(node: object): Generator; ++export function getNodeChildren(node: object, toJSON: boolean): Generator; ++export function* getNodeChildren(node: object, toJSON = false) { + for (const property in node) { + // Ignore private properties. + if (property.startsWith('_') === true) continue; + +- const object = node[property]; ++ const object = node[property as keyof typeof node] as unknown; + + if (Array.isArray(object) === true) { + for (let i = 0; i < object.length; i++) { +- const child = object[i]; +- +- if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { +- yield { property, index: i, childNode: child }; ++ const child = object[i] as unknown; ++ ++ if ( ++ child && ++ ((child as Node).isNode === true || ++ (toJSON && typeof (child as { toJSON: () => unknown }).toJSON === 'function')) ++ ) { ++ yield { property, index: i, childNode: child as Node | { toJSON: () => unknown } }; + } + } +- } else if (object && object.isNode === true) { +- yield { property, childNode: object }; ++ } else if (object && (object as Node).isNode === true) { ++ yield { property, childNode: object as Node }; + } else if (typeof object === 'object') { + for (const subProperty in object) { +- const child = object[subProperty]; +- +- if (child && (child.isNode === true || (toJSON && typeof child.toJSON === 'function'))) { +- yield { property, index: subProperty, childNode: child }; ++ const child = object[subProperty as keyof typeof object]; ++ ++ if ( ++ child && ++ ((child as Node).isNode === true || ++ (toJSON && typeof (child as { toJSON: () => unknown }).toJSON === 'function')) ++ ) { ++ yield { property, index: subProperty, childNode: child as Node | { toJSON: () => unknown } }; + } + } + } + } + } + +-export function getValueType(value) { ++export function getValueType(value: unknown) { + if (value === undefined || value === null) return null; + + const typeOf = typeof value; diff --git a/examples-jsm/examples/nodes/core/NodeVar.ts b/examples-jsm/examples/nodes/core/NodeVar.ts index e6e935b..8d04ff1 100644 --- a/examples-jsm/examples/nodes/core/NodeVar.ts diff --git a/examples-jsm/index.js b/examples-jsm/index.js index 1efd8d065..4b135bfb8 100644 --- a/examples-jsm/index.js +++ b/examples-jsm/index.js @@ -13,6 +13,7 @@ const files = [ 'nodes/core/NodeKeywords', 'nodes/core/NodeParser', 'nodes/core/NodeUniform', + 'nodes/core/NodeUtils', 'nodes/core/NodeVar', 'nodes/core/NodeVarying', 'nodes/core/constants',