super-three 0.133.5 → 0.135.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/three.js +617 -536
- package/build/three.min.js +1 -1
- package/build/three.module.js +760 -613
- package/examples/fonts/open-sans/open-sans-v15-cyrillic-ext_greek_greek-ext_cyrillic_latin_latin-ext_vietnamese-regular.woff +0 -0
- package/examples/fonts/open-sans/open-sans-v15-cyrillic-ext_greek_greek-ext_cyrillic_latin_latin-ext_vietnamese-regular.woff2 +0 -0
- package/examples/fonts/open-sans/open-sans.css +9 -0
- package/examples/fonts/tabler-icons/fonts/tabler-icons.eot +0 -0
- package/examples/fonts/tabler-icons/fonts/tabler-icons.ttf +0 -0
- package/examples/fonts/tabler-icons/fonts/tabler-icons.woff +0 -0
- package/examples/fonts/tabler-icons/fonts/tabler-icons.woff2 +0 -0
- package/examples/fonts/tabler-icons/tabler-icons.min.css +4 -0
- package/examples/js/controls/ArcballControls.js +68 -27
- package/examples/js/controls/DragControls.js +7 -0
- package/examples/js/controls/OrbitControls.js +5 -36
- package/examples/js/controls/TrackballControls.js +3 -2
- package/examples/js/csm/CSM.js +2 -2
- package/examples/js/csm/CSMFrustum.js +133 -0
- package/examples/js/exporters/GLTFExporter.js +147 -63
- package/examples/js/exporters/USDZExporter.js +45 -26
- package/examples/js/lines/LineMaterial.js +58 -20
- package/examples/js/lines/LineSegments2.js +29 -24
- package/examples/js/loaders/3DMLoader.js +24 -11
- package/examples/js/loaders/3MFLoader.js +2 -2
- package/examples/js/loaders/ColladaLoader.js +61 -3
- package/examples/js/loaders/FBXLoader.js +1 -1
- package/examples/js/loaders/GLTFLoader.js +94 -31
- package/examples/js/loaders/KTX2Loader.js +12 -0
- package/examples/js/loaders/LWOLoader.js +8 -6
- package/examples/js/loaders/LogLuvLoader.js +766 -0
- package/examples/js/loaders/PLYLoader.js +32 -7
- package/examples/js/loaders/RGBELoader.js +2 -1
- package/examples/js/loaders/SVGLoader.js +7 -3
- package/examples/js/loaders/TDSLoader.js +237 -271
- package/examples/js/loaders/lwo/LWO2Parser.js +1 -0
- package/examples/js/loaders/lwo/LWO3Parser.js +4 -2
- package/examples/js/objects/MarchingCubes.js +42 -128
- package/examples/js/renderers/CSS2DRenderer.js +4 -4
- package/examples/js/renderers/CSS3DRenderer.js +4 -4
- package/examples/js/utils/RoughnessMipmapper.js +1 -0
- package/examples/jsm/controls/ArcballControls.js +61 -29
- package/examples/jsm/controls/DragControls.js +7 -0
- package/examples/jsm/controls/OrbitControls.js +9 -51
- package/examples/jsm/controls/TrackballControls.js +1 -1
- package/examples/jsm/csm/CSM.js +3 -3
- package/examples/jsm/csm/{Frustum.js → CSMFrustum.js} +3 -3
- package/examples/jsm/exporters/GLTFExporter.js +160 -74
- package/examples/jsm/exporters/USDZExporter.js +47 -26
- package/examples/jsm/libs/flow.module.js +3218 -0
- package/examples/jsm/libs/lil-gui.module.min.js +8 -0
- package/examples/jsm/libs/rhino3dm/rhino3dm.wasm +0 -0
- package/examples/jsm/lines/LineMaterial.js +59 -23
- package/examples/jsm/lines/LineSegments2.js +22 -18
- package/examples/jsm/loaders/3DMLoader.js +18 -12
- package/examples/jsm/loaders/3MFLoader.js +2 -2
- package/examples/jsm/loaders/ColladaLoader.js +61 -3
- package/examples/jsm/loaders/FBXLoader.js +1 -1
- package/examples/jsm/loaders/GLTFLoader.js +99 -35
- package/examples/jsm/loaders/KTX2Loader.js +19 -0
- package/examples/jsm/loaders/LWOLoader.js +8 -6
- package/examples/jsm/loaders/LogLuvLoader.js +606 -0
- package/examples/jsm/loaders/PLYLoader.js +33 -7
- package/examples/jsm/loaders/SVGLoader.js +7 -4
- package/examples/jsm/loaders/TDSLoader.js +225 -285
- package/examples/jsm/loaders/lwo/LWO2Parser.js +1 -0
- package/examples/jsm/loaders/lwo/LWO3Parser.js +2 -2
- package/examples/jsm/node-editor/NodeEditor.js +455 -0
- package/examples/jsm/node-editor/accessors/NormalEditor.js +30 -0
- package/examples/jsm/node-editor/accessors/PositionEditor.js +30 -0
- package/examples/jsm/node-editor/accessors/UVEditor.js +26 -0
- package/examples/jsm/node-editor/display/BlendEditor.js +43 -0
- package/examples/jsm/node-editor/examples/animate-uv.json +1 -0
- package/examples/jsm/node-editor/examples/fake-top-light.json +1 -0
- package/examples/jsm/node-editor/examples/oscillator-color.json +1 -0
- package/examples/jsm/node-editor/examples/rim.json +1 -0
- package/examples/jsm/node-editor/inputs/ColorEditor.js +91 -0
- package/examples/jsm/node-editor/inputs/FloatEditor.js +24 -0
- package/examples/jsm/node-editor/inputs/SliderEditor.js +68 -0
- package/examples/jsm/node-editor/inputs/Vector2Editor.js +28 -0
- package/examples/jsm/node-editor/inputs/Vector3Editor.js +30 -0
- package/examples/jsm/node-editor/inputs/Vector4Editor.js +37 -0
- package/examples/jsm/node-editor/materials/StandardMaterialEditor.js +69 -0
- package/examples/jsm/node-editor/math/DotEditor.js +36 -0
- package/examples/jsm/node-editor/math/InvertEditor.js +38 -0
- package/examples/jsm/node-editor/math/LimiterEditor.js +48 -0
- package/examples/jsm/node-editor/math/NormalizeEditor.js +26 -0
- package/examples/jsm/node-editor/math/OperatorEditor.js +50 -0
- package/examples/jsm/node-editor/math/PowerEditor.js +34 -0
- package/examples/jsm/node-editor/math/TrigonometryEditor.js +39 -0
- package/examples/jsm/node-editor/procedural/CheckerEditor.js +26 -0
- package/examples/jsm/node-editor/utils/OscillatorEditor.js +42 -0
- package/examples/jsm/node-editor/utils/TimerEditor.js +57 -0
- package/examples/jsm/nodes/materials/StandardNodeMaterial.js +1 -1
- package/examples/jsm/nodes/materials/nodes/StandardNode.js +6 -6
- package/examples/jsm/nodes/utils/ColorSpaceNode.js +1 -49
- package/examples/jsm/objects/MarchingCubes.js +46 -152
- package/examples/jsm/postprocessing/AdaptiveToneMappingPass.js +1 -1
- package/examples/jsm/postprocessing/AfterimagePass.js +1 -1
- package/examples/jsm/postprocessing/BloomPass.js +1 -1
- package/examples/jsm/postprocessing/BokehPass.js +1 -1
- package/examples/jsm/postprocessing/ClearPass.js +1 -1
- package/examples/jsm/postprocessing/CubeTexturePass.js +1 -1
- package/examples/jsm/postprocessing/DotScreenPass.js +1 -1
- package/examples/jsm/postprocessing/EffectComposer.js +3 -3
- package/examples/jsm/postprocessing/FilmPass.js +1 -1
- package/examples/jsm/postprocessing/GlitchPass.js +1 -1
- package/examples/jsm/postprocessing/HalftonePass.js +1 -1
- package/examples/jsm/postprocessing/MaskPass.js +1 -1
- package/examples/jsm/postprocessing/OutlinePass.js +1 -1
- package/examples/jsm/postprocessing/RenderPass.js +1 -1
- package/examples/jsm/postprocessing/SAOPass.js +1 -1
- package/examples/jsm/postprocessing/SMAAPass.js +1 -1
- package/examples/jsm/postprocessing/SSAARenderPass.js +1 -1
- package/examples/jsm/postprocessing/SSAOPass.js +1 -1
- package/examples/jsm/postprocessing/SSRPass.js +1 -1
- package/examples/jsm/postprocessing/SSRrPass.js +1 -1
- package/examples/jsm/postprocessing/SavePass.js +1 -1
- package/examples/jsm/postprocessing/ShaderPass.js +1 -1
- package/examples/jsm/postprocessing/TAARenderPass.js +1 -1
- package/examples/jsm/postprocessing/TexturePass.js +1 -1
- package/examples/jsm/postprocessing/UnrealBloomPass.js +1 -1
- package/examples/jsm/renderers/CSS2DRenderer.js +5 -4
- package/examples/jsm/renderers/CSS3DRenderer.js +5 -4
- package/examples/jsm/renderers/nodes/Nodes.js +14 -13
- package/examples/jsm/renderers/nodes/ShaderNode.js +193 -41
- package/examples/jsm/renderers/nodes/accessors/MaterialNode.js +6 -6
- package/examples/jsm/renderers/nodes/accessors/ModelViewProjectionNode.js +5 -5
- package/examples/jsm/renderers/nodes/accessors/NormalNode.js +14 -3
- package/examples/jsm/renderers/nodes/accessors/PointUVNode.js +3 -3
- package/examples/jsm/renderers/nodes/accessors/PositionNode.js +15 -5
- package/examples/jsm/renderers/nodes/accessors/SkinningNode.js +107 -0
- package/examples/jsm/renderers/nodes/accessors/UVNode.js +7 -5
- package/examples/jsm/renderers/nodes/core/ArrayInputNode.js +3 -3
- package/examples/jsm/renderers/nodes/core/AttributeNode.js +6 -0
- package/examples/jsm/renderers/nodes/core/BypassNode.js +38 -0
- package/examples/jsm/renderers/nodes/core/CodeNode.js +3 -3
- package/examples/jsm/renderers/nodes/core/ContextNode.js +4 -19
- package/examples/jsm/renderers/nodes/core/ExpressionNode.js +13 -2
- package/examples/jsm/renderers/nodes/core/FunctionNode.js +19 -132
- package/examples/jsm/renderers/nodes/core/InputNode.js +13 -3
- package/examples/jsm/renderers/nodes/core/Node.js +32 -10
- package/examples/jsm/renderers/nodes/core/NodeBuilder.js +146 -128
- package/examples/jsm/renderers/nodes/core/NodeFunction.js +22 -0
- package/examples/jsm/renderers/nodes/core/NodeFunctionInput.js +4 -4
- package/examples/jsm/renderers/nodes/core/NodeKeywords.js +18 -179
- package/examples/jsm/renderers/nodes/core/NodeParser.js +11 -0
- package/examples/jsm/renderers/nodes/core/NodeVar.js +2 -2
- package/examples/jsm/renderers/nodes/core/PropertyNode.js +14 -2
- package/examples/jsm/renderers/nodes/core/TempNode.js +10 -13
- package/examples/jsm/renderers/nodes/core/VarNode.js +12 -7
- package/examples/jsm/renderers/nodes/core/VaryNode.js +23 -8
- package/examples/jsm/renderers/nodes/core/constants.js +2 -0
- package/examples/jsm/renderers/nodes/display/ColorSpaceNode.js +47 -25
- package/examples/jsm/renderers/nodes/display/NormalMapNode.js +21 -22
- package/examples/jsm/renderers/nodes/functions/BSDFs.js +64 -101
- package/examples/jsm/renderers/nodes/inputs/BufferNode.js +25 -0
- package/examples/jsm/renderers/nodes/inputs/IntNode.js +17 -0
- package/examples/jsm/renderers/nodes/inputs/TextureNode.js +10 -2
- package/examples/jsm/renderers/nodes/lights/LightContextNode.js +20 -14
- package/examples/jsm/renderers/nodes/lights/LightNode.js +32 -36
- package/examples/jsm/renderers/nodes/math/CondNode.js +60 -0
- package/examples/jsm/renderers/nodes/math/MathNode.js +87 -36
- package/examples/jsm/renderers/nodes/math/OperatorNode.js +124 -31
- package/examples/jsm/renderers/nodes/parsers/GLSLNodeFunction.js +137 -0
- package/examples/jsm/renderers/nodes/parsers/GLSLNodeParser.js +14 -0
- package/examples/jsm/renderers/nodes/parsers/WGSLNodeFunction.js +89 -0
- package/examples/jsm/renderers/nodes/parsers/WGSLNodeParser.js +14 -0
- package/examples/jsm/renderers/nodes/procedural/CheckerNode.js +7 -9
- package/examples/jsm/renderers/nodes/utils/ArrayElementNode.js +31 -0
- package/examples/jsm/renderers/nodes/utils/ConvertNode.js +33 -0
- package/examples/jsm/renderers/nodes/utils/JoinNode.js +7 -7
- package/examples/jsm/renderers/nodes/utils/OscNode.js +58 -0
- package/examples/jsm/renderers/nodes/utils/SplitNode.js +18 -8
- package/examples/jsm/renderers/nodes/utils/SpriteSheetUVNode.js +7 -7
- package/examples/jsm/renderers/webgl/nodes/SlotNode.js +22 -0
- package/examples/jsm/renderers/webgl/nodes/WebGLNodeBuilder.js +191 -94
- package/examples/jsm/renderers/webgl/nodes/WebGLNodes.js +2 -2
- package/examples/jsm/renderers/webgl/nodes/WebGLPhysicalContextNode.js +2 -2
- package/examples/jsm/renderers/webgpu/WebGPUBackground.js +1 -1
- package/examples/jsm/renderers/webgpu/WebGPUBindings.js +3 -3
- package/examples/jsm/renderers/webgpu/WebGPUComputePipelines.js +2 -4
- package/examples/jsm/renderers/webgpu/WebGPUProgrammableStage.js +2 -4
- package/examples/jsm/renderers/webgpu/WebGPURenderPipeline.js +15 -23
- package/examples/jsm/renderers/webgpu/WebGPURenderPipelines.js +3 -5
- package/examples/jsm/renderers/webgpu/WebGPURenderer.js +11 -27
- package/examples/jsm/renderers/webgpu/WebGPUTextureUtils.js +62 -28
- package/examples/jsm/renderers/webgpu/WebGPUTextures.js +34 -27
- package/examples/jsm/renderers/webgpu/constants.js +2 -2
- package/examples/jsm/renderers/webgpu/nodes/WebGPUNodeBuilder.js +430 -98
- package/examples/jsm/renderers/webgpu/nodes/WebGPUNodes.js +1 -1
- package/examples/jsm/utils/RoughnessMipmapper.js +1 -0
- package/examples/jsm/webxr/OculusHandPointerModel.js +6 -6
- package/package.json +10 -10
- package/src/Three.Legacy.js +6 -0
- package/src/Three.js +0 -1
- package/src/cameras/StereoCamera.js +8 -7
- package/src/constants.js +1 -2
- package/src/core/Layers.js +7 -1
- package/src/core/Object3D.js +2 -0
- package/src/extras/PMREMGenerator.js +11 -6
- package/src/loaders/FileLoader.js +89 -152
- package/src/loaders/ImageLoader.js +9 -4
- package/src/loaders/LoaderUtils.js +26 -0
- package/src/loaders/MaterialLoader.js +7 -4
- package/src/loaders/ObjectLoader.js +2 -0
- package/src/materials/Material.js +4 -4
- package/src/materials/MeshPhysicalMaterial.js +20 -14
- package/src/math/MathUtils.js +5 -16
- package/src/renderers/WebGLMultisampleRenderTarget.js +7 -1
- package/src/renderers/WebGLRenderer.js +83 -117
- package/src/renderers/shaders/ShaderChunk/bsdfs.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl.js +0 -27
- package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +0 -1
- package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +19 -6
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +2 -2
- package/src/renderers/shaders/ShaderChunk/transmission_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/transmission_pars_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +13 -5
- package/src/renderers/shaders/ShaderLib/vsm.glsl.js +2 -1
- package/src/renderers/shaders/ShaderLib.js +6 -4
- package/src/renderers/shaders/UniformsLib.js +1 -2
- package/src/renderers/webgl/WebGLExtensions.js +1 -0
- package/src/renderers/webgl/WebGLMaterials.js +27 -15
- package/src/renderers/webgl/WebGLProgram.js +10 -6
- package/src/renderers/webgl/WebGLPrograms.js +17 -12
- package/src/renderers/webgl/WebGLShadowMap.js +14 -5
- package/src/renderers/webgl/WebGLState.js +31 -17
- package/src/renderers/webgl/WebGLTextures.js +188 -51
- package/src/renderers/webgl/WebGLUniforms.js +45 -1
- package/src/renderers/webxr/WebXRManager.js +68 -107
- package/src/textures/Texture.js +6 -0
- package/src/utils.js +37 -1
- package/examples/js/controls/DeviceOrientationControls.js +0 -147
- package/examples/js/libs/dat.gui.min.js +0 -14
- package/examples/jsm/controls/DeviceOrientationControls.js +0 -153
- package/examples/jsm/libs/dat.gui.module.js +0 -3575
- package/examples/jsm/libs/glslang.js +0 -78
- package/examples/jsm/libs/glslang.wasm +0 -0
- package/examples/jsm/renderers/nodes/consts/MathConsts.js +0 -7
- package/examples/jsm/renderers/nodes/core/ConstNode.js +0 -39
- package/examples/jsm/renderers/nodes/core/NodeSlot.js +0 -13
- package/examples/jsm/renderers/nodes/core/StructNode.js +0 -80
- package/examples/jsm/renderers/nodes/core/StructVarNode.js +0 -75
- package/examples/jsm/renderers/nodes/functions/EncodingFunctions.js +0 -99
- package/examples/jsm/renderers/nodes/functions/MathFunctions.js +0 -47
- package/examples/jsm/renderers/webgpu/nodes/ShaderLib.js +0 -152
- package/src/extras/objects/ImmediateRenderObject.js +0 -31
|
@@ -1,75 +1,10 @@
|
|
|
1
|
-
import VarNode from './VarNode.js';
|
|
2
|
-
import PropertyNode from './PropertyNode.js';
|
|
3
|
-
import PositionNode from '../accessors/PositionNode.js';
|
|
4
|
-
import NormalNode from '../accessors/NormalNode.js';
|
|
5
|
-
|
|
6
|
-
import { PI, RECIPROCAL_PI, EPSILON } from '../consts/MathConsts.js';
|
|
7
|
-
import { saturateMacro, whiteComplementMacro } from '../functions/MathFunctions.js';
|
|
8
|
-
|
|
9
1
|
class NodeKeywords {
|
|
10
2
|
|
|
11
|
-
static PI = 'PI';
|
|
12
|
-
static RECIPROCAL_PI = 'RECIPROCAL_PI';
|
|
13
|
-
static EPSILON = 'EPSILON';
|
|
14
|
-
|
|
15
|
-
static Saturate = 'saturate';
|
|
16
|
-
static WhiteComplement = 'whiteComplement';
|
|
17
|
-
|
|
18
|
-
static PositionLocal = 'PositionLocal';
|
|
19
|
-
static PositionWorld = 'PositionWorld';
|
|
20
|
-
static PositionView = 'PositionView';
|
|
21
|
-
static PositionViewDirection = 'PositionViewDirection';
|
|
22
|
-
|
|
23
|
-
static NormalLocal = 'NormalLocal';
|
|
24
|
-
static NormalWorld = 'NormalWorld';
|
|
25
|
-
static NormalView = 'NormalView';
|
|
26
|
-
|
|
27
|
-
static Irradiance = 'Irradiance';
|
|
28
|
-
static ReflectedLightIndirectDiffuse = 'ReflectedLightIndirectDiffuse';
|
|
29
|
-
static ReflectedLightIndirectSpecular = 'ReflectedLightIndirectSpecular';
|
|
30
|
-
static ReflectedLightDirectDiffuse = 'ReflectedLightDirectDiffuse';
|
|
31
|
-
static ReflectedLightDirectSpecular = 'ReflectedLightDirectSpecular';
|
|
32
|
-
|
|
33
|
-
static MaterialDiffuseColor = 'MaterialDiffuseColor';
|
|
34
|
-
|
|
35
|
-
// STANDARD
|
|
36
|
-
static MaterialRoughness = 'MaterialRoughness';
|
|
37
|
-
static MaterialMetalness = 'MaterialMetalness';
|
|
38
|
-
static MaterialSpecularTint = 'MaterialSpecularTint';
|
|
39
|
-
|
|
40
3
|
constructor() {
|
|
41
4
|
|
|
42
|
-
this.keywords = [
|
|
43
|
-
// consts
|
|
44
|
-
NodeKeywords.PI,
|
|
45
|
-
NodeKeywords.RECIPROCAL_PI,
|
|
46
|
-
NodeKeywords.EPSILON,
|
|
47
|
-
// variadic macros
|
|
48
|
-
NodeKeywords.Saturate,
|
|
49
|
-
NodeKeywords.WhiteComplement,
|
|
50
|
-
// nodes
|
|
51
|
-
NodeKeywords.PositionLocal,
|
|
52
|
-
NodeKeywords.PositionWorld,
|
|
53
|
-
NodeKeywords.PositionView,
|
|
54
|
-
NodeKeywords.PositionViewDirection,
|
|
55
|
-
NodeKeywords.NormalLocal,
|
|
56
|
-
NodeKeywords.NormalWorld,
|
|
57
|
-
NodeKeywords.NormalView,
|
|
58
|
-
// vars -> float
|
|
59
|
-
NodeKeywords.MaterialRoughness,
|
|
60
|
-
NodeKeywords.MaterialMetalness,
|
|
61
|
-
// vars -> vec3
|
|
62
|
-
NodeKeywords.Irradiance,
|
|
63
|
-
NodeKeywords.ReflectedLightIndirectDiffuse,
|
|
64
|
-
NodeKeywords.ReflectedLightIndirectSpecular,
|
|
65
|
-
NodeKeywords.ReflectedLightDirectDiffuse,
|
|
66
|
-
NodeKeywords.ReflectedLightDirectSpecular,
|
|
67
|
-
NodeKeywords.MaterialSpecularTint,
|
|
68
|
-
// vars -> vec4
|
|
69
|
-
NodeKeywords.MaterialDiffuseColor
|
|
70
|
-
];
|
|
71
|
-
|
|
5
|
+
this.keywords = [];
|
|
72
6
|
this.nodes = [];
|
|
7
|
+
this.keywordsCallback = {};
|
|
73
8
|
|
|
74
9
|
}
|
|
75
10
|
|
|
@@ -77,120 +12,24 @@ class NodeKeywords {
|
|
|
77
12
|
|
|
78
13
|
let node = this.nodes[ name ];
|
|
79
14
|
|
|
80
|
-
if ( node === undefined ) {
|
|
81
|
-
|
|
82
|
-
switch ( name ) {
|
|
83
|
-
|
|
84
|
-
case NodeKeywords.PI:
|
|
85
|
-
|
|
86
|
-
node = PI;
|
|
87
|
-
|
|
88
|
-
break;
|
|
89
|
-
|
|
90
|
-
case NodeKeywords.RECIPROCAL_PI:
|
|
91
|
-
|
|
92
|
-
node = RECIPROCAL_PI;
|
|
93
|
-
|
|
94
|
-
break;
|
|
95
|
-
|
|
96
|
-
case NodeKeywords.EPSILON:
|
|
97
|
-
|
|
98
|
-
node = EPSILON;
|
|
99
|
-
|
|
100
|
-
break;
|
|
101
|
-
|
|
102
|
-
case NodeKeywords.Saturate:
|
|
103
|
-
|
|
104
|
-
node = saturateMacro;
|
|
105
|
-
|
|
106
|
-
break;
|
|
107
|
-
|
|
108
|
-
case NodeKeywords.WhiteComplement:
|
|
109
|
-
|
|
110
|
-
node = whiteComplementMacro;
|
|
111
|
-
|
|
112
|
-
break;
|
|
113
|
-
|
|
114
|
-
case NodeKeywords.PositionLocal:
|
|
115
|
-
|
|
116
|
-
node = new VarNode( new PositionNode( PositionNode.LOCAL ), name );
|
|
117
|
-
|
|
118
|
-
break;
|
|
119
|
-
|
|
120
|
-
case NodeKeywords.PositionWorld:
|
|
121
|
-
|
|
122
|
-
node = new VarNode( new PositionNode( PositionNode.WORLD ), name );
|
|
15
|
+
if ( node === undefined && this.keywordsCallback[ name ] !== undefined ) {
|
|
123
16
|
|
|
124
|
-
|
|
17
|
+
node = this.keywordsCallback[ name ]( name );
|
|
125
18
|
|
|
126
|
-
|
|
19
|
+
this.nodes[ name ] = node;
|
|
127
20
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
break;
|
|
131
|
-
|
|
132
|
-
case NodeKeywords.PositionViewDirection:
|
|
133
|
-
|
|
134
|
-
node = new VarNode( new PositionNode( PositionNode.VIEW_DIRECTION ), name );
|
|
135
|
-
|
|
136
|
-
break;
|
|
137
|
-
|
|
138
|
-
case NodeKeywords.NormalLocal:
|
|
139
|
-
|
|
140
|
-
node = new VarNode( new NormalNode( NormalNode.LOCAL ), name );
|
|
141
|
-
|
|
142
|
-
break;
|
|
143
|
-
|
|
144
|
-
case NodeKeywords.NormalWorld:
|
|
145
|
-
|
|
146
|
-
node = new VarNode( new NormalNode( NormalNode.WORLD ), name );
|
|
147
|
-
|
|
148
|
-
break;
|
|
149
|
-
|
|
150
|
-
case NodeKeywords.NormalView:
|
|
151
|
-
|
|
152
|
-
node = new VarNode( new NormalNode( NormalNode.VIEW ), name );
|
|
153
|
-
|
|
154
|
-
break;
|
|
155
|
-
|
|
156
|
-
// floats properties
|
|
157
|
-
case NodeKeywords.MaterialRoughness:
|
|
158
|
-
case NodeKeywords.MaterialMetalness:
|
|
159
|
-
|
|
160
|
-
node = new PropertyNode( name, 'float' );
|
|
161
|
-
|
|
162
|
-
break;
|
|
163
|
-
|
|
164
|
-
// vec3 properties
|
|
165
|
-
case NodeKeywords.Irradiance:
|
|
166
|
-
case NodeKeywords.ReflectedLightIndirectDiffuse:
|
|
167
|
-
case NodeKeywords.ReflectedLightIndirectSpecular:
|
|
168
|
-
case NodeKeywords.ReflectedLightDirectDiffuse:
|
|
169
|
-
case NodeKeywords.ReflectedLightDirectSpecular:
|
|
170
|
-
case NodeKeywords.MaterialSpecularTint:
|
|
171
|
-
|
|
172
|
-
node = new PropertyNode( name, 'vec3' );
|
|
173
|
-
|
|
174
|
-
break;
|
|
175
|
-
|
|
176
|
-
// vec4 properties
|
|
177
|
-
case NodeKeywords.MaterialDiffuseColor:
|
|
178
|
-
|
|
179
|
-
node = new PropertyNode( name, 'vec4' );
|
|
180
|
-
|
|
181
|
-
break;
|
|
182
|
-
|
|
183
|
-
}
|
|
21
|
+
}
|
|
184
22
|
|
|
185
|
-
|
|
23
|
+
return node;
|
|
186
24
|
|
|
187
|
-
|
|
25
|
+
}
|
|
188
26
|
|
|
189
|
-
|
|
27
|
+
addKeyword( name, callback ) {
|
|
190
28
|
|
|
191
|
-
|
|
29
|
+
this.keywords.push( name );
|
|
30
|
+
this.keywordsCallback[ name ] = callback;
|
|
192
31
|
|
|
193
|
-
return
|
|
32
|
+
return this;
|
|
194
33
|
|
|
195
34
|
}
|
|
196
35
|
|
|
@@ -202,7 +41,7 @@ class NodeKeywords {
|
|
|
202
41
|
|
|
203
42
|
const codeKeywords = code.match( regExp );
|
|
204
43
|
|
|
205
|
-
const
|
|
44
|
+
const keywordNodes = [];
|
|
206
45
|
|
|
207
46
|
if ( codeKeywords !== null ) {
|
|
208
47
|
|
|
@@ -210,9 +49,9 @@ class NodeKeywords {
|
|
|
210
49
|
|
|
211
50
|
const node = this.getNode( keyword );
|
|
212
51
|
|
|
213
|
-
if (
|
|
52
|
+
if ( node !== undefined && keywordNodes.indexOf( node ) === - 1 ) {
|
|
214
53
|
|
|
215
|
-
|
|
54
|
+
keywordNodes.push( node );
|
|
216
55
|
|
|
217
56
|
}
|
|
218
57
|
|
|
@@ -220,15 +59,15 @@ class NodeKeywords {
|
|
|
220
59
|
|
|
221
60
|
}
|
|
222
61
|
|
|
223
|
-
return
|
|
62
|
+
return keywordNodes;
|
|
224
63
|
|
|
225
64
|
}
|
|
226
65
|
|
|
227
66
|
include( builder, code ) {
|
|
228
67
|
|
|
229
|
-
const
|
|
68
|
+
const keywordNodes = this.parse( code );
|
|
230
69
|
|
|
231
|
-
for ( const keywordNode of
|
|
70
|
+
for ( const keywordNode of keywordNodes ) {
|
|
232
71
|
|
|
233
72
|
keywordNode.build( builder );
|
|
234
73
|
|
|
@@ -2,7 +2,7 @@ import Node from './Node.js';
|
|
|
2
2
|
|
|
3
3
|
class PropertyNode extends Node {
|
|
4
4
|
|
|
5
|
-
constructor( name, nodeType ) {
|
|
5
|
+
constructor( name = null, nodeType = 'vec4' ) {
|
|
6
6
|
|
|
7
7
|
super( nodeType );
|
|
8
8
|
|
|
@@ -10,10 +10,22 @@ class PropertyNode extends Node {
|
|
|
10
10
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
getHash( builder ) {
|
|
14
|
+
|
|
15
|
+
return this.name || super.getHash( builder );
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
generate( builder ) {
|
|
14
20
|
|
|
15
21
|
const nodeVary = builder.getVarFromNode( this, this.getNodeType( builder ) );
|
|
16
|
-
|
|
22
|
+
const name = this.name;
|
|
23
|
+
|
|
24
|
+
if ( name !== null ) {
|
|
25
|
+
|
|
26
|
+
nodeVary.name = name;
|
|
27
|
+
|
|
28
|
+
}
|
|
17
29
|
|
|
18
30
|
return builder.getPropertyName( nodeVary );
|
|
19
31
|
|
|
@@ -10,35 +10,32 @@ class TempNode extends Node {
|
|
|
10
10
|
|
|
11
11
|
build( builder, output ) {
|
|
12
12
|
|
|
13
|
-
const type = builder.getVectorType( this.getNodeType( builder ) );
|
|
13
|
+
const type = builder.getVectorType( this.getNodeType( builder, output ) );
|
|
14
14
|
|
|
15
|
-
if ( type !== 'void' ) {
|
|
16
|
-
|
|
17
|
-
const nodeVar = builder.getVarFromNode( this, type );
|
|
18
|
-
const propertyName = builder.getPropertyName( nodeVar );
|
|
15
|
+
if ( builder.context.temp !== false && type !== 'void ' && output !== 'void' ) {
|
|
19
16
|
|
|
20
17
|
const nodeData = builder.getDataFromNode( this );
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
if ( nodeData.snippet === undefined ) {
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
const snippet = super.build( builder, type );
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
const nodeVar = builder.getVarFromNode( this, type );
|
|
24
|
+
const propertyName = builder.getPropertyName( nodeVar );
|
|
27
25
|
|
|
28
26
|
builder.addFlowCode( `${propertyName} = ${snippet}` );
|
|
29
27
|
|
|
30
28
|
nodeData.snippet = snippet;
|
|
29
|
+
nodeData.propertyName = propertyName;
|
|
31
30
|
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
return builder.format( propertyName, type, output );
|
|
35
|
-
|
|
36
|
-
} else {
|
|
37
|
-
|
|
38
|
-
return super.build( builder, output );
|
|
33
|
+
return builder.format( nodeData.propertyName, type, output );
|
|
39
34
|
|
|
40
35
|
}
|
|
41
36
|
|
|
37
|
+
return super.build( builder, output );
|
|
38
|
+
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
}
|
|
@@ -2,32 +2,37 @@ import Node from './Node.js';
|
|
|
2
2
|
|
|
3
3
|
class VarNode extends Node {
|
|
4
4
|
|
|
5
|
-
constructor(
|
|
5
|
+
constructor( node, name = null, nodeType = null ) {
|
|
6
6
|
|
|
7
7
|
super( nodeType );
|
|
8
8
|
|
|
9
|
-
this.
|
|
9
|
+
this.node = node;
|
|
10
10
|
this.name = name;
|
|
11
11
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
getHash( builder ) {
|
|
15
|
+
|
|
16
|
+
return this.name || super.getHash( builder );
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
getNodeType( builder ) {
|
|
15
21
|
|
|
16
|
-
return super.getNodeType( builder ) || this.
|
|
22
|
+
return super.getNodeType( builder ) || this.node.getNodeType( builder );
|
|
17
23
|
|
|
18
24
|
}
|
|
19
25
|
|
|
20
26
|
generate( builder ) {
|
|
21
27
|
|
|
22
28
|
const type = builder.getVectorType( this.getNodeType( builder ) );
|
|
29
|
+
const node = this.node;
|
|
23
30
|
const name = this.name;
|
|
24
|
-
const value = this.value;
|
|
25
31
|
|
|
32
|
+
const snippet = node.build( builder, type );
|
|
26
33
|
const nodeVar = builder.getVarFromNode( this, type );
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if ( name !== '' ) {
|
|
35
|
+
if ( name !== null ) {
|
|
31
36
|
|
|
32
37
|
nodeVar.name = name;
|
|
33
38
|
|
|
@@ -3,11 +3,18 @@ import { NodeShaderStage } from './constants.js';
|
|
|
3
3
|
|
|
4
4
|
class VaryNode extends Node {
|
|
5
5
|
|
|
6
|
-
constructor(
|
|
6
|
+
constructor( node, name = null ) {
|
|
7
7
|
|
|
8
8
|
super();
|
|
9
9
|
|
|
10
|
-
this.
|
|
10
|
+
this.node = node;
|
|
11
|
+
this.name = name;
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
getHash( builder ) {
|
|
16
|
+
|
|
17
|
+
return this.name || super.getHash( builder );
|
|
11
18
|
|
|
12
19
|
}
|
|
13
20
|
|
|
@@ -15,22 +22,30 @@ class VaryNode extends Node {
|
|
|
15
22
|
|
|
16
23
|
// VaryNode is auto type
|
|
17
24
|
|
|
18
|
-
return this.
|
|
25
|
+
return this.node.getNodeType( builder );
|
|
19
26
|
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
generate( builder ) {
|
|
23
30
|
|
|
24
31
|
const type = this.getNodeType( builder );
|
|
25
|
-
const
|
|
32
|
+
const node = this.node;
|
|
33
|
+
const name = this.name;
|
|
26
34
|
|
|
27
35
|
const nodeVary = builder.getVaryFromNode( this, type );
|
|
28
|
-
const propertyName = builder.getPropertyName( nodeVary );
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
if ( name !== null ) {
|
|
38
|
+
|
|
39
|
+
nodeVary.name = name;
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const propertyName = builder.getPropertyName( nodeVary, NodeShaderStage.Vertex );
|
|
44
|
+
|
|
45
|
+
// force node run in vertex stage
|
|
46
|
+
builder.flowNodeFromShaderStage( NodeShaderStage.Vertex, node, type, propertyName );
|
|
32
47
|
|
|
33
|
-
return
|
|
48
|
+
return builder.getPropertyName( nodeVary );
|
|
34
49
|
|
|
35
50
|
}
|
|
36
51
|
|
|
@@ -1,9 +1,36 @@
|
|
|
1
1
|
import TempNode from '../core/Node.js';
|
|
2
|
-
import
|
|
3
|
-
import * as EncodingFunctions from '../functions/EncodingFunctions.js';
|
|
2
|
+
import { ShaderNode, vec3, pow, mul, add, mix, join, lessThanEqual } from '../ShaderNode.js';
|
|
4
3
|
|
|
5
|
-
import { LinearEncoding,
|
|
6
|
-
|
|
4
|
+
import { LinearEncoding,
|
|
5
|
+
sRGBEncoding/*, RGBEEncoding, RGBM7Encoding, RGBM16Encoding,
|
|
6
|
+
RGBDEncoding, GammaEncoding*/ } from 'three';
|
|
7
|
+
|
|
8
|
+
export const LinearToLinear = new ShaderNode( ( inputs ) => {
|
|
9
|
+
|
|
10
|
+
return inputs.value;
|
|
11
|
+
|
|
12
|
+
} );
|
|
13
|
+
|
|
14
|
+
export const sRGBToLinear = new ShaderNode( ( inputs ) => {
|
|
15
|
+
|
|
16
|
+
const { value } = inputs;
|
|
17
|
+
|
|
18
|
+
const rgb = value.rgb;
|
|
19
|
+
|
|
20
|
+
const a = pow( add( mul( rgb, 0.9478672986 ), vec3( 0.0521327014 ) ), vec3( 2.4 ) );
|
|
21
|
+
const b = mul( rgb, 0.0773993808 );
|
|
22
|
+
const factor = vec3( lessThanEqual( rgb, vec3( 0.04045 ) ) );
|
|
23
|
+
|
|
24
|
+
const rgbResult = mix( a, b, factor );
|
|
25
|
+
|
|
26
|
+
return join( rgbResult.r, rgbResult.g, rgbResult.b, value.a );
|
|
27
|
+
|
|
28
|
+
} );
|
|
29
|
+
|
|
30
|
+
const EncodingLib = {
|
|
31
|
+
LinearToLinear,
|
|
32
|
+
sRGBToLinear
|
|
33
|
+
};
|
|
7
34
|
|
|
8
35
|
function getEncodingComponents ( encoding ) {
|
|
9
36
|
|
|
@@ -13,6 +40,7 @@ function getEncodingComponents ( encoding ) {
|
|
|
13
40
|
return [ 'Linear' ];
|
|
14
41
|
case sRGBEncoding:
|
|
15
42
|
return [ 'sRGB' ];
|
|
43
|
+
/*
|
|
16
44
|
case RGBEEncoding:
|
|
17
45
|
return [ 'RGBE' ];
|
|
18
46
|
case RGBM7Encoding:
|
|
@@ -23,9 +51,7 @@ function getEncodingComponents ( encoding ) {
|
|
|
23
51
|
return [ 'RGBD', new FloatNode( 256.0 ).setConst( true ) ];
|
|
24
52
|
case GammaEncoding:
|
|
25
53
|
return [ 'Gamma', new CodeNode( 'float( GAMMA_FACTOR )' ) ];
|
|
26
|
-
|
|
27
|
-
return [ 'LogLuv' ];
|
|
28
|
-
|
|
54
|
+
*/
|
|
29
55
|
}
|
|
30
56
|
|
|
31
57
|
}
|
|
@@ -34,11 +60,11 @@ class ColorSpaceNode extends TempNode {
|
|
|
34
60
|
|
|
35
61
|
static LINEAR_TO_LINEAR = 'LinearToLinear';
|
|
36
62
|
|
|
37
|
-
static GAMMA_TO_LINEAR = 'GammaToLinear';
|
|
38
|
-
static LINEAR_TO_GAMMA = 'LinearToGamma';
|
|
39
|
-
|
|
40
63
|
static SRGB_TO_LINEAR = 'sRGBToLinear';
|
|
41
64
|
static LINEAR_TO_SRGB = 'LinearTosRGB';
|
|
65
|
+
/*
|
|
66
|
+
static GAMMA_TO_LINEAR = 'GammaToLinear';
|
|
67
|
+
static LINEAR_TO_GAMMA = 'LinearToGamma';
|
|
42
68
|
|
|
43
69
|
static RGBE_TO_LINEAR = 'RGBEToLinear';
|
|
44
70
|
static LINEAR_TO_RGBE = 'LinearToRGBE';
|
|
@@ -48,17 +74,14 @@ class ColorSpaceNode extends TempNode {
|
|
|
48
74
|
|
|
49
75
|
static RGBD_TO_LINEAR = 'RGBDToLinear';
|
|
50
76
|
static LINEAR_TO_RGBD = 'LinearToRGBD';
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
static LOG_LUV_TO_LINEAR = 'LogLuvToLinear';
|
|
54
|
-
|
|
55
|
-
constructor( method, input ) {
|
|
77
|
+
*/
|
|
78
|
+
constructor( method, node ) {
|
|
56
79
|
|
|
57
80
|
super( 'vec4' );
|
|
58
81
|
|
|
59
82
|
this.method = method;
|
|
60
83
|
|
|
61
|
-
this.
|
|
84
|
+
this.node = node;
|
|
62
85
|
this.factor = null;
|
|
63
86
|
|
|
64
87
|
}
|
|
@@ -90,22 +113,21 @@ class ColorSpaceNode extends TempNode {
|
|
|
90
113
|
const type = this.getNodeType( builder );
|
|
91
114
|
|
|
92
115
|
const method = this.method;
|
|
93
|
-
const
|
|
116
|
+
const node = this.node;
|
|
94
117
|
|
|
95
118
|
if ( method !== ColorSpaceNode.LINEAR_TO_LINEAR ) {
|
|
96
119
|
|
|
97
|
-
const encodingFunctionNode =
|
|
98
|
-
|
|
99
|
-
const encodingFunctionCallNode = encodingFunctionNode.call( {
|
|
100
|
-
value: input,
|
|
101
|
-
factor: this.factor
|
|
102
|
-
} );
|
|
120
|
+
const encodingFunctionNode = EncodingLib[ method ];
|
|
121
|
+
const factor = this.factor;
|
|
103
122
|
|
|
104
|
-
return
|
|
123
|
+
return encodingFunctionNode( {
|
|
124
|
+
value: node,
|
|
125
|
+
factor
|
|
126
|
+
} ).build( builder, type );
|
|
105
127
|
|
|
106
128
|
} else {
|
|
107
129
|
|
|
108
|
-
return
|
|
130
|
+
return node.build( builder, type );
|
|
109
131
|
|
|
110
132
|
}
|
|
111
133
|
|
|
@@ -5,46 +5,45 @@ import MathNode from '../math/MathNode.js';
|
|
|
5
5
|
import OperatorNode from '../math/OperatorNode.js';
|
|
6
6
|
import FloatNode from '../inputs/FloatNode.js';
|
|
7
7
|
import TempNode from '../core/TempNode.js';
|
|
8
|
-
import FunctionNode from '../core/FunctionNode.js';
|
|
9
8
|
import ModelNode from '../accessors/ModelNode.js';
|
|
9
|
+
import { ShaderNode, cond, add, mul, dFdx, dFdy, cross, max, dot, normalize, inversesqrt, equal } from '../ShaderNode.js';
|
|
10
10
|
|
|
11
11
|
import { TangentSpaceNormalMap, ObjectSpaceNormalMap } from 'three';
|
|
12
12
|
|
|
13
13
|
// Normal Mapping Without Precomputed Tangents
|
|
14
14
|
// http://www.thetenthplanet.de/archives/1180
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
vec3 ( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection, const in vec2 uv ) {
|
|
16
|
+
const perturbNormal2ArbNode = new ShaderNode( ( inputs ) => {
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
const { eye_pos, surf_norm, mapN, faceDirection, uv } = inputs;
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const q0 = dFdx( eye_pos.xyz );
|
|
21
|
+
const q1 = dFdy( eye_pos.xyz );
|
|
22
|
+
const st0 = dFdx( uv.st );
|
|
23
|
+
const st1 = dFdy( uv.st );
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
const N = surf_norm; // normalized
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
const q1perp = cross( q1, N );
|
|
28
|
+
const q0perp = cross( N, q0 );
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const T = add( mul( q1perp, st0.x ), mul( q0perp, st1.x ) );
|
|
31
|
+
const B = add( mul( q1perp, st0.y ), mul( q0perp, st1.y ) );
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const det = max( dot( T, T ), dot( B, B ) );
|
|
34
|
+
const scale = cond( equal( det, 0 ), 0, mul( faceDirection, inversesqrt( det ) ) );
|
|
36
35
|
|
|
37
|
-
return normalize( T
|
|
36
|
+
return normalize( add( mul( T, mul( mapN.x, scale ) ), mul( B, mul( mapN.y, scale ) ), mul( N, mapN.z ) ) );
|
|
38
37
|
|
|
39
|
-
}
|
|
38
|
+
} );
|
|
40
39
|
|
|
41
40
|
class NormalMapNode extends TempNode {
|
|
42
41
|
|
|
43
|
-
constructor(
|
|
42
|
+
constructor( node ) {
|
|
44
43
|
|
|
45
44
|
super( 'vec3' );
|
|
46
45
|
|
|
47
|
-
this.
|
|
46
|
+
this.node = node;
|
|
48
47
|
|
|
49
48
|
this.normalMapType = TangentSpaceNormalMap;
|
|
50
49
|
|
|
@@ -56,7 +55,7 @@ class NormalMapNode extends TempNode {
|
|
|
56
55
|
|
|
57
56
|
const normalMapType = this.normalMapType;
|
|
58
57
|
|
|
59
|
-
const normalOP = new OperatorNode( '*', this.
|
|
58
|
+
const normalOP = new OperatorNode( '*', this.node, new FloatNode( 2.0 ).setConst( true ) );
|
|
60
59
|
const normalMap = new OperatorNode( '-', normalOP, new FloatNode( 1.0 ).setConst( true ) );
|
|
61
60
|
|
|
62
61
|
if ( normalMapType === ObjectSpaceNormalMap ) {
|
|
@@ -69,7 +68,7 @@ class NormalMapNode extends TempNode {
|
|
|
69
68
|
|
|
70
69
|
} else if ( normalMapType === TangentSpaceNormalMap ) {
|
|
71
70
|
|
|
72
|
-
const perturbNormal2ArbCall =
|
|
71
|
+
const perturbNormal2ArbCall = perturbNormal2ArbNode( {
|
|
73
72
|
eye_pos: new PositionNode( PositionNode.VIEW ),
|
|
74
73
|
surf_norm: new NormalNode( NormalNode.VIEW ),
|
|
75
74
|
mapN: normalMap,
|
|
@@ -78,7 +77,7 @@ class NormalMapNode extends TempNode {
|
|
|
78
77
|
} );
|
|
79
78
|
|
|
80
79
|
return perturbNormal2ArbCall.build( builder, type );
|
|
81
|
-
|
|
80
|
+
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
}
|