diff --git a/.circleci/config.yml b/.circleci/config.yml index e82eedb63..4580b4beb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -247,7 +247,27 @@ jobs: - run: name: Report whether the gameplay tests passed - command: exit "$(cat /tmp/gameplay-tests-exit-code)" + # Summarize the failures here, where the job turns red: for each + # game, how many of its tests failed and which ones. + command: | + EXIT_CODE="$(cat /tmp/gameplay-tests-exit-code)" + if [ "$EXIT_CODE" != "0" ]; then + # For each game of the JUnit report with a failure: its path, how + # many tests passed out of how many, and the names of the failed ones. + awk ' + function attribute(tag, key) { + if (!match(tag, " " key "=\"[^\"]*\"")) return "" + value = substr(tag, RSTART + length(key) + 3, RLENGTH - length(key) - 4) + gsub(/"/, "\"", value); gsub(/</, "<", value); gsub(/>/, ">", value); gsub(/&/, "\\&", value) + return value + } + / 0 { + print "❌ " attribute($0, "name") ": " attribute($0, "tests") - attribute($0, "failures") "/" attribute($0, "tests") " gameplay tests passed" + } + /$/ { print " - " attribute($0, "name") } + ' /tmp/gameplay-tests-results/results.xml + fi + exit "$EXIT_CODE" # Check that the games are still drawn the same: their rendering tests # (gameplay tests named "Rendering: ...") take screenshots compared with the @@ -305,7 +325,28 @@ jobs: - run: name: Report whether the games are drawn like their expected images - command: exit "$(cat /tmp/rendering-screenshots-exit-code)" + # Summarize the differences here, where the job turns red: for each + # game, how many of its screenshots differ and which ones. + command: | + EXIT_CODE="$(cat /tmp/rendering-screenshots-exit-code)" + if [ "$EXIT_CODE" != "0" ]; then + # For each game of the JUnit report with a difference: its path, + # how many screenshots match out of how many, and the ones that differ. + awk ' + function attribute(tag, key) { + if (!match(tag, " " key "=\"[^\"]*\"")) return "" + value = substr(tag, RSTART + length(key) + 3, RLENGTH - length(key) - 4) + gsub(/"/, "\"", value); gsub(/</, "<", value); gsub(/>/, ">", value); gsub(/&/, "\\&", value) + return value + } + / 0 { + print "❌ " attribute($0, "name") ": " attribute($0, "tests") - attribute($0, "failures") "/" attribute($0, "tests") " screenshots match" + } + /$/ { print " - " attribute($0, "name") } + ' /tmp/rendering-screenshots-results/results.xml + echo "If the change is on purpose, update the images with: node scripts/check-rendering-screenshots.js --update" + fi + exit "$EXIT_CODE" workflows: tests: diff --git a/examples/3d-light-playground/3d-light-playground.json b/examples/3d-light-playground/3d-light-playground.json index b47efe9e3..4d4980413 100644 --- a/examples/3d-light-playground/3d-light-playground.json +++ b/examples/3d-light-playground/3d-light-playground.json @@ -1,7 +1,7 @@ { "firstLayout": "Sun and Shadows", "gdVersion": { - "build": 279, + "build": 285, "major": 5, "minor": 6, "revision": 0 @@ -98,17 +98,25 @@ "kind": "image", "metadata": "", "name": "assets/LightPlaygroundSurface.png", - "userAdded": false, "smoothed": true, - "alwaysLoaded": false + "userAdded": false + }, + { + "file": "assets/Rocks Small.glb", + "kind": "model3D", + "metadata": "", + "name": "Rocks Small.glb", + "userAdded": false, + "origin": { + "identifier": "https://asset-resources.gdevelop.io/public-resources/3D Castle Kit/Rock/d84d4980e8ce7b7a461a26357ae01465c7f12369b985d01418dccc114a4eec31_Rocks Small.glb", + "name": "Rocks Small.glb" + } } - ], - "resourceFolders": [] + ] }, "objects": [], "objectsFolderStructure": { - "folderName": "__ROOT", - "children": [] + "folderName": "__ROOT" }, "objectsGroups": [], "variables": [], @@ -116,9 +124,10 @@ { "b": 190, "disableInputWhenNotFocused": true, - "mangledName": "Sun_and_Shadows", + "mangledName": "Sun_32and_32Shadows", "name": "Sun and Shadows", "r": 120, + "renderer3DWorldScale": 100, "standardSortMethod": true, "stopSoundsOnStartup": true, "title": "", @@ -128,27 +137,28 @@ "gridType": "rectangular", "gridWidth": 32, "gridHeight": 32, + "gridDepth": 32, "gridOffsetX": 0, "gridOffsetY": 0, + "gridOffsetZ": 0, "gridColor": 10401023, "gridAlpha": 0.8, "snap": true, "zoomFactor": 0.35, - "windowMask": false + "windowMask": false, + "selectedLayer": "", + "gameEditorMode": "embedded-game" }, "objectsGroups": [], "variables": [], "instances": [ { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 20, "height": 2400, "keepRatio": true, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "b090e0d0-06ca-2518-98fa-c63d498a7de4", "width": 2400, @@ -162,20 +172,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 460, "height": 110, "keepRatio": true, "layer": "", - "locked": false, "name": "Pillar", "persistentUuid": "2b7f7d92-a9e2-c4c8-bb48-5d71fcd16b84", "width": 110, "x": -55, "y": -55, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -183,20 +189,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 320, "height": 60, "keepRatio": true, "layer": "", - "locked": false, "name": "Backdrop", "persistentUuid": "19ddede8-766d-ab48-ce0a-80a2f23bc81d", "width": 900, "x": -450, "y": -900, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -204,20 +206,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "3fdda8ff-dc0e-7c1a-f754-d933f0f4d28a", "width": 140, "x": -520, "y": -420, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -225,20 +223,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "fd2c00d2-250c-def9-2903-66670a15015c", "width": 140, "x": 380, "y": -480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -246,20 +240,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "57363f1e-d65d-3e58-ee58-8c3137384388", "width": 140, "x": -600, "y": 320, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -267,20 +257,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "87224692-c2ad-dcb7-b6b7-71b0135f42b6", "width": 140, "x": 460, "y": 300, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -288,20 +274,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "eafbcc09-5057-5dca-8e2d-a35b8111fa27", "width": 140, "x": -80, "y": -640, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -309,20 +291,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "f818a1a3-593b-2d99-78b2-ca893240b86d", "width": 140, "x": -60, "y": 480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -526,9 +504,9 @@ ], "layers": [ { - "ambientLightColorR": 120, - "ambientLightColorG": 130, "ambientLightColorB": 150, + "ambientLightColorG": 130, + "ambientLightColorR": 120, "camera2DPlaneMaxDrawingDistance": 5000, "camera3DFarPlaneDistance": 10000, "camera3DFieldOfView": 45, @@ -595,9 +573,10 @@ { "b": 12, "disableInputWhenNotFocused": true, - "mangledName": "Point_Lights", + "mangledName": "Point_32Lights", "name": "Point Lights", "r": 6, + "renderer3DWorldScale": 100, "standardSortMethod": true, "stopSoundsOnStartup": true, "title": "", @@ -607,27 +586,28 @@ "gridType": "rectangular", "gridWidth": 32, "gridHeight": 32, + "gridDepth": 32, "gridOffsetX": 0, "gridOffsetY": 0, + "gridOffsetZ": 0, "gridColor": 10401023, "gridAlpha": 0.8, "snap": true, "zoomFactor": 0.35, - "windowMask": false + "windowMask": false, + "selectedLayer": "", + "gameEditorMode": "instances-editor" }, "objectsGroups": [], "variables": [], "instances": [ { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 20, "height": 2400, "keepRatio": true, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "21d1f279-4719-1f6a-cbbb-722acfb1f6de", "width": 2400, @@ -641,20 +621,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 460, "height": 110, "keepRatio": true, "layer": "", - "locked": false, "name": "Pillar", "persistentUuid": "1e06c145-943f-f5a1-f990-12cdaa0825b5", "width": 110, "x": -55, "y": -55, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -662,20 +638,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 320, "height": 60, "keepRatio": true, "layer": "", - "locked": false, "name": "Backdrop", "persistentUuid": "b5bb5390-66f6-b9c4-1e41-87e5df707d65", "width": 900, "x": -450, "y": -900, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -683,20 +655,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "1140e6b9-97f9-67c3-4213-3ec20f479dc8", "width": 140, "x": -520, "y": -420, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -704,20 +672,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "1feaa7a2-bd77-4fae-7133-7c976038df6c", "width": 140, "x": 380, "y": -480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -725,20 +689,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "dd956ced-4997-5ff3-a7b8-1293e572377b", "width": 140, "x": -600, "y": 320, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -746,20 +706,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "97993a28-b8fc-b200-aa00-112a1d8816dd", "width": 140, "x": 460, "y": 300, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -767,20 +723,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "82992fdc-febb-527b-8ca2-32dd3bd57df4", "width": 140, "x": -80, "y": -640, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -788,20 +740,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "b675e5ea-db07-5902-72fe-4fd5f66e2190", "width": 140, "x": -60, "y": 480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -809,14 +757,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "PointLightWarm", "persistentUuid": "95051515-fb64-4ca5-6b63-80a275dc630a", "width": 0, @@ -830,14 +775,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "PointLightCool", "persistentUuid": "14004069-1b93-12bc-cfe0-9a63856a1578", "width": 0, @@ -851,14 +793,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "PointLightMagenta", "persistentUuid": "08a2515f-7cc8-93e4-7f3d-271a1e6a60e0", "width": 0, @@ -1033,6 +972,7 @@ "name": "PointLightWarm", "persistentUuid": "c5016e19-f69f-1ed8-e1c8-ded2f9101305", "type": "Light3D::PointLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -1053,6 +993,7 @@ "name": "PointLightCool", "persistentUuid": "8dc7336a-006c-23e0-f388-b946f5803983", "type": "Light3D::PointLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -1073,6 +1014,7 @@ "name": "PointLightMagenta", "persistentUuid": "e33287e0-e515-f368-29c2-c6fc3edb11c7", "type": "Light3D::PointLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -1137,9 +1079,9 @@ ], "layers": [ { - "ambientLightColorR": 14, - "ambientLightColorG": 16, "ambientLightColorB": 24, + "ambientLightColorG": 16, + "ambientLightColorR": 14, "camera2DPlaneMaxDrawingDistance": 5000, "camera3DFarPlaneDistance": 10000, "camera3DFieldOfView": 45, @@ -1183,9 +1125,10 @@ { "b": 12, "disableInputWhenNotFocused": true, - "mangledName": "Spot_Lights", + "mangledName": "Spot_32Lights", "name": "Spot Lights", "r": 6, + "renderer3DWorldScale": 100, "standardSortMethod": true, "stopSoundsOnStartup": true, "title": "", @@ -1208,14 +1151,11 @@ "instances": [ { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 20, "height": 2400, "keepRatio": true, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "ed514924-d2e4-5b2d-c862-19a99c1db74b", "width": 2400, @@ -1229,20 +1169,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 460, "height": 110, "keepRatio": true, "layer": "", - "locked": false, "name": "Pillar", "persistentUuid": "49a5c3e6-d6e6-bfb4-d8fe-6b193c5cef0c", "width": 110, "x": -55, "y": -55, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1250,20 +1186,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 320, "height": 60, "keepRatio": true, "layer": "", - "locked": false, "name": "Backdrop", "persistentUuid": "5e510294-7b95-b338-1670-2ceba2955432", "width": 900, "x": -450, "y": -900, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1271,20 +1203,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "2b92439c-dea7-1970-fb7e-3227a8cae86c", "width": 140, "x": -520, "y": -420, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1292,20 +1220,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "730511a8-9565-22bb-db96-51698cd16cda", "width": 140, "x": 380, "y": -480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1313,20 +1237,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "afa68705-e9c9-4f8f-b8ed-471122f3e33f", "width": 140, "x": -600, "y": 320, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1334,20 +1254,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "88cc375e-a0fd-7e69-7764-ce5823d83558", "width": 140, "x": 460, "y": 300, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1355,20 +1271,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "9aa9982a-7ab0-b8e1-86c1-740ec8926dcb", "width": 140, "x": -80, "y": -640, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1376,20 +1288,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "2f0fccc2-50a8-95be-f958-80b02a9b87e0", "width": 140, "x": -60, "y": 480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1397,16 +1305,14 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 90, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "SpotLightWarm", "persistentUuid": "2dab3063-cac1-5782-6165-e23ffc4a7530", + "rotationY": 90, "width": 0, "x": -450, "y": -250, @@ -1418,16 +1324,14 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 90, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "SpotLightCool", "persistentUuid": "04800480-b81c-1c1d-ce15-518cb3a1cc45", + "rotationY": 90, "width": 0, "x": 450, "y": -250, @@ -1600,6 +1504,7 @@ "name": "SpotLightWarm", "persistentUuid": "85ffde62-c943-b149-de4d-69dc43d73aee", "type": "Light3D::SpotLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -1623,6 +1528,7 @@ "name": "SpotLightCool", "persistentUuid": "434cde1f-be0b-f340-da83-67b1cb0619aa", "type": "Light3D::SpotLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -1687,9 +1593,9 @@ ], "layers": [ { - "ambientLightColorR": 14, - "ambientLightColorG": 16, "ambientLightColorB": 24, + "ambientLightColorG": 16, + "ambientLightColorR": 14, "camera2DPlaneMaxDrawingDistance": 5000, "camera3DFarPlaneDistance": 10000, "camera3DFieldOfView": 45, @@ -1733,9 +1639,10 @@ { "b": 10, "disableInputWhenNotFocused": true, - "mangledName": "Mixed_Lights", + "mangledName": "Mixed_32Lights", "name": "Mixed Lights", "r": 5, + "renderer3DWorldScale": 100, "standardSortMethod": true, "stopSoundsOnStartup": true, "title": "", @@ -1745,27 +1652,28 @@ "gridType": "rectangular", "gridWidth": 32, "gridHeight": 32, + "gridDepth": 32, "gridOffsetX": 0, "gridOffsetY": 0, + "gridOffsetZ": 0, "gridColor": 10401023, "gridAlpha": 0.8, "snap": true, "zoomFactor": 0.35, - "windowMask": false + "windowMask": false, + "selectedLayer": "", + "gameEditorMode": "embedded-game" }, "objectsGroups": [], "variables": [], "instances": [ { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 20, "height": 2400, "keepRatio": true, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "22dfa7b3-d332-db2e-6f60-a5f0c98ad1cf", "width": 2400, @@ -1779,20 +1687,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 460, "height": 110, "keepRatio": true, "layer": "", - "locked": false, "name": "Pillar", "persistentUuid": "e875554f-6f48-045f-77dd-e007ec681281", "width": 110, "x": -55, "y": -55, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1800,20 +1704,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 320, "height": 60, "keepRatio": true, "layer": "", - "locked": false, "name": "Backdrop", "persistentUuid": "fb74f53b-2e94-d59d-a8b4-b317842a75d8", "width": 900, "x": -450, "y": -900, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1821,20 +1721,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "b67acebc-c8ac-e50f-c6f5-2017cd8d2107", "width": 140, "x": -520, "y": -420, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1842,20 +1738,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "499db8ef-1794-f035-b870-0fbe178a8d40", "width": 140, "x": 380, "y": -480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1863,20 +1755,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "fc9913d1-5edb-39ee-d907-075d3f622cfe", "width": 140, "x": -600, "y": 320, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1884,20 +1772,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "e08f7f62-9efd-2c0b-a0c2-9785ba5d2b37", "width": 140, "x": 460, "y": 300, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1905,20 +1789,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "eec06225-61ec-4647-c12b-ae6b1f1b98a9", "width": 140, "x": -80, "y": -640, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1926,41 +1806,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "d976a244-aadd-5742-bba9-d35ab2568465", "width": 140, "x": -60, "y": 480, - "z": 0, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPoint", - "persistentUuid": "ab1970e9-5eb4-3852-b150-26d552a2d3f3", - "width": 0, - "x": 300, - "y": 0, - "z": 150, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -1968,14 +1823,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "MixedPoint", "persistentUuid": "049feb8a-a32e-1d93-a9f7-dc1a6965d462", "width": 0, @@ -1989,35 +1841,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPoint", - "persistentUuid": "34214cda-67bc-c49b-4f68-11d1aae4bb51", - "width": 0, - "x": 443, - "y": 641, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "MixedPoint", "persistentUuid": "591288f4-88f2-350f-f301-f579e673a03c", "width": 0, @@ -2031,56 +1859,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPoint", - "persistentUuid": "94ff4de1-22c7-0196-d87b-71cc119aff4c", - "width": 0, - "x": -106, - "y": 280, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPoint", - "persistentUuid": "e0e9e274-4cc1-3019-a049-267e669c7d64", - "width": 0, - "x": -404, - "y": 358, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "MixedPoint", "persistentUuid": "ebf66795-7cf2-bdf4-23d7-79400bba5e10", "width": 0, @@ -2094,77 +1877,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPoint", - "persistentUuid": "9a702679-4bc8-5b8f-9e12-14726f321298", - "width": 0, - "x": -990, - "y": -244, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPoint", - "persistentUuid": "244be702-6b6a-8a42-a284-f7164d8f8b9b", - "width": 0, - "x": -224, - "y": -198, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPoint", - "persistentUuid": "1392a405-3592-c7ea-b7c2-55b538b9a0d7", - "width": 0, - "x": -191, - "y": -504, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "MixedPoint", "persistentUuid": "a980b446-1fc5-7c4a-85d7-8a2b01912fab", "width": 0, @@ -2178,100 +1895,14 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPoint", - "persistentUuid": "23502fcf-1c47-165a-ec9b-f1060770a131", - "width": 0, - "x": 579, - "y": -839, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPointShadow", - "persistentUuid": "ceb10a30-edd9-540c-5f36-0c6e30f249cf", - "width": 0, - "x": 265, - "y": -139, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 0, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedPointShadow", - "persistentUuid": "d1d1da37-9c09-a782-3b97-44dea2cb51d0", - "width": 0, - "x": 540, - "y": 0, - "z": 150, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedSpot", - "persistentUuid": "d71e3361-7ee3-c6ac-efad-bd4053dbd4e5", - "width": 0, - "x": 690, - "y": 362, - "z": 560, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 90, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "MixedSpot", "persistentUuid": "9c35be70-c8e7-2aa3-2d9f-e980b98a31d5", + "rotationY": 90, "width": 0, "x": 579, "y": 839, @@ -2283,37 +1914,14 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedSpot", - "persistentUuid": "b53c7850-2186-23f2-eaae-05abd0497c35", - "width": 0, - "x": 36, - "y": 297, - "z": 560, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 90, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "MixedSpot", "persistentUuid": "7d1e615d-ce68-8d3f-dfd9-7b6369a79d3c", + "rotationY": 90, "width": 0, "x": -191, "y": 504, @@ -2325,40 +1933,17 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 90, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "MixedSpot", - "persistentUuid": "421cb74f-3386-8ef1-9c65-d043d302e8cb", - "width": 0, - "x": -583, - "y": 517, - "z": 560, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, + "persistentUuid": "cd93fb9c-82ec-8285-13a7-d9ecb08470d9", "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedSpot", - "persistentUuid": "d29b0ff9-1509-feb8-e22a-578506534d01", "width": 0, - "x": -990, - "y": 244, + "x": -276, + "y": -729, "z": 560, "zOrder": 1, "numberProperties": [], @@ -2367,132 +1952,22 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, + "customSize": true, + "depth": 232, + "height": 512, "layer": "", - "locked": false, - "name": "MixedSpot", - "persistentUuid": "e60591b7-6b99-e7f7-845d-cf586a028a6e", - "width": 0, - "x": -291, - "y": -71, - "z": 560, - "zOrder": 1, + "name": "Rocks_Small", + "persistentUuid": "26e33ad0-38f8-42f5-ab36-e2d6ff49d085", + "width": 477, + "x": -480, + "y": -576, + "zOrder": 2, "numberProperties": [], "stringProperties": [], "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedSpot", - "persistentUuid": "0d7a9528-5bac-d515-6028-070055d67a6b", - "width": 0, - "x": -404, - "y": -358, - "z": 560, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedSpot", - "persistentUuid": "cd93fb9c-82ec-8285-13a7-d9ecb08470d9", - "width": 0, - "x": -276, - "y": -729, - "z": 560, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedSpot", - "persistentUuid": "0856657d-867f-48c5-fd6b-a93e05a3c038", - "width": 0, - "x": 122, - "y": -1012, - "z": 560, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedSpotShadow", - "persistentUuid": "13bb79a9-9155-795c-1ac2-04512763cfe7", - "width": 0, - "x": 170, - "y": -246, - "z": 560, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - }, - { - "angle": 0, - "rotationX": 0, - "rotationY": 90, - "customSize": false, - "depth": 0, - "height": 0, - "keepRatio": true, - "layer": "", - "locked": false, - "name": "MixedSpotShadow", - "persistentUuid": "79357827-b406-c6e4-9c08-45e541722891", - "width": 0, - "x": 478, - "y": -250, - "z": 560, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - } - ], - "objects": [ + } + ], + "objects": [ { "assetStoreId": "", "name": "Ground", @@ -2654,6 +2129,7 @@ "name": "MixedPoint", "persistentUuid": "d9b5850c-4ba6-6924-bb12-3a71d641af26", "type": "Light3D::PointLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -2674,6 +2150,7 @@ "name": "MixedPointShadow", "persistentUuid": "3f5d7912-6537-ef1f-fe3d-b050d6dbd394", "type": "Light3D::PointLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -2694,6 +2171,7 @@ "name": "MixedSpot", "persistentUuid": "a13deb4c-0901-17be-ca1a-d875b1e16807", "type": "Light3D::SpotLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -2704,12 +2182,13 @@ "Smoothing": 1, "Decay": 1, "Image": "", - "IsCastingShadow": false, - "ShadowQuality": "Medium", + "IsCastingShadow": true, + "ShadowQuality": "VeryHigh", "ShadowCameraNearPlane": 20, "ShadowCameraFarPlane": 2000, "ConeLength": 2000, - "ShadowBias": 0 + "ShadowBias": 0, + "ShadowNormalBias": 1 } }, { @@ -2717,6 +2196,7 @@ "name": "MixedSpotShadow", "persistentUuid": "6697f33c-05c5-ea0e-56ea-dd7b9637f87b", "type": "Light3D::SpotLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -2734,6 +2214,32 @@ "ConeLength": 2000, "ShadowBias": 0 } + }, + { + "assetStoreId": "5378f99b6d0aa259410412069f69c60ee8d9d5ba56711b341daa7909ea42d6c9", + "name": "Rocks_Small", + "persistentUuid": "8ca638da-5c8f-45d0-8fbd-1382692e4370", + "type": "Scene3D::Model3DObject", + "variables": [], + "effects": [], + "behaviors": [], + "content": { + "centerLocation": "CenteredOnZ", + "crossfadeDuration": 0.10000000149011612, + "depth": 111, + "height": 111, + "isCastingShadow": true, + "isReceivingShadow": true, + "keepAspectRatio": true, + "materialType": "StandardWithoutMetalness", + "modelResourceName": "Rocks Small.glb", + "originLocation": "ModelOrigin", + "rotationX": 90, + "rotationY": 0, + "rotationZ": 0, + "width": 111, + "animations": [] + } } ], "objectsFolderStructure": { @@ -2762,6 +2268,9 @@ }, { "objectName": "MixedSpotShadow" + }, + { + "objectName": "Rocks_Small" } ] }, @@ -2787,9 +2296,9 @@ ], "layers": [ { - "ambientLightColorR": 12, - "ambientLightColorG": 14, "ambientLightColorB": 20, + "ambientLightColorG": 14, + "ambientLightColorR": 12, "camera2DPlaneMaxDrawingDistance": 5000, "camera3DFarPlaneDistance": 10000, "camera3DFieldOfView": 45, @@ -2833,9 +2342,10 @@ { "b": 10, "disableInputWhenNotFocused": true, - "mangledName": "Crowded_Point_Lights", + "mangledName": "Crowded_32Point_32Lights", "name": "Crowded Point Lights", "r": 5, + "renderer3DWorldScale": 100, "standardSortMethod": true, "stopSoundsOnStartup": true, "title": "", @@ -2858,14 +2368,11 @@ "instances": [ { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 20, "height": 2400, "keepRatio": true, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "22dfa7b3-d332-db2e-6f60-a5f0c98ad1cf", "width": 2400, @@ -2879,20 +2386,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 460, "height": 110, "keepRatio": true, "layer": "", - "locked": false, "name": "Pillar", "persistentUuid": "e875554f-6f48-045f-77dd-e007ec681281", "width": 110, "x": -55, "y": -55, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -2900,20 +2403,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 320, "height": 60, "keepRatio": true, "layer": "", - "locked": false, "name": "Backdrop", "persistentUuid": "fb74f53b-2e94-d59d-a8b4-b317842a75d8", "width": 900, "x": -450, "y": -900, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -2921,20 +2420,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "b67acebc-c8ac-e50f-c6f5-2017cd8d2107", "width": 140, "x": -520, "y": -420, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -2942,20 +2437,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "499db8ef-1794-f035-b870-0fbe178a8d40", "width": 140, "x": 380, "y": -480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -2963,20 +2454,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "fc9913d1-5edb-39ee-d907-075d3f622cfe", "width": 140, "x": -600, "y": 320, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -2984,20 +2471,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "e08f7f62-9efd-2c0b-a0c2-9785ba5d2b37", "width": 140, "x": 460, "y": 300, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3005,20 +2488,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "eec06225-61ec-4647-c12b-ae6b1f1b98a9", "width": 140, "x": -80, "y": -640, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3026,20 +2505,16 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": true, "depth": 140, "height": 140, "keepRatio": true, "layer": "", - "locked": false, "name": "Crate", "persistentUuid": "d976a244-aadd-5742-bba9-d35ab2568465", "width": 140, "x": -60, "y": 480, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3047,14 +2522,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "CrowdedPointShadow", "persistentUuid": "41a578a3-0e8e-4af5-81ce-2810d7c55432", "width": 0, @@ -3068,14 +2540,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "CrowdedPointShadow", "persistentUuid": "08c119c4-8fc7-4232-a70c-d9c43181f2c1", "width": 0, @@ -3089,14 +2558,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "CrowdedPointShadow", "persistentUuid": "aceb6eb8-0c1c-473b-bfdf-cdffdccfd9cd", "width": 0, @@ -3110,14 +2576,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "CrowdedPointShadow", "persistentUuid": "ee7abeab-387e-4761-a427-b7e05e50442a", "width": 0, @@ -3131,14 +2594,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "CrowdedPointShadow", "persistentUuid": "d4e10e44-ae1d-4eae-a1a6-102eebd60e48", "width": 0, @@ -3152,14 +2612,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "CrowdedPointShadow", "persistentUuid": "d6e2e318-0c7f-4425-bf35-48704f62f167", "width": 0, @@ -3173,14 +2630,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "CrowdedPointShadow", "persistentUuid": "dbbe65db-8b5b-45ac-8faa-9ed8109abb84", "width": 0, @@ -3194,14 +2648,11 @@ }, { "angle": 0, - "rotationX": 0, - "rotationY": 0, "customSize": false, "depth": 0, "height": 0, "keepRatio": true, "layer": "", - "locked": false, "name": "CrowdedPointShadow", "persistentUuid": "cdfc7464-a19f-495f-ae6b-e6a3b404784d", "width": 0, @@ -3376,6 +2827,7 @@ "name": "CrowdedPointShadow", "persistentUuid": "c4164626-0bc3-4ec5-8e5d-33fdab7d9bcd", "type": "Light3D::PointLight3D", + "variant": "", "variables": [], "effects": [], "behaviors": [], @@ -3434,9 +2886,9 @@ ], "layers": [ { - "ambientLightColorR": 12, - "ambientLightColorG": 14, "ambientLightColorB": 20, + "ambientLightColorG": 14, + "ambientLightColorR": 12, "camera2DPlaneMaxDrawingDistance": 5000, "camera3DFarPlaneDistance": 10000, "camera3DFieldOfView": 45, @@ -3479,5095 +2931,10 @@ } ], "externalEvents": [], - "externalLayouts": [], - "eventsFunctionsExtensions": [ + "tests": [ { - "author": "", - "category": "Visual effect", - "dimension": "3D", - "extensionNamespace": "", - "fullName": "3D lights", - "gdevelopVersion": ">=5.5.222", - "helpPath": "/objects/3d-light", - "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWxpZ2h0YnVsYi1vbi1vdXRsaW5lIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTIwLDExSDIzVjEzSDIwVjExTTEsMTFINFYxM0gxVjExTTEzLDFWNEgxMVYxSDEzTTQuOTIsMy41TDcuMDUsNS42NEw1LjYzLDcuMDVMMy41LDQuOTNMNC45MiwzLjVNMTYuOTUsNS42M0wxOS4wNywzLjVMMjAuNSw0LjkzTDE4LjM3LDcuMDVMMTYuOTUsNS42M00xMiw2QTYsNiAwIDAsMSAxOCwxMkMxOCwxNC4yMiAxNi43OSwxNi4xNiAxNSwxNy4yVjE5QTEsMSAwIDAsMSAxNCwyMEgxMEExLDEgMCAwLDEgOSwxOVYxNy4yQzcuMjEsMTYuMTYgNiwxNC4yMiA2LDEyQTYsNiAwIDAsMSAxMiw2TTE0LDIxVjIyQTEsMSAwIDAsMSAxMywyM0gxMUExLDEgMCAwLDEgMTAsMjJWMjFIMTRNMTEsMThIMTNWMTUuODdDMTQuNzMsMTUuNDMgMTYsMTMuODYgMTYsMTJBNCw0IDAgMCwwIDEyLDhBNCw0IDAgMCwwIDgsMTJDOCwxMy44NiA5LjI3LDE1LjQzIDExLDE1Ljg3VjE4WiIgLz48L3N2Zz4=", - "name": "Light3D", - "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", - "shortDescription": "A collection of light object for 3D.", - "version": "2.0.0", - "description": "A collection of light object for 3D.", - "origin": { - "identifier": "Light3D", - "name": "gdevelop-extension-store" - }, - "tags": [ - "3d", - "light" - ], - "authorIds": [ - "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" - ], - "changelog": [ - { - "version": "2.0.0", - "breaking": "- Point and spot lights now fade with the distance like they do with the 3D renderer of recent GDevelop versions (Three.js r185), including on previous GDevelop versions. Lights made for a previous version of the extension need a higher intensity (and possibly a lower decay) to look the same." - } - ], - "dependencies": [], - "globalVariables": [], - "sceneVariables": [], - "eventsFunctions": [ - { - "fullName": "", - "functionType": "Action", - "name": "onFirstSceneLoaded", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "// Before Three.js r165, GDevelop rendered with \"legacy lights\": point and spot", - "// lights faded linearly up to their range and every light color was", - "// multiplied by PI. Recent GDevelop versions use the physically based falloff", - "// of Three.js r185 instead, which is what the light properties are tuned for.", - "// Use the same falloff with older GDevelop versions so that lights look the", - "// same with every version:", - "// - distances are divided by 100 because recent GDevelop versions render 3D", - "// with a default world scale of 100 pixels per unit, while older versions", - "// work in pixels,", - "// - the attenuation is divided by PI as the legacy light colors are multiplied by PI.", - "// It must be patched before any shader using lights is compiled, as Three.js", - "// caches compiled shaders.", - "const lightsParsBegin = THREE.ShaderChunk.lights_pars_begin;", - "if (!lightsParsBegin.includes('#if defined ( LEGACY_LIGHTS )')) {", - " return;", - "}", - "THREE.ShaderChunk.lights_pars_begin = lightsParsBegin.replace(", - " /#if defined \\( LEGACY_LIGHTS \\)[\\s\\S]*?#else/,", - " [", - " '#if defined ( LEGACY_LIGHTS )',", - " '\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance * 0.01, decayExponent ), 0.01 );',", - " '\\t\\tif ( cutoffDistance > 0.0 ) {',", - " '\\t\\t\\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );',", - " '\\t\\t}',", - " '\\t\\treturn distanceFalloff * RECIPROCAL_PI;',", - " '\\t#else',", - " ].join('\\n')", - ");" - ], - "parameterObjects": "", - "useStrict": true, - "eventsSheetExpanded": true - } - ], - "parameters": [], - "objectGroups": [] - }, - { - "description": "Define spot light helper classes JavaScript code.", - "fullName": "Define spot light helper classes", - "functionType": "Action", - "name": "DefineSpotLightHelperClasses", - "private": true, - "sentence": "Define spot light helper classes JavaScript code", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "//@ts-ignore", - "if (gdjs.__light3DExtension.spot) {", - " //@ts-ignore", - " return;", - "}", - "", - "/**", - " * @typedef {gdjs.CustomRuntimeObject3D & {__light3D: THREE.SpotLight, _getIsCastingShadow: () => boolean, _getConeAngle: () => number, _getColor: () => string}} SpotLightRuntimeObject", - " */", - "", - "const game = runtimeScene.getGame();", - "", - "const coneLength = 64;", - "", - "class SpotLightHelper extends THREE.Object3D {", - " /** @type {SpotLightRuntimeObject} */", - " object;", - " /** @type {THREE.LineSegments} */", - " cone;", - " /** @type {THREE.LineSegments} */", - " centerLine;", - " /** @type {THREE.Mesh} */", - " originBox;", - "", - "\t/**", - " * @param {SpotLightRuntimeObject} object", - "\t */", - " constructor(object) {", - " super();", - " this.object = object;", - " this.type = 'SpotLightHelper';", - "", - " const coneGeometry = new THREE.BufferGeometry();", - " const conePositions = [", - " 0, 0, 0, 1, 0, 0,", - " 0, 0, 0, 1, 1, 0,", - " 0, 0, 0, 1, - 1, 0,", - " 0, 0, 0, 1, 0, 1,", - " 0, 0, 0, 1, 0, - 1", - " ];", - " for (let i = 0, j = 1, l = 32; i < l; i++ , j++) {", - " const p1 = (i / l) * Math.PI * 2;", - " const p2 = (j / l) * Math.PI * 2;", - " conePositions.push(", - " 1, Math.cos(p1), Math.sin(p1),", - " 1, Math.cos(p2), Math.sin(p2)", - " );", - " }", - " coneGeometry.setAttribute('position', new THREE.Float32BufferAttribute(conePositions, 3));", - " this.cone = new THREE.LineSegments(", - " coneGeometry,", - " new THREE.LineBasicMaterial({ fog: false, toneMapped: false })", - " );", - " this.add(this.cone);", - " const centerLineGeometry = new THREE.BufferGeometry();", - " centerLineGeometry.setAttribute('position', new THREE.Float32BufferAttribute([", - " 0, 0, 0, coneLength, 0, 0", - " ], 3));", - " this.centerLine = new THREE.LineSegments(", - " centerLineGeometry,", - " new THREE.LineBasicMaterial({ fog: false, toneMapped: false })", - " );", - " this.add(this.centerLine);", - "", - " this.originBox = new THREE.Mesh(", - " new THREE.BoxGeometry(16, 16, 16),", - " new THREE.MeshBasicMaterial({ fog: false, toneMapped: false })", - " );", - " this.add(this.originBox);", - " this.update();", - "", - " //@ts-ignore", - " this.originBox.gdjsRuntimeObject = object;", - " }", - "", - " dispose() {", - " this.cone.geometry.dispose();", - " this.cone.material.dispose();", - " this.centerLine.geometry.dispose();", - " this.centerLine.material.dispose();", - " this.originBox.geometry.dispose();", - " this.originBox.material.dispose();", - " }", - "", - " update() {", - " /** @type {number} */", - " const coneAngle = gdjs.toRad(this.object._getConeAngle());", - " const coneWidth = coneLength * Math.sin(coneAngle);", - " const coneHeight = coneLength * Math.cos(coneAngle);", - " this.cone.scale.set(coneHeight, coneWidth, coneWidth);", - " const color = gdjs.rgbOrHexStringToNumber(this.object._getColor());", - " this.cone.material.color.set(color);", - " this.centerLine.material.color.set(color);", - " this.originBox.material.color.set(color);", - " }", - "}", - "", - "/**", - " * @param {string} colorString", - " * @param {THREE.Color} threeColor", - " */", - "const setThreeColor = (colorString, threeColor) => {", - " const integerColor = gdjs.rgbOrHexToRGBColor(colorString);", - " threeColor.r = integerColor[0] / 255;", - " threeColor.g = integerColor[1] / 255;", - " threeColor.b = integerColor[2] / 255;", - "};", - "", - "class SpotLightAdapter {", - " /**", - " * @param object {gdjs.CustomRuntimeObject3D}", - " * @param spotLight {THREE.SpotLight}", - " */", - " constructor(object, spotLight) {", - " this.object = object;", - " this.spotLight = spotLight;", - " }", - "", - " /**", - " * @param targetX {number}", - " * @param targetY {number}", - " * @param targetZ {number}", - " */", - " lookAtPosition(targetX, targetY, targetZ) {", - " const runtimeSene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", - "", - " // Remove from the parent to avoid the scene scale of -1 on Y to mess with the formula.", - " const parent = this.spotLight.parent;", - " this.spotLight.parent = null;", - " this.spotLight.lookAt(", - " targetX * inverseWorldScale,", - " targetY * inverseWorldScale,", - " targetZ * inverseWorldScale);", - " this.spotLight.parent = parent;", - "", - " // Angle setters update Three.js angles, so we save them first.", - " const rotationX = gdjs.toDegrees(this.spotLight.rotation.x);", - " const rotationY = gdjs.toDegrees(this.spotLight.rotation.y);", - " const rotationZ = gdjs.toDegrees(this.spotLight.rotation.z);", - " this.object.setRotationX(rotationX);", - " this.object.setRotationY(rotationY);", - " this.object.setAngle(rotationZ + 90);", - " }", - "", - " /**", - " * @param color {string}", - " */", - " setColor(color) {", - " setThreeColor(color, this.spotLight.color);", - " }", - "", - " /**", - " * @param intensity {number}", - " */", - " setIntensity(intensity) {", - " this.spotLight.intensity = intensity;", - " }", - "", - " /**", - " * @param decay {number}", - " */", - " setDecay(decay) {", - " this.spotLight.decay = decay;", - " }", - "", - " /**", - " * @param value {number}", - " */", - " setConeLength(value) {", - " const runtimeSene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", - " this.spotLight.distance = value * inverseWorldScale;", - " }", - "", - " /**", - " * @param coneAngle {number}", - " */", - " setConeAngle(coneAngle) {", - " this.spotLight.angle = coneAngle * Math.PI / 180;", - " }", - "", - " /**", - " * @param smoothing {number}", - " */", - " setSmoothing(smoothing) {", - " this.spotLight.penumbra = smoothing;", - " }", - "", - " /**", - " * @param isCastingShadow {boolean}", - " */", - " setCastingShadow(isCastingShadow) {", - " // This is applied by applyVisibilityAndShadow", - " }", - "", - " /**", - " * @param shadowQuality {\"Low\" | \"Medium\" | \"High\" | \"VeryHigh\"}", - " */", - " setShadowQuality(shadowQuality) {", - " let size = 512;", - " switch (shadowQuality) {", - " case \"Low\":", - " size = 256;", - " break;", - " case \"Medium\":", - " size = 512;", - " break;", - " case \"High\":", - " size = 1024;", - " break;", - " case \"VeryHigh\":", - " size = 2048;", - " break;", - " }", - " const shadow = this.spotLight.shadow;", - " const mapSize = shadow.mapSize;", - " if (mapSize.width !== size) {", - " mapSize.set(size, size);", - "", - " // Force the recreation of the shadow map texture:", - " if (shadow.map) {", - " shadow.map.dispose();", - " shadow.map = null;", - " }", - " shadow.needsUpdate = true;", - " }", - " }", - "", - " /**", - " * @param value {number}", - " */", - " setShadowCameraNearPlane(value) {", - " const runtimeSene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", - " this.spotLight.shadow.camera.near = value * inverseWorldScale;", - " }", - "", - " /**", - " * @param value {number}", - " */", - " setShadowCameraFarPlane(value) {", - " const runtimeSene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", - " this.spotLight.shadow.camera.far = value * inverseWorldScale;", - " }", - "", - " /**", - " * @param value {number}", - " * @param quality {\"Low\" | \"Medium\" | \"High\" | \"VeryHigh\"}", - " * @param coneAngle {number}", - " */", - " setShadowBias(value, quality, coneAngle) {", - " const runtimeSene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", - " const biasMultiplier =", - " quality === 'Low'", - " ? 8", - " : quality === 'Medium'", - " ? 4", - " : quality === 'High'", - " ? 2 : 1;", - " // Multiply by 0.125 to make values around 0.001 work best.", - " this.spotLight.shadow.bias = -value * 0.125 * biasMultiplier *", - " Math.tan(gdjs.toRad(gdjs.evtTools.common.clamp(coneAngle, 0, 89))) *", - " inverseWorldScale;", - " }", - "", - " /**", - " * @param resourceName {string}", - " */", - " setImage(resourceName) {", - " if (!resourceName) {", - " this.spotLight.map = null;", - " return;", - " }", - " const texture = game.getImageManager().getThreeTexture(resourceName);", - " this.spotLight.map = texture;", - " }", - "}", - "", - "//@ts-ignore", - "gdjs.__light3DExtension.spot = {", - " SpotLightAdapter,", - " SpotLightHelper,", - "}" - ], - "parameterObjects": "", - "useStrict": true, - "eventsSheetExpanded": true - } - ], - "parameters": [], - "objectGroups": [] - }, - { - "description": "Define point light helper classes JavaScript code.", - "fullName": "Define point light helper classes", - "functionType": "Action", - "name": "DefinePointLightHelperClasses", - "private": true, - "sentence": "Define point light helper classes JavaScript code", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "//@ts-ignore", - "if (gdjs.__light3DExtension.point) {", - " //@ts-ignore", - " return;", - "}", - "", - "/**", - " * @typedef {gdjs.CustomRuntimeObject3D & {__light3D: THREE.PointLight, _getIsCastingShadow: () => boolean, _getColor: () => string}} PointLightRuntimeObject", - " */", - "", - "const game = runtimeScene.getGame();", - "", - "/**", - " * @extends {THREE.Mesh}", - " */", - "class PointLightHelper extends THREE.Mesh {", - " /** @type {PointLightRuntimeObject} */", - " object;", - "", - "\t/**", - " * @param {PointLightRuntimeObject} object", - "\t */", - " constructor(object) {", - " const geometry = new THREE.SphereGeometry(16, 4, 2);", - " const material = new THREE.MeshBasicMaterial({ wireframe: true, fog: false, toneMapped: false });", - " super(geometry, material);", - " this.object = object;", - " this.update();", - "", - " //@ts-ignore", - " this.gdjsRuntimeObject = object;", - " }", - "", - " dispose() {", - " this.geometry.dispose();", - " this.material.dispose();", - " }", - "", - " update() {", - " const color = gdjs.rgbOrHexStringToNumber(this.object._getColor());", - " this.material.color.set(color);", - " }", - "}", - "", - "/**", - " * @param {string} colorString", - " * @param {THREE.Color} threeColor", - " */", - "const setThreeColor = (colorString, threeColor) => {", - " const integerColor = gdjs.rgbOrHexToRGBColor(colorString);", - " threeColor.r = integerColor[0] / 255;", - " threeColor.g = integerColor[1] / 255;", - " threeColor.b = integerColor[2] / 255;", - "};", - "", - "class PointLightAdapter {", - " /**", - " * @param object {gdjs.CustomRuntimeObject3D}", - " * @param pointLight {THREE.PointLight}", - " */", - " constructor(object, pointLight) {", - " this.object = object;", - " this.pointLight = pointLight;", - " }", - "", - " /**", - " * @param color {string}", - " */", - " setColor(color) {", - " setThreeColor(color, this.pointLight.color);", - " }", - "", - " /**", - " * @param intensity {number}", - " */", - " setIntensity(intensity) {", - " this.pointLight.intensity = intensity;", - " }", - "", - " /**", - " * @param decay {number}", - " */", - " setDecay(decay) {", - " this.pointLight.decay = decay;", - " }", - "", - " /**", - " * @param value {number}", - " */", - " setRange(value) {", - " const runtimeScene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", - " this.pointLight.distance = value * inverseWorldScale;", - " }", - "", - " /**", - " * @param isCastingShadow {boolean}", - " */", - " setCastingShadow(isCastingShadow) {", - " // This is applied by applyVisibilityAndShadow", - " }", - "", - " /**", - " * @param shadowQuality {\"Low\" | \"Medium\" | \"High\"}", - " */", - " setShadowQuality(shadowQuality) {", - " let size = 512;", - " switch (shadowQuality) {", - " case \"Low\":", - " size = 512;", - " break;", - " case \"Medium\":", - " size = 1024;", - " break;", - " case \"High\":", - " size = 2048;", - " break;", - " }", - " const shadow = this.pointLight.shadow;", - " const mapSize = shadow.mapSize;", - " if (mapSize.width !== size) {", - " mapSize.set(size, size);", - "", - " // Force the recreation of the shadow map texture:", - " if (shadow.map) {", - " shadow.map.dispose();", - " shadow.map = null;", - " }", - " shadow.needsUpdate = true;", - " }", - " }", - "", - " /**", - " * @param value {number}", - " */", - " setShadowCameraNearPlane(value) {", - " const runtimeSene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", - "", - " this.pointLight.shadow.camera.near = value * inverseWorldScale;", - " }", - "", - " /**", - " * @param value {number}", - " */", - " setShadowCameraFarPlane(value) {", - " const runtimeSene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", - "", - " this.pointLight.shadow.camera.far = value * inverseWorldScale;", - " }", - "", - " /**", - " * @param value {number}", - " * @param quality {\"Low\" | \"Medium\" | \"High\"}", - " */", - " setShadowBias(value, quality) {", - " const runtimeSene = this.object.getRuntimeScene();", - " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", - "", - " const biasMultiplier =", - " quality === 'Low'", - " ? 4", - " : quality === 'Medium'", - " ? 2", - " : 1;", - " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", - " }", - "}", - "", - "//@ts-ignore", - "gdjs.__light3DExtension.point = {", - " PointLightAdapter,", - " PointLightHelper,", - "}" - ], - "parameterObjects": "", - "useStrict": true, - "eventsSheetExpanded": true - } - ], - "parameters": [], - "objectGroups": [] - }, - { - "description": "Define helper classes JavaScript code.", - "fullName": "Define helper classes", - "functionType": "Action", - "name": "DefineHelperClasses", - "private": true, - "sentence": "Define helper classes JavaScript code", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "//@ts-ignore", - "if (gdjs.__light3DExtension) {", - " //@ts-ignore", - " return;", - "}", - "", - "/**", - " * @typedef {gdjs.CustomRuntimeObject3D & {__light3D: THREE.SpotLight | THREE.PointLight, _getIsCastingShadow: () => boolean}} LightRuntimeObject", - " */", - "", - "const game = runtimeScene.getGame();", - "const isInGameEdition = game.isInGameEdition && game.isInGameEdition();", - "const logger = new gdjs.Logger('3D lights');", - "", - "", - "class Light3DRenderer extends gdjs.CustomRuntimeObject3DRenderer {", - "", - " constructor(", - " object,", - " instanceContainer,", - " parent", - " ) {", - " super(object, instanceContainer, parent);", - " }", - "", - " _updateThreeGroup() {", - " /** @type {LightRuntimeObject} */", - " //@ts-ignore", - " const object = this._object;", - " const threeObject3D = this.get3DRendererObject();", - "", - " threeObject3D.rotation.set(", - " gdjs.toRad(object.getRotationX()),", - " gdjs.toRad(object.getRotationY()),", - " gdjs.toRad(object.angle)", - " );", - "", - " threeObject3D.position.set(", - " object.getX(),", - " object.getY(),", - " object.getZ()", - " );", - "", - " // Force the scale to 1 because the light doesn't really has a size.", - " threeObject3D.scale.set(", - " object.isFlippedX() ? -1 : 1,", - " object.isFlippedY() ? -1 : 1,", - " object.isFlippedZ() ? -1 : 1", - " );", - "", - " threeObject3D.visible = !this._object.hidden;", - "", - " const spotLight = object.__light3D;", - "", - " const editor = game.getInGameEditor ? game.getInGameEditor() : null;", - "", - " spotLight.castShadow = false;", - " spotLight.visible = false;", - "", - " // Instances hidden at start stay visible in the editor, but their light must not shine.", - " const isHiddenAtStartInEditor =", - " !!editor && !!editor.isInstanceHiddenAtStart && editor.isInstanceHiddenAtStart(object);", - "", - " if (!object.isHidden() && !isHiddenAtStartInEditor) {", - " let isSelected = false;", - " if (editor) {", - " const selectedObject = editor._selection.getLastSelectedObject();", - " let parentObject = object;", - " isSelected = parentObject === selectedObject;", - " while (!isSelected && parentObject.getInstanceContainer()", - " //@ts-ignore", - " .getOwner) {", - " parentObject = parentObject.getInstanceContainer()", - " //@ts-ignore", - " .getOwner();", - " isSelected = parentObject === selectedObject;", - " }", - " }", - " if (!editor || !editor.areEffectsHidden() || isSelected) {", - " let rootObject = object;", - " while (rootObject.getInstanceContainer()", - " //@ts-ignore", - " .getOwner) {", - " rootObject = rootObject.getInstanceContainer()", - " //@ts-ignore", - " .getOwner();", - " }", - " const runtimeScene = rootObject.getRuntimeScene();", - " let distanceSq = 0;", - " if (!isSelected) {", - " const layerName = rootObject.getLayer();", - " const cameraX = gdjs.evtTools.camera.getCameraX(runtimeScene, layerName, 0);", - " const cameraY = gdjs.evtTools.camera.getCameraY(runtimeScene, layerName, 0);", - " const cameraZ = gdjs.scene3d.camera.getCameraZ(runtimeScene, layerName, 0);", - " const deltaX = rootObject.getX() - cameraX;", - " const deltaY = rootObject.getY() - cameraY;", - " const deltaZ = rootObject.getZ() - cameraZ;", - " distanceSq = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;", - " }", - " getLightManager(", - " //@ts-ignore", - " runtimeScene", - " ).applyVisibilityAndShadow(object, distanceSq);", - " }", - " }", - "", - " // Force the visibility to be checked every frame", - " this._isContainerDirty = true;", - " }", - "}", - "", - "const editorLightCountMax = {", - " value: 20", - "};", - "", - "const lightCountMax = {", - " value: 20", - "};", - "", - "const editorLightShadowCountMax = {", - " value: 4", - "};", - "", - "const lightShadowCountMax = {", - " value: 4", - "};", - "", - "gdjs.registerRuntimeScenePreEventsCallback(", - " runtimeScene => {", - " getLightManager(", - " //@ts-ignore", - " runtimeScene.getScene()", - " ).clear();", - " });", - "if (gdjs.registerInGameEditorPostStepCallback) {", - " gdjs.registerInGameEditorPostStepCallback(", - " inGameEditor => {", - " getLightManager(", - " //@ts-ignore", - " inGameEditor.getEditedInstanceContainer().getScene()", - " ).clear();", - " });", - "}", - "", - "/**", - " * How many lights of each kind this device can take.", - " *", - " * These are hard limits rather than performance trade-offs. three.js binds one", - " * texture unit per shadow map and one more for a spot light's projected", - " * texture, and spends a varying on every shadow casting light. Going over what", - " * the driver allows does not make the scene slower - the shader fails to link", - " * and everything using that material renders black. Only 16 fragment texture", - " * units and 15 varyings are guaranteed across devices, and materials need most", - " * of those, so the budget is read from the device instead of being fixed.", - " *", - " * The budget is shared between the light kinds a scene uses, so it is given", - " * how many of them there are rather than assuming all of them: a scene lit by", - " * point lights alone would otherwise have three quarters of its texture units", - " * held back for kinds that never show up.", - " *", - " * @param {THREE.WebGLRenderer | null} threeRenderer", - " * @param {number} kindCount How many light kinds the scene uses, at least one.", - " * @returns {{shadowCount: number, mapCount: number, count: number}}", - " */", - "function computeDeviceLightBudget(threeRenderer, kindCount) {", - " // When the renderer cannot be reached, assume the guaranteed minimums", - " // rather than the device this happens to be running on.", - " const capabilities = (threeRenderer && threeRenderer.capabilities) || {};", - " const maxTextures = capabilities.maxTextures || 16;", - " const maxVaryings = capabilities.maxVaryings || 15;", - " const maxFragmentUniforms = capabilities.maxFragmentUniforms || 224;", - "", - " // Left for the material itself: colour, normal, roughness, metalness,", - " // emissive, ambient occlusion and the environment map.", - " const textureUnitsForMaterials = 8;", - " // Varyings already spent on positions, normals, uvs and fog.", - " const varyingsForGeometry = 12;", - " // Uniform vectors already spent on matrices, material properties and the", - " // uv transforms of a material's own textures.", - " const uniformVectorsForMaterials = 64;", - " // Measured on a MeshStandardMaterial: a point light costs 4 uniform", - " // vectors, a spot light 7, and casting a shadow adds around 11 more on", - " // top of either. Take the dearest of them, since a kind count says how", - " // many kinds a scene uses but not which ones.", - " const uniformVectorsPerLight = 8;", - " const uniformVectorsPerShadow = 12;", - "", - " const availableTextureUnits = Math.max(", - " kindCount, maxTextures - textureUnitsForMaterials);", - " const availableVaryings = Math.max(", - " kindCount, maxVaryings - varyingsForGeometry);", - " const availableUniformVectors = Math.max(", - " 16, maxFragmentUniforms - uniformVectorsForMaterials);", - "", - " // Every shadow caster costs a texture unit and a varying, whichever kind", - " // it is. Keep a share of the texture units back for projected textures.", - " const shadowCount = Math.max(0, Math.min(", - " Math.floor(availableTextureUnits / (kindCount + 1)),", - " Math.floor(availableVaryings / kindCount)", - " ));", - " // What is left bounds how many spot lights can project a texture. Lights", - " // that neither cast a shadow nor project a texture cost no texture unit.", - " const mapCount = Math.max(0,", - " availableTextureUnits - shadowCount * kindCount);", - " // Shadow casters are paid for first, then the uniform vectors left over", - " // decide how many lights of each kind can be lit at all.", - " const uniformVectorsForShadows =", - " shadowCount * kindCount * uniformVectorsPerShadow;", - " const count = Math.max(1, Math.floor(", - " Math.max(uniformVectorsPerLight * kindCount,", - " availableUniformVectors - uniformVectorsForShadows)", - " / (uniformVectorsPerLight * kindCount)));", - "", - " return { shadowCount, mapCount, count };", - "}", - "", - "/**", - " * A capacity that never goes past what the device can take, however high the", - " * game sets its own maximum. Both sides are read through getters, so that", - " * changing the game's maximum at runtime still takes effect, and so that a", - " * device budget recomputed for more light kinds is picked up as well.", - " *", - " * @param {{value: number}} requested", - " * @param {() => number} getDeviceMax", - " * @returns {{value: number}}", - " */", - "function makeDeviceCappedCapacity(requested, getDeviceMax) {", - " return {", - " get value() {", - " return Math.min(requested.value, getDeviceMax());", - " }", - " };", - "}", - "", - "/**", - " * Get the light manager of a scene.", - " * @param {gdjs.RuntimeScene & {__lightManager: LightManager}} runtimeScene", - " */", - "function getLightManager(runtimeScene) {", - " if (!runtimeScene.__lightManager) {", - " // Create the shared manager if necessary.", - " const requestedCount = isInGameEdition", - " ? editorLightCountMax : lightCountMax;", - " const requestedShadowCount = isInGameEdition", - " ? editorLightShadowCountMax : lightShadowCountMax;", - "", - " // The renderer is read anew on every recomputation: it may not", - " // exist yet when the manager is created on the first frame.", - " runtimeScene.__lightManager = new LightManager(", - " requestedCount, requestedShadowCount,", - " kindCount => computeDeviceLightBudget(", - " runtimeScene.getGame().getRenderer().getThreeRenderer(),", - " kindCount));", - " }", - " return runtimeScene.__lightManager;", - "}", - "", - "/**", - " * Lights kept sorted by their distance to the camera, capped to a fixed", - " * number of entries.", - " *", - " * The cap is a *count* and not a weighted cost, on purpose: three.js compiles", - " * the number of lights of each type into its shaders, so a list whose length", - " * changes from one frame to the next forces a shader recompilation every time", - " * a new length is seen. A count based cap keeps the length pinned to", - " * `capacity` for as long as enough lights are candidates.", - " */", - "class CappedLightList {", - " /** @type {Array<{object: LightRuntimeObject, sortDistance: number}>} */", - " objects = [];", - " /** @type {{value: number}} */", - " capacity;", - " /** @type {(object: LightRuntimeObject) => void} */", - " onInsertion;", - " /** @type {(object: LightRuntimeObject) => void} */", - " onDeletion;", - "", - " /**", - " * @param {{value: number}} capacity", - " * @param {(object: LightRuntimeObject) => void} onInsertion", - " * @param {(object: LightRuntimeObject) => void} onDeletion", - " */", - " constructor(capacity, onInsertion, onDeletion) {", - " this.capacity = capacity;", - " this.onInsertion = onInsertion;", - " this.onDeletion = onDeletion;", - " }", - "", - " clear() {", - " this.objects.length = 0;", - " }", - "", - " /** Drop the farthest lights until the list fits its capacity again. */", - " trimToCapacity() {", - " while (this.objects.length > this.capacity.value) {", - " this.onDeletion(this.objects.pop().object);", - " }", - " }", - "", - " /**", - " * @param object {LightRuntimeObject}", - " * @param sortDistance {number} The squared distance to the camera.", - " */", - " insertByDistance(object, sortDistance) {", - " // A render can happen without a game step in between (the editor", - " // and the gameplay test harness render a paused game), so a light", - " // can be offered again before the lists were cleared. Keep it once,", - " // or the duplicates would evict the other lights - but apply its", - " // state again, as the renderer reset it before offering the light.", - " for (const pair of this.objects) {", - " if (pair.object === object) {", - " this.onInsertion(object);", - " return;", - " }", - " }", - " let insertionIndex = 0;", - " for (let index = this.objects.length - 1; index >= 0; index--) {", - " if (sortDistance >= this.objects[index].sortDistance) {", - " insertionIndex = index + 1;", - " break;", - " }", - " }", - " if (insertionIndex >= this.capacity.value) {", - " // Farther away than every light already filling the list.", - " return;", - " }", - "", - " // Make room first, reusing an evicted pair to avoid allocating one", - " // on every frame.", - " let pair = null;", - " while (this.objects.length >= this.capacity.value) {", - " pair = this.objects.pop();", - " this.onDeletion(pair.object);", - " }", - " if (pair) {", - " pair.object = object;", - " pair.sortDistance = sortDistance;", - " }", - " else {", - " pair = { object, sortDistance };", - " }", - " this.objects.splice(insertionIndex, 0, pair);", - " this.onInsertion(object);", - " }", - "}", - "", - "/** @param object {LightRuntimeObject} */", - "const showLight = (object) => { object.__light3D.visible = true; };", - "/** @param object {LightRuntimeObject} */", - "const hideLight = (object) => { object.__light3D.visible = false; };", - "/** @param object {LightRuntimeObject} */", - "const enableShadow = (object) => { object.__light3D.castShadow = true; };", - "/** @param object {LightRuntimeObject} */", - "const disableShadow = (object) => { object.__light3D.castShadow = false; };", - "", - "/**", - " * The lights of a scene, budgeted so that the numbers three.js compiles into", - " * its shaders stay put.", - " *", - " * three.js keys its shader programs on how many lights of each kind it can", - " * see - NUM_POINT_LIGHTS, NUM_SPOT_LIGHTS, NUM_SPOT_LIGHT_MAPS and the", - " * matching shadow counts. A single budget shared by every kind keeps the", - " * *total* pinned to the cap but lets the mix drift as the camera moves, and", - " * each mix that has not been seen before costs a shader compilation - a", - " * stutter the player feels. So each kind gets its own budget instead, which", - " * pins each of those numbers individually.", - " */", - "class LightManager {", - " /** @type {Map} Visible lights, by light kind. */", - " visibleLists = new Map();", - " /** @type {Map} Shadow casters, by light kind. */", - " shadowLists = new Map();", - " /** @type {Map} Lit light capacity, by light kind. */", - " maxCountByKind;", - " /** @type {Map} Shadow caster capacity, by light kind. */", - " shadowCountByKind;", - " /** @type {Set} The light kinds this scene has actually used. */", - " usedKinds = new Set();", - " /** @type {{shadowCount: number, mapCount: number, count: number}} */", - " deviceBudget;", - " /** @type {(kindCount: number) => {shadowCount: number, mapCount: number, count: number}} */", - " _computeDeviceBudget;", - " /** @type {{value: number}} */", - " _requestedCount;", - " /** @type {{value: number}} */", - " _requestedShadowCount;", - "", - " /**", - " * @param maxCount {{value: number}} The maximum number of lit lights, for", - " * each light kind, as the game asked for it.", - " * @param shadowCount {{value: number}} The maximum number of shadow", - " * casting lights, for each light kind, as the game asked for it.", - " * @param computeDeviceBudget {(kindCount: number) => {shadowCount: number, mapCount: number, count: number}}", - " * What the device can take, for a given number of light kinds.", - " */", - " constructor(maxCount, shadowCount, computeDeviceBudget) {", - " this._computeDeviceBudget = computeDeviceBudget;", - " this._requestedCount = maxCount;", - " this._requestedShadowCount = shadowCount;", - " // A scene that uses lights at all uses at least one kind of them.", - " this.deviceBudget = computeDeviceBudget(1);", - "", - " // Spot lights that project a texture already spend a texture unit on", - " // that texture, so they get the tighter of the two budgets.", - " this.maxCountByKind = new Map([", - " ['point', makeDeviceCappedCapacity(", - " maxCount, () => this.deviceBudget.count)],", - " ['spot', makeDeviceCappedCapacity(", - " maxCount, () => this.deviceBudget.count)],", - " ['spotWithMap', makeDeviceCappedCapacity(maxCount, () => Math.min(", - " this.deviceBudget.count, this.deviceBudget.mapCount))],", - " ]);", - " this.shadowCountByKind = new Map([", - " ['point', makeDeviceCappedCapacity(", - " shadowCount, () => this.deviceBudget.shadowCount)],", - " ['spot', makeDeviceCappedCapacity(", - " shadowCount, () => this.deviceBudget.shadowCount)],", - " ['spotWithMap', makeDeviceCappedCapacity(", - " shadowCount, () => this.deviceBudget.shadowCount)],", - " ]);", - " }", - "", - " /**", - " * Take note that the scene uses lights of this kind, sharing the device", - " * budget between one more kind if it had not been seen before.", - " *", - " * A kind can only ever be added, never dropped: a light that goes away for", - " * a while must not give the others a wider budget, or the numbers three.js", - " * compiles into its shaders would move again.", - " *", - " * @param kind {string}", - " */", - " _useKind(kind) {", - " if (this.usedKinds.has(kind)) {", - " return;", - " }", - " this.usedKinds.add(kind);", - " this.deviceBudget = this._computeDeviceBudget(this.usedKinds.size);", - "", - " // The budget just shrank: evict the lights that no longer fit, so", - " // that even this frame stays within what the device can take.", - " for (const list of this.visibleLists.values()) {", - " list.trimToCapacity();", - " }", - " for (const list of this.shadowLists.values()) {", - " list.trimToCapacity();", - " }", - "", - " if (this.deviceBudget.count < this._requestedCount.value", - " || this.deviceBudget.shadowCount", - " < this._requestedShadowCount.value) {", - " logger.info(", - " 'This device limits 3D lights to ' + this.deviceBudget.count", - " + ' per kind (' + this.deviceBudget.shadowCount", - " + ' casting a shadow, ' + this.deviceBudget.mapCount", - " + ' projecting a texture), now that ' + this.usedKinds.size", - " + ' kind(s) of light share its budget. Going over what it '", - " + 'reports would stop the shaders from linking.'", - " );", - " }", - " }", - "", - " clear() {", - " for (const list of this.visibleLists.values()) {", - " list.clear();", - " }", - " for (const list of this.shadowLists.values()) {", - " list.clear();", - " }", - " }", - "", - " /**", - " * The kind of a light, as far as the shaders are concerned. Lights of", - " * different kinds are counted separately by three.js, so they must be", - " * budgeted separately too.", - " * @param light {THREE.SpotLight | THREE.PointLight}", - " * @returns {string}", - " */", - " static getLightKind(light) {", - " //@ts-ignore - `isSpotLight` is set by three.js on SpotLight instances.", - " if (!light.isSpotLight) {", - " return 'point';", - " }", - " // A projected texture adds to NUM_SPOT_LIGHT_MAPS, so a spot light", - " // that has one is a different kind from a spot light that has not.", - " //@ts-ignore - only spot lights have a projected texture.", - " return light.map ? 'spotWithMap' : 'spot';", - " }", - "", - " /**", - " * @param lists {Map}", - " * @param kind {string}", - " * @param capacity {{value: number}}", - " * @param onInsertion {(object: LightRuntimeObject) => void}", - " * @param onDeletion {(object: LightRuntimeObject) => void}", - " * @returns {CappedLightList}", - " */", - " static _getListForKind(lists, kind, capacity, onInsertion, onDeletion) {", - " let list = lists.get(kind);", - " if (!list) {", - " list = new CappedLightList(capacity, onInsertion, onDeletion);", - " lists.set(kind, list);", - " }", - " return list;", - " }", - "", - " /**", - " * @param object {LightRuntimeObject}", - " * @param distance {number} The squared distance to the camera.", - " */", - " applyVisibilityAndShadow(object, distance) {", - " const light = object.__light3D;", - " const kind = LightManager.getLightKind(light);", - " this._useKind(kind);", - "", - " if (object._getIsCastingShadow()) {", - " LightManager._getListForKind(", - " this.shadowLists, kind, this.shadowCountByKind.get(kind),", - " enableShadow, disableShadow", - " ).insertByDistance(object, distance);", - " }", - " LightManager._getListForKind(", - " this.visibleLists, kind, this.maxCountByKind.get(kind),", - " showLight, hideLight", - " ).insertByDistance(object, distance);", - " }", - "}", - "", - "//@ts-ignore", - "gdjs.__light3DExtension = {", - " Light3DRenderer,", - " lightCountMax,", - " lightShadowCountMax,", - "}" - ], - "parameterObjects": "", - "useStrict": true, - "eventsSheetExpanded": true - } - ], - "parameters": [], - "objectGroups": [] - }, - { - "description": "the maximum number of nearest lights displayed simultaneously, counted separately for each kind of light (point lights, spot lights, spot lights projecting a texture). Devices that can't take that many lights enforce a lower limit.", - "fullName": "Max lights count", - "functionType": "ExpressionAndCondition", - "name": "LightCountMax", - "sentence": "max lights count", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::DefineHelperClasses" - }, - "parameters": [ - "", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": "eventsFunctionContext.returnValue = gdjs.__light3DExtension.lightCountMax.value;", - "parameterObjects": "", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "LightCountMax", - "name": "SetLightCountMax", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::DefineHelperClasses" - }, - "parameters": [ - "", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const value = eventsFunctionContext.getArgument(\"Value\");", - "", - "gdjs.__light3DExtension.lightCountMax.value = value;" - ], - "parameterObjects": "", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [], - "objectGroups": [] - }, - { - "description": "the maximum number of nearest lights displayed with shadow simultaneously, counted separately for each kind of light (point lights, spot lights, spot lights projecting a texture). Devices that can't take that many shadows enforce a lower limit.", - "fullName": "Max lights with shadow count", - "functionType": "ExpressionAndCondition", - "name": "LightShadowCountMax", - "sentence": "max lights with shadow count", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::DefineHelperClasses" - }, - "parameters": [ - "", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": "eventsFunctionContext.returnValue = gdjs.__light3DExtension.lightShadowCountMax.value;", - "parameterObjects": "", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "LightShadowCountMax", - "name": "SetLightShadowCountMax", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::DefineHelperClasses" - }, - "parameters": [ - "", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const value = eventsFunctionContext.getArgument(\"Value\");", - "", - "gdjs.__light3DExtension.lightShadowCountMax.value = value;" - ], - "parameterObjects": "", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [], - "objectGroups": [] - } - ], - "eventsFunctionsFolderStructure": { - "folderName": "__ROOT", - "children": [ - { - "functionName": "onFirstSceneLoaded" - }, - { - "functionName": "DefineHelperClasses" - }, - { - "functionName": "DefineSpotLightHelperClasses" - }, - { - "functionName": "DefinePointLightHelperClasses" - }, - { - "functionName": "LightCountMax" - }, - { - "functionName": "SetLightCountMax" - }, - { - "functionName": "LightShadowCountMax" - }, - { - "functionName": "SetLightShadowCountMax" - } - ] - }, - "eventsBasedBehaviors": [], - "eventsBasedObjects": [ - { - "areaMaxX": 20, - "areaMaxY": 20, - "areaMaxZ": 20, - "areaMinX": -20, - "areaMinY": -20, - "areaMinZ": -20, - "defaultName": "SpotLight", - "description": "Light up a cone like a flashlight.", - "fullName": "3D spot light", - "helpPath": "", - "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWZsYXNobGlnaHQiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNOSwxMEw2LDVIMThMMTUsMTBIOU0xOCw0SDZWMkgxOFY0TTksMjJWMTFIMTVWMjJIOU0xMiwxM0ExLDEgMCAwLDAgMTEsMTRBMSwxIDAgMCwwIDEyLDE1QTEsMSAwIDAsMCAxMywxNEExLDEgMCAwLDAgMTIsMTNaIiAvPjwvc3ZnPg==", - "is3D": true, - "isUsingLegacyInstancesRenderer": false, - "name": "SpotLight3D", - "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/b627f8e676b3aac26945b2c38db0cfa787d34d2eff23755d4eb1289452f6cd28_flashlight.svg", - "objects": [ - { - "assetStoreId": "", - "name": "Placeholder", - "persistentUuid": "6786eefd-3c18-4fcb-b3ae-95b07f953045", - "type": "Scene3D::Cube3DObject", - "variables": [], - "effects": [], - "behaviors": [], - "content": { - "width": 80, - "height": 80, - "depth": 80, - "enableTextureTransparency": false, - "facesOrientation": "Z", - "frontFaceResourceName": "", - "backFaceResourceName": "", - "backFaceUpThroughWhichAxisRotation": "X", - "leftFaceResourceName": "", - "rightFaceResourceName": "", - "topFaceResourceName": "", - "bottomFaceResourceName": "", - "frontFaceVisible": true, - "backFaceVisible": true, - "leftFaceVisible": true, - "rightFaceVisible": true, - "topFaceVisible": true, - "bottomFaceVisible": true, - "frontFaceResourceRepeat": false, - "backFaceResourceRepeat": false, - "leftFaceResourceRepeat": false, - "rightFaceResourceRepeat": false, - "topFaceResourceRepeat": false, - "bottomFaceResourceRepeat": false, - "materialType": "Basic", - "tint": "255;255;255", - "isCastingShadow": false, - "isReceivingShadow": false - } - } - ], - "objectsFolderStructure": { - "folderName": "__ROOT", - "children": [ - { - "objectName": "Placeholder" - } - ] - }, - "objectsGroups": [], - "layers": [ - { - "ambientLightColorB": 200, - "ambientLightColorG": 200, - "ambientLightColorR": 200, - "camera2DPlaneMaxDrawingDistance": 5000, - "camera3DFarPlaneDistance": 10000, - "camera3DFieldOfView": 45, - "camera3DNearPlaneDistance": 3, - "cameraType": "", - "followBaseLayerCamera": false, - "isLightingLayer": false, - "isLocked": false, - "name": "", - "renderingType": "", - "visibility": true, - "cameras": [ - { - "defaultSize": true, - "defaultViewport": true, - "height": 0, - "viewportBottom": 1, - "viewportLeft": 0, - "viewportRight": 1, - "viewportTop": 0, - "width": 0 - } - ], - "effects": [] - } - ], - "instances": [ - { - "angle": 0, - "customSize": true, - "depth": 40, - "height": 40, - "layer": "", - "name": "Placeholder", - "persistentUuid": "1310c768-04d4-4133-98d9-37d836f8a990", - "width": 40, - "x": -20, - "y": -20, - "z": -20, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - } - ], - "editionSettings": { - "grid": false, - "gridType": "rectangular", - "gridWidth": 32, - "gridHeight": 32, - "gridDepth": 32, - "gridOffsetX": 0, - "gridOffsetY": 0, - "gridOffsetZ": 0, - "gridColor": 10401023, - "gridAlpha": 0.8, - "snap": false, - "zoomFactor": 9.06473532531222, - "windowMask": false, - "selectedLayer": "", - "gameEditorMode": "instances-editor" - }, - "eventsFunctions": [ - { - "fullName": "", - "functionType": "Action", - "name": "onCreated", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::DefineHelperClasses" - }, - "parameters": [ - "", - "" - ] - }, - { - "type": { - "value": "Light3D::DefineSpotLightHelperClasses" - }, - "parameters": [ - "", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const {", - " Light3DRenderer,", - " //@ts-ignore", - "} = gdjs.__light3DExtension;", - "const {", - " SpotLightAdapter,", - " SpotLightHelper,", - " //@ts-ignore", - "} = gdjs.__light3DExtension.spot;", - "", - "/** @type {gdjs.CustomRuntimeObject3D} */", - "//@ts-ignore", - "const object = objects[0];", - "", - "const game = runtimeScene.getGame();", - "", - "// This is a hack that may break in future releases.", - "// Replace the group that would hold children objects by the light.", - "const layer = object.getInstanceContainer().getLayer(object.getLayer());", - "const group = object.getRenderer()._threeGroup;", - "layer.getRenderer().remove3DRendererObject(group);", - "", - "const spotLight = new THREE.SpotLight(0xffffff);", - "spotLight.position.copy(group.position);", - "spotLight.rotation.copy(group.rotation);", - "spotLight.add(spotLight.target);", - "spotLight.target.position.x = 100;", - "spotLight.up.set(0, 0, 1);", - "spotLight.shadow.camera.up.set(0, 0, 1);", - "//@ts-ignore", - "object.__light3D = spotLight;", - "//@ts-ignore", - "object.__spotLightAdapter = new SpotLightAdapter(object, spotLight);", - "", - "const spotLight3DRenderer = new Light3DRenderer(object, object._instanceContainer, object.getInstanceContainer());", - "object._renderer = spotLight3DRenderer;", - "if (game.isInGameEdition && game.isInGameEdition()) {", - " const spotLightHelper = new SpotLightHelper(object);", - " spotLightHelper.rotation.order = 'ZYX';", - " spotLightHelper.add(spotLight);", - " spotLight3DRenderer._threeGroup = spotLightHelper;", - " layer.getRenderer().add3DRendererObject(spotLightHelper);", - "}", - "else {", - " spotLight3DRenderer._threeGroup = spotLight;", - " layer.getRenderer().add3DRendererObject(spotLight);", - "}", - "", - "spotLight.updateMatrixWorld(true);", - "", - "// Allow to tween the light color.", - "//@ts-ignore", - "if (!object.setColor && !object.getColor) {", - " const prototype = Object.getPrototypeOf(object);", - " prototype.setColor = function(tint) {", - " this._setColor(tint);", - " this.__spotLightAdapter.setColor(tint);", - " }", - " prototype.getColor = function() {", - " return this._getColor(eventsFunctionContext);", - " }", - "}", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": true - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::SpotLight3D::UpdateFromProperties" - }, - "parameters": [ - "Object", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "Action", - "name": "onDestroy", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "/** @type {gdjs.CustomRuntimeObject} */", - "const object = objects[0];", - "// Here runtimeScene is the gdjs.CustomRuntimeObjectInstanceContainer inside the custom object.", - "const gameScene = object.getRuntimeScene();", - "", - "object.__light3D.dispose();", - "object.get3DRendererObject().dispose();", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": true - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "Action", - "name": "onHotReloading", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::SpotLight3D::UpdateFromProperties" - }, - "parameters": [ - "Object", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "Update from properties.", - "fullName": "Update from properties", - "functionType": "Action", - "name": "UpdateFromProperties", - "private": true, - "sentence": "Update from properties of _PARAM0_", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::SpotLight3D::SetColor" - }, - "parameters": [ - "Object", - "=", - "Color", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetIntensity" - }, - "parameters": [ - "Object", - "=", - "Intensity", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetDecay" - }, - "parameters": [ - "Object", - "=", - "Decay", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetConeLength" - }, - "parameters": [ - "Object", - "=", - "ConeLength", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetConeAngle" - }, - "parameters": [ - "Object", - "=", - "ConeAngle", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetSmoothing" - }, - "parameters": [ - "Object", - "=", - "Smoothing", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetShadowQuality" - }, - "parameters": [ - "Object", - "=", - "ShadowQuality", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetShadowCameraNearPlane" - }, - "parameters": [ - "Object", - "=", - "ShadowCameraNearPlane", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetShadowCameraFarPlane" - }, - "parameters": [ - "Object", - "=", - "ShadowCameraFarPlane", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::SetShadowBias" - }, - "parameters": [ - "Object", - "=", - "ShadowBias", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::UpdateImage" - }, - "parameters": [ - "Object", - "" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::UpdateHelper" - }, - "parameters": [ - "Object", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "=", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "Light3D::SpotLight3D::SetCastingShadow" - }, - "parameters": [ - "Object", - "no", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "True", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "Light3D::SpotLight3D::SetCastingShadow" - }, - "parameters": [ - "Object", - "yes", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "Update helper", - "functionType": "Action", - "name": "UpdateHelper", - "private": true, - "sentence": "Update graphical helper of _PARAM0_", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const game = runtimeScene.getGame();", - "if (game.isInGameEdition && game.isInGameEdition()) {", - " const spotLightHelper = objects[0].get3DRendererObject();", - " spotLightHelper.update();", - "}", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "Update image", - "functionType": "Action", - "name": "UpdateImage", - "private": true, - "sentence": "Update the image of _PARAM0_", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "/** @type {gdjs.CustomRuntimeObject3D} */\r", - "const object = objects[0];\r", - "const resourceName = object._getImage();\r", - "object.__spotLightAdapter.setImage(resourceName);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": true - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the cone angle of the light.", - "fullName": "Cone angle", - "functionType": "ExpressionAndCondition", - "name": "ConeAngle", - "sentence": "the cone angle", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "ConeAngle" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ConeAngle", - "name": "SetConeAngle", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "ConeAngle", - "=", - "Value" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::ApplyShadowBias" - }, - "parameters": [ - "Object", - "ShadowBias", - "ShadowQuality", - "ConeAngle", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const coneAngle = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setConeAngle(coneAngle);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the color of the light.", - "fullName": "Color", - "functionType": "ExpressionAndCondition", - "name": "Color", - "sentence": "the color", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnString" - }, - "parameters": [ - "Color" - ] - } - ] - } - ], - "expressionType": { - "type": "color" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "Color", - "name": "SetColor", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetStringVariable" - }, - "parameters": [ - "Color", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const color = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setColor(color);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the smoothing of the light. Percent of the spotlight cone that is attenuated due to penumbra (between 0 and 1).", - "fullName": "Smoothing", - "functionType": "ExpressionAndCondition", - "name": "Smoothing", - "sentence": "the smoothing", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "Smoothing" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "Smoothing", - "name": "SetSmoothing", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "Smoothing", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setSmoothing(value);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the intensity of the light.", - "fullName": "Intensity", - "functionType": "ExpressionAndCondition", - "name": "Intensity", - "sentence": "the intensity", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "Intensity" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "Intensity", - "name": "SetIntensity", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "Intensity", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setIntensity(value);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the decay of the light. The amount the light dims along the distance of the light.", - "fullName": "Decay", - "functionType": "ExpressionAndCondition", - "name": "Decay", - "sentence": "the decay", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "Decay" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "Decay", - "name": "SetDecay", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "Decay", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setDecay(value);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "Check if the light is casting shadows.", - "fullName": "Shadow casting", - "functionType": "Condition", - "group": "3D spot light shadow configuration", - "name": "IsCastingShadow", - "sentence": "_PARAM0_ casting shadows", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "True", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "SetReturnBoolean" - }, - "parameters": [ - "True" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "Change if the light is casting shadows.", - "fullName": "Shadow casting", - "functionType": "Action", - "group": "3D spot light shadow configuration", - "name": "SetCastingShadow", - "sentence": "_PARAM0_ casting shadows: _PARAM1_", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "Value", - "False", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "SetBooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "False", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "Value", - "True", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "SetBooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "True", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setCastingShadow(value);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::SpotLight3D::SetConeLength" - }, - "parameters": [ - "Object", - "=", - "ConeLength", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - }, - { - "defaultValue": "yes", - "description": "Shadow casting", - "name": "Value", - "optional": true, - "type": "yesorno" - } - ], - "objectGroups": [] - }, - { - "description": "Rotate the light to light up a position.", - "fullName": "Look at position", - "functionType": "Action", - "group": "Angle", - "name": "LookAtPosition", - "sentence": "_PARAM0_ look at _PARAM1_ ; _PARAM2_ ; _PARAM3_", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const targetX = eventsFunctionContext.getArgument(\"TargetX\");\r", - "const targetY = eventsFunctionContext.getArgument(\"TargetY\");\r", - "const targetZ = eventsFunctionContext.getArgument(\"TargetZ\");\r", - "\r", - "object.__spotLightAdapter.lookAtPosition(targetX, targetY, targetZ);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - }, - { - "description": "Target X", - "name": "TargetX", - "type": "expression" - }, - { - "description": "Target Y", - "name": "TargetY", - "type": "expression" - }, - { - "description": "Target Z", - "name": "TargetZ", - "type": "expression" - } - ], - "objectGroups": [] - }, - { - "description": "Rotate the light to light up an object.", - "fullName": "Look at object", - "functionType": "Action", - "group": "Angle", - "name": "LookAtObject", - "sentence": "_PARAM0_ look at _PARAM1_", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::SpotLight3D::LookAtPosition" - }, - "parameters": [ - "Object", - "Target.CenterX()", - "Target.CenterY()", - "Target.Object3D::CenterZ()", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - }, - { - "description": "Object", - "name": "Target", - "type": "objectList" - }, - { - "description": "3D capability", - "name": "Object3D", - "supplementaryInformation": "Scene3D::Base3DBehavior", - "type": "behavior" - } - ], - "objectGroups": [] - }, - { - "description": "the shadow quality of the light.", - "fullName": "Shadow quality", - "functionType": "ExpressionAndCondition", - "group": "3D spot light shadow configuration", - "name": "ShadowQuality", - "sentence": "the shadow quality", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnString" - }, - "parameters": [ - "ShadowQuality" - ] - } - ] - } - ], - "expressionType": { - "supplementaryInformation": "[\"Low\",\"Medium\",\"High\"]", - "type": "stringWithSelector" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ShadowQuality", - "group": "3D spot light shadow configuration", - "name": "SetShadowQuality", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetStringVariable" - }, - "parameters": [ - "ShadowQuality", - "=", - "Value" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::ApplyShadowBias" - }, - "parameters": [ - "Object", - "ShadowBias", - "ShadowQuality", - "ConeAngle", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setShadowQuality(value);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the shadow camera near plane of the light.", - "fullName": "Shadow camera near plane", - "functionType": "ExpressionAndCondition", - "group": "3D spot light shadow configuration", - "name": "ShadowCameraNearPlane", - "sentence": "the shadow camera near plane", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "ShadowCameraNearPlane" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ShadowCameraNearPlane", - "group": "3D spot light shadow configuration", - "name": "SetShadowCameraNearPlane", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "ShadowCameraNearPlane", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setShadowCameraNearPlane(value);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the shadow camera far plane of the light.", - "fullName": "Shadow camera far plane", - "functionType": "ExpressionAndCondition", - "group": "3D spot light shadow configuration", - "name": "ShadowCameraFarPlane", - "sentence": "the shadow camera far plane", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "ShadowCameraFarPlane" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ShadowCameraFarPlane", - "group": "3D spot light shadow configuration", - "name": "SetShadowCameraFarPlane", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "ShadowCameraFarPlane", - "=", - "Value" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::ApplyShadowCameraFarPlane" - }, - "parameters": [ - "Object", - "min(Value, ConeLength)", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the cone length of the light. 0 means no limit.", - "fullName": "Cone length", - "functionType": "ExpressionAndCondition", - "name": "ConeLength", - "sentence": "the cone length", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "ConeLength" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ConeLength", - "name": "SetConeLength", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "ConeLength", - "=", - "Value" - ] - } - ], - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setConeLength(value);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ] - }, - { - "type": "BuiltinCommonInstructions::Comment", - "color": { - "b": 109, - "g": 230, - "r": 255, - "textB": 0, - "textG": 0, - "textR": 0 - }, - "comment": "Three.js reduces the far plane to match the light range.\nSo, we need to set it again or it will stay at the lowest value the range took.\nWe do the min() on our side to in order:\n- to avoid a side effect when Three.js is upgraded\n- because Three.js keeps the old value in cache and doesn't apply it back unless we set the lower value explicitly ourselves." - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::SpotLight3D::ApplyShadowCameraFarPlane" - }, - "parameters": [ - "Object", - "min(Value, ShadowCameraFarPlane)", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "Apply shadow camera far plane", - "functionType": "Action", - "group": "3D spot light shadow configuration", - "name": "ApplyShadowCameraFarPlane", - "private": true, - "sentence": "Apply shadow camera far plane of _PARAM0_ to _PARAM1_", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__spotLightAdapter.setShadowCameraFarPlane(value);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - }, - { - "description": "Value", - "name": "Value", - "type": "expression" - } - ], - "objectGroups": [] - }, - { - "description": "the shadow bias of the light. Use this to avoid \"shadow acne\" due to depth buffer precision. Choose a value small enough like 0.001 to avoid creating distance between shadows and objects but not too small to avoid shadow glitches on low/medium quality. This value is used for high quality, and multiplied by 2 for medium quality and 4 for low quality.", - "fullName": "Shadow bias", - "functionType": "ExpressionAndCondition", - "group": "3D spot light shadow configuration", - "name": "ShadowBias", - "sentence": "the shadow bias", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "ShadowBias" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ShadowBias", - "group": "3D spot light shadow configuration", - "name": "SetShadowBias", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "ShadowBias", - "=", - "Value" - ] - }, - { - "type": { - "value": "Light3D::SpotLight3D::ApplyShadowBias" - }, - "parameters": [ - "Object", - "Value", - "ShadowQuality", - "ConeAngle", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "Apply shadow bias", - "functionType": "Action", - "group": "3D spot light shadow configuration", - "name": "ApplyShadowBias", - "private": true, - "sentence": "Apply shadow bias of _PARAM0_ to _PARAM1_ for a _PARAM2_ quality and cone angle _PARAM3_", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "const quality = eventsFunctionContext.getArgument(\"Quality\");\r", - "const coneAngle = eventsFunctionContext.getArgument(\"Angle\");\r", - "\r", - "object.__spotLightAdapter.setShadowBias(value, quality, coneAngle);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::SpotLight3D", - "type": "object" - }, - { - "description": "Value", - "name": "Value", - "type": "expression" - }, - { - "description": "Quality", - "name": "Quality", - "type": "string" - }, - { - "description": "Cone angle", - "name": "Angle", - "type": "expression" - } - ], - "objectGroups": [] - } - ], - "eventsFunctionsFolderStructure": { - "folderName": "__ROOT", - "children": [ - { - "functionName": "onCreated" - }, - { - "functionName": "onDestroy" - }, - { - "functionName": "onHotReloading" - }, - { - "functionName": "UpdateFromProperties" - }, - { - "functionName": "UpdateHelper" - }, - { - "functionName": "UpdateImage" - }, - { - "folderName": "Angle", - "children": [ - { - "functionName": "LookAtPosition" - }, - { - "functionName": "LookAtObject" - } - ] - }, - { - "functionName": "Color" - }, - { - "functionName": "SetColor" - }, - { - "functionName": "Intensity" - }, - { - "functionName": "SetIntensity" - }, - { - "functionName": "Decay" - }, - { - "functionName": "SetDecay" - }, - { - "functionName": "ConeLength" - }, - { - "functionName": "SetConeLength" - }, - { - "functionName": "ConeAngle" - }, - { - "functionName": "SetConeAngle" - }, - { - "functionName": "Smoothing" - }, - { - "functionName": "SetSmoothing" - }, - { - "folderName": "3D spot light shadow configuration", - "children": [ - { - "functionName": "IsCastingShadow" - }, - { - "functionName": "SetCastingShadow" - }, - { - "functionName": "ShadowQuality" - }, - { - "functionName": "SetShadowQuality" - }, - { - "functionName": "ShadowCameraNearPlane" - }, - { - "functionName": "SetShadowCameraNearPlane" - }, - { - "functionName": "ShadowCameraFarPlane" - }, - { - "functionName": "SetShadowCameraFarPlane" - }, - { - "functionName": "ApplyShadowCameraFarPlane" - }, - { - "functionName": "ShadowBias" - }, - { - "functionName": "SetShadowBias" - }, - { - "functionName": "ApplyShadowBias" - } - ] - } - ] - }, - "propertyDescriptors": [ - { - "value": "255;255;255", - "type": "Color", - "label": "Color", - "name": "Color" - }, - { - "value": "30", - "type": "Number", - "unit": "DegreeAngle", - "label": "Cone angle", - "group": "Cone", - "name": "ConeAngle" - }, - { - "value": "1", - "type": "Number", - "label": "Intensity", - "name": "Intensity" - }, - { - "value": "1", - "type": "Number", - "label": "Smoothing", - "description": "Percent of the spotlight cone that is attenuated due to penumbra (between 0 and 1).", - "group": "Cone", - "name": "Smoothing" - }, - { - "value": "2", - "type": "Number", - "label": "Decay", - "description": "The amount the light dims along the distance of the light.", - "name": "Decay" - }, - { - "value": "", - "type": "Resource", - "label": "Image", - "description": "Shadow casting must be enabled for the image to have any effect.", - "group": "Shadow", - "extraInformation": [ - "image" - ], - "choices": [], - "hidden": true, - "name": "Image" - }, - { - "value": "true", - "type": "Boolean", - "label": "Shadow casting", - "group": "Shadow", - "name": "IsCastingShadow" - }, - { - "value": "Medium", - "type": "Choice", - "label": "Shadow quality", - "group": "Shadow", - "choices": [ - { - "label": "Low", - "value": "Low" - }, - { - "label": "Medium", - "value": "Medium" - }, - { - "label": "High", - "value": "High" - }, - { - "label": "Very high", - "value": "VeryHigh" - } - ], - "name": "ShadowQuality" - }, - { - "value": "20", - "type": "Number", - "unit": "Pixel", - "label": "Shadow camera near plane", - "group": "Shadow", - "advanced": true, - "name": "ShadowCameraNearPlane" - }, - { - "value": "2000", - "type": "Number", - "unit": "Pixel", - "label": "Shadow camera far plane", - "group": "Shadow", - "advanced": true, - "name": "ShadowCameraFarPlane" - }, - { - "value": "2000", - "type": "Number", - "unit": "Pixel", - "label": "Cone length", - "description": "0 means no limit.", - "group": "Cone", - "name": "ConeLength" - }, - { - "value": "0", - "type": "Number", - "label": "Shadow bias", - "description": "Use this to avoid \"shadow acne\" due to depth buffer precision. Choose a value small enough like 0.001 to avoid creating distance between shadows and objects but not too small to avoid shadow glitches on low/medium quality. This value is used for high quality, and multiplied by 2 for medium quality and 4 for low quality.", - "group": "Shadow", - "advanced": true, - "name": "ShadowBias" - } - ], - "propertiesFolderStructure": { - "folderName": "__ROOT", - "children": [ - { - "propertyName": "Color" - }, - { - "propertyName": "Intensity" - }, - { - "propertyName": "Decay" - }, - { - "folderName": "Cone", - "children": [ - { - "propertyName": "ConeAngle" - }, - { - "propertyName": "ConeLength" - }, - { - "propertyName": "Smoothing" - } - ] - }, - { - "folderName": "Shadow", - "children": [ - { - "propertyName": "IsCastingShadow" - }, - { - "propertyName": "ShadowQuality" - }, - { - "propertyName": "Image" - }, - { - "propertyName": "ShadowCameraNearPlane" - }, - { - "propertyName": "ShadowCameraFarPlane" - }, - { - "propertyName": "ShadowBias" - } - ] - } - ] - } - }, - { - "areaMaxX": 20, - "areaMaxY": 20, - "areaMaxZ": 20, - "areaMinX": -20, - "areaMinY": -20, - "areaMinZ": -20, - "defaultName": "PointLight", - "description": "Light up in all directions like a fire.", - "fullName": "3D point light", - "helpPath": "", - "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXRvcmNoIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTguNiA5LjZDOSAxMC4yIDkuNSAxMC43IDEwLjIgMTFIMTQuMkMxNC41IDEwLjkgMTQuNyAxMC43IDE0LjkgMTAuNUMxNS45IDkuNSAxNi4zIDggMTUuOCA2LjdMMTUuNyA2LjVDMTUuNiA2LjIgMTUuNCA2IDE1LjIgNS44QzE1LjEgNS42IDE0LjkgNS41IDE0LjggNS4zQzE0LjQgNSAxNCA0LjcgMTMuNiA0LjNDMTIuNyAzLjQgMTIuNiAyIDEzLjEgMUMxMi42IDEuMSAxMi4xIDEuNCAxMS43IDEuOEMxMC4yIDMgOS42IDUuMSAxMC4zIDdWNy4yQzEwLjMgNy4zIDEwLjIgNy40IDEwLjEgNy41QzEwIDcuNiA5LjggNy41IDkuNyA3LjRMOS42IDcuM0M5IDYuNSA4LjkgNS4zIDkuMyA0LjNDOC40IDUuMSA3LjkgNi40IDggNy43QzggOCA4LjEgOC4zIDguMiA4LjZDOC4yIDguOSA4LjQgOS4zIDguNiA5LjZNMTIuMyA4LjFDMTIuNCA3LjYgMTIuMiA3LjIgMTIuMSA2LjhDMTIgNi40IDEyIDYgMTIuMiA1LjZMMTIuNSA2LjJDMTIuOSA2LjggMTMuNiA3IDEzLjggNy44VjguMUMxMy44IDguNiAxMy42IDkuMSAxMy4zIDkuNEMxMy4xIDkuNSAxMi45IDkuNyAxMi43IDkuN0MxMi4xIDkuOSAxMS40IDkuNiAxMSA5LjJDMTEuOCA5LjIgMTIuMiA4LjYgMTIuMyA4LjFNMTUgMTJWMTRIMTRMMTMgMjJIMTFMMTAgMTRIOVYxMkgxNVoiIC8+PC9zdmc+", - "is3D": true, - "isUsingLegacyInstancesRenderer": false, - "name": "PointLight3D", - "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/bf9158c96f4346dabd9e8ae0ddd737809652797812eb50376bae62463ac7fc42_torch.svg", - "objects": [ - { - "assetStoreId": "", - "name": "Placeholder", - "persistentUuid": "6786eefd-3c18-4fcb-b3ae-95b07f953045", - "type": "Scene3D::Cube3DObject", - "variables": [], - "effects": [], - "behaviors": [], - "content": { - "width": 80, - "height": 80, - "depth": 80, - "enableTextureTransparency": false, - "facesOrientation": "Z", - "frontFaceResourceName": "", - "backFaceResourceName": "", - "backFaceUpThroughWhichAxisRotation": "X", - "leftFaceResourceName": "", - "rightFaceResourceName": "", - "topFaceResourceName": "", - "bottomFaceResourceName": "", - "frontFaceVisible": true, - "backFaceVisible": true, - "leftFaceVisible": true, - "rightFaceVisible": true, - "topFaceVisible": true, - "bottomFaceVisible": true, - "frontFaceResourceRepeat": false, - "backFaceResourceRepeat": false, - "leftFaceResourceRepeat": false, - "rightFaceResourceRepeat": false, - "topFaceResourceRepeat": false, - "bottomFaceResourceRepeat": false, - "materialType": "Basic", - "tint": "255;255;255", - "isCastingShadow": false, - "isReceivingShadow": false - } - } - ], - "objectsFolderStructure": { - "folderName": "__ROOT", - "children": [ - { - "objectName": "Placeholder" - } - ] - }, - "objectsGroups": [], - "layers": [ - { - "ambientLightColorB": 200, - "ambientLightColorG": 200, - "ambientLightColorR": 200, - "camera2DPlaneMaxDrawingDistance": 5000, - "camera3DFarPlaneDistance": 10000, - "camera3DFieldOfView": 45, - "camera3DNearPlaneDistance": 3, - "cameraType": "", - "followBaseLayerCamera": false, - "isLightingLayer": false, - "isLocked": false, - "name": "", - "renderingType": "", - "visibility": true, - "cameras": [ - { - "defaultSize": true, - "defaultViewport": true, - "height": 0, - "viewportBottom": 1, - "viewportLeft": 0, - "viewportRight": 1, - "viewportTop": 0, - "width": 0 - } - ], - "effects": [] - } - ], - "instances": [ - { - "angle": 0, - "customSize": true, - "depth": 40, - "height": 40, - "layer": "", - "name": "Placeholder", - "persistentUuid": "1310c768-04d4-4133-98d9-37d836f8a990", - "width": 40, - "x": -20, - "y": -20, - "z": -20, - "zOrder": 1, - "numberProperties": [], - "stringProperties": [], - "initialVariables": [] - } - ], - "editionSettings": { - "grid": false, - "gridType": "rectangular", - "gridWidth": 32, - "gridHeight": 32, - "gridDepth": 32, - "gridOffsetX": 0, - "gridOffsetY": 0, - "gridOffsetZ": 0, - "gridColor": 10401023, - "gridAlpha": 0.8, - "snap": false, - "zoomFactor": 9.06473532531222, - "windowMask": false, - "selectedLayer": "", - "gameEditorMode": "instances-editor" - }, - "eventsFunctions": [ - { - "fullName": "", - "functionType": "Action", - "name": "onCreated", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::DefineHelperClasses" - }, - "parameters": [ - "", - "" - ] - }, - { - "type": { - "value": "Light3D::DefinePointLightHelperClasses" - }, - "parameters": [ - "", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const {", - " Light3DRenderer,", - " //@ts-ignore", - "} = gdjs.__light3DExtension;", - "const {", - " PointLightAdapter,", - " PointLightHelper,", - " //@ts-ignore", - "} = gdjs.__light3DExtension.point;", - "", - "/** @type {gdjs.CustomRuntimeObject3D} */", - "//@ts-ignore", - "const object = objects[0];", - "", - "const game = runtimeScene.getGame();", - "", - "// This is a hack that may break in future releases.", - "// Replace the group that would hold children objects by the light.", - "const layer = object.getInstanceContainer().getLayer(object.getLayer());", - "const group = object.getRenderer()._threeGroup;", - "layer.getRenderer().remove3DRendererObject(group);", - "", - "const pointLight = new THREE.PointLight(0xffffff);", - "pointLight.position.copy(group.position);", - "pointLight.rotation.copy(group.rotation);", - "pointLight.up.set(0, 0, 1);", - "pointLight.shadow.camera.up.set(0, 0, 1);", - "//@ts-ignore", - "object.__light3D = pointLight;", - "//@ts-ignore", - "object.__pointLightAdapter = new PointLightAdapter(object, pointLight);", - "", - "const pointLight3DRenderer = new Light3DRenderer(object, object._instanceContainer, object.getInstanceContainer());", - "object._renderer = pointLight3DRenderer;", - "if (game.isInGameEdition && game.isInGameEdition()) {", - " const pointLightHelper = new PointLightHelper(object);", - " pointLightHelper.rotation.order = 'ZYX';", - " pointLightHelper.add(pointLight);", - " pointLight3DRenderer._threeGroup = pointLightHelper;", - " layer.getRenderer().add3DRendererObject(pointLightHelper);", - "}", - "else {", - " pointLight3DRenderer._threeGroup = pointLight;", - " layer.getRenderer().add3DRendererObject(pointLight);", - "}", - "", - "pointLight.updateMatrixWorld(true);", - "", - "// Allow to tween the light color.", - "//@ts-ignore", - "if (!object.setColor && !object.getColor) {", - " const prototype = Object.getPrototypeOf(object);", - " prototype.setColor = function(tint) {", - " this._setColor(tint);", - " this.__pointLightAdapter.setColor(tint);", - " }", - " prototype.getColor = function() {", - " return this._getColor(eventsFunctionContext);", - " }", - "}", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": true - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::PointLight3D::UpdateFromProperties" - }, - "parameters": [ - "Object", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "Action", - "name": "onDestroy", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "/** @type {gdjs.CustomRuntimeObject} */", - "const object = objects[0];", - "// Here runtimeScene is the gdjs.CustomRuntimeObjectInstanceContainer inside the custom object.", - "const gameScene = object.getRuntimeScene();", - "", - "object.__light3D.dispose();", - "object.get3DRendererObject().dispose();", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": true - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "Action", - "name": "onHotReloading", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::PointLight3D::UpdateFromProperties" - }, - "parameters": [ - "Object", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "Update from properties.", - "fullName": "Update from properties", - "functionType": "Action", - "name": "UpdateFromProperties", - "private": true, - "sentence": "Update from properties of _PARAM0_", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::PointLight3D::SetColor" - }, - "parameters": [ - "Object", - "=", - "Color", - "" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::SetIntensity" - }, - "parameters": [ - "Object", - "=", - "Intensity", - "" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::SetDecay" - }, - "parameters": [ - "Object", - "=", - "Decay", - "" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::SetRange" - }, - "parameters": [ - "Object", - "=", - "Range", - "" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::SetShadowQuality" - }, - "parameters": [ - "Object", - "=", - "ShadowQuality", - "" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::SetShadowCameraNearPlane" - }, - "parameters": [ - "Object", - "=", - "ShadowCameraNearPlane", - "" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::SetShadowCameraFarPlane" - }, - "parameters": [ - "Object", - "=", - "ShadowCameraFarPlane", - "" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::SetShadowBias" - }, - "parameters": [ - "Object", - "=", - "ShadowBias", - "" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::UpdateHelper" - }, - "parameters": [ - "Object", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "=", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "Light3D::PointLight3D::SetCastingShadow" - }, - "parameters": [ - "Object", - "no", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "True", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "Light3D::PointLight3D::SetCastingShadow" - }, - "parameters": [ - "Object", - "yes", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "Update helper", - "functionType": "Action", - "name": "UpdateHelper", - "private": true, - "sentence": "Update graphical helper of _PARAM0_", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const game = runtimeScene.getGame();", - "if (game.isInGameEdition && game.isInGameEdition()) {", - " const pointLightHelper = objects[0].get3DRendererObject();", - " pointLightHelper.update();", - "}", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the color of the light.", - "fullName": "Color", - "functionType": "ExpressionAndCondition", - "name": "Color", - "sentence": "the color", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnString" - }, - "parameters": [ - "Color" - ] - } - ] - } - ], - "expressionType": { - "type": "color" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "Color", - "name": "SetColor", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetStringVariable" - }, - "parameters": [ - "Color", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const color = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__pointLightAdapter.setColor(color);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the intensity of the light.", - "fullName": "Intensity", - "functionType": "ExpressionAndCondition", - "name": "Intensity", - "sentence": "the intensity", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "Intensity" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "Intensity", - "name": "SetIntensity", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "Intensity", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__pointLightAdapter.setIntensity(value);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the decay of the light. The amount the light dims along the distance of the light.", - "fullName": "Decay", - "functionType": "ExpressionAndCondition", - "name": "Decay", - "sentence": "the decay", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "Decay" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "Decay", - "name": "SetDecay", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "Decay", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__pointLightAdapter.setDecay(value);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "Check if the light is casting shadows.", - "fullName": "Shadow casting", - "functionType": "Condition", - "group": "3D point light shadow configuration", - "name": "IsCastingShadow", - "sentence": "_PARAM0_ casting shadows", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "True", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "SetReturnBoolean" - }, - "parameters": [ - "True" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::SetRange" - }, - "parameters": [ - "Object", - "=", - "Range", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "Change if the light is casting shadows.", - "fullName": "Shadow casting", - "functionType": "Action", - "group": "3D point light shadow configuration", - "name": "SetCastingShadow", - "sentence": "_PARAM0_ casting shadows: _PARAM1_", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "Value", - "False", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "SetBooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "False", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [ - { - "type": { - "value": "BooleanVariable" - }, - "parameters": [ - "Value", - "True", - "" - ] - } - ], - "actions": [ - { - "type": { - "value": "SetBooleanVariable" - }, - "parameters": [ - "IsCastingShadow", - "True", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__pointLightAdapter.setCastingShadow(value);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - }, - { - "defaultValue": "yes", - "description": "Shadow casting", - "name": "Value", - "optional": true, - "type": "yesorno" - } - ], - "objectGroups": [] - }, - { - "description": "the shadow quality of the light.", - "fullName": "Shadow quality", - "functionType": "ExpressionAndCondition", - "group": "3D point light shadow configuration", - "name": "ShadowQuality", - "sentence": "the shadow quality", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnString" - }, - "parameters": [ - "ShadowQuality" - ] - } - ] - } - ], - "expressionType": { - "supplementaryInformation": "[\"Low\",\"Medium\",\"High\"]", - "type": "stringWithSelector" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ShadowQuality", - "group": "3D point light shadow configuration", - "name": "SetShadowQuality", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetStringVariable" - }, - "parameters": [ - "ShadowQuality", - "=", - "Value" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::ApplyShadowBias" - }, - "parameters": [ - "Object", - "ShadowBias", - "ShadowQuality", - "" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__pointLightAdapter.setShadowQuality(value);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the shadow camera near plane of the light.", - "fullName": "Shadow camera near plane", - "functionType": "ExpressionAndCondition", - "group": "3D point light shadow configuration", - "name": "ShadowCameraNearPlane", - "sentence": "the shadow camera near plane", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "ShadowCameraNearPlane" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ShadowCameraNearPlane", - "group": "3D point light shadow configuration", - "name": "SetShadowCameraNearPlane", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "ShadowCameraNearPlane", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__pointLightAdapter.setShadowCameraNearPlane(value);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::PointLight3D::SetRange" - }, - "parameters": [ - "Object", - "=", - "Range", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the shadow camera far plane of the light.", - "fullName": "Shadow camera far plane", - "functionType": "ExpressionAndCondition", - "group": "3D point light shadow configuration", - "name": "ShadowCameraFarPlane", - "sentence": "the shadow camera far plane", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "ShadowCameraFarPlane" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ShadowCameraFarPlane", - "group": "3D point light shadow configuration", - "name": "SetShadowCameraFarPlane", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "ShadowCameraFarPlane", - "=", - "Value" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::ApplyShadowCameraFarPlane" - }, - "parameters": [ - "Object", - "min(Value, Range)", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "description": "the range of the light. 0 means no limit.", - "fullName": "Range", - "functionType": "ExpressionAndCondition", - "name": "Range", - "sentence": "the range", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "Range" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "Range", - "name": "SetRange", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "Range", - "=", - "Value" - ] - } - ] - }, - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__pointLightAdapter.setRange(value);" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - }, - { - "type": "BuiltinCommonInstructions::Comment", - "color": { - "b": 109, - "g": 230, - "r": 255, - "textB": 0, - "textG": 0, - "textR": 0 - }, - "comment": "Three.js reduces the far plane to match the light range.\nSo, we need to set it again or it will stay at the lowest value the range took.\nWe do the min() on our side to in order:\n- to avoid a side effect when Three.js is upgraded\n- because Three.js keeps the old value in cache and doesn't apply it back unless we set the lower value explicitly ourselves." - }, - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "Light3D::PointLight3D::ApplyShadowCameraFarPlane" - }, - "parameters": [ - "Object", - "min(Value, ShadowCameraFarPlane)", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "Apply shadow camera far plane", - "functionType": "Action", - "group": "3D point light shadow configuration", - "name": "ApplyShadowCameraFarPlane", - "private": true, - "sentence": "Apply shadow camera far plane of _PARAM0_ to _PARAM1_", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "\r", - "object.__pointLightAdapter.setShadowCameraFarPlane(value);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - }, - { - "description": "Value", - "name": "Value", - "type": "expression" - } - ], - "objectGroups": [] - }, - { - "description": "the shadow bias of the light. Use this to avoid \"shadow acne\" due to depth buffer precision. Choose a value small enough like 0.001 to avoid creating distance between shadows and objects but not too small to avoid shadow glitches on low/medium quality. This value is used for high quality, and multiplied by 2 for medium quality and 4 for low quality.", - "fullName": "Shadow bias", - "functionType": "ExpressionAndCondition", - "group": "3D point light shadow configuration", - "name": "ShadowBias", - "sentence": "the shadow bias", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetReturnNumber" - }, - "parameters": [ - "ShadowBias" - ] - } - ] - } - ], - "expressionType": { - "type": "expression" - }, - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "", - "functionType": "ActionWithOperator", - "getterName": "ShadowBias", - "group": "3D point light shadow configuration", - "name": "SetShadowBias", - "sentence": "", - "events": [ - { - "type": "BuiltinCommonInstructions::Standard", - "conditions": [], - "actions": [ - { - "type": { - "value": "SetNumberVariable" - }, - "parameters": [ - "ShadowBias", - "=", - "Value" - ] - }, - { - "type": { - "value": "Light3D::PointLight3D::ApplyShadowBias" - }, - "parameters": [ - "Object", - "Value", - "ShadowQuality", - "" - ] - } - ] - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - } - ], - "objectGroups": [] - }, - { - "fullName": "Apply shadow bias", - "functionType": "Action", - "group": "3D point light shadow configuration", - "name": "ApplyShadowBias", - "private": true, - "sentence": "Apply shadow bias of _PARAM0_ to _PARAM1_ for a _PARAM2_ quality", - "events": [ - { - "type": "BuiltinCommonInstructions::JsCode", - "inlineCode": [ - "const object = objects[0];\r", - "const value = eventsFunctionContext.getArgument(\"Value\");\r", - "const quality = eventsFunctionContext.getArgument(\"Quality\");\r", - "\r", - "object.__pointLightAdapter.setShadowBias(value, quality);\r", - "" - ], - "parameterObjects": "Object", - "useStrict": true, - "eventsSheetExpanded": false - } - ], - "parameters": [ - { - "description": "Object", - "name": "Object", - "supplementaryInformation": "Light3D::PointLight3D", - "type": "object" - }, - { - "description": "Value", - "name": "Value", - "type": "expression" - }, - { - "description": "Quality", - "name": "Quality", - "type": "string" - } - ], - "objectGroups": [] - } - ], - "eventsFunctionsFolderStructure": { - "folderName": "__ROOT", - "children": [ - { - "functionName": "onCreated" - }, - { - "functionName": "onDestroy" - }, - { - "functionName": "onHotReloading" - }, - { - "functionName": "UpdateFromProperties" - }, - { - "functionName": "UpdateHelper" - }, - { - "functionName": "Color" - }, - { - "functionName": "SetColor" - }, - { - "functionName": "Intensity" - }, - { - "functionName": "SetIntensity" - }, - { - "functionName": "Decay" - }, - { - "functionName": "SetDecay" - }, - { - "functionName": "Range" - }, - { - "functionName": "SetRange" - }, - { - "folderName": "3D point light shadow configuration", - "children": [ - { - "functionName": "IsCastingShadow" - }, - { - "functionName": "SetCastingShadow" - }, - { - "functionName": "ShadowQuality" - }, - { - "functionName": "SetShadowQuality" - }, - { - "functionName": "ShadowCameraNearPlane" - }, - { - "functionName": "SetShadowCameraNearPlane" - }, - { - "functionName": "ShadowCameraFarPlane" - }, - { - "functionName": "SetShadowCameraFarPlane" - }, - { - "functionName": "ApplyShadowCameraFarPlane" - }, - { - "functionName": "ShadowBias" - }, - { - "functionName": "SetShadowBias" - }, - { - "functionName": "ApplyShadowBias" - } - ] - } - ] - }, - "propertyDescriptors": [ - { - "value": "255;255;255", - "type": "Color", - "label": "Color", - "name": "Color" - }, - { - "value": "1", - "type": "Number", - "label": "Intensity", - "name": "Intensity" - }, - { - "value": "2", - "type": "Number", - "label": "Decay", - "description": "The amount the light dims along the distance of the light.", - "name": "Decay" - }, - { - "value": "true", - "type": "Boolean", - "label": "Shadow casting", - "group": "Shadow", - "name": "IsCastingShadow" - }, - { - "value": "Medium", - "type": "Choice", - "label": "Shadow quality", - "group": "Shadow", - "choices": [ - { - "label": "", - "value": "Low" - }, - { - "label": "", - "value": "Medium" - }, - { - "label": "", - "value": "High" - } - ], - "name": "ShadowQuality" - }, - { - "value": "20", - "type": "Number", - "unit": "Pixel", - "label": "Shadow camera near plane", - "group": "Shadow", - "advanced": true, - "name": "ShadowCameraNearPlane" - }, - { - "value": "2000", - "type": "Number", - "unit": "Pixel", - "label": "Shadow camera far plane", - "group": "Shadow", - "advanced": true, - "name": "ShadowCameraFarPlane" - }, - { - "value": "2000", - "type": "Number", - "unit": "Pixel", - "label": "Range", - "description": "0 means no limit.", - "name": "Range" - }, - { - "value": "0", - "type": "Number", - "label": "Shadow Bias", - "description": "Use this to avoid \"shadow acne\" due to depth buffer precision. Choose a value small enough like 0.001 to avoid creating distance between shadows and objects but not too small to avoid shadow glitches on low/medium quality. This value is used for high quality, and multiplied by 2 for medium quality and 4 for low quality.", - "group": "Shadow", - "advanced": true, - "name": "ShadowBias" - } - ], - "propertiesFolderStructure": { - "folderName": "__ROOT", - "children": [ - { - "propertyName": "Color" - }, - { - "propertyName": "Intensity" - }, - { - "propertyName": "Decay" - }, - { - "propertyName": "Range" - }, - { - "folderName": "Shadow", - "children": [ - { - "propertyName": "IsCastingShadow" - }, - { - "propertyName": "ShadowQuality" - }, - { - "propertyName": "ShadowCameraNearPlane" - }, - { - "propertyName": "ShadowCameraFarPlane" - }, - { - "propertyName": "ShadowBias" - } - ] - } - ] - } - } - ] - } - ], - "tests": [ - { - "name": "The sun lights the scene and casts shadows", "description": "The directional light of the scene reaches the 3D renderer with shadow casting on, and lights the props.", + "name": "The sun lights the scene and casts shadows", "type": "gameplay", "source": [ "// Look at the lights the 3D renderer can actually see, the way three.js does:", @@ -8612,8 +2979,8 @@ ] }, { - "name": "Point lights light the scene at night", "description": "The three point lights reach the 3D renderer, keep the colour each was given, and stay lit when one of them moves.", + "name": "Point lights light the scene at night", "type": "gameplay", "source": [ "// Look at the lights the 3D renderer can actually see, the way three.js does:", @@ -8667,8 +3034,8 @@ ] }, { - "name": "Spot lights light the scene and cast shadows", "description": "Both spot lights reach the 3D renderer as spot lights, keep their own colour, and cast shadows.", + "name": "Spot lights light the scene and cast shadows", "type": "gameplay", "source": [ "// Look at the lights the 3D renderer can actually see, the way three.js does:", @@ -8712,8 +3079,8 @@ ] }, { - "name": "Mixed light kinds stay within a stable budget", "description": "With more lights placed than one budget can hold, and of two kinds the shaders count separately (point lights and spot lights), the number of each kind that is lit must stay the same while the lights move. A count that moves makes the renderer compile a new shader, which drops a frame.", + "name": "Mixed light kinds stay within a stable budget", "type": "gameplay", "source": [ "// Look at the lights the 3D renderer can actually see, the way three.js does:", @@ -8746,7 +3113,7 @@ "", "const names = ['MixedPoint', 'MixedPointShadow', 'MixedSpot', 'MixedSpotShadow'];", "const placed = names.reduce((all, n) => all.concat(harness.getObjects(n)), []);", - "harness.assert(placed.length === 26, '26 lights are placed (' + placed.length + ').');", + "harness.assert(placed.length === 7, '7 lights are placed (' + placed.length + ').');", "", "const first = readLights();", "console.log('lights=' + describe(first));", @@ -8779,8 +3146,8 @@ ] }, { - "name": "One light kind gets the whole device budget", "description": "Eight shadow casting point lights, and nothing else: a scene that uses a single light kind must be given the device budget for that kind rather than a third of it, so it keeps as many shadow casters as the device really allows. The counts must also stay put while the camera moves, or the renderer compiles another shader and drops a frame.", + "name": "One light kind gets the whole device budget", "type": "gameplay", "source": [ "// Look at the lights the 3D renderer can actually see, the way three.js does:", @@ -8853,9 +3220,9 @@ ] }, { + "description": "", "name": "Rendering: the lights of each scene", "type": "gameplay", - "description": "", "source": [ "harness.setMaxScreenshots(8);", "for (const sceneName of ['Sun and Shadows', 'Point Lights', 'Spot Lights', 'Mixed Lights']) {", @@ -8867,5 +3234,5371 @@ "harness.assert(true, 'Every scene was drawn.');" ] } - ] + ], + "eventsFunctionsExtensions": [ + { + "author": "", + "category": "Visual effect", + "dimension": "3D", + "extensionNamespace": "", + "fullName": "3D lights", + "gdevelopVersion": ">=5.5.222", + "helpPath": "/objects/3d-light", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWxpZ2h0YnVsYi1vbi1vdXRsaW5lIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTIwLDExSDIzVjEzSDIwVjExTTEsMTFINFYxM0gxVjExTTEzLDFWNEgxMVYxSDEzTTQuOTIsMy41TDcuMDUsNS42NEw1LjYzLDcuMDVMMy41LDQuOTNMNC45MiwzLjVNMTYuOTUsNS42M0wxOS4wNywzLjVMMjAuNSw0LjkzTDE4LjM3LDcuMDVMMTYuOTUsNS42M00xMiw2QTYsNiAwIDAsMSAxOCwxMkMxOCwxNC4yMiAxNi43OSwxNi4xNiAxNSwxNy4yVjE5QTEsMSAwIDAsMSAxNCwyMEgxMEExLDEgMCAwLDEgOSwxOVYxNy4yQzcuMjEsMTYuMTYgNiwxNC4yMiA2LDEyQTYsNiAwIDAsMSAxMiw2TTE0LDIxVjIyQTEsMSAwIDAsMSAxMywyM0gxMUExLDEgMCAwLDEgMTAsMjJWMjFIMTRNMTEsMThIMTNWMTUuODdDMTQuNzMsMTUuNDMgMTYsMTMuODYgMTYsMTJBNCw0IDAgMCwwIDEyLDhBNCw0IDAgMCwwIDgsMTJDOCwxMy44NiA5LjI3LDE1LjQzIDExLDE1Ljg3VjE4WiIgLz48L3N2Zz4=", + "name": "Light3D", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", + "shortDescription": "A collection of light object for 3D.", + "version": "2.1.0", + "description": "A collection of light object for 3D.", + "origin": { + "identifier": "Light3D", + "name": "gdevelop-extension-store" + }, + "tags": [ + "3d", + "light" + ], + "authorIds": [ + "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" + ], + "changelog": [ + { + "version": "2.0.0", + "breaking": "- Point and spot lights now fade with the distance like they do with the 3D renderer of recent GDevelop versions (Three.js r185), including on previous GDevelop versions. Lights made for a previous version of the extension need a higher intensity (and possibly a lower decay) to look the same." + } + ], + "dependencies": [], + "globalVariables": [], + "sceneVariables": [], + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onFirstSceneLoaded", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "// Before Three.js r165, GDevelop rendered with \"legacy lights\": point and spot", + "// lights faded linearly up to their range and every light color was", + "// multiplied by PI. Recent GDevelop versions use the physically based falloff", + "// of Three.js r185 instead, which is what the light properties are tuned for.", + "// Use the same falloff with older GDevelop versions so that lights look the", + "// same with every version:", + "// - distances are divided by 100 because recent GDevelop versions render 3D", + "// with a default world scale of 100 pixels per unit, while older versions", + "// work in pixels,", + "// - the attenuation is divided by PI as the legacy light colors are multiplied by PI.", + "// It must be patched before any shader using lights is compiled, as Three.js", + "// caches compiled shaders.", + "const lightsParsBegin = THREE.ShaderChunk.lights_pars_begin;", + "if (!lightsParsBegin.includes('#if defined ( LEGACY_LIGHTS )')) {", + " return;", + "}", + "THREE.ShaderChunk.lights_pars_begin = lightsParsBegin.replace(", + " /#if defined \\( LEGACY_LIGHTS \\)[\\s\\S]*?#else/,", + " [", + " '#if defined ( LEGACY_LIGHTS )',", + " '\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance * 0.01, decayExponent ), 0.01 );',", + " '\\t\\tif ( cutoffDistance > 0.0 ) {',", + " '\\t\\t\\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );',", + " '\\t\\t}',", + " '\\t\\treturn distanceFalloff * RECIPROCAL_PI;',", + " '\\t#else',", + " ].join('\\n')", + ");" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "Define spot light helper classes JavaScript code.", + "fullName": "Define spot light helper classes", + "functionType": "Action", + "name": "DefineSpotLightHelperClasses", + "private": true, + "sentence": "Define spot light helper classes JavaScript code", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//@ts-ignore", + "if (gdjs.__light3DExtension.spot) {", + " //@ts-ignore", + " return;", + "}", + "", + "/**", + " * @typedef {gdjs.CustomRuntimeObject3D & {__light3D: THREE.SpotLight, _getIsCastingShadow: () => boolean, _getConeAngle: () => number, _getColor: () => string}} SpotLightRuntimeObject", + " */", + "", + "const game = runtimeScene.getGame();", + "", + "const coneLength = 64;", + "", + "class SpotLightHelper extends THREE.Object3D {", + " /** @type {SpotLightRuntimeObject} */", + " object;", + " /** @type {THREE.LineSegments} */", + " cone;", + " /** @type {THREE.LineSegments} */", + " centerLine;", + " /** @type {THREE.Mesh} */", + " originBox;", + "", + "\t/**", + " * @param {SpotLightRuntimeObject} object", + "\t */", + " constructor(object) {", + " super();", + " this.object = object;", + " this.type = 'SpotLightHelper';", + "", + " const coneGeometry = new THREE.BufferGeometry();", + " const conePositions = [", + " 0, 0, 0, 1, 0, 0,", + " 0, 0, 0, 1, 1, 0,", + " 0, 0, 0, 1, - 1, 0,", + " 0, 0, 0, 1, 0, 1,", + " 0, 0, 0, 1, 0, - 1", + " ];", + " for (let i = 0, j = 1, l = 32; i < l; i++ , j++) {", + " const p1 = (i / l) * Math.PI * 2;", + " const p2 = (j / l) * Math.PI * 2;", + " conePositions.push(", + " 1, Math.cos(p1), Math.sin(p1),", + " 1, Math.cos(p2), Math.sin(p2)", + " );", + " }", + " coneGeometry.setAttribute('position', new THREE.Float32BufferAttribute(conePositions, 3));", + " this.cone = new THREE.LineSegments(", + " coneGeometry,", + " new THREE.LineBasicMaterial({ fog: false, toneMapped: false })", + " );", + " this.add(this.cone);", + " const centerLineGeometry = new THREE.BufferGeometry();", + " centerLineGeometry.setAttribute('position', new THREE.Float32BufferAttribute([", + " 0, 0, 0, coneLength, 0, 0", + " ], 3));", + " this.centerLine = new THREE.LineSegments(", + " centerLineGeometry,", + " new THREE.LineBasicMaterial({ fog: false, toneMapped: false })", + " );", + " this.add(this.centerLine);", + "", + " this.originBox = new THREE.Mesh(", + " new THREE.BoxGeometry(16, 16, 16),", + " new THREE.MeshBasicMaterial({ fog: false, toneMapped: false })", + " );", + " this.add(this.originBox);", + " this.update();", + "", + " //@ts-ignore", + " this.originBox.gdjsRuntimeObject = object;", + " }", + "", + " dispose() {", + " this.cone.geometry.dispose();", + " this.cone.material.dispose();", + " this.centerLine.geometry.dispose();", + " this.centerLine.material.dispose();", + " this.originBox.geometry.dispose();", + " this.originBox.material.dispose();", + " }", + "", + " update() {", + " /** @type {number} */", + " const coneAngle = gdjs.toRad(this.object._getConeAngle());", + " const coneWidth = coneLength * Math.sin(coneAngle);", + " const coneHeight = coneLength * Math.cos(coneAngle);", + " this.cone.scale.set(coneHeight, coneWidth, coneWidth);", + " const color = gdjs.rgbOrHexStringToNumber(this.object._getColor());", + " this.cone.material.color.set(color);", + " this.centerLine.material.color.set(color);", + " this.originBox.material.color.set(color);", + " }", + "}", + "", + "/**", + " * @param {string} colorString", + " * @param {THREE.Color} threeColor", + " */", + "const setThreeColor = (colorString, threeColor) => {", + " const integerColor = gdjs.rgbOrHexToRGBColor(colorString);", + " threeColor.r = integerColor[0] / 255;", + " threeColor.g = integerColor[1] / 255;", + " threeColor.b = integerColor[2] / 255;", + "};", + "", + "class SpotLightAdapter {", + " /**", + " * @param object {gdjs.CustomRuntimeObject3D}", + " * @param spotLight {THREE.SpotLight}", + " */", + " constructor(object, spotLight) {", + " this.object = object;", + " this.spotLight = spotLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", + " }", + "", + " /**", + " * @param targetX {number}", + " * @param targetY {number}", + " * @param targetZ {number}", + " */", + " lookAtPosition(targetX, targetY, targetZ) {", + " const runtimeSene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", + "", + " // Remove from the parent to avoid the scene scale of -1 on Y to mess with the formula.", + " const parent = this.spotLight.parent;", + " this.spotLight.parent = null;", + " this.spotLight.lookAt(", + " targetX * inverseWorldScale,", + " targetY * inverseWorldScale,", + " targetZ * inverseWorldScale);", + " this.spotLight.parent = parent;", + "", + " // Angle setters update Three.js angles, so we save them first.", + " const rotationX = gdjs.toDegrees(this.spotLight.rotation.x);", + " const rotationY = gdjs.toDegrees(this.spotLight.rotation.y);", + " const rotationZ = gdjs.toDegrees(this.spotLight.rotation.z);", + " this.object.setRotationX(rotationX);", + " this.object.setRotationY(rotationY);", + " this.object.setAngle(rotationZ + 90);", + " }", + "", + " /**", + " * @param color {string}", + " */", + " setColor(color) {", + " setThreeColor(color, this.spotLight.color);", + " }", + "", + " /**", + " * @param intensity {number}", + " */", + " setIntensity(intensity) {", + " this.spotLight.intensity = intensity;", + " }", + "", + " /**", + " * @param decay {number}", + " */", + " setDecay(decay) {", + " this.spotLight.decay = decay;", + " }", + "", + " /**", + " * @param value {number}", + " */", + " setConeLength(value) {", + " const runtimeSene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", + " this.spotLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * @param coneAngle {number}", + " */", + " setConeAngle(coneAngle) {", + " this.spotLight.angle = coneAngle * Math.PI / 180;", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * @param smoothing {number}", + " */", + " setSmoothing(smoothing) {", + " this.spotLight.penumbra = smoothing;", + " }", + "", + " /**", + " * @param isCastingShadow {boolean}", + " */", + " setCastingShadow(isCastingShadow) {", + " // This is applied by applyVisibilityAndShadow", + " }", + "", + " /**", + " * @param shadowQuality {\"Low\" | \"Medium\" | \"High\" | \"VeryHigh\"}", + " */", + " setShadowQuality(shadowQuality) {", + " let size = 512;", + " switch (shadowQuality) {", + " case \"Low\":", + " size = 256;", + " break;", + " case \"Medium\":", + " size = 512;", + " break;", + " case \"High\":", + " size = 1024;", + " break;", + " case \"VeryHigh\":", + " size = 2048;", + " break;", + " }", + " const shadow = this.spotLight.shadow;", + " const mapSize = shadow.mapSize;", + " if (mapSize.width !== size) {", + " mapSize.set(size, size);", + " this.updateShadowNormalBias();", + "", + " // Force the recreation of the shadow map texture:", + " if (shadow.map) {", + " shadow.map.dispose();", + " shadow.map = null;", + " }", + " shadow.needsUpdate = true;", + " }", + " }", + "", + " /**", + " * @param value {number}", + " */", + " setShadowCameraNearPlane(value) {", + " const runtimeSene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", + " this.spotLight.shadow.camera.near = value * inverseWorldScale;", + " }", + "", + " /**", + " * @param value {number}", + " */", + " setShadowCameraFarPlane(value) {", + " const runtimeSene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", + " this.spotLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * @param value {number}", + " * @param quality {\"Low\" | \"Medium\" | \"High\" | \"VeryHigh\"}", + " * @param coneAngle {number}", + " */", + " setShadowBias(value, quality, coneAngle) {", + " const runtimeSene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", + " const biasMultiplier =", + " quality === 'Low'", + " ? 8", + " : quality === 'Medium'", + " ? 4", + " : quality === 'High'", + " ? 2 : 1;", + " // Multiply by 0.125 to make values around 0.001 work best.", + " this.spotLight.shadow.bias = -value * 0.125 * biasMultiplier *", + " Math.tan(gdjs.toRad(gdjs.evtTools.common.clamp(coneAngle, 0, 89))) *", + " inverseWorldScale;", + " }", + "", + " /**", + " * @param resourceName {string}", + " */", + " setImage(resourceName) {", + " if (!resourceName) {", + " this.spotLight.map = null;", + " return;", + " }", + " const texture = game.getImageManager().getThreeTexture(resourceName);", + " this.spotLight.map = texture;", + " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.spotLight.shadow;", + " // Three.js uses the cone length as the far plane of the shadow camera.", + " const shadowDistance = this.spotLight.distance || shadow.camera.far;", + " const coneAngle = Math.min(this.spotLight.angle, gdjs.toRad(89));", + " const shadowMapWidth = 2 * shadowDistance * Math.tan(coneAngle);", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", + "}", + "", + "//@ts-ignore", + "gdjs.__light3DExtension.spot = {", + " SpotLightAdapter,", + " SpotLightHelper,", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "Define point light helper classes JavaScript code.", + "fullName": "Define point light helper classes", + "functionType": "Action", + "name": "DefinePointLightHelperClasses", + "private": true, + "sentence": "Define point light helper classes JavaScript code", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//@ts-ignore", + "if (gdjs.__light3DExtension.point) {", + " //@ts-ignore", + " return;", + "}", + "", + "/**", + " * @typedef {gdjs.CustomRuntimeObject3D & {__light3D: THREE.PointLight, _getIsCastingShadow: () => boolean, _getColor: () => string}} PointLightRuntimeObject", + " */", + "", + "const game = runtimeScene.getGame();", + "", + "/**", + " * @extends {THREE.Mesh}", + " */", + "class PointLightHelper extends THREE.Mesh {", + " /** @type {PointLightRuntimeObject} */", + " object;", + "", + "\t/**", + " * @param {PointLightRuntimeObject} object", + "\t */", + " constructor(object) {", + " const geometry = new THREE.SphereGeometry(16, 4, 2);", + " const material = new THREE.MeshBasicMaterial({ wireframe: true, fog: false, toneMapped: false });", + " super(geometry, material);", + " this.object = object;", + " this.update();", + "", + " //@ts-ignore", + " this.gdjsRuntimeObject = object;", + " }", + "", + " dispose() {", + " this.geometry.dispose();", + " this.material.dispose();", + " }", + "", + " update() {", + " const color = gdjs.rgbOrHexStringToNumber(this.object._getColor());", + " this.material.color.set(color);", + " }", + "}", + "", + "/**", + " * @param {string} colorString", + " * @param {THREE.Color} threeColor", + " */", + "const setThreeColor = (colorString, threeColor) => {", + " const integerColor = gdjs.rgbOrHexToRGBColor(colorString);", + " threeColor.r = integerColor[0] / 255;", + " threeColor.g = integerColor[1] / 255;", + " threeColor.b = integerColor[2] / 255;", + "};", + "", + "class PointLightAdapter {", + " /**", + " * @param object {gdjs.CustomRuntimeObject3D}", + " * @param pointLight {THREE.PointLight}", + " */", + " constructor(object, pointLight) {", + " this.object = object;", + " this.pointLight = pointLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", + " }", + "", + " /**", + " * @param color {string}", + " */", + " setColor(color) {", + " setThreeColor(color, this.pointLight.color);", + " }", + "", + " /**", + " * @param intensity {number}", + " */", + " setIntensity(intensity) {", + " this.pointLight.intensity = intensity;", + " }", + "", + " /**", + " * @param decay {number}", + " */", + " setDecay(decay) {", + " this.pointLight.decay = decay;", + " }", + "", + " /**", + " * @param value {number}", + " */", + " setRange(value) {", + " const runtimeScene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", + " this.pointLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * @param isCastingShadow {boolean}", + " */", + " setCastingShadow(isCastingShadow) {", + " // This is applied by applyVisibilityAndShadow", + " }", + "", + " /**", + " * @param shadowQuality {\"Low\" | \"Medium\" | \"High\"}", + " */", + " setShadowQuality(shadowQuality) {", + " let size = 512;", + " switch (shadowQuality) {", + " case \"Low\":", + " size = 512;", + " break;", + " case \"Medium\":", + " size = 1024;", + " break;", + " case \"High\":", + " size = 2048;", + " break;", + " }", + " const shadow = this.pointLight.shadow;", + " const mapSize = shadow.mapSize;", + " if (mapSize.width !== size) {", + " mapSize.set(size, size);", + " this.updateShadowNormalBias();", + "", + " // Force the recreation of the shadow map texture:", + " if (shadow.map) {", + " shadow.map.dispose();", + " shadow.map = null;", + " }", + " shadow.needsUpdate = true;", + " }", + " }", + "", + " /**", + " * @param value {number}", + " */", + " setShadowCameraNearPlane(value) {", + " const runtimeSene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", + "", + " this.pointLight.shadow.camera.near = value * inverseWorldScale;", + " }", + "", + " /**", + " * @param value {number}", + " */", + " setShadowCameraFarPlane(value) {", + " const runtimeSene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", + "", + " this.pointLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * @param value {number}", + " * @param quality {\"Low\" | \"Medium\" | \"High\"}", + " */", + " setShadowBias(value, quality) {", + " const runtimeSene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", + "", + " const biasMultiplier =", + " quality === 'Low'", + " ? 4", + " : quality === 'Medium'", + " ? 2", + " : 1;", + " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", + " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.pointLight.shadow;", + " // Three.js uses the range as the far plane of the shadow cameras.", + " const shadowDistance = this.pointLight.distance || shadow.camera.far;", + " // Each face of the shadow cube map covers 90 degrees.", + " const shadowMapWidth = 2 * shadowDistance;", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", + "}", + "", + "//@ts-ignore", + "gdjs.__light3DExtension.point = {", + " PointLightAdapter,", + " PointLightHelper,", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "Define helper classes JavaScript code.", + "fullName": "Define helper classes", + "functionType": "Action", + "name": "DefineHelperClasses", + "private": true, + "sentence": "Define helper classes JavaScript code", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "//@ts-ignore", + "if (gdjs.__light3DExtension) {", + " //@ts-ignore", + " return;", + "}", + "", + "/**", + " * @typedef {gdjs.CustomRuntimeObject3D & {__light3D: THREE.SpotLight | THREE.PointLight, _getIsCastingShadow: () => boolean}} LightRuntimeObject", + " */", + "", + "const game = runtimeScene.getGame();", + "const isInGameEdition = game.isInGameEdition && game.isInGameEdition();", + "const logger = new gdjs.Logger('3D lights');", + "", + "", + "class Light3DRenderer extends gdjs.CustomRuntimeObject3DRenderer {", + "", + " constructor(", + " object,", + " instanceContainer,", + " parent", + " ) {", + " super(object, instanceContainer, parent);", + " }", + "", + " _updateThreeGroup() {", + " /** @type {LightRuntimeObject} */", + " //@ts-ignore", + " const object = this._object;", + " const threeObject3D = this.get3DRendererObject();", + "", + " threeObject3D.rotation.set(", + " gdjs.toRad(object.getRotationX()),", + " gdjs.toRad(object.getRotationY()),", + " gdjs.toRad(object.angle)", + " );", + "", + " threeObject3D.position.set(", + " object.getX(),", + " object.getY(),", + " object.getZ()", + " );", + "", + " // Force the scale to 1 because the light doesn't really has a size.", + " threeObject3D.scale.set(", + " object.isFlippedX() ? -1 : 1,", + " object.isFlippedY() ? -1 : 1,", + " object.isFlippedZ() ? -1 : 1", + " );", + "", + " threeObject3D.visible = !this._object.hidden;", + "", + " const spotLight = object.__light3D;", + "", + " const editor = game.getInGameEditor ? game.getInGameEditor() : null;", + "", + " spotLight.castShadow = false;", + " spotLight.visible = false;", + "", + " // Instances hidden at start stay visible in the editor, but their light must not shine.", + " const isHiddenAtStartInEditor =", + " !!editor && !!editor.isInstanceHiddenAtStart && editor.isInstanceHiddenAtStart(object);", + "", + " if (!object.isHidden() && !isHiddenAtStartInEditor) {", + " let isSelected = false;", + " if (editor) {", + " const selectedObject = editor._selection.getLastSelectedObject();", + " let parentObject = object;", + " isSelected = parentObject === selectedObject;", + " while (!isSelected && parentObject.getInstanceContainer()", + " //@ts-ignore", + " .getOwner) {", + " parentObject = parentObject.getInstanceContainer()", + " //@ts-ignore", + " .getOwner();", + " isSelected = parentObject === selectedObject;", + " }", + " }", + " if (!editor || !editor.areEffectsHidden() || isSelected) {", + " let rootObject = object;", + " while (rootObject.getInstanceContainer()", + " //@ts-ignore", + " .getOwner) {", + " rootObject = rootObject.getInstanceContainer()", + " //@ts-ignore", + " .getOwner();", + " }", + " const runtimeScene = rootObject.getRuntimeScene();", + " let distanceSq = 0;", + " if (!isSelected) {", + " const layerName = rootObject.getLayer();", + " const cameraX = gdjs.evtTools.camera.getCameraX(runtimeScene, layerName, 0);", + " const cameraY = gdjs.evtTools.camera.getCameraY(runtimeScene, layerName, 0);", + " const cameraZ = gdjs.scene3d.camera.getCameraZ(runtimeScene, layerName, 0);", + " const deltaX = rootObject.getX() - cameraX;", + " const deltaY = rootObject.getY() - cameraY;", + " const deltaZ = rootObject.getZ() - cameraZ;", + " distanceSq = deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ;", + " }", + " getLightManager(", + " //@ts-ignore", + " runtimeScene", + " ).applyVisibilityAndShadow(object, distanceSq);", + " }", + " }", + "", + " // Force the visibility to be checked every frame", + " this._isContainerDirty = true;", + " }", + "}", + "", + "const editorLightCountMax = {", + " value: 20", + "};", + "", + "const lightCountMax = {", + " value: 20", + "};", + "", + "const editorLightShadowCountMax = {", + " value: 4", + "};", + "", + "const lightShadowCountMax = {", + " value: 4", + "};", + "", + "gdjs.registerRuntimeScenePreEventsCallback(", + " runtimeScene => {", + " getLightManager(", + " //@ts-ignore", + " runtimeScene.getScene()", + " ).clear();", + " });", + "if (gdjs.registerInGameEditorPostStepCallback) {", + " gdjs.registerInGameEditorPostStepCallback(", + " inGameEditor => {", + " getLightManager(", + " //@ts-ignore", + " inGameEditor.getEditedInstanceContainer().getScene()", + " ).clear();", + " });", + "}", + "", + "/**", + " * How many lights of each kind this device can take.", + " *", + " * These are hard limits rather than performance trade-offs. three.js binds one", + " * texture unit per shadow map and one more for a spot light's projected", + " * texture, and spends a varying on every shadow casting light. Going over what", + " * the driver allows does not make the scene slower - the shader fails to link", + " * and everything using that material renders black. Only 16 fragment texture", + " * units and 15 varyings are guaranteed across devices, and materials need most", + " * of those, so the budget is read from the device instead of being fixed.", + " *", + " * The budget is shared between the light kinds a scene uses, so it is given", + " * how many of them there are rather than assuming all of them: a scene lit by", + " * point lights alone would otherwise have three quarters of its texture units", + " * held back for kinds that never show up.", + " *", + " * @param {THREE.WebGLRenderer | null} threeRenderer", + " * @param {number} kindCount How many light kinds the scene uses, at least one.", + " * @returns {{shadowCount: number, mapCount: number, count: number}}", + " */", + "function computeDeviceLightBudget(threeRenderer, kindCount) {", + " // When the renderer cannot be reached, assume the guaranteed minimums", + " // rather than the device this happens to be running on.", + " const capabilities = (threeRenderer && threeRenderer.capabilities) || {};", + " const maxTextures = capabilities.maxTextures || 16;", + " const maxVaryings = capabilities.maxVaryings || 15;", + " const maxFragmentUniforms = capabilities.maxFragmentUniforms || 224;", + "", + " // Left for the material itself: colour, normal, roughness, metalness,", + " // emissive, ambient occlusion and the environment map.", + " const textureUnitsForMaterials = 8;", + " // Varyings already spent on positions, normals, uvs and fog.", + " const varyingsForGeometry = 12;", + " // Uniform vectors already spent on matrices, material properties and the", + " // uv transforms of a material's own textures.", + " const uniformVectorsForMaterials = 64;", + " // Measured on a MeshStandardMaterial: a point light costs 4 uniform", + " // vectors, a spot light 7, and casting a shadow adds around 11 more on", + " // top of either. Take the dearest of them, since a kind count says how", + " // many kinds a scene uses but not which ones.", + " const uniformVectorsPerLight = 8;", + " const uniformVectorsPerShadow = 12;", + "", + " const availableTextureUnits = Math.max(", + " kindCount, maxTextures - textureUnitsForMaterials);", + " const availableVaryings = Math.max(", + " kindCount, maxVaryings - varyingsForGeometry);", + " const availableUniformVectors = Math.max(", + " 16, maxFragmentUniforms - uniformVectorsForMaterials);", + "", + " // Every shadow caster costs a texture unit and a varying, whichever kind", + " // it is. Keep a share of the texture units back for projected textures.", + " const shadowCount = Math.max(0, Math.min(", + " Math.floor(availableTextureUnits / (kindCount + 1)),", + " Math.floor(availableVaryings / kindCount)", + " ));", + " // What is left bounds how many spot lights can project a texture. Lights", + " // that neither cast a shadow nor project a texture cost no texture unit.", + " const mapCount = Math.max(0,", + " availableTextureUnits - shadowCount * kindCount);", + " // Shadow casters are paid for first, then the uniform vectors left over", + " // decide how many lights of each kind can be lit at all.", + " const uniformVectorsForShadows =", + " shadowCount * kindCount * uniformVectorsPerShadow;", + " const count = Math.max(1, Math.floor(", + " Math.max(uniformVectorsPerLight * kindCount,", + " availableUniformVectors - uniformVectorsForShadows)", + " / (uniformVectorsPerLight * kindCount)));", + "", + " return { shadowCount, mapCount, count };", + "}", + "", + "/**", + " * A capacity that never goes past what the device can take, however high the", + " * game sets its own maximum. Both sides are read through getters, so that", + " * changing the game's maximum at runtime still takes effect, and so that a", + " * device budget recomputed for more light kinds is picked up as well.", + " *", + " * @param {{value: number}} requested", + " * @param {() => number} getDeviceMax", + " * @returns {{value: number}}", + " */", + "function makeDeviceCappedCapacity(requested, getDeviceMax) {", + " return {", + " get value() {", + " return Math.min(requested.value, getDeviceMax());", + " }", + " };", + "}", + "", + "/**", + " * Get the light manager of a scene.", + " * @param {gdjs.RuntimeScene & {__lightManager: LightManager}} runtimeScene", + " */", + "function getLightManager(runtimeScene) {", + " if (!runtimeScene.__lightManager) {", + " // Create the shared manager if necessary.", + " const requestedCount = isInGameEdition", + " ? editorLightCountMax : lightCountMax;", + " const requestedShadowCount = isInGameEdition", + " ? editorLightShadowCountMax : lightShadowCountMax;", + "", + " // The renderer is read anew on every recomputation: it may not", + " // exist yet when the manager is created on the first frame.", + " runtimeScene.__lightManager = new LightManager(", + " requestedCount, requestedShadowCount,", + " kindCount => computeDeviceLightBudget(", + " runtimeScene.getGame().getRenderer().getThreeRenderer(),", + " kindCount));", + " }", + " return runtimeScene.__lightManager;", + "}", + "", + "/**", + " * Lights kept sorted by their distance to the camera, capped to a fixed", + " * number of entries.", + " *", + " * The cap is a *count* and not a weighted cost, on purpose: three.js compiles", + " * the number of lights of each type into its shaders, so a list whose length", + " * changes from one frame to the next forces a shader recompilation every time", + " * a new length is seen. A count based cap keeps the length pinned to", + " * `capacity` for as long as enough lights are candidates.", + " */", + "class CappedLightList {", + " /** @type {Array<{object: LightRuntimeObject, sortDistance: number}>} */", + " objects = [];", + " /** @type {{value: number}} */", + " capacity;", + " /** @type {(object: LightRuntimeObject) => void} */", + " onInsertion;", + " /** @type {(object: LightRuntimeObject) => void} */", + " onDeletion;", + "", + " /**", + " * @param {{value: number}} capacity", + " * @param {(object: LightRuntimeObject) => void} onInsertion", + " * @param {(object: LightRuntimeObject) => void} onDeletion", + " */", + " constructor(capacity, onInsertion, onDeletion) {", + " this.capacity = capacity;", + " this.onInsertion = onInsertion;", + " this.onDeletion = onDeletion;", + " }", + "", + " clear() {", + " this.objects.length = 0;", + " }", + "", + " /** Drop the farthest lights until the list fits its capacity again. */", + " trimToCapacity() {", + " while (this.objects.length > this.capacity.value) {", + " this.onDeletion(this.objects.pop().object);", + " }", + " }", + "", + " /**", + " * @param object {LightRuntimeObject}", + " * @param sortDistance {number} The squared distance to the camera.", + " */", + " insertByDistance(object, sortDistance) {", + " // A render can happen without a game step in between (the editor", + " // and the gameplay test harness render a paused game), so a light", + " // can be offered again before the lists were cleared. Keep it once,", + " // or the duplicates would evict the other lights - but apply its", + " // state again, as the renderer reset it before offering the light.", + " for (const pair of this.objects) {", + " if (pair.object === object) {", + " this.onInsertion(object);", + " return;", + " }", + " }", + " let insertionIndex = 0;", + " for (let index = this.objects.length - 1; index >= 0; index--) {", + " if (sortDistance >= this.objects[index].sortDistance) {", + " insertionIndex = index + 1;", + " break;", + " }", + " }", + " if (insertionIndex >= this.capacity.value) {", + " // Farther away than every light already filling the list.", + " return;", + " }", + "", + " // Make room first, reusing an evicted pair to avoid allocating one", + " // on every frame.", + " let pair = null;", + " while (this.objects.length >= this.capacity.value) {", + " pair = this.objects.pop();", + " this.onDeletion(pair.object);", + " }", + " if (pair) {", + " pair.object = object;", + " pair.sortDistance = sortDistance;", + " }", + " else {", + " pair = { object, sortDistance };", + " }", + " this.objects.splice(insertionIndex, 0, pair);", + " this.onInsertion(object);", + " }", + "}", + "", + "/** @param object {LightRuntimeObject} */", + "const showLight = (object) => { object.__light3D.visible = true; };", + "/** @param object {LightRuntimeObject} */", + "const hideLight = (object) => { object.__light3D.visible = false; };", + "/** @param object {LightRuntimeObject} */", + "const enableShadow = (object) => { object.__light3D.castShadow = true; };", + "/** @param object {LightRuntimeObject} */", + "const disableShadow = (object) => { object.__light3D.castShadow = false; };", + "", + "/**", + " * The lights of a scene, budgeted so that the numbers three.js compiles into", + " * its shaders stay put.", + " *", + " * three.js keys its shader programs on how many lights of each kind it can", + " * see - NUM_POINT_LIGHTS, NUM_SPOT_LIGHTS, NUM_SPOT_LIGHT_MAPS and the", + " * matching shadow counts. A single budget shared by every kind keeps the", + " * *total* pinned to the cap but lets the mix drift as the camera moves, and", + " * each mix that has not been seen before costs a shader compilation - a", + " * stutter the player feels. So each kind gets its own budget instead, which", + " * pins each of those numbers individually.", + " */", + "class LightManager {", + " /** @type {Map} Visible lights, by light kind. */", + " visibleLists = new Map();", + " /** @type {Map} Shadow casters, by light kind. */", + " shadowLists = new Map();", + " /** @type {Map} Lit light capacity, by light kind. */", + " maxCountByKind;", + " /** @type {Map} Shadow caster capacity, by light kind. */", + " shadowCountByKind;", + " /** @type {Set} The light kinds this scene has actually used. */", + " usedKinds = new Set();", + " /** @type {{shadowCount: number, mapCount: number, count: number}} */", + " deviceBudget;", + " /** @type {(kindCount: number) => {shadowCount: number, mapCount: number, count: number}} */", + " _computeDeviceBudget;", + " /** @type {{value: number}} */", + " _requestedCount;", + " /** @type {{value: number}} */", + " _requestedShadowCount;", + "", + " /**", + " * @param maxCount {{value: number}} The maximum number of lit lights, for", + " * each light kind, as the game asked for it.", + " * @param shadowCount {{value: number}} The maximum number of shadow", + " * casting lights, for each light kind, as the game asked for it.", + " * @param computeDeviceBudget {(kindCount: number) => {shadowCount: number, mapCount: number, count: number}}", + " * What the device can take, for a given number of light kinds.", + " */", + " constructor(maxCount, shadowCount, computeDeviceBudget) {", + " this._computeDeviceBudget = computeDeviceBudget;", + " this._requestedCount = maxCount;", + " this._requestedShadowCount = shadowCount;", + " // A scene that uses lights at all uses at least one kind of them.", + " this.deviceBudget = computeDeviceBudget(1);", + "", + " // Spot lights that project a texture already spend a texture unit on", + " // that texture, so they get the tighter of the two budgets.", + " this.maxCountByKind = new Map([", + " ['point', makeDeviceCappedCapacity(", + " maxCount, () => this.deviceBudget.count)],", + " ['spot', makeDeviceCappedCapacity(", + " maxCount, () => this.deviceBudget.count)],", + " ['spotWithMap', makeDeviceCappedCapacity(maxCount, () => Math.min(", + " this.deviceBudget.count, this.deviceBudget.mapCount))],", + " ]);", + " this.shadowCountByKind = new Map([", + " ['point', makeDeviceCappedCapacity(", + " shadowCount, () => this.deviceBudget.shadowCount)],", + " ['spot', makeDeviceCappedCapacity(", + " shadowCount, () => this.deviceBudget.shadowCount)],", + " ['spotWithMap', makeDeviceCappedCapacity(", + " shadowCount, () => this.deviceBudget.shadowCount)],", + " ]);", + " }", + "", + " /**", + " * Take note that the scene uses lights of this kind, sharing the device", + " * budget between one more kind if it had not been seen before.", + " *", + " * A kind can only ever be added, never dropped: a light that goes away for", + " * a while must not give the others a wider budget, or the numbers three.js", + " * compiles into its shaders would move again.", + " *", + " * @param kind {string}", + " */", + " _useKind(kind) {", + " if (this.usedKinds.has(kind)) {", + " return;", + " }", + " this.usedKinds.add(kind);", + " this.deviceBudget = this._computeDeviceBudget(this.usedKinds.size);", + "", + " // The budget just shrank: evict the lights that no longer fit, so", + " // that even this frame stays within what the device can take.", + " for (const list of this.visibleLists.values()) {", + " list.trimToCapacity();", + " }", + " for (const list of this.shadowLists.values()) {", + " list.trimToCapacity();", + " }", + "", + " if (this.deviceBudget.count < this._requestedCount.value", + " || this.deviceBudget.shadowCount", + " < this._requestedShadowCount.value) {", + " logger.info(", + " 'This device limits 3D lights to ' + this.deviceBudget.count", + " + ' per kind (' + this.deviceBudget.shadowCount", + " + ' casting a shadow, ' + this.deviceBudget.mapCount", + " + ' projecting a texture), now that ' + this.usedKinds.size", + " + ' kind(s) of light share its budget. Going over what it '", + " + 'reports would stop the shaders from linking.'", + " );", + " }", + " }", + "", + " clear() {", + " for (const list of this.visibleLists.values()) {", + " list.clear();", + " }", + " for (const list of this.shadowLists.values()) {", + " list.clear();", + " }", + " }", + "", + " /**", + " * The kind of a light, as far as the shaders are concerned. Lights of", + " * different kinds are counted separately by three.js, so they must be", + " * budgeted separately too.", + " * @param light {THREE.SpotLight | THREE.PointLight}", + " * @returns {string}", + " */", + " static getLightKind(light) {", + " //@ts-ignore - `isSpotLight` is set by three.js on SpotLight instances.", + " if (!light.isSpotLight) {", + " return 'point';", + " }", + " // A projected texture adds to NUM_SPOT_LIGHT_MAPS, so a spot light", + " // that has one is a different kind from a spot light that has not.", + " //@ts-ignore - only spot lights have a projected texture.", + " return light.map ? 'spotWithMap' : 'spot';", + " }", + "", + " /**", + " * @param lists {Map}", + " * @param kind {string}", + " * @param capacity {{value: number}}", + " * @param onInsertion {(object: LightRuntimeObject) => void}", + " * @param onDeletion {(object: LightRuntimeObject) => void}", + " * @returns {CappedLightList}", + " */", + " static _getListForKind(lists, kind, capacity, onInsertion, onDeletion) {", + " let list = lists.get(kind);", + " if (!list) {", + " list = new CappedLightList(capacity, onInsertion, onDeletion);", + " lists.set(kind, list);", + " }", + " return list;", + " }", + "", + " /**", + " * @param object {LightRuntimeObject}", + " * @param distance {number} The squared distance to the camera.", + " */", + " applyVisibilityAndShadow(object, distance) {", + " const light = object.__light3D;", + " const kind = LightManager.getLightKind(light);", + " this._useKind(kind);", + "", + " if (object._getIsCastingShadow()) {", + " LightManager._getListForKind(", + " this.shadowLists, kind, this.shadowCountByKind.get(kind),", + " enableShadow, disableShadow", + " ).insertByDistance(object, distance);", + " }", + " LightManager._getListForKind(", + " this.visibleLists, kind, this.maxCountByKind.get(kind),", + " showLight, hideLight", + " ).insertByDistance(object, distance);", + " }", + "}", + "", + "//@ts-ignore", + "gdjs.__light3DExtension = {", + " Light3DRenderer,", + " lightCountMax,", + " lightShadowCountMax,", + "}" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "the maximum number of nearest lights displayed simultaneously, counted separately for each kind of light (point lights, spot lights, spot lights projecting a texture). Devices that can't take that many lights enforce a lower limit.", + "fullName": "Max lights count", + "functionType": "ExpressionAndCondition", + "name": "LightCountMax", + "sentence": "max lights count", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::DefineHelperClasses" + }, + "parameters": [ + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = gdjs.__light3DExtension.lightCountMax.value;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "LightCountMax", + "name": "SetLightCountMax", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::DefineHelperClasses" + }, + "parameters": [ + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "gdjs.__light3DExtension.lightCountMax.value = value;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [], + "objectGroups": [] + }, + { + "description": "the maximum number of nearest lights displayed with shadow simultaneously, counted separately for each kind of light (point lights, spot lights, spot lights projecting a texture). Devices that can't take that many shadows enforce a lower limit.", + "fullName": "Max lights with shadow count", + "functionType": "ExpressionAndCondition", + "name": "LightShadowCountMax", + "sentence": "max lights with shadow count", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::DefineHelperClasses" + }, + "parameters": [ + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": "eventsFunctionContext.returnValue = gdjs.__light3DExtension.lightShadowCountMax.value;", + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "LightShadowCountMax", + "name": "SetLightShadowCountMax", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::DefineHelperClasses" + }, + "parameters": [ + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "gdjs.__light3DExtension.lightShadowCountMax.value = value;" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [], + "objectGroups": [] + } + ], + "eventsFunctionsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "functionName": "onFirstSceneLoaded" + }, + { + "functionName": "DefineHelperClasses" + }, + { + "functionName": "DefineSpotLightHelperClasses" + }, + { + "functionName": "DefinePointLightHelperClasses" + }, + { + "functionName": "LightCountMax" + }, + { + "functionName": "SetLightCountMax" + }, + { + "functionName": "LightShadowCountMax" + }, + { + "functionName": "SetLightShadowCountMax" + } + ] + }, + "eventsBasedBehaviors": [], + "eventsBasedObjects": [ + { + "areaMaxX": 20, + "areaMaxY": 20, + "areaMaxZ": 20, + "areaMinX": -20, + "areaMinY": -20, + "areaMinZ": -20, + "defaultName": "SpotLight", + "description": "Light up a cone like a flashlight.", + "fullName": "3D spot light", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLWZsYXNobGlnaHQiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNOSwxMEw2LDVIMThMMTUsMTBIOU0xOCw0SDZWMkgxOFY0TTksMjJWMTFIMTVWMjJIOU0xMiwxM0ExLDEgMCAwLDAgMTEsMTRBMSwxIDAgMCwwIDEyLDE1QTEsMSAwIDAsMCAxMywxNEExLDEgMCAwLDAgMTIsMTNaIiAvPjwvc3ZnPg==", + "is3D": true, + "isUsingLegacyInstancesRenderer": false, + "name": "SpotLight3D", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/b627f8e676b3aac26945b2c38db0cfa787d34d2eff23755d4eb1289452f6cd28_flashlight.svg", + "objects": [ + { + "assetStoreId": "", + "name": "Placeholder", + "persistentUuid": "6786eefd-3c18-4fcb-b3ae-95b07f953045", + "type": "Scene3D::Cube3DObject", + "variables": [], + "effects": [], + "behaviors": [], + "content": { + "width": 80, + "height": 80, + "depth": 80, + "enableTextureTransparency": false, + "facesOrientation": "Z", + "frontFaceResourceName": "", + "backFaceResourceName": "", + "backFaceUpThroughWhichAxisRotation": "X", + "leftFaceResourceName": "", + "rightFaceResourceName": "", + "topFaceResourceName": "", + "bottomFaceResourceName": "", + "frontFaceVisible": true, + "backFaceVisible": true, + "leftFaceVisible": true, + "rightFaceVisible": true, + "topFaceVisible": true, + "bottomFaceVisible": true, + "frontFaceResourceRepeat": false, + "backFaceResourceRepeat": false, + "leftFaceResourceRepeat": false, + "rightFaceResourceRepeat": false, + "topFaceResourceRepeat": false, + "bottomFaceResourceRepeat": false, + "materialType": "Basic", + "tint": "255;255;255", + "isCastingShadow": false, + "isReceivingShadow": false + } + } + ], + "objectsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "objectName": "Placeholder" + } + ] + }, + "objectsGroups": [], + "layers": [ + { + "ambientLightColorB": 200, + "ambientLightColorG": 200, + "ambientLightColorR": 200, + "camera2DPlaneMaxDrawingDistance": 5000, + "camera3DFarPlaneDistance": 10000, + "camera3DFieldOfView": 45, + "camera3DNearPlaneDistance": 3, + "cameraType": "", + "followBaseLayerCamera": false, + "isLightingLayer": false, + "isLocked": false, + "name": "", + "renderingType": "", + "visibility": true, + "cameras": [ + { + "defaultSize": true, + "defaultViewport": true, + "height": 0, + "viewportBottom": 1, + "viewportLeft": 0, + "viewportRight": 1, + "viewportTop": 0, + "width": 0 + } + ], + "effects": [] + } + ], + "instances": [ + { + "angle": 0, + "customSize": true, + "depth": 40, + "height": 40, + "layer": "", + "name": "Placeholder", + "persistentUuid": "1310c768-04d4-4133-98d9-37d836f8a990", + "width": 40, + "x": -20, + "y": -20, + "z": -20, + "zOrder": 1, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + } + ], + "editionSettings": { + "grid": false, + "gridType": "rectangular", + "gridWidth": 32, + "gridHeight": 32, + "gridDepth": 32, + "gridOffsetX": 0, + "gridOffsetY": 0, + "gridOffsetZ": 0, + "gridColor": 10401023, + "gridAlpha": 0.8, + "snap": false, + "zoomFactor": 9.06473532531222, + "windowMask": false, + "selectedLayer": "", + "gameEditorMode": "instances-editor" + }, + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::DefineHelperClasses" + }, + "parameters": [ + "", + "" + ] + }, + { + "type": { + "value": "Light3D::DefineSpotLightHelperClasses" + }, + "parameters": [ + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const {", + " Light3DRenderer,", + " //@ts-ignore", + "} = gdjs.__light3DExtension;", + "const {", + " SpotLightAdapter,", + " SpotLightHelper,", + " //@ts-ignore", + "} = gdjs.__light3DExtension.spot;", + "", + "/** @type {gdjs.CustomRuntimeObject3D} */", + "//@ts-ignore", + "const object = objects[0];", + "", + "const game = runtimeScene.getGame();", + "", + "// This is a hack that may break in future releases.", + "// Replace the group that would hold children objects by the light.", + "const layer = object.getInstanceContainer().getLayer(object.getLayer());", + "const group = object.getRenderer()._threeGroup;", + "layer.getRenderer().remove3DRendererObject(group);", + "", + "const spotLight = new THREE.SpotLight(0xffffff);", + "spotLight.position.copy(group.position);", + "spotLight.rotation.copy(group.rotation);", + "spotLight.add(spotLight.target);", + "spotLight.target.position.x = 100;", + "spotLight.up.set(0, 0, 1);", + "spotLight.shadow.camera.up.set(0, 0, 1);", + "//@ts-ignore", + "object.__light3D = spotLight;", + "//@ts-ignore", + "object.__spotLightAdapter = new SpotLightAdapter(object, spotLight);", + "", + "const spotLight3DRenderer = new Light3DRenderer(object, object._instanceContainer, object.getInstanceContainer());", + "object._renderer = spotLight3DRenderer;", + "if (game.isInGameEdition && game.isInGameEdition()) {", + " const spotLightHelper = new SpotLightHelper(object);", + " spotLightHelper.rotation.order = 'ZYX';", + " spotLightHelper.add(spotLight);", + " spotLight3DRenderer._threeGroup = spotLightHelper;", + " layer.getRenderer().add3DRendererObject(spotLightHelper);", + "}", + "else {", + " spotLight3DRenderer._threeGroup = spotLight;", + " layer.getRenderer().add3DRendererObject(spotLight);", + "}", + "", + "spotLight.updateMatrixWorld(true);", + "", + "// Allow to tween the light color.", + "//@ts-ignore", + "if (!object.setColor && !object.getColor) {", + " const prototype = Object.getPrototypeOf(object);", + " prototype.setColor = function(tint) {", + " this._setColor(tint);", + " this.__spotLightAdapter.setColor(tint);", + " }", + " prototype.getColor = function() {", + " return this._getColor(eventsFunctionContext);", + " }", + "}", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::SpotLight3D::UpdateFromProperties" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onDestroy", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.CustomRuntimeObject} */", + "const object = objects[0];", + "// Here runtimeScene is the gdjs.CustomRuntimeObjectInstanceContainer inside the custom object.", + "const gameScene = object.getRuntimeScene();", + "", + "object.__light3D.dispose();", + "object.get3DRendererObject().dispose();", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onHotReloading", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::SpotLight3D::UpdateFromProperties" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Update from properties.", + "fullName": "Update from properties", + "functionType": "Action", + "name": "UpdateFromProperties", + "private": true, + "sentence": "Update from properties of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::SpotLight3D::SetColor" + }, + "parameters": [ + "Object", + "=", + "Color", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetIntensity" + }, + "parameters": [ + "Object", + "=", + "Intensity", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetDecay" + }, + "parameters": [ + "Object", + "=", + "Decay", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetConeLength" + }, + "parameters": [ + "Object", + "=", + "ConeLength", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetConeAngle" + }, + "parameters": [ + "Object", + "=", + "ConeAngle", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetSmoothing" + }, + "parameters": [ + "Object", + "=", + "Smoothing", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowQuality" + }, + "parameters": [ + "Object", + "=", + "ShadowQuality", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowCameraNearPlane" + }, + "parameters": [ + "Object", + "=", + "ShadowCameraNearPlane", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowCameraFarPlane" + }, + "parameters": [ + "Object", + "=", + "ShadowCameraFarPlane", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowBias" + }, + "parameters": [ + "Object", + "=", + "ShadowBias", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::UpdateImage" + }, + "parameters": [ + "Object", + "" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::UpdateHelper" + }, + "parameters": [ + "Object", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "=", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Light3D::SpotLight3D::SetCastingShadow" + }, + "parameters": [ + "Object", + "no", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "True", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Light3D::SpotLight3D::SetCastingShadow" + }, + "parameters": [ + "Object", + "yes", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "Update helper", + "functionType": "Action", + "name": "UpdateHelper", + "private": true, + "sentence": "Update graphical helper of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const game = runtimeScene.getGame();", + "if (game.isInGameEdition && game.isInGameEdition()) {", + " const spotLightHelper = objects[0].get3DRendererObject();", + " spotLightHelper.update();", + "}", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "Update image", + "functionType": "Action", + "name": "UpdateImage", + "private": true, + "sentence": "Update the image of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.CustomRuntimeObject3D} */\r", + "const object = objects[0];\r", + "const resourceName = object._getImage();\r", + "object.__spotLightAdapter.setImage(resourceName);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the cone angle of the light.", + "fullName": "Cone angle", + "functionType": "ExpressionAndCondition", + "name": "ConeAngle", + "sentence": "the cone angle", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ConeAngle" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ConeAngle", + "name": "SetConeAngle", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ConeAngle", + "=", + "Value" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::ApplyShadowBias" + }, + "parameters": [ + "Object", + "ShadowBias", + "ShadowQuality", + "ConeAngle", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const coneAngle = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setConeAngle(coneAngle);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the color of the light.", + "fullName": "Color", + "functionType": "ExpressionAndCondition", + "name": "Color", + "sentence": "the color", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Color" + ] + } + ] + } + ], + "expressionType": { + "type": "color" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Color", + "name": "SetColor", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetStringVariable" + }, + "parameters": [ + "Color", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const color = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setColor(color);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the smoothing of the light. Percent of the spotlight cone that is attenuated due to penumbra (between 0 and 1).", + "fullName": "Smoothing", + "functionType": "ExpressionAndCondition", + "name": "Smoothing", + "sentence": "the smoothing", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Smoothing" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Smoothing", + "name": "SetSmoothing", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "Smoothing", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setSmoothing(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the intensity of the light.", + "fullName": "Intensity", + "functionType": "ExpressionAndCondition", + "name": "Intensity", + "sentence": "the intensity", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Intensity" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Intensity", + "name": "SetIntensity", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "Intensity", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setIntensity(value);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the decay of the light. The amount the light dims along the distance of the light.", + "fullName": "Decay", + "functionType": "ExpressionAndCondition", + "name": "Decay", + "sentence": "the decay", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Decay" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Decay", + "name": "SetDecay", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "Decay", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setDecay(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the light is casting shadows.", + "fullName": "Shadow casting", + "functionType": "Condition", + "group": "3D spot light shadow configuration", + "name": "IsCastingShadow", + "sentence": "_PARAM0_ casting shadows", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "True", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Change if the light is casting shadows.", + "fullName": "Shadow casting", + "functionType": "Action", + "group": "3D spot light shadow configuration", + "name": "SetCastingShadow", + "sentence": "_PARAM0_ casting shadows: _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "Value", + "False", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetBooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "False", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "Value", + "True", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetBooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "True", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setCastingShadow(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::SpotLight3D::SetConeLength" + }, + "parameters": [ + "Object", + "=", + "ConeLength", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + }, + { + "defaultValue": "yes", + "description": "Shadow casting", + "name": "Value", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "Rotate the light to light up a position.", + "fullName": "Look at position", + "functionType": "Action", + "group": "Angle", + "name": "LookAtPosition", + "sentence": "_PARAM0_ look at _PARAM1_ ; _PARAM2_ ; _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const targetX = eventsFunctionContext.getArgument(\"TargetX\");\r", + "const targetY = eventsFunctionContext.getArgument(\"TargetY\");\r", + "const targetZ = eventsFunctionContext.getArgument(\"TargetZ\");\r", + "\r", + "object.__spotLightAdapter.lookAtPosition(targetX, targetY, targetZ);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + }, + { + "description": "Target X", + "name": "TargetX", + "type": "expression" + }, + { + "description": "Target Y", + "name": "TargetY", + "type": "expression" + }, + { + "description": "Target Z", + "name": "TargetZ", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "Rotate the light to light up an object.", + "fullName": "Look at object", + "functionType": "Action", + "group": "Angle", + "name": "LookAtObject", + "sentence": "_PARAM0_ look at _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::SpotLight3D::LookAtPosition" + }, + "parameters": [ + "Object", + "Target.CenterX()", + "Target.CenterY()", + "Target.Object3D::CenterZ()", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + }, + { + "description": "Object", + "name": "Target", + "type": "objectList" + }, + { + "description": "3D capability", + "name": "Object3D", + "supplementaryInformation": "Scene3D::Base3DBehavior", + "type": "behavior" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow quality of the light.", + "fullName": "Shadow quality", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowQuality", + "sentence": "the shadow quality", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "ShadowQuality" + ] + } + ] + } + ], + "expressionType": { + "supplementaryInformation": "[\"Low\",\"Medium\",\"High\"]", + "type": "stringWithSelector" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowQuality", + "group": "3D spot light shadow configuration", + "name": "SetShadowQuality", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetStringVariable" + }, + "parameters": [ + "ShadowQuality", + "=", + "Value" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::ApplyShadowBias" + }, + "parameters": [ + "Object", + "ShadowBias", + "ShadowQuality", + "ConeAngle", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setShadowQuality(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow camera near plane of the light.", + "fullName": "Shadow camera near plane", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowCameraNearPlane", + "sentence": "the shadow camera near plane", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowCameraNearPlane" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowCameraNearPlane", + "group": "3D spot light shadow configuration", + "name": "SetShadowCameraNearPlane", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowCameraNearPlane", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setShadowCameraNearPlane(value);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow camera far plane of the light.", + "fullName": "Shadow camera far plane", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowCameraFarPlane", + "sentence": "the shadow camera far plane", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowCameraFarPlane" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowCameraFarPlane", + "group": "3D spot light shadow configuration", + "name": "SetShadowCameraFarPlane", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowCameraFarPlane", + "=", + "Value" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::ApplyShadowCameraFarPlane" + }, + "parameters": [ + "Object", + "min(Value, ConeLength)", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the cone length of the light. 0 means no limit.", + "fullName": "Cone length", + "functionType": "ExpressionAndCondition", + "name": "ConeLength", + "sentence": "the cone length", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ConeLength" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ConeLength", + "name": "SetConeLength", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ConeLength", + "=", + "Value" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setConeLength(value);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ] + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Three.js reduces the far plane to match the light range.\nSo, we need to set it again or it will stay at the lowest value the range took.\nWe do the min() on our side to in order:\n- to avoid a side effect when Three.js is upgraded\n- because Three.js keeps the old value in cache and doesn't apply it back unless we set the lower value explicitly ourselves." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::SpotLight3D::ApplyShadowCameraFarPlane" + }, + "parameters": [ + "Object", + "min(Value, ShadowCameraFarPlane)", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "Apply shadow camera far plane", + "functionType": "Action", + "group": "3D spot light shadow configuration", + "name": "ApplyShadowCameraFarPlane", + "private": true, + "sentence": "Apply shadow camera far plane of _PARAM0_ to _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__spotLightAdapter.setShadowCameraFarPlane(value);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow bias of the light. Use this to avoid \"shadow acne\" due to depth buffer precision. Choose a value small enough like 0.001 to avoid creating distance between shadows and objects but not too small to avoid shadow glitches on low/medium quality. This value is used for high quality, and multiplied by 2 for medium quality and 4 for low quality.", + "fullName": "Shadow bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowBias", + "sentence": "the shadow bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowBias", + "=", + "Value" + ] + }, + { + "type": { + "value": "Light3D::SpotLight3D::ApplyShadowBias" + }, + "parameters": [ + "Object", + "Value", + "ShadowQuality", + "ConeAngle", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "Apply shadow bias", + "functionType": "Action", + "group": "3D spot light shadow configuration", + "name": "ApplyShadowBias", + "private": true, + "sentence": "Apply shadow bias of _PARAM0_ to _PARAM1_ for a _PARAM2_ quality and cone angle _PARAM3_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "const quality = eventsFunctionContext.getArgument(\"Quality\");\r", + "const coneAngle = eventsFunctionContext.getArgument(\"Angle\");\r", + "\r", + "object.__spotLightAdapter.setShadowBias(value, quality, coneAngle);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + }, + { + "description": "Quality", + "name": "Quality", + "type": "string" + }, + { + "description": "Cone angle", + "name": "Angle", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__spotLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + } + ], + "eventsFunctionsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "functionName": "onCreated" + }, + { + "functionName": "onDestroy" + }, + { + "functionName": "onHotReloading" + }, + { + "functionName": "UpdateFromProperties" + }, + { + "functionName": "UpdateHelper" + }, + { + "functionName": "UpdateImage" + }, + { + "folderName": "Angle", + "children": [ + { + "functionName": "LookAtPosition" + }, + { + "functionName": "LookAtObject" + } + ] + }, + { + "functionName": "Color" + }, + { + "functionName": "SetColor" + }, + { + "functionName": "Intensity" + }, + { + "functionName": "SetIntensity" + }, + { + "functionName": "Decay" + }, + { + "functionName": "SetDecay" + }, + { + "functionName": "ConeLength" + }, + { + "functionName": "SetConeLength" + }, + { + "functionName": "ConeAngle" + }, + { + "functionName": "SetConeAngle" + }, + { + "functionName": "Smoothing" + }, + { + "functionName": "SetSmoothing" + }, + { + "folderName": "3D spot light shadow configuration", + "children": [ + { + "functionName": "IsCastingShadow" + }, + { + "functionName": "SetCastingShadow" + }, + { + "functionName": "ShadowQuality" + }, + { + "functionName": "SetShadowQuality" + }, + { + "functionName": "ShadowCameraNearPlane" + }, + { + "functionName": "SetShadowCameraNearPlane" + }, + { + "functionName": "ShadowCameraFarPlane" + }, + { + "functionName": "SetShadowCameraFarPlane" + }, + { + "functionName": "ApplyShadowCameraFarPlane" + }, + { + "functionName": "ShadowBias" + }, + { + "functionName": "SetShadowBias" + }, + { + "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" + } + ] + } + ] + }, + "propertyDescriptors": [ + { + "value": "255;255;255", + "type": "Color", + "label": "Color", + "name": "Color" + }, + { + "value": "30", + "type": "Number", + "unit": "DegreeAngle", + "label": "Cone angle", + "group": "Cone", + "name": "ConeAngle" + }, + { + "value": "1", + "type": "Number", + "label": "Intensity", + "name": "Intensity" + }, + { + "value": "1", + "type": "Number", + "label": "Smoothing", + "description": "Percent of the spotlight cone that is attenuated due to penumbra (between 0 and 1).", + "group": "Cone", + "name": "Smoothing" + }, + { + "value": "2", + "type": "Number", + "label": "Decay", + "description": "The amount the light dims along the distance of the light.", + "name": "Decay" + }, + { + "value": "", + "type": "Resource", + "label": "Image", + "description": "Shadow casting must be enabled for the image to have any effect.", + "group": "Shadow", + "extraInformation": [ + "image" + ], + "choices": [], + "hidden": true, + "name": "Image" + }, + { + "value": "true", + "type": "Boolean", + "label": "Shadow casting", + "group": "Shadow", + "name": "IsCastingShadow" + }, + { + "value": "Medium", + "type": "Choice", + "label": "Shadow quality", + "group": "Shadow", + "choices": [ + { + "label": "Low", + "value": "Low" + }, + { + "label": "Medium", + "value": "Medium" + }, + { + "label": "High", + "value": "High" + }, + { + "label": "Very high", + "value": "VeryHigh" + } + ], + "name": "ShadowQuality" + }, + { + "value": "20", + "type": "Number", + "unit": "Pixel", + "label": "Shadow camera near plane", + "group": "Shadow", + "advanced": true, + "name": "ShadowCameraNearPlane" + }, + { + "value": "2000", + "type": "Number", + "unit": "Pixel", + "label": "Shadow camera far plane", + "group": "Shadow", + "advanced": true, + "name": "ShadowCameraFarPlane" + }, + { + "value": "2000", + "type": "Number", + "unit": "Pixel", + "label": "Cone length", + "description": "0 means no limit.", + "group": "Cone", + "name": "ConeLength" + }, + { + "value": "0", + "type": "Number", + "label": "Shadow bias", + "description": "Use this to avoid \"shadow acne\" due to depth buffer precision. Choose a value small enough like 0.001 to avoid creating distance between shadows and objects but not too small to avoid shadow glitches on low/medium quality. This value is used for high quality, and multiplied by 2 for medium quality and 4 for low quality.", + "group": "Shadow", + "advanced": true, + "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" + } + ], + "propertiesFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "propertyName": "Color" + }, + { + "propertyName": "Intensity" + }, + { + "propertyName": "Decay" + }, + { + "folderName": "Cone", + "children": [ + { + "propertyName": "ConeAngle" + }, + { + "propertyName": "ConeLength" + }, + { + "propertyName": "Smoothing" + } + ] + }, + { + "folderName": "Shadow", + "children": [ + { + "propertyName": "IsCastingShadow" + }, + { + "propertyName": "ShadowQuality" + }, + { + "propertyName": "Image" + }, + { + "propertyName": "ShadowCameraNearPlane" + }, + { + "propertyName": "ShadowCameraFarPlane" + }, + { + "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" + } + ] + } + ] + }, + "variants": [] + }, + { + "areaMaxX": 20, + "areaMaxY": 20, + "areaMaxZ": 20, + "areaMinX": -20, + "areaMinY": -20, + "areaMinZ": -20, + "defaultName": "PointLight", + "description": "Light up in all directions like a fire.", + "fullName": "3D point light", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXRvcmNoIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTguNiA5LjZDOSAxMC4yIDkuNSAxMC43IDEwLjIgMTFIMTQuMkMxNC41IDEwLjkgMTQuNyAxMC43IDE0LjkgMTAuNUMxNS45IDkuNSAxNi4zIDggMTUuOCA2LjdMMTUuNyA2LjVDMTUuNiA2LjIgMTUuNCA2IDE1LjIgNS44QzE1LjEgNS42IDE0LjkgNS41IDE0LjggNS4zQzE0LjQgNSAxNCA0LjcgMTMuNiA0LjNDMTIuNyAzLjQgMTIuNiAyIDEzLjEgMUMxMi42IDEuMSAxMi4xIDEuNCAxMS43IDEuOEMxMC4yIDMgOS42IDUuMSAxMC4zIDdWNy4yQzEwLjMgNy4zIDEwLjIgNy40IDEwLjEgNy41QzEwIDcuNiA5LjggNy41IDkuNyA3LjRMOS42IDcuM0M5IDYuNSA4LjkgNS4zIDkuMyA0LjNDOC40IDUuMSA3LjkgNi40IDggNy43QzggOCA4LjEgOC4zIDguMiA4LjZDOC4yIDguOSA4LjQgOS4zIDguNiA5LjZNMTIuMyA4LjFDMTIuNCA3LjYgMTIuMiA3LjIgMTIuMSA2LjhDMTIgNi40IDEyIDYgMTIuMiA1LjZMMTIuNSA2LjJDMTIuOSA2LjggMTMuNiA3IDEzLjggNy44VjguMUMxMy44IDguNiAxMy42IDkuMSAxMy4zIDkuNEMxMy4xIDkuNSAxMi45IDkuNyAxMi43IDkuN0MxMi4xIDkuOSAxMS40IDkuNiAxMSA5LjJDMTEuOCA5LjIgMTIuMiA4LjYgMTIuMyA4LjFNMTUgMTJWMTRIMTRMMTMgMjJIMTFMMTAgMTRIOVYxMkgxNVoiIC8+PC9zdmc+", + "is3D": true, + "isUsingLegacyInstancesRenderer": false, + "name": "PointLight3D", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/bf9158c96f4346dabd9e8ae0ddd737809652797812eb50376bae62463ac7fc42_torch.svg", + "objects": [ + { + "assetStoreId": "", + "name": "Placeholder", + "persistentUuid": "6786eefd-3c18-4fcb-b3ae-95b07f953045", + "type": "Scene3D::Cube3DObject", + "variables": [], + "effects": [], + "behaviors": [], + "content": { + "width": 80, + "height": 80, + "depth": 80, + "enableTextureTransparency": false, + "facesOrientation": "Z", + "frontFaceResourceName": "", + "backFaceResourceName": "", + "backFaceUpThroughWhichAxisRotation": "X", + "leftFaceResourceName": "", + "rightFaceResourceName": "", + "topFaceResourceName": "", + "bottomFaceResourceName": "", + "frontFaceVisible": true, + "backFaceVisible": true, + "leftFaceVisible": true, + "rightFaceVisible": true, + "topFaceVisible": true, + "bottomFaceVisible": true, + "frontFaceResourceRepeat": false, + "backFaceResourceRepeat": false, + "leftFaceResourceRepeat": false, + "rightFaceResourceRepeat": false, + "topFaceResourceRepeat": false, + "bottomFaceResourceRepeat": false, + "materialType": "Basic", + "tint": "255;255;255", + "isCastingShadow": false, + "isReceivingShadow": false + } + } + ], + "objectsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "objectName": "Placeholder" + } + ] + }, + "objectsGroups": [], + "layers": [ + { + "ambientLightColorB": 200, + "ambientLightColorG": 200, + "ambientLightColorR": 200, + "camera2DPlaneMaxDrawingDistance": 5000, + "camera3DFarPlaneDistance": 10000, + "camera3DFieldOfView": 45, + "camera3DNearPlaneDistance": 3, + "cameraType": "", + "followBaseLayerCamera": false, + "isLightingLayer": false, + "isLocked": false, + "name": "", + "renderingType": "", + "visibility": true, + "cameras": [ + { + "defaultSize": true, + "defaultViewport": true, + "height": 0, + "viewportBottom": 1, + "viewportLeft": 0, + "viewportRight": 1, + "viewportTop": 0, + "width": 0 + } + ], + "effects": [] + } + ], + "instances": [ + { + "angle": 0, + "customSize": true, + "depth": 40, + "height": 40, + "layer": "", + "name": "Placeholder", + "persistentUuid": "1310c768-04d4-4133-98d9-37d836f8a990", + "width": 40, + "x": -20, + "y": -20, + "z": -20, + "zOrder": 1, + "numberProperties": [], + "stringProperties": [], + "initialVariables": [] + } + ], + "editionSettings": { + "grid": false, + "gridType": "rectangular", + "gridWidth": 32, + "gridHeight": 32, + "gridDepth": 32, + "gridOffsetX": 0, + "gridOffsetY": 0, + "gridOffsetZ": 0, + "gridColor": 10401023, + "gridAlpha": 0.8, + "snap": false, + "zoomFactor": 9.06473532531222, + "windowMask": false, + "selectedLayer": "", + "gameEditorMode": "instances-editor" + }, + "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onCreated", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::DefineHelperClasses" + }, + "parameters": [ + "", + "" + ] + }, + { + "type": { + "value": "Light3D::DefinePointLightHelperClasses" + }, + "parameters": [ + "", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const {", + " Light3DRenderer,", + " //@ts-ignore", + "} = gdjs.__light3DExtension;", + "const {", + " PointLightAdapter,", + " PointLightHelper,", + " //@ts-ignore", + "} = gdjs.__light3DExtension.point;", + "", + "/** @type {gdjs.CustomRuntimeObject3D} */", + "//@ts-ignore", + "const object = objects[0];", + "", + "const game = runtimeScene.getGame();", + "", + "// This is a hack that may break in future releases.", + "// Replace the group that would hold children objects by the light.", + "const layer = object.getInstanceContainer().getLayer(object.getLayer());", + "const group = object.getRenderer()._threeGroup;", + "layer.getRenderer().remove3DRendererObject(group);", + "", + "const pointLight = new THREE.PointLight(0xffffff);", + "pointLight.position.copy(group.position);", + "pointLight.rotation.copy(group.rotation);", + "pointLight.up.set(0, 0, 1);", + "pointLight.shadow.camera.up.set(0, 0, 1);", + "//@ts-ignore", + "object.__light3D = pointLight;", + "//@ts-ignore", + "object.__pointLightAdapter = new PointLightAdapter(object, pointLight);", + "", + "const pointLight3DRenderer = new Light3DRenderer(object, object._instanceContainer, object.getInstanceContainer());", + "object._renderer = pointLight3DRenderer;", + "if (game.isInGameEdition && game.isInGameEdition()) {", + " const pointLightHelper = new PointLightHelper(object);", + " pointLightHelper.rotation.order = 'ZYX';", + " pointLightHelper.add(pointLight);", + " pointLight3DRenderer._threeGroup = pointLightHelper;", + " layer.getRenderer().add3DRendererObject(pointLightHelper);", + "}", + "else {", + " pointLight3DRenderer._threeGroup = pointLight;", + " layer.getRenderer().add3DRendererObject(pointLight);", + "}", + "", + "pointLight.updateMatrixWorld(true);", + "", + "// Allow to tween the light color.", + "//@ts-ignore", + "if (!object.setColor && !object.getColor) {", + " const prototype = Object.getPrototypeOf(object);", + " prototype.setColor = function(tint) {", + " this._setColor(tint);", + " this.__pointLightAdapter.setColor(tint);", + " }", + " prototype.getColor = function() {", + " return this._getColor(eventsFunctionContext);", + " }", + "}", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::PointLight3D::UpdateFromProperties" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onDestroy", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "/** @type {gdjs.CustomRuntimeObject} */", + "const object = objects[0];", + "// Here runtimeScene is the gdjs.CustomRuntimeObjectInstanceContainer inside the custom object.", + "const gameScene = object.getRuntimeScene();", + "", + "object.__light3D.dispose();", + "object.get3DRendererObject().dispose();", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "Action", + "name": "onHotReloading", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::PointLight3D::UpdateFromProperties" + }, + "parameters": [ + "Object", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Update from properties.", + "fullName": "Update from properties", + "functionType": "Action", + "name": "UpdateFromProperties", + "private": true, + "sentence": "Update from properties of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::PointLight3D::SetColor" + }, + "parameters": [ + "Object", + "=", + "Color", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetIntensity" + }, + "parameters": [ + "Object", + "=", + "Intensity", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetDecay" + }, + "parameters": [ + "Object", + "=", + "Decay", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetRange" + }, + "parameters": [ + "Object", + "=", + "Range", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowQuality" + }, + "parameters": [ + "Object", + "=", + "ShadowQuality", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowCameraNearPlane" + }, + "parameters": [ + "Object", + "=", + "ShadowCameraNearPlane", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowCameraFarPlane" + }, + "parameters": [ + "Object", + "=", + "ShadowCameraFarPlane", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowBias" + }, + "parameters": [ + "Object", + "=", + "ShadowBias", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::UpdateHelper" + }, + "parameters": [ + "Object", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "=", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Light3D::PointLight3D::SetCastingShadow" + }, + "parameters": [ + "Object", + "no", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "True", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "Light3D::PointLight3D::SetCastingShadow" + }, + "parameters": [ + "Object", + "yes", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "Update helper", + "functionType": "Action", + "name": "UpdateHelper", + "private": true, + "sentence": "Update graphical helper of _PARAM0_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const game = runtimeScene.getGame();", + "if (game.isInGameEdition && game.isInGameEdition()) {", + " const pointLightHelper = objects[0].get3DRendererObject();", + " pointLightHelper.update();", + "}", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the color of the light.", + "fullName": "Color", + "functionType": "ExpressionAndCondition", + "name": "Color", + "sentence": "the color", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "Color" + ] + } + ] + } + ], + "expressionType": { + "type": "color" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Color", + "name": "SetColor", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetStringVariable" + }, + "parameters": [ + "Color", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const color = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__pointLightAdapter.setColor(color);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the intensity of the light.", + "fullName": "Intensity", + "functionType": "ExpressionAndCondition", + "name": "Intensity", + "sentence": "the intensity", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Intensity" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Intensity", + "name": "SetIntensity", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "Intensity", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__pointLightAdapter.setIntensity(value);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the decay of the light. The amount the light dims along the distance of the light.", + "fullName": "Decay", + "functionType": "ExpressionAndCondition", + "name": "Decay", + "sentence": "the decay", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Decay" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Decay", + "name": "SetDecay", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "Decay", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__pointLightAdapter.setDecay(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Check if the light is casting shadows.", + "fullName": "Shadow casting", + "functionType": "Condition", + "group": "3D point light shadow configuration", + "name": "IsCastingShadow", + "sentence": "_PARAM0_ casting shadows", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "True", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetReturnBoolean" + }, + "parameters": [ + "True" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::SetRange" + }, + "parameters": [ + "Object", + "=", + "Range", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "Change if the light is casting shadows.", + "fullName": "Shadow casting", + "functionType": "Action", + "group": "3D point light shadow configuration", + "name": "SetCastingShadow", + "sentence": "_PARAM0_ casting shadows: _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "Value", + "False", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetBooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "False", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BooleanVariable" + }, + "parameters": [ + "Value", + "True", + "" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetBooleanVariable" + }, + "parameters": [ + "IsCastingShadow", + "True", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__pointLightAdapter.setCastingShadow(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + }, + { + "defaultValue": "yes", + "description": "Shadow casting", + "name": "Value", + "optional": true, + "type": "yesorno" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow quality of the light.", + "fullName": "Shadow quality", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowQuality", + "sentence": "the shadow quality", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnString" + }, + "parameters": [ + "ShadowQuality" + ] + } + ] + } + ], + "expressionType": { + "supplementaryInformation": "[\"Low\",\"Medium\",\"High\"]", + "type": "stringWithSelector" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowQuality", + "group": "3D point light shadow configuration", + "name": "SetShadowQuality", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetStringVariable" + }, + "parameters": [ + "ShadowQuality", + "=", + "Value" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::ApplyShadowBias" + }, + "parameters": [ + "Object", + "ShadowBias", + "ShadowQuality", + "" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__pointLightAdapter.setShadowQuality(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow camera near plane of the light.", + "fullName": "Shadow camera near plane", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowCameraNearPlane", + "sentence": "the shadow camera near plane", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowCameraNearPlane" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowCameraNearPlane", + "group": "3D point light shadow configuration", + "name": "SetShadowCameraNearPlane", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowCameraNearPlane", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__pointLightAdapter.setShadowCameraNearPlane(value);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::PointLight3D::SetRange" + }, + "parameters": [ + "Object", + "=", + "Range", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow camera far plane of the light.", + "fullName": "Shadow camera far plane", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowCameraFarPlane", + "sentence": "the shadow camera far plane", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowCameraFarPlane" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowCameraFarPlane", + "group": "3D point light shadow configuration", + "name": "SetShadowCameraFarPlane", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowCameraFarPlane", + "=", + "Value" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::ApplyShadowCameraFarPlane" + }, + "parameters": [ + "Object", + "min(Value, Range)", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "description": "the range of the light. 0 means no limit.", + "fullName": "Range", + "functionType": "ExpressionAndCondition", + "name": "Range", + "sentence": "the range", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "Range" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "Range", + "name": "SetRange", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "Range", + "=", + "Value" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__pointLightAdapter.setRange(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + }, + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Three.js reduces the far plane to match the light range.\nSo, we need to set it again or it will stay at the lowest value the range took.\nWe do the min() on our side to in order:\n- to avoid a side effect when Three.js is upgraded\n- because Three.js keeps the old value in cache and doesn't apply it back unless we set the lower value explicitly ourselves." + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "Light3D::PointLight3D::ApplyShadowCameraFarPlane" + }, + "parameters": [ + "Object", + "min(Value, ShadowCameraFarPlane)", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "Apply shadow camera far plane", + "functionType": "Action", + "group": "3D point light shadow configuration", + "name": "ApplyShadowCameraFarPlane", + "private": true, + "sentence": "Apply shadow camera far plane of _PARAM0_ to _PARAM1_", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "\r", + "object.__pointLightAdapter.setShadowCameraFarPlane(value);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow bias of the light. Use this to avoid \"shadow acne\" due to depth buffer precision. Choose a value small enough like 0.001 to avoid creating distance between shadows and objects but not too small to avoid shadow glitches on low/medium quality. This value is used for high quality, and multiplied by 2 for medium quality and 4 for low quality.", + "fullName": "Shadow bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowBias", + "sentence": "the shadow bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowBias", + "group": "3D point light shadow configuration", + "name": "SetShadowBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowBias", + "=", + "Value" + ] + }, + { + "type": { + "value": "Light3D::PointLight3D::ApplyShadowBias" + }, + "parameters": [ + "Object", + "Value", + "ShadowQuality", + "" + ] + } + ] + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "Apply shadow bias", + "functionType": "Action", + "group": "3D point light shadow configuration", + "name": "ApplyShadowBias", + "private": true, + "sentence": "Apply shadow bias of _PARAM0_ to _PARAM1_ for a _PARAM2_ quality", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];\r", + "const value = eventsFunctionContext.getArgument(\"Value\");\r", + "const quality = eventsFunctionContext.getArgument(\"Quality\");\r", + "\r", + "object.__pointLightAdapter.setShadowBias(value, quality);\r", + "" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + }, + { + "description": "Value", + "name": "Value", + "type": "expression" + }, + { + "description": "Quality", + "name": "Quality", + "type": "string" + } + ], + "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D point light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__pointLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + } + ], + "eventsFunctionsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "functionName": "onCreated" + }, + { + "functionName": "onDestroy" + }, + { + "functionName": "onHotReloading" + }, + { + "functionName": "UpdateFromProperties" + }, + { + "functionName": "UpdateHelper" + }, + { + "functionName": "Color" + }, + { + "functionName": "SetColor" + }, + { + "functionName": "Intensity" + }, + { + "functionName": "SetIntensity" + }, + { + "functionName": "Decay" + }, + { + "functionName": "SetDecay" + }, + { + "functionName": "Range" + }, + { + "functionName": "SetRange" + }, + { + "folderName": "3D point light shadow configuration", + "children": [ + { + "functionName": "IsCastingShadow" + }, + { + "functionName": "SetCastingShadow" + }, + { + "functionName": "ShadowQuality" + }, + { + "functionName": "SetShadowQuality" + }, + { + "functionName": "ShadowCameraNearPlane" + }, + { + "functionName": "SetShadowCameraNearPlane" + }, + { + "functionName": "ShadowCameraFarPlane" + }, + { + "functionName": "SetShadowCameraFarPlane" + }, + { + "functionName": "ApplyShadowCameraFarPlane" + }, + { + "functionName": "ShadowBias" + }, + { + "functionName": "SetShadowBias" + }, + { + "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" + } + ] + } + ] + }, + "propertyDescriptors": [ + { + "value": "255;255;255", + "type": "Color", + "label": "Color", + "name": "Color" + }, + { + "value": "1", + "type": "Number", + "label": "Intensity", + "name": "Intensity" + }, + { + "value": "2", + "type": "Number", + "label": "Decay", + "description": "The amount the light dims along the distance of the light.", + "name": "Decay" + }, + { + "value": "true", + "type": "Boolean", + "label": "Shadow casting", + "group": "Shadow", + "name": "IsCastingShadow" + }, + { + "value": "Medium", + "type": "Choice", + "label": "Shadow quality", + "group": "Shadow", + "choices": [ + { + "label": "", + "value": "Low" + }, + { + "label": "", + "value": "Medium" + }, + { + "label": "", + "value": "High" + } + ], + "name": "ShadowQuality" + }, + { + "value": "20", + "type": "Number", + "unit": "Pixel", + "label": "Shadow camera near plane", + "group": "Shadow", + "advanced": true, + "name": "ShadowCameraNearPlane" + }, + { + "value": "2000", + "type": "Number", + "unit": "Pixel", + "label": "Shadow camera far plane", + "group": "Shadow", + "advanced": true, + "name": "ShadowCameraFarPlane" + }, + { + "value": "2000", + "type": "Number", + "unit": "Pixel", + "label": "Range", + "description": "0 means no limit.", + "name": "Range" + }, + { + "value": "0", + "type": "Number", + "label": "Shadow Bias", + "description": "Use this to avoid \"shadow acne\" due to depth buffer precision. Choose a value small enough like 0.001 to avoid creating distance between shadows and objects but not too small to avoid shadow glitches on low/medium quality. This value is used for high quality, and multiplied by 2 for medium quality and 4 for low quality.", + "group": "Shadow", + "advanced": true, + "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" + } + ], + "propertiesFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "propertyName": "Color" + }, + { + "propertyName": "Intensity" + }, + { + "propertyName": "Decay" + }, + { + "propertyName": "Range" + }, + { + "folderName": "Shadow", + "children": [ + { + "propertyName": "IsCastingShadow" + }, + { + "propertyName": "ShadowQuality" + }, + { + "propertyName": "ShadowCameraNearPlane" + }, + { + "propertyName": "ShadowCameraFarPlane" + }, + { + "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" + } + ] + } + ] + }, + "variants": [] + } + ] + } + ], + "externalLayouts": [] } diff --git a/examples/3d-light-playground/assets/Rocks Small.glb b/examples/3d-light-playground/assets/Rocks Small.glb new file mode 100644 index 000000000..f88b4eaea Binary files /dev/null and b/examples/3d-light-playground/assets/Rocks Small.glb differ diff --git a/examples/starting-3d-camera-monitoring/starting-3d-camera-monitoring.json b/examples/starting-3d-camera-monitoring/starting-3d-camera-monitoring.json index 33e755e83..053b58705 100644 --- a/examples/starting-3d-camera-monitoring/starting-3d-camera-monitoring.json +++ b/examples/starting-3d-camera-monitoring/starting-3d-camera-monitoring.json @@ -1371,7 +1371,7 @@ "content": { "Decay": 4, "Intensity": 4, - "Range": 400, + "Range": 0, "IsCastingShadow": false } }, @@ -2931,7 +2931,7 @@ "name": "Light3D", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", "shortDescription": "A collection of light object for 3D.", - "version": "1.0.3", + "version": "2.1.0", "description": "A collection of light object for 3D.", "origin": { "identifier": "Light3D", @@ -2944,10 +2944,62 @@ "authorIds": [ "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" ], + "changelog": [ + { + "version": "2.0.0", + "breaking": "- Point and spot lights now fade with the distance like they do with the 3D renderer of recent GDevelop versions (Three.js r185), including on previous GDevelop versions. Lights made for a previous version of the extension need a higher intensity (and possibly a lower decay) to look the same." + } + ], "dependencies": [], "globalVariables": [], "sceneVariables": [], "eventsFunctions": [ + { + "fullName": "", + "functionType": "Action", + "name": "onFirstSceneLoaded", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "// Before Three.js r165, GDevelop rendered with \"legacy lights\": point and spot", + "// lights faded linearly up to their range and every light color was", + "// multiplied by PI. Recent GDevelop versions use the physically based falloff", + "// of Three.js r185 instead, which is what the light properties are tuned for.", + "// Use the same falloff with older GDevelop versions so that lights look the", + "// same with every version:", + "// - distances are divided by 100 because recent GDevelop versions render 3D", + "// with a default world scale of 100 pixels per unit, while older versions", + "// work in pixels,", + "// - the attenuation is divided by PI as the legacy light colors are multiplied by PI.", + "// It must be patched before any shader using lights is compiled, as Three.js", + "// caches compiled shaders.", + "const lightsParsBegin = THREE.ShaderChunk.lights_pars_begin;", + "if (!lightsParsBegin.includes('#if defined ( LEGACY_LIGHTS )')) {", + " return;", + "}", + "THREE.ShaderChunk.lights_pars_begin = lightsParsBegin.replace(", + " /#if defined \\( LEGACY_LIGHTS \\)[\\s\\S]*?#else/,", + " [", + " '#if defined ( LEGACY_LIGHTS )',", + " '\\t\\tfloat distanceFalloff = 1.0 / max( pow( lightDistance * 0.01, decayExponent ), 0.01 );',", + " '\\t\\tif ( cutoffDistance > 0.0 ) {',", + " '\\t\\t\\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );',", + " '\\t\\t}',", + " '\\t\\treturn distanceFalloff * RECIPROCAL_PI;',", + " '\\t#else',", + " ].join('\\n')", + ");" + ], + "parameterObjects": "", + "useStrict": true, + "eventsSheetExpanded": true + } + ], + "parameters": [], + "objectGroups": [] + }, { "description": "Define spot light helper classes JavaScript code.", "fullName": "Define spot light helper classes", @@ -3075,6 +3127,8 @@ " constructor(object, spotLight) {", " this.object = object;", " this.spotLight = spotLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -3132,6 +3186,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -3139,6 +3194,7 @@ " */", " setConeAngle(coneAngle) {", " this.spotLight.angle = coneAngle * Math.PI / 180;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -3178,6 +3234,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -3204,6 +3261,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -3238,6 +3296,28 @@ " const texture = game.getImageManager().getThreeTexture(resourceName);", " this.spotLight.map = texture;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.spotLight.shadow;", + " // Three.js uses the cone length as the far plane of the shadow camera.", + " const shadowDistance = this.spotLight.distance || shadow.camera.far;", + " const coneAngle = Math.min(this.spotLight.angle, gdjs.toRad(89));", + " const shadowMapWidth = 2 * shadowDistance * Math.tan(coneAngle);", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -3328,6 +3408,8 @@ " constructor(object, pointLight) {", " this.object = object;", " this.pointLight = pointLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -3355,7 +3437,10 @@ " * @param value {number}", " */", " setRange(value) {", - " this.pointLight.distance = value;", + " const runtimeScene = this.object.getRuntimeScene();", + " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", + " this.pointLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -3385,6 +3470,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -3413,6 +3499,7 @@ " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", "", " this.pointLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -3431,6 +3518,28 @@ " : 1;", " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.pointLight.shadow;", + " // Three.js uses the range as the far plane of the shadow cameras.", + " const shadowDistance = this.pointLight.distance || shadow.camera.far;", + " // Each face of the shadow cube map covers 90 degrees.", + " const shadowMapWidth = 2 * shadowDistance;", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -3517,7 +3626,11 @@ " spotLight.castShadow = false;", " spotLight.visible = false;", "", - " if (!object.isHidden()) {", + " // Instances hidden at start stay visible in the editor, but their light must not shine.", + " const isHiddenAtStartInEditor =", + " !!editor && !!editor.isInstanceHiddenAtStart && editor.isInstanceHiddenAtStart(object);", + "", + " if (!object.isHidden() && !isHiddenAtStartInEditor) {", " let isSelected = false;", " if (editor) {", " const selectedObject = editor._selection.getLastSelectedObject();", @@ -3758,6 +3871,17 @@ " * @param sortDistance {number} The squared distance to the camera.", " */", " insertByDistance(object, sortDistance) {", + " // A render can happen without a game step in between (the editor", + " // and the gameplay test harness render a paused game), so a light", + " // can be offered again before the lists were cleared. Keep it once,", + " // or the duplicates would evict the other lights - but apply its", + " // state again, as the renderer reset it before offering the light.", + " for (const pair of this.objects) {", + " if (pair.object === object) {", + " this.onInsertion(object);", + " return;", + " }", + " }", " let insertionIndex = 0;", " for (let index = this.objects.length - 1; index >= 0; index--) {", " if (sortDistance >= this.objects[index].sortDistance) {", @@ -4136,6 +4260,9 @@ "eventsFunctionsFolderStructure": { "folderName": "__ROOT", "children": [ + { + "functionName": "onFirstSceneLoaded" + }, { "functionName": "DefineHelperClasses" }, @@ -4609,6 +4736,17 @@ "" ] }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::SpotLight3D::UpdateImage" @@ -5965,6 +6103,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__spotLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -6073,6 +6294,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -6194,6 +6421,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -6242,6 +6478,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } @@ -6673,6 +6912,17 @@ "" ] }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::PointLight3D::UpdateHelper" @@ -7719,6 +7969,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D point light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__pointLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -7801,6 +8134,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -7888,6 +8227,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -7922,6 +8270,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } diff --git a/examples/starting-3d-fnaf-five-nights-at-freddys/starting-3d-fnaf-five-nights-at-freddys.json b/examples/starting-3d-fnaf-five-nights-at-freddys/starting-3d-fnaf-five-nights-at-freddys.json index 516b7c258..9e2de2678 100644 --- a/examples/starting-3d-fnaf-five-nights-at-freddys/starting-3d-fnaf-five-nights-at-freddys.json +++ b/examples/starting-3d-fnaf-five-nights-at-freddys/starting-3d-fnaf-five-nights-at-freddys.json @@ -2612,7 +2612,6 @@ "Smoothing": 0.5, "ShadowQuality": "Medium", "Intensity": 8.2, - "ShadowBias": 0.00001, "IsCastingShadow": false, "Decay": 1 } @@ -10033,7 +10032,7 @@ "name": "Light3D", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", "shortDescription": "A collection of light object for 3D.", - "version": "2.0.0", + "version": "2.1.0", "description": "A collection of light object for 3D.", "origin": { "identifier": "Light3D", @@ -10229,6 +10228,8 @@ " constructor(object, spotLight) {", " this.object = object;", " this.spotLight = spotLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -10286,6 +10287,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -10293,6 +10295,7 @@ " */", " setConeAngle(coneAngle) {", " this.spotLight.angle = coneAngle * Math.PI / 180;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -10332,6 +10335,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -10358,6 +10362,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -10392,6 +10397,28 @@ " const texture = game.getImageManager().getThreeTexture(resourceName);", " this.spotLight.map = texture;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.spotLight.shadow;", + " // Three.js uses the cone length as the far plane of the shadow camera.", + " const shadowDistance = this.spotLight.distance || shadow.camera.far;", + " const coneAngle = Math.min(this.spotLight.angle, gdjs.toRad(89));", + " const shadowMapWidth = 2 * shadowDistance * Math.tan(coneAngle);", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -10482,6 +10509,8 @@ " constructor(object, pointLight) {", " this.object = object;", " this.pointLight = pointLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -10512,6 +10541,7 @@ " const runtimeScene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", " this.pointLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -10541,6 +10571,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -10569,6 +10600,7 @@ " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", "", " this.pointLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -10587,6 +10619,28 @@ " : 1;", " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.pointLight.shadow;", + " // Three.js uses the range as the far plane of the shadow cameras.", + " const shadowDistance = this.pointLight.distance || shadow.camera.far;", + " // Each face of the shadow cube map covers 90 degrees.", + " const shadowMapWidth = 2 * shadowDistance;", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -11783,6 +11837,17 @@ "" ] }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::SpotLight3D::UpdateImage" @@ -13139,6 +13204,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__spotLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -13247,6 +13395,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -13368,6 +13522,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -13416,6 +13579,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } @@ -13847,6 +14013,17 @@ "" ] }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::PointLight3D::UpdateHelper" @@ -14893,6 +15070,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D point light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__pointLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -14975,6 +15235,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -15062,6 +15328,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -15096,6 +15371,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } diff --git a/examples/starting-expanded-3d-house-horror/starting-expanded-3d-house-horror.json b/examples/starting-expanded-3d-house-horror/starting-expanded-3d-house-horror.json index 382d4d70d..3320e4a68 100644 --- a/examples/starting-expanded-3d-house-horror/starting-expanded-3d-house-horror.json +++ b/examples/starting-expanded-3d-house-horror/starting-expanded-3d-house-horror.json @@ -1,7 +1,7 @@ { "firstLayout": "", "gdVersion": { - "build": 283, + "build": 285, "major": 5, "minor": 6, "revision": 0 @@ -203,72 +203,72 @@ "kind": "image", "metadata": "", "name": "assets/HouseWallpaper.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/HouseFloor.png", "kind": "image", "metadata": "", "name": "assets/HouseFloor.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/HouseCeiling.png", "kind": "image", "metadata": "", "name": "assets/HouseCeiling.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/HouseSiding.png", "kind": "image", "metadata": "", "name": "assets/HouseSiding.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/HouseRoof.png", "kind": "image", "metadata": "", "name": "assets/HouseRoof.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/HouseDoor.png", "kind": "image", "metadata": "", "name": "assets/HouseDoor.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/HouseYard.png", "kind": "image", "metadata": "", "name": "assets/HouseYard.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/StarterGlass.png", "kind": "image", "metadata": "", "name": "assets/StarterGlass.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/HouseCrate.png", "kind": "image", "metadata": "", "name": "assets/HouseCrate.png", - "userAdded": true, - "smoothed": true + "smoothed": true, + "userAdded": true }, { "file": "assets/Fence.glb", @@ -467,6 +467,7 @@ "mangledName": "Game_32Scene", "name": "Game Scene", "r": 255, + "renderer3DWorldScale": 100, "standardSortMethod": true, "stopSoundsOnStartup": true, "title": "", @@ -525,11 +526,13 @@ }, { "name": "HasKey", + "persistentUuid": "455e1a70-6d92-4a3b-9fd9-5e4df4156574", "type": "boolean", "value": false }, { "name": "Escaped", + "persistentUuid": "e4b8d34b-764f-4acd-b9a1-9f5cc402dbd1", "type": "boolean", "value": false } @@ -606,2859 +609,2625 @@ { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 200, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "d5336879-bc6d-5e29-8df5-c7a98a131af5", + "width": 200, "x": 0, "y": 0, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "51191bd2-6990-5840-9653-72d2eafa7785", + "width": 160, "x": 200, "y": 0, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "52eaf006-6cd6-561a-a925-c10225d042ea", + "width": 160, "x": 200, "y": 0, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "b25d287d-c860-53d7-a429-15c0666e9335", + "width": 160, "x": 200, "y": 0, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 690, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "df1f0704-aacb-54bb-9654-773541698607", + "width": 690, "x": 360, "y": 0, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "56c5b998-cdbe-5170-a348-bcb4a042f713", + "width": 160, "x": 1050, "y": 0, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "77f1873f-6ae8-5344-a582-826931cec1bf", + "width": 160, "x": 1050, "y": 0, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "5f727540-8089-5810-80c6-90d4ac6ca9a2", + "width": 160, "x": 1050, "y": 0, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 190, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "302db6d2-e70c-59d8-a532-8f51e575abfb", + "width": 190, "x": 1210, "y": 0, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 190, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "ed251035-4f9c-581b-9d04-911ad0abdec7", + "width": 190, "x": 10, "y": 10, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "6ceea474-aac4-5d04-912a-267246ab7096", + "width": 160, "x": 200, "y": 10, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "3edc88cf-772a-5d4b-a5c8-a25ab81029ad", + "width": 160, "x": 200, "y": 10, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "1a93c034-ce76-5682-80c0-f61e8949384d", + "width": 160, "x": 200, "y": 10, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 690, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "4ea9d8e0-84b5-5bc5-a4db-2c3317f15626", + "width": 690, "x": 360, "y": 10, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "34d61c2b-5ab5-5089-ae86-a5d56c6853a5", + "width": 160, "x": 1050, "y": 10, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "249cdba7-9b65-550e-92e7-fd06325d479c", + "width": 160, "x": 1050, "y": 10, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "35bfd319-7af9-5cfa-b010-9c6ef15fc2ad", + "width": 160, "x": 1050, "y": 10, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 180, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "9e481ea5-47c4-5047-85ad-5882118a158d", + "width": 180, "x": 1210, "y": 10, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 200, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "54baec08-497c-5dc6-9bd9-75da1ac78a46", + "width": 200, "x": 0, "y": 990, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "73289677-cc57-5920-91e7-5d845e77ed3d", + "width": 160, "x": 200, "y": 990, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "a16ac16c-9701-5e93-9484-10d1a9bc1174", + "width": 160, "x": 200, "y": 990, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "4b249373-5264-5434-b7fe-24d20f8c3b20", + "width": 160, "x": 200, "y": 990, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 200, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "54245683-fd29-5297-8164-1132452070dd", + "width": 200, "x": 360, "y": 990, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 140, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "dd69f5ef-d24c-5a6d-816a-7816033ba4fe", + "width": 140, "x": 560, "y": 990, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 140, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "af4f5509-f926-5761-a49c-7d901553d30a", + "width": 140, "x": 560, "y": 990, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 450, "height": 10, - "width": 20, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "a7f7354e-bb88-5f04-91de-f2874f992f62", + "width": 20, "x": 700, "y": 990, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 450 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 20, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "ebb27bb0-24a1-58e8-8b53-578b604b1a47", + "width": 20, "x": 700, "y": 990, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 330, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "2ae1397b-fcd5-58fa-9c09-43a49bf6880e", + "width": 330, "x": 720, "y": 990, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "2d0cfc21-88c8-5cb7-a458-4e7ba355456d", + "width": 160, "x": 1050, "y": 990, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "1457d685-029c-55a1-a790-333171719672", + "width": 160, "x": 1050, "y": 990, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "dea66d77-360e-5f0d-9dcf-4f2254f8f8ac", + "width": 160, "x": 1050, "y": 990, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 190, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "51d212cf-73d5-5578-86c1-f864bdf6c6a4", + "width": 190, "x": 1210, "y": 990, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 190, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "c0108f26-e2cd-5a80-bb20-9757f9f3f665", + "width": 190, "x": 10, "y": 980, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "b80cb36b-816f-5518-adcf-5256b5151e09", + "width": 160, "x": 200, "y": 980, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "cad6ea7b-ee2c-50c5-924e-011e95b01972", + "width": 160, "x": 200, "y": 980, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "98904f22-4e65-5522-9906-844aead77986", + "width": 160, "x": 200, "y": 980, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 200, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "fb7ee0d9-281c-5144-87ce-2bdcdc1339a6", + "width": 200, "x": 360, "y": 980, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 140, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "be06e5f2-903b-5348-bc7d-d843aebba042", + "width": 140, "x": 560, "y": 980, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 140, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "84f16040-407a-59a0-83ed-0c1417eacbee", + "width": 140, "x": 560, "y": 980, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 450, "height": 10, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "e272f068-9986-5f17-affb-c5725a796337", + "width": 20, "x": 700, "y": 980, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 450 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "a2120900-b300-5a05-a76b-ac1f31409986", + "width": 20, "x": 700, "y": 980, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 330, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "c8d7f830-ccb7-5832-a476-c61977c7a712", + "width": 330, "x": 720, "y": 980, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "b7dff05b-9593-56e6-b2c8-4c64e8b87763", + "width": 160, "x": 1050, "y": 980, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "c3d61135-f6e8-5102-a5f8-e2d83ddbb383", + "width": 160, "x": 1050, "y": 980, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 10, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "07953a65-6054-541f-8c51-ebe93e54f69b", + "width": 160, "x": 1050, "y": 980, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 10, - "width": 180, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "e8226859-b104-55f0-8286-c9e870c986dc", + "width": 180, "x": 1210, "y": 980, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 110, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "256b175d-277b-5761-b9f6-d830639e2fa7", + "width": 10, "x": 0, "y": 10, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "c2f40a11-be4c-5e41-b500-785f3bcb17e4", + "width": 10, "x": 0, "y": 120, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "8ce5ac81-9eb4-553e-81d0-c8eaea400ce2", + "width": 10, "x": 0, "y": 120, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "e8461610-41e5-5815-9b60-a1999009d1a1", + "width": 10, "x": 0, "y": 120, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 370, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "3a9ad51c-b977-54b5-99ed-ba1e363ae2de", + "width": 10, "x": 0, "y": 280, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "0b1da844-d66d-5b87-b0af-b8bcad235d89", + "width": 10, "x": 0, "y": 650, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "a2990fa8-9c3b-5782-94ba-c020928f38d1", + "width": 10, "x": 0, "y": 650, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "181bad6f-2ec9-57e1-a51e-4fb2e88dbd56", + "width": 10, "x": 0, "y": 650, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 180, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "08588805-735f-5a20-98ef-afd5f1b8cce8", + "width": 10, "x": 0, "y": 810, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 100, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "2aa5bdcc-0e25-5834-8902-abd9a4937a17", + "width": 10, "x": 10, "y": 20, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "3806fb8b-712c-5aab-a99c-4e84fc78a10b", + "width": 10, "x": 10, "y": 120, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "9430fc56-0885-5c0e-be1f-4a02f38e8b46", + "width": 10, "x": 10, "y": 120, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "84fb447c-c59e-5630-947d-9723d12de60d", + "width": 10, "x": 10, "y": 120, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 370, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "bc8d9067-8f23-5ed4-8c8f-bac85106bf65", + "width": 10, "x": 10, "y": 280, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "9421f71f-92b9-58ff-9f52-1067d0c61f50", + "width": 10, "x": 10, "y": 650, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "9b6566a3-0bcb-5c69-850a-4a859ef19224", + "width": 10, "x": 10, "y": 650, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "d64b3d0c-13f9-53cf-93a2-0351e76c8706", + "width": 10, "x": 10, "y": 650, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 170, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "7378ddd5-27b9-5099-96f6-3bb1d4deff6f", + "width": 10, "x": 10, "y": 810, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 110, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "26f3cd12-d2e1-58fa-8308-b9f701189979", + "width": 10, "x": 1390, "y": 10, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 450, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "8f03a476-ca42-5e11-bd92-e005b5eeb518", + "width": 10, "x": 1390, "y": 120, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 450 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "7fc0da59-888d-5198-8555-84232278668d", + "width": 10, "x": 1390, "y": 120, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 370, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "e756c535-e011-59af-a31f-fcba34c9654e", + "width": 10, "x": 1390, "y": 280, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "ceacb24c-e57b-59ea-835e-2e5a611ad659", + "width": 10, "x": 1390, "y": 650, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "37133fd2-77f1-516c-860b-11006982d45d", + "width": 10, "x": 1390, "y": 650, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "27b49f2d-d20a-5010-9b20-8493cb2d2680", + "width": 10, "x": 1390, "y": 650, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 180, - "width": 10, "layer": "", - "locked": false, "name": "OuterWall", "persistentUuid": "4499620d-ee1d-5d33-a7b6-4ea44c880c0f", + "width": 10, "x": 1390, "y": 810, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 100, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "d0911579-3068-554b-ac19-d4c411253869", + "width": 10, "x": 1380, "y": 20, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 450, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "295fb4aa-151a-55cc-9393-249ec43acc6e", + "width": 10, "x": 1380, "y": 120, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 450 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "120aa216-f0a0-53f3-b2c5-ad2462329fe8", + "width": 10, "x": 1380, "y": 120, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 370, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "2ae646ad-e725-51d4-878d-74b3bbfe93ab", + "width": 10, "x": 1380, "y": 280, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 130, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "0e2c961a-b055-5a5d-bfb2-058a75d40cdf", + "width": 10, "x": 1380, "y": 650, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 130 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 220, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "f8e0c98a-572f-5823-bf30-2100e27e1110", + "width": 10, "x": 1380, "y": 650, "z": 230, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 220 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 70, "height": 160, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "9904404f-4c2a-558d-bc18-b7ce4787a8d1", + "width": 10, "x": 1380, "y": 650, "z": 550, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 70 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 620, "height": 170, - "width": 10, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "95047f84-5278-5b7b-beeb-b8a557ab3a44", + "width": 10, "x": 1380, "y": 810, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 620 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "3235af4a-3166-53bc-802a-723516913528", + "width": 160, "x": 200, "y": 8, "z": 130, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "48252751-2d37-506f-ac7b-d71707f8da34", + "width": 160, "x": 1050, "y": 8, "z": 130, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "e092bace-091d-590e-9aa8-aba792247965", + "width": 160, "x": 200, "y": 8, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "6943f24f-46e1-55c4-a098-b9547b80ef55", + "width": 160, "x": 1050, "y": 8, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "86ae3594-46be-5a70-9af8-afffd8e32a08", + "width": 160, "x": 200, "y": 988, "z": 130, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "a78211ef-7e39-5ee1-adb9-cd24aa2d19f3", + "width": 160, "x": 1050, "y": 988, "z": 130, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "94ac4da4-58f1-54dc-afd2-e74f5a64fe63", + "width": 160, "x": 200, "y": 988, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "c51cfb65-8846-5d57-8469-83ea56e4dd63", + "width": 160, "x": 560, "y": 988, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 4, - "width": 160, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "ba65ec8a-ac33-5b4a-a683-5faeb4948f11", + "width": 160, "x": 1050, "y": 988, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 160, - "width": 4, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "b6b447a6-3ea2-5f39-9c4e-970a763122e2", + "width": 4, "x": 8, "y": 120, "z": 130, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 160, - "width": 4, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "37e66342-23a8-5efb-957d-2d0baf55e31d", + "width": 4, "x": 8, "y": 650, "z": 130, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 160, - "width": 4, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "99ca77df-74c1-510b-938c-77d672fe2e0c", + "width": 4, "x": 8, "y": 120, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 160, - "width": 4, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "dbe9875b-4f07-5f4d-a3e1-e878725c2be5", + "width": 4, "x": 8, "y": 650, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 160, - "width": 4, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "97b0366a-409a-5ba7-be26-0d2d9e404c92", + "width": 4, "x": 1388, "y": 650, "z": 130, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 160, - "width": 4, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "ce699687-b02b-59f8-9499-6b6359ce3ae3", + "width": 4, "x": 1388, "y": 120, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 160, - "width": 4, "layer": "", - "locked": false, "name": "Window", "persistentUuid": "87882c8f-6dd2-586d-8eed-a811f8625716", + "width": 4, "x": 1388, "y": 650, "z": 450, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 1000, - "width": 1400, "layer": "", - "locked": false, "name": "Floor", "persistentUuid": "d313548c-a7b0-565f-a8d3-44d4dbc45120", + "width": 1400, "x": 0, "y": 0, "z": -20, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 100, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "4ea8afe7-1adb-549a-8eca-0e9ffbe7a1a1", + "width": 20, "x": 490, "y": 20, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 80, "height": 160, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "e6fe246b-a6aa-5df5-aa05-848bde548038", + "width": 20, "x": 490, "y": 120, "z": 220, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 80 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 370, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "5d8b653f-152c-559d-bcec-6adced1bb31c", + "width": 20, "x": 490, "y": 280, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 80, "height": 160, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "80368d75-8070-5375-a4e5-1712fcea83d0", + "width": 20, "x": 490, "y": 650, "z": 220, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 80 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 170, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "fcf50328-09be-5d1b-a76b-d2fe9a4e81d9", + "width": 20, "x": 490, "y": 810, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 60, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "b1ea7094-f150-5d31-b911-547c47d5462a", + "width": 20, "x": 890, "y": 20, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 80, "height": 160, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "ac8c36fb-a50d-5482-ae48-59156f3264d5", + "width": 20, "x": 890, "y": 80, "z": 220, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 80 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 740, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "c34db666-1556-52ec-bfb8-5e9b91f975e9", + "width": 20, "x": 890, "y": 240, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 20, - "width": 150, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "07429443-dc54-5c07-a6ea-7e2636a0e8d9", + "width": 150, "x": 20, "y": 390, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 80, "height": 20, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "17ec4434-e904-520a-9957-8ef96d42ba6e", + "width": 160, "x": 170, "y": 390, "z": 220, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 80 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 20, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "09441bac-bd0d-5a94-9b87-48ac0dd1db56", + "width": 160, "x": 330, "y": 390, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 20, - "width": 150, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "9e5dac8a-dd1c-5476-a1ba-e00f19f2038f", + "width": 150, "x": 910, "y": 390, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 80, "height": 20, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "35bd4fd2-d79f-5fbd-9926-d8b97bb1e67e", + "width": 160, "x": 1060, "y": 390, "z": 220, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 80 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 300, "height": 20, - "width": 160, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "40647d0b-e425-566a-97fa-3b6440612b99", + "width": 160, "x": 1220, "y": 390, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 300 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 16, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "7adcb961-d375-5e7d-9f28-6107fb041810", + "width": 190, "x": 700, "y": 868, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 16 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 32, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "b502ae6b-e75e-5766-8c21-727af9e2346d", + "width": 190, "x": 700, "y": 836, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 32 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 48, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "cfe86e63-b93d-5cdd-9ac9-3f40007db489", + "width": 190, "x": 700, "y": 804, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 48 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 64, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "2780b98e-d776-5d5e-91a3-fefbc570c5c1", + "width": 190, "x": 700, "y": 772, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 64 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 80, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "8cc85f48-00db-56ba-9f21-d4ee4aa69ce7", + "width": 190, "x": 700, "y": 740, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 80 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 96, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "64eead34-2b65-53eb-8e3c-15f32eeb0e8c", + "width": 190, "x": 700, "y": 708, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 96 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 112, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "b62cd1b3-7599-5389-8847-72dab397260d", + "width": 190, "x": 700, "y": 676, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 112 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 128, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "276beb74-9f1c-5a76-8941-8d3a99ea753f", + "width": 190, "x": 700, "y": 644, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 128 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 144, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "30de2b60-325b-559a-9fab-af83338b1f72", + "width": 190, "x": 700, "y": 612, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 144 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 160, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "2ddfa692-c822-54b9-82f9-0bd85f4f975f", + "width": 190, "x": 700, "y": 580, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 160 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 176, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "3c42386c-61c8-5f9c-b7ff-879856745742", + "width": 190, "x": 700, "y": 548, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 176 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 192, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "85e04bd6-8384-50b8-a184-ba57cf66214a", + "width": 190, "x": 700, "y": 516, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 192 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 208, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "4fc77077-d68a-58c7-b6ab-9ee25b23bfa9", + "width": 190, "x": 700, "y": 484, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 208 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 224, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "25de4e02-bfb2-56b4-951e-cab8a86522e1", + "width": 190, "x": 700, "y": 452, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 224 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 240, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "11df2c23-c49d-5575-8d90-21b3e7b21289", + "width": 190, "x": 700, "y": 420, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 240 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 256, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "f7614b4a-1339-5d55-9912-a87524335a1d", + "width": 190, "x": 700, "y": 388, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 256 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 272, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "87db051c-8d27-513f-9e5d-236e5bbe270c", + "width": 190, "x": 700, "y": 356, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 272 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 288, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "0d21e1cb-e9fa-5603-8073-b85ecd09f6be", + "width": 190, "x": 700, "y": 324, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 288 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 304, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "c2203695-1b47-5f3b-b60d-6d083e625b69", + "width": 190, "x": 700, "y": 292, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 304 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 320, "height": 32, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "bd7b9d07-1824-53ec-860d-d3a7a67e5a7b", + "width": 190, "x": 700, "y": 260, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 320 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 960, - "width": 680, "layer": "", - "locked": false, "name": "Floor", "persistentUuid": "f603c15b-94b8-588e-adb3-61b3853b224f", + "width": 680, "x": 20, "y": 20, "z": 300, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 960, - "width": 490, "layer": "", - "locked": false, "name": "Floor", "persistentUuid": "a699d277-1c24-5ae8-963e-6d2fcc9cb4c4", + "width": 490, "x": 890, "y": 20, "z": 300, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 240, - "width": 190, "layer": "", - "locked": false, "name": "Floor", "persistentUuid": "d75a70e6-2337-520c-b5c2-b4720932cadc", + "width": 190, "x": 700, "y": 20, "z": 300, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 280, - "width": 190, "layer": "", - "locked": false, "name": "Floor", "persistentUuid": "7b704f7a-1c18-5021-a2e5-939d03f91998", + "width": 190, "x": 700, "y": 700, "z": 300, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 440, - "width": 12, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "68a339f0-be45-511b-921f-ad98acd25344", + "width": 12, "x": 688, "y": 260, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 100, "height": 12, - "width": 190, "layer": "", - "locked": false, "name": "Stairs", "persistentUuid": "b80100c4-2fae-56b7-af1e-fb0c63d73f83", + "width": 190, "x": 700, "y": 700, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 100 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 280, "height": 80, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "6cc54f9a-a3a8-5578-a44d-68e18101fbb1", + "width": 20, "x": 490, "y": 20, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 280 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 60, "height": 160, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "77c44654-0ed7-5c1e-8f05-59602066be76", + "width": 20, "x": 490, "y": 100, "z": 540, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 60 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 280, "height": 500, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "94efd55f-4d7b-5481-97cc-08c0eabdd637", + "width": 20, "x": 490, "y": 260, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 280 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 60, "height": 160, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "54319adb-6da8-5990-bea7-bfea318cbd82", + "width": 20, "x": 490, "y": 760, "z": 540, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 60 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 280, "height": 60, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "f9953752-55ad-5abd-bb78-49344662c23f", + "width": 20, "x": 490, "y": 920, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 280 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 280, "height": 80, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "ed253d29-c948-57a4-80b5-cc7bc5b8b055", + "width": 20, "x": 890, "y": 20, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 280 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 60, "height": 160, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "bfb7335e-4204-576c-aa4d-e5120dfd4659", + "width": 20, "x": 890, "y": 100, "z": 540, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 60 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 280, "height": 500, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "e43fd7d2-46e9-5170-b044-582fe1caf22c", + "width": 20, "x": 890, "y": 260, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 280 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 60, "height": 160, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "c8e20882-e195-5260-8ab6-64cdccec9a66", + "width": 20, "x": 890, "y": 760, "z": 540, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 60 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 280, "height": 60, - "width": 20, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "143f1de7-e919-5701-a8ca-ed78635f9855", + "width": 20, "x": 890, "y": 920, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 280 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 280, "height": 20, - "width": 470, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "b2f19d43-acf7-50b0-b626-ff6d3191d4a8", + "width": 470, "x": 20, "y": 490, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 280 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 280, "height": 20, - "width": 470, "layer": "", - "locked": false, "name": "Wall", "persistentUuid": "16bd2cf8-1e25-5596-8ffd-aba8ff0fc8f6", + "width": 470, "x": 910, "y": 390, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 280 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 960, - "width": 1360, "layer": "", - "locked": false, "name": "Floor", "persistentUuid": "2a898768-fb7b-566c-8245-db215c183055", + "width": 1360, "x": 20, "y": 20, "z": 600, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 30, "height": 1080, - "width": 1480, "layer": "", - "locked": false, "name": "Roof", "persistentUuid": "94717079-421b-5839-bb42-9d4a4c1de9f4", + "width": 1480, "x": -40, "y": -40, "z": 620, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 30 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 150, "height": 100, - "width": 100, "layer": "", - "locked": false, "name": "Roof", "persistentUuid": "0105b549-5984-5c5d-8b1f-1fc6d7624a00", + "width": 100, "x": 1150, "y": 150, "z": 650, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 150 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 28, "height": 140, - "width": 300, "layer": "", - "locked": false, "name": "Floor", "persistentUuid": "f56bb65e-f4e2-5885-98c2-1102a2c8595d", + "width": 300, "x": 480, "y": 1000, "z": -20, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 28 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 230, "height": 10, - "width": 140, "layer": "", - "locked": false, "name": "Door", "persistentUuid": "5eb543f4-a5e1-5fc8-b156-952e122d7875", + "width": 140, "x": 560, "y": 990, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 230 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 30, "height": 500, - "width": 2600, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "012f4e33-9ed9-5c14-854d-bfef74b80a69", + "width": 2600, "x": -600, "y": -500, "z": -30, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 30 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 30, "height": 900, - "width": 2600, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "8fe512d2-fc1f-5fca-9a2f-33a5fa1107c1", + "width": 2600, "x": -600, "y": 1000, "z": -30, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 30 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 30, "height": 1000, - "width": 600, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "3bef1146-7c36-51f9-9f0d-6f5c42701ba4", + "width": 600, "x": -600, "y": 0, "z": -30, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 30 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 30, "height": 1000, - "width": 600, "layer": "", - "locked": false, "name": "Ground", "persistentUuid": "2e49d285-efd7-5297-a76c-7b36d040ed79", + "width": 600, "x": 1400, "y": 0, "z": -30, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 30 + "initialVariables": [] }, { "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "63fddf63-4495-5dd5-be7f-0338a18dae1c", + "width": 0, "x": -350, "y": -400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3468,14 +3237,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "835a2143-db23-5487-b002-fde3220d34b8", + "width": 0, "x": -50, "y": -400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3485,14 +3252,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "3e2e9b25-a79e-5d69-84e2-c8846776016a", + "width": 0, "x": 250, "y": -400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3502,14 +3267,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "543df4db-bc5a-53f0-a376-ff433c6e3e70", + "width": 0, "x": 550, "y": -400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3519,14 +3282,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "bef37868-1434-5deb-a5f3-2f18dbb2e6f0", + "width": 0, "x": 850, "y": -400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3536,14 +3297,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "ab7f43f2-2960-5d01-90c9-86b6b28b6e4f", + "width": 0, "x": 1150, "y": -400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3553,14 +3312,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "3886e7c9-1cb2-5bcc-b4a6-5a0280b87597", + "width": 0, "x": 1450, "y": -400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3570,14 +3327,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "ba95f666-bff3-5be6-9062-83402dd89656", + "width": 0, "x": 1750, "y": -400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3587,14 +3342,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "d6c7d087-0b0d-5db5-815e-7e1deedd1ced", + "width": 0, "x": -330, "y": 1800, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3604,14 +3357,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "850d0a2d-2245-56ad-8756-2dc7215d3de3", + "width": 0, "x": 10, "y": 1800, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3621,14 +3372,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "3521e77b-b720-54f8-bc7d-4ae814d26292", + "width": 0, "x": 350, "y": 1800, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3638,14 +3387,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "3e07abe2-b7c1-5c18-98e0-273d2f7c05e8", + "width": 0, "x": 885, "y": 1800, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3655,14 +3402,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "f6e96a10-cde2-5d8a-82dc-3ccb671e997b", + "width": 0, "x": 1175, "y": 1800, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3672,14 +3417,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "33c25ec0-53f6-58b8-9f83-c456318f36ca", + "width": 0, "x": 1465, "y": 1800, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3689,14 +3432,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "40d8c87c-dda6-54a3-9c7f-815f3cb8dfdc", + "width": 0, "x": 1755, "y": 1800, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3706,14 +3447,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "65a3421e-3c24-553c-bc03-02ebdb911c18", + "width": 0, "x": -500, "y": -242.9, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3723,14 +3462,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "3f88046f-03d8-54c2-97f9-0123147a94aa", + "width": 0, "x": -500, "y": 71.4, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3740,14 +3477,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "04d6f513-d38c-5cdd-b121-67d6f3b6a752", + "width": 0, "x": -500, "y": 385.7, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3757,14 +3492,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "3207b075-d54d-54d6-8627-842a13f1dbff", + "width": 0, "x": -500, "y": 700, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3774,14 +3507,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "bb4de374-279c-5a02-8b19-101b5b8c7268", + "width": 0, "x": -500, "y": 1014.3, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3791,14 +3522,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "6b47f462-bc42-5446-9401-dc73a3b2b4e5", + "width": 0, "x": -500, "y": 1328.6, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3808,14 +3537,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "9cd253fa-87c5-519d-a5d4-b5a232e1fa84", + "width": 0, "x": -500, "y": 1642.9, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3825,14 +3552,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "416e4eae-20d1-59bd-a695-88a2058014e9", + "width": 0, "x": 1900, "y": -242.9, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3842,14 +3567,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "5d72914a-1f04-5ba4-84d2-a7e6756664e5", + "width": 0, "x": 1900, "y": 71.4, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3859,14 +3582,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "68645427-c3b1-5015-8bfc-0cad92140661", + "width": 0, "x": 1900, "y": 385.7, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3876,14 +3597,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "7d376e74-0378-5123-a974-e213e41abb86", + "width": 0, "x": 1900, "y": 700, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3893,14 +3612,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "06676615-5b0a-5a3a-8e46-be67e1945b53", + "width": 0, "x": 1900, "y": 1014.3, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3910,14 +3627,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "d525f725-af15-5b9a-8d23-a43e57c84e4d", + "width": 0, "x": 1900, "y": 1328.6, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3927,14 +3642,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Fence", "persistentUuid": "9135d3cb-3961-581d-8f71-2af78faa631c", + "width": 0, "x": 1900, "y": 1642.9, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -3943,105 +3656,97 @@ { "angle": 0, "customSize": true, + "depth": 200, "height": 90, - "width": 220, "layer": "", - "locked": false, "name": "ExitZone", "persistentUuid": "5cc5f986-a2ff-5bd6-853e-bd936ed2c503", + "width": 220, "x": 520, "y": 1810, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 200 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 430, "height": 40, - "width": 2600, "layer": "", - "locked": false, "name": "Boundary", "persistentUuid": "8e429f5c-af1d-5691-b2f6-2bfdc47b71e7", + "width": 2600, "x": -600, "y": 1900, "z": -30, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 430 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 430, "height": 2400, - "width": 40, "layer": "", - "locked": false, "name": "Boundary", "persistentUuid": "7535d900-c89c-5426-aa11-70b8c2580782", + "width": 40, "x": -640, "y": -500, "z": -30, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 430 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 430, "height": 2400, - "width": 40, "layer": "", - "locked": false, "name": "Boundary", "persistentUuid": "22ddcbdb-a568-5bbd-b88e-310d7452a91d", + "width": 40, "x": 2000, "y": -500, "z": -30, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 430 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 430, "height": 40, - "width": 2600, "layer": "", - "locked": false, "name": "Boundary", "persistentUuid": "a21f7ce6-37eb-5774-be8a-47bca8f0cc1c", + "width": 2600, "x": -600, "y": -540, "z": -30, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 430 + "initialVariables": [] }, { "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Lightpost", "persistentUuid": "3d90bbe5-f9df-5f2d-a685-0f63010220d8", + "width": 0, "x": 490, "y": 1760, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4051,14 +3756,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Lightpost", "persistentUuid": "4486200d-34f2-52be-b456-f4cc2d9be191", + "width": 0, "x": 770, "y": 1760, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4068,14 +3771,12 @@ "angle": 10, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "DeadTree", "persistentUuid": "b453cb7b-7f25-55dd-bdff-7a19be659902", + "width": 0, "x": -300, "y": 1300, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4085,14 +3786,12 @@ "angle": 80, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "DeadWillow", "persistentUuid": "1b440069-51b7-53ad-a359-f18289d58e80", + "width": 0, "x": 1700, "y": 1400, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4102,14 +3801,12 @@ "angle": 150, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "DeadWillow", "persistentUuid": "a505629a-6717-57af-9e4f-796d8220d7c6", + "width": 0, "x": -350, "y": 200, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4119,14 +3816,12 @@ "angle": 220, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "DeadTree", "persistentUuid": "08303ef7-1b22-596a-b309-7350b4a60969", + "width": 0, "x": 1750, "y": 300, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4136,14 +3831,12 @@ "angle": 300, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "DeadTree", "persistentUuid": "753d36ce-fb4f-5e23-b0a0-b3ac1e18132b", + "width": 0, "x": 1600, "y": 1650, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4153,14 +3846,12 @@ "angle": 40, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "DeadWillow", "persistentUuid": "7a80d3b5-f91e-552b-8531-4c1941b8f105", + "width": 0, "x": 150, "y": 1600, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4170,14 +3861,12 @@ "angle": 30, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Rock", "persistentUuid": "d8bc52cd-197d-5e22-be45-c02b71859561", + "width": 0, "x": -150, "y": 1500, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4187,14 +3876,12 @@ "angle": 200, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Rock", "persistentUuid": "09440e77-dcbc-56d2-a0d7-a821af535f0e", + "width": 0, "x": 1500, "y": 1200, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4204,14 +3891,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Rock", "persistentUuid": "b691190b-9d45-55e7-ac9d-39764d1dbf23", + "width": 0, "x": 1650, "y": -200, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4221,14 +3906,12 @@ "angle": 60, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "SmallRock", "persistentUuid": "597bfb8a-cd8b-5791-91d4-c13d64956fef", + "width": 0, "x": 380, "y": 1250, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4238,14 +3921,12 @@ "angle": 140, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "SmallRock", "persistentUuid": "8e16629b-25a2-51f6-bf2a-cfe7f981f97c", + "width": 0, "x": 960, "y": 1450, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4255,14 +3936,12 @@ "angle": 10, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "SmallRock", "persistentUuid": "0779f9b2-fd07-515f-a3de-b4dff8c71c9e", + "width": 0, "x": -400, "y": 700, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4272,14 +3951,12 @@ "angle": 250, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "SmallRock", "persistentUuid": "3703d8f9-5329-539b-81fa-aefb3b6db7be", + "width": 0, "x": 1800, "y": 900, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4289,14 +3966,12 @@ "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Commode", "persistentUuid": "9f9be44f-8dc5-55bc-8584-bd97de1960c6", + "width": 0, "x": 48.4, "y": 520, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4306,11 +3981,10 @@ "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "TV", "persistentUuid": "ba17903b-42e0-5bf5-a54f-5fe0dfece4af", + "width": 0, "x": 48.4, "y": 520, "z": 110, @@ -4323,14 +3997,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Sofa", "persistentUuid": "57ec8049-d6a1-5a87-9855-04d0bac4bc37", + "width": 0, "x": 330, "y": 520, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4340,14 +4012,12 @@ "angle": 135, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "RockingChair", "persistentUuid": "9c2a6e88-0859-5b35-962f-544d2ad50f29", + "width": 0, "x": 200, "y": 700, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4357,14 +4027,12 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Bookshelf", "persistentUuid": "8f378a0b-ad56-54c2-b25e-bc614396913e", + "width": 0, "x": 430, "y": 956.9, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4374,14 +4042,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Nightstand", "persistentUuid": "8e213ad2-7775-5ca4-a9ee-4a3c9c55d920", + "width": 0, "x": 55, "y": 935, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4391,11 +4057,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "OilLamp", "persistentUuid": "8ed06690-e407-5a82-8033-0aeecfab5481", + "width": 0, "x": 55, "y": 935, "z": 50, @@ -4408,14 +4073,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Cupboard", "persistentUuid": "209fc463-686a-5d7d-92f9-e3d0a97ebedc", + "width": 0, "x": 420, "y": 433.3, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4425,14 +4088,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "KitchenCabinet", "persistentUuid": "afbbeda0-cb3c-5bd8-827c-095cf9ebbdc6", + "width": 0, "x": 61.5, "y": 41.4, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4442,14 +4103,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Stove", "persistentUuid": "15a72f32-af36-5a08-a79e-4f7c9d0bfe1f", + "width": 0, "x": 121.5, "y": 48.4, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4459,14 +4118,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "KitchenCabinet", "persistentUuid": "baa6fdec-725a-5591-b936-8f8e39898286", + "width": 0, "x": 181.5, "y": 41.4, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4476,14 +4133,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "KitchenCabinet", "persistentUuid": "d503f35e-04aa-54ac-9311-d259eda2a556", + "width": 0, "x": 258.5, "y": 41.4, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4493,14 +4148,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Cupboard", "persistentUuid": "025a9971-85f1-5c93-98d7-b9bc93630dfa", + "width": 0, "x": 458.9, "y": 43.3, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4510,14 +4163,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Table", "persistentUuid": "20376d54-b701-5be9-9bcb-b53c033ecbdd", + "width": 0, "x": 255, "y": 245, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4527,14 +4178,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Chair", "persistentUuid": "8e792451-ccf9-5c33-989e-4364bd55f2b5", + "width": 0, "x": 217.5, "y": 208, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4544,14 +4193,12 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Chair", "persistentUuid": "fbf4b307-46f6-528f-98cf-f6cff1d1182c", + "width": 0, "x": 217.5, "y": 282, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4561,14 +4208,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Chair", "persistentUuid": "e808f0ba-6504-52f2-93eb-6c9702f9196f", + "width": 0, "x": 292.5, "y": 208, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4578,14 +4223,12 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Chair", "persistentUuid": "ace3fa25-91a4-590c-a621-a9c05fbc15fc", + "width": 0, "x": 292.5, "y": 282, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4595,14 +4238,12 @@ "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Clock", "persistentUuid": "c05087ac-a221-567a-9550-9d78729ab7f8", + "width": 0, "x": 527.6, "y": 880, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4612,14 +4253,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Commode", "persistentUuid": "7a992004-3cb2-5d7e-9460-86a8d0709c05", + "width": 0, "x": 600, "y": 48.4, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4629,11 +4268,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "OilLamp", "persistentUuid": "adbfeb3d-681e-5dad-af93-7ca2e33f5f7b", + "width": 0, "x": 600, "y": 48.4, "z": 110, @@ -4646,14 +4284,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Bookshelf", "persistentUuid": "5ba30d7e-782c-50e6-9fc4-413bdb50b4cc", + "width": 0, "x": 1356.9, "y": 500, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4663,14 +4299,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Bookshelf", "persistentUuid": "3a705d13-b54f-5abb-847b-89b4a06a24b7", + "width": 0, "x": 1356.9, "y": 900, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4680,14 +4314,12 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Desk", "persistentUuid": "f255fd87-06fe-53cf-9ee6-87f87c45747c", + "width": 0, "x": 1130, "y": 954, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4697,14 +4329,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Chair", "persistentUuid": "30954c16-f1dd-5389-8b8b-918a01f8ed5d", + "width": 0, "x": 1130, "y": 922.4, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4714,14 +4344,12 @@ "angle": 315, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "RockingChair", "persistentUuid": "9ccd061c-cebf-5308-9a97-bba36e816db9", + "width": 0, "x": 990, "y": 500, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4731,14 +4359,12 @@ "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Cupboard", "persistentUuid": "1ebf103a-58d4-5e73-a0a3-2a76235da6dd", + "width": 0, "x": 933.3, "y": 880, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4748,14 +4374,12 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Rack", "persistentUuid": "f8114557-0b73-55f7-9563-b587795e774b", + "width": 0, "x": 1355.9, "y": 90, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4765,14 +4389,12 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Rack", "persistentUuid": "04e57876-907a-52ea-934d-154da3544920", + "width": 0, "x": 1290, "y": 44.1, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], @@ -4781,120 +4403,108 @@ { "angle": 0, "customSize": true, + "depth": 43, "height": 43, - "width": 43, "layer": "", - "locked": false, "name": "PushableBox", "persistentUuid": "cbea3126-dfd6-5f4a-9206-4c469b169d6a", + "width": 43, "x": 963.5, "y": 48.5, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 43 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 43, "height": 43, - "width": 43, "layer": "", - "locked": false, "name": "PushableBox", "persistentUuid": "90872ff4-af6e-5a1a-aeca-9cc246125b24", + "width": 43, "x": 1008.5, "y": 48.5, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 43 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 43, "height": 43, - "width": 43, "layer": "", - "locked": false, "name": "PushableBox", "persistentUuid": "a70f609f-adfa-507e-b315-63c1be290665", + "width": 43, "x": 985.5, "y": 48.5, "z": 43, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 43 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 43, "height": 43, - "width": 43, "layer": "", - "locked": false, "name": "PushableBox", "persistentUuid": "ed5603c0-d275-5be8-90c1-ef6de445329a", + "width": 43, "x": 1053.5, "y": 48.5, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 43 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 43, "height": 43, - "width": 43, "layer": "", - "locked": false, "name": "PushableBox", "persistentUuid": "328d614c-cb35-5e3b-a7ef-2c243b6f0b6d", + "width": 43, "x": 1228.5, "y": 278.5, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 43 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 43, "height": 43, - "width": 43, "layer": "", - "locked": false, "name": "PushableBox", "persistentUuid": "f607896b-bf20-5257-ac6a-8c2035fc1380", + "width": 43, "x": 1178.5, "y": 298.5, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 43 + "initialVariables": [] }, { "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Bed", "persistentUuid": "92a59422-8b9b-51e0-8778-219e77743c53", + "width": 0, "x": 54.5, "y": 200, "z": 320, @@ -4907,11 +4517,10 @@ "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Nightstand", "persistentUuid": "2c7d4e3f-462f-51f5-b8c7-6856fe6538a3", + "width": 0, "x": 37.2, "y": 360, "z": 320, @@ -4924,11 +4533,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "OilLamp", "persistentUuid": "cd657883-4e52-5639-a761-93290acd2617", + "width": 0, "x": 37.2, "y": 360, "z": 370, @@ -4941,11 +4549,10 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Cupboard", "persistentUuid": "5e90851b-5888-5a44-ab31-797eb7f90303", + "width": 0, "x": 300, "y": 466.7, "z": 320, @@ -4958,11 +4565,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Mirror", "persistentUuid": "6ce24e7c-ff4d-5a4f-ae64-4cff9bae9442", + "width": 0, "x": 420, "y": 24.3, "z": 320, @@ -4975,11 +4581,10 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "DoubleBed", "persistentUuid": "0e7b09ee-f18f-57c0-a6b4-18da79ee37db", + "width": 0, "x": 120, "y": 893, "z": 320, @@ -4992,11 +4597,10 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Nightstand", "persistentUuid": "ca11b634-7f6b-5b12-b225-94f369d05106", + "width": 0, "x": 235, "y": 962.9, "z": 320, @@ -5009,11 +4613,10 @@ "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Bookshelf", "persistentUuid": "dc32a92e-acba-585c-8896-76931d3d8448", + "width": 0, "x": 43.2, "y": 580, "z": 320, @@ -5026,11 +4629,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Commode", "persistentUuid": "351e723e-f010-5b90-915b-11ec9f6013a4", + "width": 0, "x": 300, "y": 538.4, "z": 320, @@ -5043,11 +4645,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Mirror", "persistentUuid": "bd3d5382-973b-5e3b-9310-b1397e5292f0", + "width": 0, "x": 985, "y": 24.3, "z": 320, @@ -5060,11 +4661,10 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Commode", "persistentUuid": "5f84610f-34bd-55f7-ad45-9f4dbfa51360", + "width": 0, "x": 1150, "y": 361.7, "z": 320, @@ -5077,11 +4677,10 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Cupboard", "persistentUuid": "9d3072d8-a9b7-520d-91e1-80626f2d0f9f", + "width": 0, "x": 1356.7, "y": 330, "z": 320, @@ -5094,11 +4693,10 @@ "angle": 120, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "RockingChair", "persistentUuid": "2de02fa1-0f79-58f1-a754-628df0af565d", + "width": 0, "x": 1250, "y": 170, "z": 320, @@ -5111,11 +4709,10 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "DoubleBed", "persistentUuid": "f9893ab1-996e-5e1c-a358-af3f7bc9022b", + "width": 0, "x": 1293, "y": 530, "z": 320, @@ -5128,11 +4725,10 @@ "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Nightstand", "persistentUuid": "39cfa858-a88a-569b-aa27-ef9a7a27df14", + "width": 0, "x": 1362.9, "y": 625, "z": 320, @@ -5145,11 +4741,10 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Desk", "persistentUuid": "d1da462f-26de-505e-a02b-d0fea252924a", + "width": 0, "x": 1000, "y": 954, "z": 320, @@ -5162,11 +4757,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Chair", "persistentUuid": "ee4585d2-99cd-5192-8b84-04c5d383c1f0", + "width": 0, "x": 1000, "y": 922.4, "z": 320, @@ -5179,11 +4773,10 @@ "angle": 180, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Commode", "persistentUuid": "a4bfe232-ae46-536e-8287-6d116902fbf1", + "width": 0, "x": 1290, "y": 951.7, "z": 320, @@ -5196,11 +4789,10 @@ "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Mirror", "persistentUuid": "6009c336-6942-59e1-bc8f-ef1cd53efcb3", + "width": 0, "x": 914.3, "y": 500, "z": 320, @@ -5213,11 +4805,10 @@ "angle": 270, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Cupboard", "persistentUuid": "a9168138-74ff-5290-86de-56e76321e969", + "width": 0, "x": 933.3, "y": 650, "z": 320, @@ -5230,11 +4821,10 @@ "angle": 240, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "RockingChair", "persistentUuid": "5b1d75ae-9572-5ddb-89b2-b7362210a2c5", + "width": 0, "x": 1130, "y": 700, "z": 320, @@ -5247,11 +4837,10 @@ "angle": 30, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Key", "persistentUuid": "079ee210-7242-58d1-beab-2f2a9ecd22e9", + "width": 0, "x": 1000, "y": 954, "z": 380.2, @@ -5263,246 +4852,226 @@ { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "b31b22be-9bc8-5bdc-b16b-d82acfa7d2dc", + "width": 20, "x": 100, "y": 310, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "8cc3f6c1-9971-52a6-888e-88e937acd8a2", + "width": 20, "x": 245, "y": 610, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "c1c5f8d6-c582-5723-b7e9-c44a50985881", + "width": 20, "x": 590, "y": 110, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "727e97f7-8683-567c-b15b-380308262f43", + "width": 20, "x": 590, "y": 870, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "57bc6b95-95ff-58d0-ae99-049b35152b5d", + "width": 20, "x": 1140, "y": 630, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "6169e802-1652-5f8b-9f43-f4b1ae97941e", + "width": 20, "x": 1140, "y": 220, - "z": 0, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "4bb5d5ec-23f9-5291-a71e-093e9dfe5dee", + "width": 20, "x": 590, "y": 130, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "0341e202-1d27-5b98-a55a-cdb1e3e8b67a", + "width": 20, "x": 240, "y": 250, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "5e7d5e20-da7c-5bb2-b364-8158e992ed92", + "width": 20, "x": 245, "y": 710, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "18a486b0-149e-5c3e-b364-e1a9288b428b", + "width": 20, "x": 1140, "y": 240, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "d467ebb4-8296-5cd0-a822-17e371823258", + "width": 20, "x": 1090, "y": 640, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 20, "height": 20, - "width": 20, "layer": "", - "locked": false, "name": "PatrolPoint", "persistentUuid": "5f1f4397-5031-55d8-8111-eff433152313", + "width": 20, "x": 790, "y": 840, "z": 320, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 20 + "initialVariables": [] }, { "angle": 0, "customSize": true, + "depth": 107, "height": 50, - "width": 50, "layer": "", - "locked": false, "name": "Player", "persistentUuid": "172ec3ef-00be-52cb-8ed8-d9b42301272a", + "width": 50, "x": 125, "y": 575, "z": 1, "zOrder": 1, "numberProperties": [], "stringProperties": [], - "initialVariables": [], - "depth": 107 + "initialVariables": [] }, { "angle": 90, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Monster", "persistentUuid": "e80bc693-d928-507e-84fe-39be0663094a", + "width": 0, "x": 340, "y": 300, "z": 321, @@ -5515,11 +5084,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Lamp", "persistentUuid": "da37a255-a60f-5a28-ab23-e289d4f62728", + "width": 0, "x": 55, "y": 935, "z": 100, @@ -5532,11 +5100,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Lamp", "persistentUuid": "2694b250-57d6-5fa1-9ced-b955917b2d3f", + "width": 0, "x": 60, "y": 360, "z": 400, @@ -5549,11 +5116,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "FlickeringLamp", "persistentUuid": "8891ef66-55a8-50c8-9344-195c4610267d", + "width": 0, "x": 600, "y": 140, "z": 260, @@ -5566,11 +5132,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "FlickeringLamp", "persistentUuid": "ac474268-be95-50a4-b1d1-92047a87f390", + "width": 0, "x": 1150, "y": 650, "z": 570, @@ -5583,11 +5148,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Lamp", "persistentUuid": "51a7c087-478f-5dd1-b1fd-ee192c248a18", + "width": 0, "x": 490, "y": 1760, "z": 250, @@ -5600,11 +5164,10 @@ "angle": 0, "customSize": false, "height": 0, - "width": 0, "layer": "", - "locked": false, "name": "Lamp", "persistentUuid": "a0d8ead6-6851-5b2d-bce0-be7b19a8adb9", + "width": 0, "x": 770, "y": 1760, "z": 250, @@ -5617,14 +5180,12 @@ "angle": 0, "customSize": true, "height": 80, - "width": 1000, "layer": "UI", - "locked": false, "name": "MessageText", "persistentUuid": "f52c8071-f18a-5884-8f29-9d3f808908a2", + "width": 1000, "x": 140, "y": 520, - "z": 0, "zOrder": 10, "numberProperties": [], "stringProperties": [], @@ -5634,14 +5195,12 @@ "angle": 0, "customSize": true, "height": 40, - "width": 500, "layer": "UI", - "locked": false, "name": "ObjectiveText", "persistentUuid": "c0ff9949-98c4-5974-9af8-bef5a48f09b5", + "width": 500, "x": 32, "y": 128, - "z": 0, "zOrder": 10, "numberProperties": [], "stringProperties": [], @@ -5657,6 +5216,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": false + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -5684,13 +5250,6 @@ "massCenterOffsetY": 0, "massCenterOffsetZ": 0, "massOverride": 0 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": false } ], "content": { @@ -6232,8 +5791,7 @@ "ConeLength": 4000, "ConeAngle": 22, "Decay": 1, - "Smoothing": 0.15, - "ShadowBias": 0.0001 + "Smoothing": 0.15 } }, { @@ -6244,6 +5802,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6272,13 +5837,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -6320,6 +5878,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6348,13 +5913,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -6396,6 +5954,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": false + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6424,13 +5989,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": false } ], "content": { @@ -6472,6 +6030,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": false + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6500,13 +6065,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": false } ], "content": { @@ -6587,6 +6145,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6615,13 +6180,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -6663,6 +6221,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6691,13 +6256,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -6778,6 +6336,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6806,13 +6371,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -6892,6 +6450,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6920,13 +6485,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -6954,6 +6512,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -6982,13 +6547,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7016,6 +6574,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7044,13 +6609,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7078,6 +6636,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7106,13 +6671,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7140,6 +6698,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7168,13 +6733,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7227,6 +6785,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7255,13 +6820,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7314,6 +6872,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7342,13 +6907,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7376,6 +6934,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7404,13 +6969,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7463,6 +7021,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7491,13 +7056,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7525,6 +7083,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7553,13 +7118,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7587,6 +7145,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7615,13 +7180,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7649,6 +7207,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7677,13 +7242,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7711,6 +7269,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7739,13 +7304,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7773,6 +7331,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7801,13 +7366,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7835,6 +7393,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7863,13 +7428,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7897,6 +7455,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7925,13 +7490,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -7959,6 +7517,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -7987,13 +7552,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -8021,6 +7579,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -8049,13 +7614,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -8083,6 +7641,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -8111,13 +7676,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -8145,6 +7703,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -8173,13 +7738,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -8207,6 +7765,13 @@ "variables": [], "effects": [], "behaviors": [ + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior", + "shape": "Box", + "meshShapeResourceName": "", + "obstacleOnly": true + }, { "name": "Physics3D", "type": "Physics3D::Physics3DBehavior", @@ -8235,13 +7800,6 @@ "gravityScale": 1, "layers": 17, "masks": 17 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior", - "shape": "Box", - "meshShapeResourceName": "", - "obstacleOnly": true } ], "content": { @@ -8290,6 +7848,7 @@ { "assetStoreId": "", "name": "Lamp", + "persistentUuid": "1b20ca95-9efd-43b8-a0bd-1e690c3b5ca4", "type": "Light3D::PointLight3D", "variant": "", "variables": [], @@ -8300,12 +7859,15 @@ "Intensity": 2.5, "Decay": 2, "Range": 480, - "IsCastingShadow": false + "IsCastingShadow": true, + "ShadowNormalBias": 1, + "ShadowBias": 0 } }, { "assetStoreId": "", "name": "FlickeringLamp", + "persistentUuid": "9bf378d4-8779-45b5-9a6d-bd87f5f9cea0", "type": "Light3D::PointLight3D", "variant": "", "variables": [], @@ -8316,7 +7878,7 @@ "Intensity": 1.5, "Decay": 2, "Range": 380, - "IsCastingShadow": false + "IsCastingShadow": true } }, { @@ -8715,7 +8277,6 @@ "type": "BuiltinCommonInstructions::Group", "events": [ { - "folded": false, "type": "BuiltinCommonInstructions::Comment", "color": { "b": 109, @@ -8895,7 +8456,6 @@ ] }, { - "folded": false, "type": "BuiltinCommonInstructions::Comment", "color": { "b": 109, @@ -9104,7 +8664,6 @@ ] }, { - "folded": false, "type": "BuiltinCommonInstructions::Comment", "color": { "b": 109, @@ -9587,10 +9146,14 @@ "parameters": [] }, { - "type": "BuiltinCommonInstructions::Group", + "colorB": 196, + "colorG": 196, + "colorR": 196, + "creationTime": 0, "folded": true, "name": "Key and door", "source": "", + "type": "BuiltinCommonInstructions::Group", "events": [ { "type": "BuiltinCommonInstructions::Comment", @@ -9849,17 +9412,17 @@ ] } ], - "parameters": [], + "parameters": [] + }, + { "colorB": 196, "colorG": 196, "colorR": 196, - "creationTime": 0 - }, - { - "type": "BuiltinCommonInstructions::Group", + "creationTime": 0, "folded": true, "name": "Escape", "source": "", + "type": "BuiltinCommonInstructions::Group", "events": [ { "type": "BuiltinCommonInstructions::Comment", @@ -9993,17 +9556,17 @@ ] } ], - "parameters": [], + "parameters": [] + }, + { "colorB": 196, "colorG": 196, "colorR": 196, - "creationTime": 0 - }, - { - "type": "BuiltinCommonInstructions::Group", + "creationTime": 0, "folded": true, "name": "Flickering lights", "source": "", + "type": "BuiltinCommonInstructions::Group", "events": [ { "type": "BuiltinCommonInstructions::Comment", @@ -10046,11 +9609,7 @@ ] } ], - "parameters": [], - "colorB": 196, - "colorG": 196, - "colorR": 196, - "creationTime": 0 + "parameters": [] } ], "layers": [ @@ -10196,6 +9755,21 @@ "name": "MultitouchButton", "type": "SpriteMultitouchJoystick::MultitouchButton" }, + { + "name": "NavMeshCharacter", + "type": "NavMeshPathfinding::NavMeshCharacterBehavior", + "cellSize": 10, + "cellDepth": 2, + "slopeMaxAngle": 40, + "stairHeightMax": 20, + "walkableRadius": -1, + "speedScaleY": 1, + "walkableDepth": 150 + }, + { + "name": "NavMeshObstacle", + "type": "NavMeshPathfinding::NavMeshObstacleBehavior" + }, { "name": "Object3D", "type": "Scene3D::Base3DBehavior" @@ -10235,21 +9809,6 @@ { "name": "Tween", "type": "Tween::TweenBehavior" - }, - { - "name": "NavMeshCharacter", - "type": "NavMeshPathfinding::NavMeshCharacterBehavior", - "cellSize": 10, - "cellDepth": 2, - "slopeMaxAngle": 40, - "stairHeightMax": 20, - "walkableRadius": -1, - "speedScaleY": 1, - "walkableDepth": 150 - }, - { - "name": "NavMeshObstacle", - "type": "NavMeshPathfinding::NavMeshObstacleBehavior" } ] } @@ -10347,8 +9906,8 @@ ] }, { - "name": "Picking up the key", "description": "Puts the player next to the key: the key is picked up and the player has it.", + "name": "Picking up the key", "type": "gameplay", "source": [ "await harness.goToScene('Game Scene');", @@ -10381,8 +9940,8 @@ ] }, { - "name": "The front door opens only with the key", "description": "Walks the player into the front door: it stays closed without the key, and opens with it.", + "name": "The front door opens only with the key", "type": "gameplay", "source": [ "await harness.goToScene('Game Scene');", @@ -10425,8 +9984,8 @@ ] }, { - "name": "Reaching the gate of the yard escapes the house", "description": "Puts the player in front of the open gate and walks it through: the player escaped, and the game starts again.", + "name": "Reaching the gate of the yard escapes the house", "type": "gameplay", "source": [ "await harness.goToScene('Game Scene');", @@ -10461,8 +10020,8 @@ ] }, { - "name": "The monster chases and catches the player", "description": "Puts the monster in sight of the player in the hall: it runs to the player and catching them restarts the scene.", + "name": "The monster chases and catches the player", "type": "gameplay", "source": [ "await harness.goToScene('Game Scene');", @@ -10489,8 +10048,8 @@ ] }, { - "name": "The monster follows the player upstairs", "description": "Puts the player upstairs and the monster at the foot of the stairs, hearing the player: the monster climbs the stairs and catches the player.", + "name": "The monster follows the player upstairs", "type": "gameplay", "source": [ "await harness.goToScene('Game Scene');", @@ -10530,9 +10089,9 @@ ] }, { + "description": "", "name": "Rendering: the house", "type": "gameplay", - "description": "", "source": [ "await harness.goToScene('Game Scene');", "harness.setRandomSeed(1);", @@ -15496,7 +15055,6 @@ "name": "PlatformerMultitouchMapper", "objectType": "", "previewIconUrl": "", - "quickCustomizationVisibility": "hidden", "eventsFunctions": [ { "fullName": "", @@ -15750,7 +15308,6 @@ "name": "Platformer3DMultitouchMapper", "objectType": "", "previewIconUrl": "", - "quickCustomizationVisibility": "hidden", "eventsFunctions": [ { "fullName": "", @@ -15925,7 +15482,6 @@ "name": "Shooter3DMultitouchMapper", "objectType": "", "previewIconUrl": "", - "quickCustomizationVisibility": "hidden", "eventsFunctions": [ { "fullName": "", @@ -16089,7 +15645,6 @@ "name": "FirstPersonMultitouchMapper", "objectType": "", "previewIconUrl": "", - "quickCustomizationVisibility": "hidden", "eventsFunctions": [ { "fullName": "", @@ -17294,7 +16849,6 @@ "name": "PhysicsCar3DMultitouchMapper", "objectType": "", "previewIconUrl": "", - "quickCustomizationVisibility": "hidden", "eventsFunctions": [ { "fullName": "", @@ -17507,7 +17061,6 @@ "name": "TopDownMultitouchMapper", "objectType": "", "previewIconUrl": "", - "quickCustomizationVisibility": "hidden", "eventsFunctions": [ { "fullName": "", @@ -19542,13 +19095,15 @@ "propertyName": "ShouldBeHiddenWhenReleased" } ] - } + }, + "variants": [] } ] }, { "author": "PANDAKO-GitHub", "category": "Input", + "dimension": "", "extensionNamespace": "", "fullName": "Mouse Pointer Lock", "gdevelopVersion": ">=5.5.222", @@ -20381,12 +19936,68 @@ "objectGroups": [] } ], + "eventsFunctionsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "functionName": "onFirstSceneLoaded" + }, + { + "functionName": "onScenePostEvents" + }, + { + "functionName": "RequestPointerLock" + }, + { + "functionName": "ExitPointerLock" + }, + { + "functionName": "isPointerLocked" + }, + { + "functionName": "isPointerActuallyLocked" + }, + { + "functionName": "isEmulatingPointerLock" + }, + { + "functionName": "IsMoving" + }, + { + "functionName": "MovementX" + }, + { + "functionName": "SetMovementX" + }, + { + "functionName": "MovementY" + }, + { + "functionName": "SetMovementY" + }, + { + "functionName": "TouchX" + }, + { + "functionName": "TouchY" + }, + { + "functionName": "TouchSpeedFactor" + }, + { + "functionName": "SetTouchSpeedFactor" + } + ] + }, "eventsBasedBehaviors": [ { "description": "Control camera rotations with a mouse.", "fullName": "First person camera mouse mapper", + "helpPath": "", + "iconUrl": "", "name": "FirstPersonPointerMapper", "objectType": "", + "previewIconUrl": "", "eventsFunctions": [ { "fullName": "", @@ -20673,6 +20284,7 @@ "fullName": "", "functionType": "ActionWithOperator", "getterName": "HorizontalSpeed", + "group": "First person camera mouse mapper configuration", "name": "SetHorizontalSpeed", "sentence": "", "events": [ @@ -20753,6 +20365,7 @@ "fullName": "", "functionType": "ActionWithOperator", "getterName": "VerticalSpeed", + "group": "First person camera mouse mapper configuration", "name": "SetVerticalSpeed", "sentence": "", "events": [ @@ -20833,6 +20446,7 @@ "fullName": "", "functionType": "ActionWithOperator", "getterName": "VerticalAngleMin", + "group": "First person camera mouse mapper configuration", "name": "SetVerticalAngleMin", "sentence": "", "events": [ @@ -20913,6 +20527,7 @@ "fullName": "", "functionType": "ActionWithOperator", "getterName": "VerticalAngleMax", + "group": "First person camera mouse mapper configuration", "name": "SetVerticalAngleMax", "sentence": "", "events": [ @@ -20993,6 +20608,7 @@ "fullName": "", "functionType": "ActionWithOperator", "getterName": "OffsetZ", + "group": "First person camera mouse mapper configuration", "name": "SetOffsetZ", "sentence": "", "events": [ @@ -21029,6 +20645,57 @@ "objectGroups": [] } ], + "eventsFunctionsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "functionName": "doStepPreEvents" + }, + { + "folderName": "Layers and cameras", + "children": [ + { + "functionName": "LookFromObjectEyes" + } + ] + }, + { + "folderName": "First person camera mouse mapper configuration", + "children": [ + { + "functionName": "HorizontalSpeed" + }, + { + "functionName": "SetHorizontalSpeed" + }, + { + "functionName": "VerticalSpeed" + }, + { + "functionName": "SetVerticalSpeed" + }, + { + "functionName": "VerticalAngleMin" + }, + { + "functionName": "SetVerticalAngleMin" + }, + { + "functionName": "VerticalAngleMax" + }, + { + "functionName": "SetVerticalAngleMax" + }, + { + "functionName": "OffsetZ" + }, + { + "functionName": "SetOffsetZ" + } + ] + } + ] + }, "propertyDescriptors": [ { "value": "", @@ -21082,7 +20749,32 @@ "name": "ShouldLock" } ], - "sharedPropertyDescriptors": [] + "propertiesFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "propertyName": "Object3D" + }, + { + "propertyName": "HorizontalSpeed" + }, + { + "propertyName": "VerticalSpeed" + }, + { + "propertyName": "VerticalAngleMin" + }, + { + "propertyName": "VerticalAngleMax" + }, + { + "propertyName": "OffsetZ" + }, + { + "propertyName": "ShouldLock" + } + ] + } } ], "eventsBasedObjects": [] @@ -25330,7 +25022,7 @@ "name": "Light3D", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", "shortDescription": "A collection of light object for 3D.", - "version": "2.0.0", + "version": "2.1.0", "description": "A collection of light object for 3D.", "origin": { "identifier": "Light3D", @@ -25526,6 +25218,8 @@ " constructor(object, spotLight) {", " this.object = object;", " this.spotLight = spotLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -25583,6 +25277,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -25590,6 +25285,7 @@ " */", " setConeAngle(coneAngle) {", " this.spotLight.angle = coneAngle * Math.PI / 180;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -25629,6 +25325,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -25655,6 +25352,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -25689,6 +25387,28 @@ " const texture = game.getImageManager().getThreeTexture(resourceName);", " this.spotLight.map = texture;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.spotLight.shadow;", + " // Three.js uses the cone length as the far plane of the shadow camera.", + " const shadowDistance = this.spotLight.distance || shadow.camera.far;", + " const coneAngle = Math.min(this.spotLight.angle, gdjs.toRad(89));", + " const shadowMapWidth = 2 * shadowDistance * Math.tan(coneAngle);", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -25779,6 +25499,8 @@ " constructor(object, pointLight) {", " this.object = object;", " this.pointLight = pointLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -25809,6 +25531,7 @@ " const runtimeScene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", " this.pointLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -25838,6 +25561,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -25866,6 +25590,7 @@ " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", "", " this.pointLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -25884,6 +25609,28 @@ " : 1;", " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.pointLight.shadow;", + " // Three.js uses the range as the far plane of the shadow cameras.", + " const shadowDistance = this.pointLight.distance || shadow.camera.far;", + " // Each face of the shadow cube map covers 90 degrees.", + " const shadowMapWidth = 2 * shadowDistance;", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -27080,6 +26827,17 @@ "" ] }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::SpotLight3D::UpdateImage" @@ -28436,6 +28194,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__spotLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -28544,6 +28385,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -28665,6 +28512,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -28713,6 +28569,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } @@ -29144,6 +29003,17 @@ "" ] }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::PointLight3D::UpdateHelper" @@ -30190,6 +30060,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D point light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__pointLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -30272,6 +30225,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -30359,6 +30318,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -30393,6 +30361,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } diff --git a/examples/starting-expanded-first-person-horror/starting-expanded-first-person-horror.json b/examples/starting-expanded-first-person-horror/starting-expanded-first-person-horror.json index f832e279b..0a036d738 100644 --- a/examples/starting-expanded-first-person-horror/starting-expanded-first-person-horror.json +++ b/examples/starting-expanded-first-person-horror/starting-expanded-first-person-horror.json @@ -1441,8 +1441,7 @@ "ConeLength": 4000, "ConeAngle": 22, "Decay": 1, - "Smoothing": 0.15, - "ShadowBias": 0.0001 + "Smoothing": 0.15 } }, { @@ -18389,7 +18388,7 @@ "name": "Light3D", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", "shortDescription": "A collection of light object for 3D.", - "version": "2.0.0", + "version": "2.1.0", "description": "A collection of light object for 3D.", "origin": { "identifier": "Light3D", @@ -18585,6 +18584,8 @@ " constructor(object, spotLight) {", " this.object = object;", " this.spotLight = spotLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -18642,6 +18643,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -18649,6 +18651,7 @@ " */", " setConeAngle(coneAngle) {", " this.spotLight.angle = coneAngle * Math.PI / 180;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -18688,6 +18691,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -18714,6 +18718,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -18748,6 +18753,28 @@ " const texture = game.getImageManager().getThreeTexture(resourceName);", " this.spotLight.map = texture;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.spotLight.shadow;", + " // Three.js uses the cone length as the far plane of the shadow camera.", + " const shadowDistance = this.spotLight.distance || shadow.camera.far;", + " const coneAngle = Math.min(this.spotLight.angle, gdjs.toRad(89));", + " const shadowMapWidth = 2 * shadowDistance * Math.tan(coneAngle);", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -18838,6 +18865,8 @@ " constructor(object, pointLight) {", " this.object = object;", " this.pointLight = pointLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -18868,6 +18897,7 @@ " const runtimeScene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", " this.pointLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -18897,6 +18927,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -18925,6 +18956,7 @@ " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", "", " this.pointLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -18943,6 +18975,28 @@ " : 1;", " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.pointLight.shadow;", + " // Three.js uses the range as the far plane of the shadow cameras.", + " const shadowDistance = this.pointLight.distance || shadow.camera.far;", + " // Each face of the shadow cube map covers 90 degrees.", + " const shadowMapWidth = 2 * shadowDistance;", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -20139,6 +20193,17 @@ "" ] }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::SpotLight3D::UpdateImage" @@ -21495,6 +21560,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__spotLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -21603,6 +21751,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -21724,6 +21878,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -21772,6 +21935,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } @@ -22203,6 +22369,17 @@ "" ] }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::PointLight3D::UpdateHelper" @@ -23249,6 +23426,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D point light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__pointLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -23331,6 +23591,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -23418,6 +23684,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -23452,6 +23727,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } diff --git a/examples/starting-expanded-first-person-shooter-horror/starting-expanded-first-person-shooter-horror.json b/examples/starting-expanded-first-person-shooter-horror/starting-expanded-first-person-shooter-horror.json index 6a1db37a2..64e6a9aee 100644 --- a/examples/starting-expanded-first-person-shooter-horror/starting-expanded-first-person-shooter-horror.json +++ b/examples/starting-expanded-first-person-shooter-horror/starting-expanded-first-person-shooter-horror.json @@ -2599,8 +2599,7 @@ "Intensity": 9, "ConeAngle": 22, "ConeLength": 4000, - "Smoothing": 0.15, - "ShadowBias": 0.0001 + "Smoothing": 0.15 } }, { @@ -42932,7 +42931,7 @@ "name": "Light3D", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", "shortDescription": "A collection of light object for 3D.", - "version": "2.0.0", + "version": "2.1.0", "description": "A collection of light object for 3D.", "origin": { "identifier": "Light3D", @@ -43128,6 +43127,8 @@ " constructor(object, spotLight) {", " this.object = object;", " this.spotLight = spotLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -43185,6 +43186,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -43192,6 +43194,7 @@ " */", " setConeAngle(coneAngle) {", " this.spotLight.angle = coneAngle * Math.PI / 180;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -43231,6 +43234,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -43257,6 +43261,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -43291,6 +43296,28 @@ " const texture = game.getImageManager().getThreeTexture(resourceName);", " this.spotLight.map = texture;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.spotLight.shadow;", + " // Three.js uses the cone length as the far plane of the shadow camera.", + " const shadowDistance = this.spotLight.distance || shadow.camera.far;", + " const coneAngle = Math.min(this.spotLight.angle, gdjs.toRad(89));", + " const shadowMapWidth = 2 * shadowDistance * Math.tan(coneAngle);", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -43381,6 +43408,8 @@ " constructor(object, pointLight) {", " this.object = object;", " this.pointLight = pointLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -43411,6 +43440,7 @@ " const runtimeScene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", " this.pointLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -43440,6 +43470,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -43468,6 +43499,7 @@ " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", "", " this.pointLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -43486,6 +43518,28 @@ " : 1;", " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.pointLight.shadow;", + " // Three.js uses the range as the far plane of the shadow cameras.", + " const shadowDistance = this.pointLight.distance || shadow.camera.far;", + " // Each face of the shadow cube map covers 90 degrees.", + " const shadowMapWidth = 2 * shadowDistance;", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -44682,6 +44736,17 @@ "" ] }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::SpotLight3D::UpdateImage" @@ -46038,6 +46103,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__spotLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -46146,6 +46294,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -46267,6 +46421,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -46315,6 +46478,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } @@ -46746,6 +46912,17 @@ "" ] }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::PointLight3D::UpdateHelper" @@ -47792,6 +47969,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D point light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__pointLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -47874,6 +48134,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -47961,6 +48227,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -47995,6 +48270,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } diff --git a/examples/starting-first-person-horror/starting-first-person-horror.json b/examples/starting-first-person-horror/starting-first-person-horror.json index 971ccca6e..699cbb184 100644 --- a/examples/starting-first-person-horror/starting-first-person-horror.json +++ b/examples/starting-first-person-horror/starting-first-person-horror.json @@ -1516,8 +1516,7 @@ "ConeLength": 4000, "ConeAngle": 22, "Decay": 1, - "Smoothing": 0.15, - "ShadowBias": 0.0001 + "Smoothing": 0.15 } }, { @@ -17653,7 +17652,7 @@ "name": "Light3D", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", "shortDescription": "A collection of light object for 3D.", - "version": "2.0.0", + "version": "2.1.0", "description": "A collection of light object for 3D.", "origin": { "identifier": "Light3D", @@ -17849,6 +17848,8 @@ " constructor(object, spotLight) {", " this.object = object;", " this.spotLight = spotLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -17906,6 +17907,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -17913,6 +17915,7 @@ " */", " setConeAngle(coneAngle) {", " this.spotLight.angle = coneAngle * Math.PI / 180;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -17952,6 +17955,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -17978,6 +17982,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -18012,6 +18017,28 @@ " const texture = game.getImageManager().getThreeTexture(resourceName);", " this.spotLight.map = texture;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.spotLight.shadow;", + " // Three.js uses the cone length as the far plane of the shadow camera.", + " const shadowDistance = this.spotLight.distance || shadow.camera.far;", + " const coneAngle = Math.min(this.spotLight.angle, gdjs.toRad(89));", + " const shadowMapWidth = 2 * shadowDistance * Math.tan(coneAngle);", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -18102,6 +18129,8 @@ " constructor(object, pointLight) {", " this.object = object;", " this.pointLight = pointLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -18132,6 +18161,7 @@ " const runtimeScene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", " this.pointLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -18161,6 +18191,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -18189,6 +18220,7 @@ " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", "", " this.pointLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -18207,6 +18239,28 @@ " : 1;", " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.pointLight.shadow;", + " // Three.js uses the range as the far plane of the shadow cameras.", + " const shadowDistance = this.pointLight.distance || shadow.camera.far;", + " // Each face of the shadow cube map covers 90 degrees.", + " const shadowMapWidth = 2 * shadowDistance;", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -19403,6 +19457,17 @@ "" ] }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::SpotLight3D::UpdateImage" @@ -20759,6 +20824,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__spotLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -20867,6 +21015,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -20988,6 +21142,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -21036,6 +21199,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } @@ -21467,6 +21633,17 @@ "" ] }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::PointLight3D::UpdateHelper" @@ -22513,6 +22690,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D point light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__pointLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -22595,6 +22855,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -22682,6 +22948,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -22716,6 +22991,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } diff --git a/examples/starting-first-person-shooter-horror/starting-first-person-shooter-horror.json b/examples/starting-first-person-shooter-horror/starting-first-person-shooter-horror.json index e19a24b0e..3dad64afb 100644 --- a/examples/starting-first-person-shooter-horror/starting-first-person-shooter-horror.json +++ b/examples/starting-first-person-shooter-horror/starting-first-person-shooter-horror.json @@ -1896,8 +1896,7 @@ "Intensity": 9, "ConeAngle": 22, "ConeLength": 4000, - "Smoothing": 0.15, - "ShadowBias": 0.0001 + "Smoothing": 0.15 } }, { @@ -40960,7 +40959,7 @@ "name": "Light3D", "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/f237ae4e3b857c556846c7b2c0b132556fd4bcdeff217034b4d9c97dc1aab1d6_lightbulb-on-outline.svg", "shortDescription": "A collection of light object for 3D.", - "version": "2.0.0", + "version": "2.1.0", "description": "A collection of light object for 3D.", "origin": { "identifier": "Light3D", @@ -41156,6 +41155,8 @@ " constructor(object, spotLight) {", " this.object = object;", " this.spotLight = spotLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -41213,6 +41214,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -41220,6 +41222,7 @@ " */", " setConeAngle(coneAngle) {", " this.spotLight.angle = coneAngle * Math.PI / 180;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -41259,6 +41262,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -41285,6 +41289,7 @@ " const runtimeSene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", " this.spotLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -41319,6 +41324,28 @@ " const texture = game.getImageManager().getThreeTexture(resourceName);", " this.spotLight.map = texture;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.spotLight.shadow;", + " // Three.js uses the cone length as the far plane of the shadow camera.", + " const shadowDistance = this.spotLight.distance || shadow.camera.far;", + " const coneAngle = Math.min(this.spotLight.angle, gdjs.toRad(89));", + " const shadowMapWidth = 2 * shadowDistance * Math.tan(coneAngle);", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -41409,6 +41436,8 @@ " constructor(object, pointLight) {", " this.object = object;", " this.pointLight = pointLight;", + " /** In texels of the shadow map. */", + " this.shadowNormalBias = 0;", " }", "", " /**", @@ -41439,6 +41468,7 @@ " const runtimeScene = this.object.getRuntimeScene();", " const inverseWorldScale = runtimeScene.getRenderer3DInverseWorldScale ? runtimeScene.getRenderer3DInverseWorldScale() : 1;", " this.pointLight.distance = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -41468,6 +41498,7 @@ " const mapSize = shadow.mapSize;", " if (mapSize.width !== size) {", " mapSize.set(size, size);", + " this.updateShadowNormalBias();", "", " // Force the recreation of the shadow map texture:", " if (shadow.map) {", @@ -41496,6 +41527,7 @@ " const inverseWorldScale = runtimeSene.getRenderer3DInverseWorldScale ? runtimeSene.getRenderer3DInverseWorldScale() : 1;", "", " this.pointLight.shadow.camera.far = value * inverseWorldScale;", + " this.updateShadowNormalBias();", " }", "", " /**", @@ -41514,6 +41546,28 @@ " : 1;", " this.pointLight.shadow.bias = -value * biasMultiplier * inverseWorldScale;", " }", + "", + " /**", + " * @param value {number} in texels of the shadow map", + " */", + " setShadowNormalBias(value) {", + " this.shadowNormalBias = Math.max(0, value);", + " this.updateShadowNormalBias();", + " }", + "", + " /**", + " * Contrary to the bias, the normal bias is a distance in the world.", + " * As texels of a perspective shadow map get bigger with the distance,", + " * it is converted from the texels at the farthest lit distance.", + " */", + " updateShadowNormalBias() {", + " const shadow = this.pointLight.shadow;", + " // Three.js uses the range as the far plane of the shadow cameras.", + " const shadowDistance = this.pointLight.distance || shadow.camera.far;", + " // Each face of the shadow cube map covers 90 degrees.", + " const shadowMapWidth = 2 * shadowDistance;", + " shadow.normalBias = this.shadowNormalBias * shadowMapWidth / shadow.mapSize.width;", + " }", "}", "", "//@ts-ignore", @@ -42710,6 +42764,17 @@ "" ] }, + { + "type": { + "value": "Light3D::SpotLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::SpotLight3D::UpdateImage" @@ -44066,6 +44131,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D spot light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D spot light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__spotLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::SpotLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -44174,6 +44322,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -44295,6 +44449,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -44343,6 +44506,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } @@ -44774,6 +44940,17 @@ "" ] }, + { + "type": { + "value": "Light3D::PointLight3D::SetShadowNormalBias" + }, + "parameters": [ + "Object", + "=", + "ShadowNormalBias", + "" + ] + }, { "type": { "value": "Light3D::PointLight3D::UpdateHelper" @@ -45820,6 +45997,89 @@ } ], "objectGroups": [] + }, + { + "description": "the shadow normal bias of the light. Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "fullName": "Shadow normal bias", + "functionType": "ExpressionAndCondition", + "group": "3D point light shadow configuration", + "name": "ShadowNormalBias", + "sentence": "the shadow normal bias", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetReturnNumber" + }, + "parameters": [ + "ShadowNormalBias" + ] + } + ] + } + ], + "expressionType": { + "type": "expression" + }, + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] + }, + { + "fullName": "", + "functionType": "ActionWithOperator", + "getterName": "ShadowNormalBias", + "group": "3D point light shadow configuration", + "name": "SetShadowNormalBias", + "sentence": "", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "ShadowNormalBias", + "=", + "max(0, Value)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::JsCode", + "inlineCode": [ + "const object = objects[0];", + "const value = eventsFunctionContext.getArgument(\"Value\");", + "", + "object.__pointLightAdapter.setShadowNormalBias(value);" + ], + "parameterObjects": "Object", + "useStrict": true, + "eventsSheetExpanded": false + } + ], + "parameters": [ + { + "description": "Object", + "name": "Object", + "supplementaryInformation": "Light3D::PointLight3D", + "type": "object" + } + ], + "objectGroups": [] } ], "eventsFunctionsFolderStructure": { @@ -45902,6 +46162,12 @@ }, { "functionName": "ApplyShadowBias" + }, + { + "functionName": "ShadowNormalBias" + }, + { + "functionName": "SetShadowNormalBias" } ] } @@ -45989,6 +46255,15 @@ "group": "Shadow", "advanced": true, "name": "ShadowBias" + }, + { + "value": "1", + "type": "Number", + "label": "Shadow normal bias", + "description": "Reduce the dark stripes (\"shadow acne\") that can appear on surfaces lit from the side. Raise it if stripes are still visible, 0 disables it.", + "group": "Shadow", + "advanced": true, + "name": "ShadowNormalBias" } ], "propertiesFolderStructure": { @@ -46023,6 +46298,9 @@ }, { "propertyName": "ShadowBias" + }, + { + "propertyName": "ShadowNormalBias" } ] } diff --git a/rendering-screenshots/3d-light-playground/mixed-lights.png b/rendering-screenshots/3d-light-playground/mixed-lights.png index 2bfc00ac8..cec5b61b1 100644 Binary files a/rendering-screenshots/3d-light-playground/mixed-lights.png and b/rendering-screenshots/3d-light-playground/mixed-lights.png differ diff --git a/rendering-screenshots/3d-light-playground/point-lights.png b/rendering-screenshots/3d-light-playground/point-lights.png index 1ab80c19c..2a4ac0268 100644 Binary files a/rendering-screenshots/3d-light-playground/point-lights.png and b/rendering-screenshots/3d-light-playground/point-lights.png differ diff --git a/rendering-screenshots/starting-expanded-3d-house-horror/the-view-of-the-player.png b/rendering-screenshots/starting-expanded-3d-house-horror/the-view-of-the-player.png index aad781eda..c356a97a9 100644 Binary files a/rendering-screenshots/starting-expanded-3d-house-horror/the-view-of-the-player.png and b/rendering-screenshots/starting-expanded-3d-house-horror/the-view-of-the-player.png differ