From 3ccfbde749ec5ade3f77b33b622ba3d856e581c5 Mon Sep 17 00:00:00 2001 From: M-II-R Date: Sat, 8 Mar 2025 10:17:02 +0000 Subject: [PATCH] Automated Extension submission for issue #1574 --- extensions/community/Water3D.json | 554 ++++++++++++++++++++++++++++++ 1 file changed, 554 insertions(+) create mode 100644 extensions/community/Water3D.json diff --git a/extensions/community/Water3D.json b/extensions/community/Water3D.json new file mode 100644 index 000000000..21aa4d524 --- /dev/null +++ b/extensions/community/Water3D.json @@ -0,0 +1,554 @@ +{ + "author": "", + "category": "Visual effect", + "extensionNamespace": "", + "fullName": "Water3D", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXdhdmVzIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTIwLDEySDIyVjE0SDIwQzE4LjYyLDE0IDE3LjI2LDEzLjY1IDE2LDEzQzEzLjUsMTQuMyAxMC41LDE0LjMgOCwxM0M2Ljc0LDEzLjY1IDUuMzcsMTQgNCwxNEgyVjEySDRDNS4zOSwxMiA2Ljc4LDExLjUzIDgsMTAuNjdDMTAuNDQsMTIuMzggMTMuNTYsMTIuMzggMTYsMTAuNjdDMTcuMjIsMTEuNTMgMTguNjEsMTIgMjAsMTJNMjAsNkgyMlY4SDIwQzE4LjYyLDggMTcuMjYsNy42NSAxNiw3QzEzLjUsOC4zIDEwLjUsOC4zIDgsN0M2Ljc0LDcuNjUgNS4zNyw4IDQsOEgyVjZINEM1LjM5LDYgNi43OCw1LjUzIDgsNC42N0MxMC40NCw2LjM4IDEzLjU2LDYuMzggMTYsNC42N0MxNy4yMiw1LjUzIDE4LjYxLDYgMjAsNk0yMCwxOEgyMlYyMEgyMEMxOC42MiwyMCAxNy4yNiwxOS42NSAxNiwxOUMxMy41LDIwLjMgMTAuNSwyMC4zIDgsMTlDNi43NCwxOS42NSA1LjM3LDIwIDQsMjBIMlYxOEg0QzUuMzksMTggNi43OCwxNy41MyA4LDE2LjY3QzEwLjQ0LDE4LjM4IDEzLjU2LDE4LjM4IDE2LDE2LjY3QzE3LjIyLDE3LjUzIDE4LjYxLDE4IDIwLDE4WiIgLz48L3N2Zz4=", + "name": "Water3D", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/b3a2b134aedcce6a3ae5e6f0342ad4a9bb9c19d234d2207ac42087df9a919a6d_waves.svg", + "shortDescription": "Extension for creating 3D water.", + "version": "1.0.0", + "description": "With this extension you can create fnd manipulate 3D objects representing water. You can create, move and delete these objects.", + "tags": [ + "water", + "3d" + ], + "authorIds": [ + "iCuOTzgvSYOOXr4HW0sFJLIaP082" + ], + "dependencies": [], + "globalVariables": [], + "sceneVariables": [], + "eventsFunctions": [ + { + "description": "Create 3D water.", + "fullName": "Create water", + "functionType": "Action", + "name": "CreateWater", + "sentence": "Create 3D water with name: _PARAM1_, position: _PARAM2_, _PARAM3_, _PARAM4_, width: _PARAM5_, height: _PARAM6_, texture width: _PARAM7_, texture height: _PARAM8_, normals texture: _PARAM9_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/*", + "\tWater from: https://github.com/mrdoob/three.js/blob/02a6845f1f1d6b15f27becc8bb92da663dd695a1/examples/jsm/objects/Water.js#L30", + "*/", + "class Water extends THREE.Mesh {", + "", + "\tconstructor( geometry, options = {} ) {", + "", + "\t\tsuper( geometry );", + "", + "\t\tthis.isWater = true;", + "", + "\t\tconst scope = this;", + "", + "\t\tconst textureWidth = options.textureWidth !== undefined ? options.textureWidth : 512;", + "\t\tconst textureHeight = options.textureHeight !== undefined ? options.textureHeight : 512;", + "", + "\t\tconst clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;", + "\t\tconst alpha = options.alpha !== undefined ? options.alpha : 1.0;", + "\t\tconst time = options.time !== undefined ? options.time : 0.0;", + "\t\tconst normalSampler = options.waterNormals !== undefined ? options.waterNormals : new THREE.TextureLoader().load( 'https://threejs.org/examples/textures/waternormals.jpg', function(texture ) {texture.wrapS = texture.wrapT = THREE.RepeatWrapping;} );", + "\t\tconst sunDirection = options.sunDirection !== undefined ? options.sunDirection : new THREE.Vector3( 0.70707, 0.70707, 0.0 );", + "\t\tconst sunColor = new THREE.Color( options.sunColor !== undefined ? options.sunColor : 0xffffff );", + "\t\tconst waterColor = new THREE.Color( options.waterColor !== undefined ? options.waterColor : 0x7F7F7F );", + "\t\tconst eye = options.eye !== undefined ? options.eye : new THREE.Vector3( 0, 0, 0 );", + "\t\tconst distortionScale = options.distortionScale !== undefined ? options.distortionScale : 20.0;", + "\t\tconst side = options.side !== undefined ? options.side : THREE.FrontSide;", + "\t\tconst fog = options.fog !== undefined ? options.fog : false;", + "", + "\t\t//", + "", + "\t\tconst mirrorPlane = new THREE.Plane();", + "\t\tconst normal = new THREE.Vector3();", + "\t\tconst mirrorWorldPosition = new THREE.Vector3();", + "\t\tconst cameraWorldPosition = new THREE.Vector3();", + "\t\tconst rotationMatrix = new THREE.Matrix4();", + "\t\tconst lookAtPosition = new THREE.Vector3( 0, 0, - 1 );", + "\t\tconst clipPlane = new THREE.Vector4();", + "", + "\t\tconst view = new THREE.Vector3();", + "\t\tconst target = new THREE.Vector3();", + "\t\tconst q = new THREE.Vector4();", + "", + "\t\tconst textureMatrix = new THREE.Matrix4();", + "", + "\t\tconst mirrorCamera = new THREE.PerspectiveCamera();", + "", + "\t\tconst renderTarget = new THREE.WebGLRenderTarget( textureWidth, textureHeight );", + "", + "\t\tconst mirrorShader = {", + "", + "\t\t\tname: 'MirrorShader',", + "", + "\t\t\tuniforms: THREE.UniformsUtils.merge( [", + "\t\t\t\tTHREE.UniformsLib[ 'fog' ],", + "\t\t\t\tTHREE.UniformsLib[ 'lights' ],", + "\t\t\t\t{", + "\t\t\t\t\t'normalSampler': { value: null },", + "\t\t\t\t\t'mirrorSampler': { value: null },", + "\t\t\t\t\t'alpha': { value: 1.0 },", + "\t\t\t\t\t'time': { value: 0.0 },", + "\t\t\t\t\t'size': { value: 1.0 },", + "\t\t\t\t\t'distortionScale': { value: 20.0 },", + "\t\t\t\t\t'textureMatrix': { value: new THREE.Matrix4() },", + "\t\t\t\t\t'sunColor': { value: new THREE.Color( 0x7F7F7F ) },", + "\t\t\t\t\t'sunDirection': { value: new THREE.Vector3( 0.70707, 0.70707, 0 ) },", + "\t\t\t\t\t'eye': { value: new THREE.Vector3() },", + "\t\t\t\t\t'waterColor': { value: new THREE.Color( 0x555555 ) }", + "\t\t\t\t}", + "\t\t\t] ),", + "", + "\t\t\tvertexShader: /* glsl */`", + "\t\t\t\tuniform mat4 textureMatrix;", + "\t\t\t\tuniform float time;", + "", + "\t\t\t\tvarying vec4 mirrorCoord;", + "\t\t\t\tvarying vec4 worldPosition;", + "", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "", + "\t\t\t\tvoid main() {", + "\t\t\t\t\tmirrorCoord = modelMatrix * vec4( position, 1.0 );", + "\t\t\t\t\tworldPosition = mirrorCoord.xyzw;", + "\t\t\t\t\tmirrorCoord = textureMatrix * mirrorCoord;", + "\t\t\t\t\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", + "\t\t\t\t\tgl_Position = projectionMatrix * mvPosition;", + "", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t}`,", + "", + "\t\t\tfragmentShader: /* glsl */`", + "\t\t\t\tuniform sampler2D mirrorSampler;", + "\t\t\t\tuniform float alpha;", + "\t\t\t\tuniform float time;", + "\t\t\t\tuniform float size;", + "\t\t\t\tuniform float distortionScale;", + "\t\t\t\tuniform sampler2D normalSampler;", + "\t\t\t\tuniform vec3 sunColor;", + "\t\t\t\tuniform vec3 sunDirection;", + "\t\t\t\tuniform vec3 eye;", + "\t\t\t\tuniform vec3 waterColor;", + "", + "\t\t\t\tvarying vec4 mirrorCoord;", + "\t\t\t\tvarying vec4 worldPosition;", + "", + "\t\t\t\tvec4 getNoise( vec2 uv ) {", + "\t\t\t\t\tvec2 uv0 = ( uv / 103.0 ) + vec2(time / 17.0, time / 29.0);", + "\t\t\t\t\tvec2 uv1 = uv / 107.0-vec2( time / -19.0, time / 31.0 );", + "\t\t\t\t\tvec2 uv2 = uv / vec2( 8907.0, 9803.0 ) + vec2( time / 101.0, time / 97.0 );", + "\t\t\t\t\tvec2 uv3 = uv / vec2( 1091.0, 1027.0 ) - vec2( time / 109.0, time / -113.0 );", + "\t\t\t\t\tvec4 noise = texture2D( normalSampler, uv0 ) +", + "\t\t\t\t\t\ttexture2D( normalSampler, uv1 ) +", + "\t\t\t\t\t\ttexture2D( normalSampler, uv2 ) +", + "\t\t\t\t\t\ttexture2D( normalSampler, uv3 );", + "\t\t\t\t\treturn noise * 0.5 - 1.0;", + "\t\t\t\t}", + "", + "\t\t\t\tvoid sunLight( const vec3 surfaceNormal, const vec3 eyeDirection, float shiny, float spec, float diffuse, inout vec3 diffuseColor, inout vec3 specularColor ) {", + "\t\t\t\t\tvec3 reflection = normalize( reflect( -sunDirection, surfaceNormal ) );", + "\t\t\t\t\tfloat direction = max( 0.0, dot( eyeDirection, reflection ) );", + "\t\t\t\t\tspecularColor += pow( direction, shiny ) * sunColor * spec;", + "\t\t\t\t\tdiffuseColor += max( dot( sunDirection, surfaceNormal ), 0.0 ) * sunColor * diffuse;", + "\t\t\t\t}", + "", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "\t\t\t\t#include ", + "", + "\t\t\t\tvoid main() {", + "", + "\t\t\t\t\t#include ", + "\t\t\t\t\tvec4 noise = getNoise( worldPosition.xy * size );", + "\t\t\t\t\tvec3 surfaceNormal = normalize( noise.xyz * vec3( 1.5, 1.0, 1.5 ) );", + "", + "\t\t\t\t\tvec3 diffuseLight = vec3(0.0);", + "\t\t\t\t\tvec3 specularLight = vec3(0.0);", + "", + "\t\t\t\t\tvec3 worldToEye = eye-worldPosition.xyz;", + "\t\t\t\t\tvec3 eyeDirection = normalize( worldToEye );", + "\t\t\t\t\tsunLight( surfaceNormal, eyeDirection, 100.0, 2.0, 0.5, diffuseLight, specularLight );", + "", + "\t\t\t\t\tfloat distance = length(worldToEye);", + "", + "\t\t\t\t\tvec2 distortion = surfaceNormal.xz * ( 0.001 + 1.0 / distance ) * distortionScale;", + "\t\t\t\t\tvec3 reflectionSample = vec3( texture2D( mirrorSampler, mirrorCoord.xy / mirrorCoord.w + distortion ) );", + "", + "\t\t\t\t\tfloat theta = max( dot( eyeDirection, surfaceNormal ), 0.0 );", + "\t\t\t\t\tfloat rf0 = 0.3;", + "\t\t\t\t\tfloat reflectance = rf0 + ( 1.0 - rf0 ) * pow( ( 1.0 - theta ), 5.0 );", + "\t\t\t\t\tvec3 scatter = max( 0.0, dot( surfaceNormal, eyeDirection ) ) * waterColor;", + "\t\t\t\t\tvec3 albedo = mix( ( sunColor * diffuseLight * 0.3 + scatter ) * getShadowMask(), ( vec3( 0.1 ) + reflectionSample * 0.9 + reflectionSample * specularLight ), reflectance);", + "\t\t\t\t\tvec3 outgoingLight = albedo;", + "\t\t\t\t\tgl_FragColor = vec4( outgoingLight, alpha );", + "", + "\t\t\t\t\t#include ", + "\t\t\t\t\t#include ", + "\t\t\t\t\t#include \t", + "\t\t\t\t}`", + "", + "\t\t};", + "", + "\t\tconst material = new THREE.ShaderMaterial( {", + "\t\t\tname: mirrorShader.name,", + "\t\t\tuniforms: THREE.UniformsUtils.clone( mirrorShader.uniforms ),", + "\t\t\tvertexShader: mirrorShader.vertexShader,", + "\t\t\tfragmentShader: mirrorShader.fragmentShader,", + "\t\t\tlights: true,", + "\t\t\tside: side,", + "\t\t\tfog: fog", + "\t\t} );", + "", + "\t\tmaterial.uniforms[ 'mirrorSampler' ].value = renderTarget.texture;", + "\t\tmaterial.uniforms[ 'textureMatrix' ].value = textureMatrix;", + "\t\tmaterial.uniforms[ 'alpha' ].value = alpha;", + "\t\tmaterial.uniforms[ 'time' ].value = time;", + "\t\tmaterial.uniforms[ 'normalSampler' ].value = normalSampler;", + "\t\tmaterial.uniforms[ 'sunColor' ].value = sunColor;", + "\t\tmaterial.uniforms[ 'waterColor' ].value = waterColor;", + "\t\tmaterial.uniforms[ 'sunDirection' ].value = sunDirection;", + "\t\tmaterial.uniforms[ 'distortionScale' ].value = distortionScale;", + "", + "\t\tmaterial.uniforms[ 'eye' ].value = eye;", + "", + "\t\tscope.material = material;", + "", + "\t\tscope.onBeforeRender = function ( renderer, scene, camera ) {", + "", + "\t\t\tmirrorWorldPosition.setFromMatrixPosition( scope.matrixWorld );", + "\t\t\tcameraWorldPosition.setFromMatrixPosition( camera.matrixWorld );", + "", + "\t\t\trotationMatrix.extractRotation( scope.matrixWorld );", + "", + "\t\t\tnormal.set( 0, 0, 1 );", + "\t\t\tnormal.applyMatrix4( rotationMatrix );", + "", + "\t\t\tview.subVectors( mirrorWorldPosition, cameraWorldPosition );", + "", + "\t\t\t// Avoid rendering when mirror is facing away", + "", + "\t\t\tif ( view.dot( normal ) > 0 ) return;", + "", + "\t\t\tview.reflect( normal ).negate();", + "\t\t\tview.add( mirrorWorldPosition );", + "", + "\t\t\trotationMatrix.extractRotation( camera.matrixWorld );", + "", + "\t\t\tlookAtPosition.set( 0, 0, - 1 );", + "\t\t\tlookAtPosition.applyMatrix4( rotationMatrix );", + "\t\t\tlookAtPosition.add( cameraWorldPosition );", + "", + "\t\t\ttarget.subVectors( mirrorWorldPosition, lookAtPosition );", + "\t\t\ttarget.reflect( normal ).negate();", + "\t\t\ttarget.add( mirrorWorldPosition );", + "", + "\t\t\tmirrorCamera.position.copy( view );", + "\t\t\tmirrorCamera.up.set( 0, 1, 0 );", + "\t\t\tmirrorCamera.up.applyMatrix4( rotationMatrix );", + "\t\t\tmirrorCamera.up.reflect( normal );", + "\t\t\tmirrorCamera.lookAt( target );", + "", + "\t\t\tmirrorCamera.far = camera.far; // Used in WebGLBackground", + "", + "\t\t\tmirrorCamera.updateMatrixWorld();", + "\t\t\tmirrorCamera.projectionMatrix.copy( camera.projectionMatrix );", + "", + "\t\t\t// Update the texture matrix", + "\t\t\ttextureMatrix.set(", + "\t\t\t\t0.5, 0.0, 0.0, 0.5,", + "\t\t\t\t0.0, 0.5, 0.0, 0.5,", + "\t\t\t\t0.0, 0.0, 0.5, 0.5,", + "\t\t\t\t0.0, 0.0, 0.0, 1.0", + "\t\t\t);", + "\t\t\ttextureMatrix.multiply( mirrorCamera.projectionMatrix );", + "\t\t\ttextureMatrix.multiply( mirrorCamera.matrixWorldInverse );", + "", + "\t\t\t// Now update projection matrix with new clip plane, implementing code from: http://www.terathon.com/code/oblique.html", + "\t\t\t// Paper explaining this technique: http://www.terathon.com/lengyel/Lengyel-Oblique.pdf", + "\t\t\tmirrorPlane.setFromNormalAndCoplanarPoint( normal, mirrorWorldPosition );", + "\t\t\tmirrorPlane.applyMatrix4( mirrorCamera.matrixWorldInverse );", + "", + "\t\t\tclipPlane.set( mirrorPlane.normal.x, mirrorPlane.normal.y, mirrorPlane.normal.z, mirrorPlane.constant );", + "", + "\t\t\tconst projectionMatrix = mirrorCamera.projectionMatrix;", + "", + "\t\t\tq.x = ( Math.sign( clipPlane.x ) + projectionMatrix.elements[ 8 ] ) / projectionMatrix.elements[ 0 ];", + "\t\t\tq.y = ( Math.sign( clipPlane.y ) + projectionMatrix.elements[ 9 ] ) / projectionMatrix.elements[ 5 ];", + "\t\t\tq.z = - 1.0;", + "\t\t\tq.w = ( 1.0 + projectionMatrix.elements[ 10 ] ) / projectionMatrix.elements[ 14 ];", + "", + "\t\t\t// Calculate the scaled plane vector", + "\t\t\tclipPlane.multiplyScalar( 2.0 / clipPlane.dot( q ) );", + "", + "\t\t\t// Replacing the third row of the projection matrix", + "\t\t\tprojectionMatrix.elements[ 2 ] = clipPlane.x;", + "\t\t\tprojectionMatrix.elements[ 6 ] = clipPlane.y;", + "\t\t\tprojectionMatrix.elements[ 10 ] = clipPlane.z + 1.0 - clipBias;", + "\t\t\tprojectionMatrix.elements[ 14 ] = clipPlane.w;", + "", + "\t\t\teye.setFromMatrixPosition( camera.matrixWorld );", + "", + "\t\t\t// Render", + "", + "\t\t\tconst currentRenderTarget = renderer.getRenderTarget();", + "", + "\t\t\tconst currentXrEnabled = renderer.xr.enabled;", + "\t\t\tconst currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;", + "", + "\t\t\tscope.visible = false;", + "", + "\t\t\trenderer.xr.enabled = false; // Avoid camera modification and recursion", + "\t\t\trenderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows", + "", + "\t\t\trenderer.setRenderTarget( renderTarget );", + "", + "\t\t\trenderer.state.buffers.depth.setMask( true ); // make sure the depth buffer is writable so it can be properly cleared, see #18897", + "", + "\t\t\tif ( renderer.autoClear === false ) renderer.clear();", + "\t\t\trenderer.render( scene, mirrorCamera );", + "", + "\t\t\tscope.visible = true;", + "", + "\t\t\trenderer.xr.enabled = currentXrEnabled;", + "\t\t\trenderer.shadowMap.autoUpdate = currentShadowAutoUpdate;", + "", + "\t\t\trenderer.setRenderTarget( currentRenderTarget );", + "", + "\t\t\t// Restore viewport", + "", + "\t\t\tconst viewport = camera.viewport;", + "", + "\t\t\tif ( viewport !== undefined ) {", + "", + "\t\t\t\trenderer.state.viewport( viewport );", + "", + "\t\t\t}", + "", + "\t\t};", + "", + "\t}", + "", + "}", + "", + "const scene = runtimeScene.getLayer('Base layer').getRenderer().getThreeScene();", + "const x = eventsFunctionContext.getArgument('X');", + "const y = eventsFunctionContext.getArgument('Y');", + "const z = eventsFunctionContext.getArgument('Z');", + "const w = eventsFunctionContext.getArgument('W');", + "const h = eventsFunctionContext.getArgument('H');", + "const tw = eventsFunctionContext.getArgument('TW');", + "const th = eventsFunctionContext.getArgument('TH');", + "const resourceName = eventsFunctionContext.getArgument('Norm');", + "const image = new THREE.TextureLoader().load(resourceName);", + "image.wrapS = image.wrapT = THREE.RepeatWrapping;", + "", + "const waterGeometry = new THREE.PlaneGeometry( w, h );", + "let water = new Water(", + "\twaterGeometry,", + "\t{", + "\t\ttextureWidth: tw,", + "\t\ttextureHeight: th,", + "\t\twaterNormals: image,", + "\t\tsunDirection: new THREE.Vector3(),", + "\t\tsunColor: 0xffffff,", + "\t\twaterColor: 0x001e0f,", + "\t\tdistortionScale: 3.7,", + "\t\tfog: scene.fog !== undefined", + "\t}", + ");", + "water.position.x = x;", + "water.position.y = y;", + "water.position.z = z;", + "", + "scene.add( water );", + "", + "function updateWater (){", + " water.material.uniforms[ 'time' ].value += 1.0 / 60.0;", + " requestAnimationFrame(updateWater);", + "}", + "updateWater();", + "let waterForSaving = {", + "\tname: eventsFunctionContext.getArgument('Name'),", + "\twater: water", + "};", + "", + "if (gdjs._water3DSavingArray == undefined){", + "\tgdjs._water3DSavingArray = new Array();", + "}", + "gdjs._water3DSavingArray.push(waterForSaving);" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object name (for manipulating)", + "name": "Name", + "type": "string" + }, + { + "description": "X", + "name": "X", + "type": "expression" + }, + { + "description": "Y", + "name": "Y", + "type": "expression" + }, + { + "description": "Z", + "name": "Z", + "type": "expression" + }, + { + "description": "Width", + "name": "W", + "type": "expression" + }, + { + "description": "Weight", + "name": "H", + "type": "expression" + }, + { + "description": "Texture width. Default: 512", + "name": "TW", + "type": "expression" + }, + { + "description": "Texture height. Default: 512", + "name": "TH", + "type": "expression" + }, + { + "description": "Normals texture (image)", + "name": "Norm", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "Change water position.", + "fullName": "Change water position", + "functionType": "Action", + "name": "ChangePosition", + "sentence": "Change water _PARAM1_ position: X: _PARAM2_, Y: _PARAM3_, Z: _PARAM4_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const name = eventsFunctionContext.getArgument(\"Name\");\r", + "const x = eventsFunctionContext.getArgument('X');\r", + "const y = eventsFunctionContext.getArgument('Y');\r", + "const z = eventsFunctionContext.getArgument('Z');\r", + "const scene3D = runtimeScene.getLayer('Base layer').getRenderer().getThreeScene();\r", + "if (gdjs._water3DSavingArray != undefined) {\r", + " var water = gdjs._water3DSavingArray;\r", + " for (let i = 0; i < water.length; i+=1) {\r", + " if (water[i].name == name) {\r", + " water[i].water.position.x = x;\r", + " water[i].water.position.y = y;\r", + " water[i].water.position.z = z;\r", + " }\r", + " }\r", + "}\r", + "else {\r", + " console.log(\"No water on the scene.\")\r", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Water object name", + "name": "Name", + "type": "string" + }, + { + "description": "X", + "name": "X", + "type": "expression" + }, + { + "description": "Y", + "name": "Y", + "type": "expression" + }, + { + "description": "Z", + "name": "Z", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Remove water.", + "fullName": "Remove water", + "functionType": "Action", + "name": "RemoveWater", + "sentence": "Remove water with name: _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const name = eventsFunctionContext.getArgument(\"Name\");\r", + "const scene3D = runtimeScene.getLayer('Base layer').getRenderer().getThreeScene();\r", + "if (gdjs._water3DSavingArray != undefined) {\r", + " var water = gdjs._water3DSavingArray;\r", + " for (let i = 0; i < water.length; i+=1) {\r", + " if (water[i].name == name) {\r", + " if (water[i].water.material.uniforms.mirrorSampler.value) {\r", + " water[i].water.material.uniforms.mirrorSampler.value.dispose();\r", + " }\r", + " water[i].water.geometry.dispose();\r", + " water[i].water.material.dispose();\r", + " scene3D.remove(water[i].water);\r", + " water.splice(i, 1);\r", + " console.log(\"Water \" + name +\" deleted\");\r", + " }\r", + " }\r", + "}\r", + "else {\r", + " console.log(\"No water on the scene.\")\r", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Water object name", + "name": "Name", + "type": "string" + } + ], + "objectGroups": [] + } + ], + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] +} \ No newline at end of file