diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..8ad74f78 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/Models/CubeVisibility/README.body.md b/Models/CubeVisibility/README.body.md new file mode 100644 index 00000000..ef0ace61 --- /dev/null +++ b/Models/CubeVisibility/README.body.md @@ -0,0 +1,9 @@ +This model demonstrates the `KHR_node_visibility` extension and its interaction with `KHR_animation_pointer`. + +- If your implementation shows either of the red cubes, it is not compliant with `KHR_node_visibility`. + +- If your implementation does not have the blue cube hiding and showing every 0.5 seconds, either the animation is not playing, or it does not support using `KHR_animation_pointer` to animate the `KHR_node_visibility` visible property. + +Animated screenshot of the test model in action: + +![Cube Visibility](screenshot/screenshot_animated.webp) diff --git a/Models/CubeVisibility/glTF-Binary/CubeVisibility.glb b/Models/CubeVisibility/glTF-Binary/CubeVisibility.glb new file mode 100644 index 00000000..48e06900 Binary files /dev/null and b/Models/CubeVisibility/glTF-Binary/CubeVisibility.glb differ diff --git a/Models/CubeVisibility/glTF/CubeVisibility.gltf b/Models/CubeVisibility/glTF/CubeVisibility.gltf new file mode 100644 index 00000000..f489bdc6 --- /dev/null +++ b/Models/CubeVisibility/glTF/CubeVisibility.gltf @@ -0,0 +1,47 @@ +{ + "accessors": [ + { "bufferView": 0, "componentType": 5126, "count": 24, "max": [0.5, 0.5, 0.5], "min": [-0.5, -0.5, -0.5], "normalized": false, "type": "VEC3" }, + { "bufferView": 1, "componentType": 5126, "count": 24, "max": [1.0, 1.0, 1.0], "min": [-1.0, -1.0, -1.0], "normalized": false, "type": "VEC3" }, + { "bufferView": 2, "componentType": 5121, "count": 36, "max": [23], "min": [0], "normalized": false, "type": "SCALAR" }, + { "bufferView": 3, "componentType": 5126, "count": 11, "max": [5.0], "min": [0.0], "normalized": false, "type": "SCALAR" }, + { "bufferView": 4, "componentType": 5121, "count": 11, "max": [1], "min": [0], "normalized": false, "type": "SCALAR" } + ], + "animations": [ + { + "channels": [{ "sampler": 0, "target": { "extensions": { "KHR_animation_pointer": { "pointer": "/nodes/5/extensions/KHR_node_visibility/visible" } }, "path": "pointer" } }], + "name": "BlinkingBlueCube", + "samplers": [{ "input": 3, "interpolation": "STEP", "output": 4 }] + } + ], + "asset": { "copyright": "2025 The Khronos Group", "generator": "Godot Engine v4.6.dev.custom_build", "version": "2.0" }, + "bufferViews": [ + { "buffer": 0, "byteLength": 288, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 288, "byteOffset": 288, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 36, "byteOffset": 576, "target": 34963 }, + { "buffer": 0, "byteLength": 44, "byteOffset": 612 }, + { "buffer": 0, "byteLength": 11, "byteOffset": 656 } + ], + "buffers": [{ "byteLength": 667, "uri": "CubeVisibility0.bin" }], + "extensionsRequired": ["KHR_node_visibility"], + "extensionsUsed": ["KHR_animation_pointer", "KHR_node_visibility"], + "materials": [ + { "pbrMetallicRoughness": { "baseColorFactor": [0.855, 0.0, 0.0, 1.0], "metallicFactor": 0.0, "roughnessFactor": 1.0 } }, + { "pbrMetallicRoughness": { "baseColorFactor": [0.0, 0.855, 0.0, 1.0], "metallicFactor": 0.0, "roughnessFactor": 1.0 } }, + { "pbrMetallicRoughness": { "baseColorFactor": [0.0, 0.0, 0.855, 1.0], "metallicFactor": 0.0, "roughnessFactor": 1.0 } } + ], + "meshes": [ + { "primitives": [{ "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "material": 0, "mode": 4 }] }, + { "primitives": [{ "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "material": 1, "mode": 4 }] }, + { "primitives": [{ "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "material": 2, "mode": 4 }] } + ], + "nodes": [ + { "children": [1, 4, 5], "name": "CubeVisibility" }, + { "children": [2], "extensions": { "KHR_node_visibility": { "visible": false } }, "mesh": 0, "name": "InvisibleCube", "translation": [-1.5, 0.0, 0.0] }, + { "children": [3], "mesh": 0, "name": "ChildOfInvisibleShouldBeInvisible", "translation": [0.0, 1.5, 0.0] }, + { "mesh": 0, "name": "DescendantOfInvisibleShouldBeInvisible", "translation": [0.0, 1.5, 0.0] }, + { "mesh": 1, "name": "VisibleCube" }, + { "extensions": { "KHR_node_visibility": { "visible": true } }, "mesh": 2, "name": "AnimatedVisibility", "translation": [1.5, 0.0, 0.0] } + ], + "scene": 0, + "scenes": [{ "nodes": [0] }] +} diff --git a/Models/CubeVisibility/glTF/CubeVisibility0.bin b/Models/CubeVisibility/glTF/CubeVisibility0.bin new file mode 100644 index 00000000..cf8e779a Binary files /dev/null and b/Models/CubeVisibility/glTF/CubeVisibility0.bin differ diff --git a/Models/CubeVisibility/metadata.json b/Models/CubeVisibility/metadata.json new file mode 100644 index 00000000..2805e6a0 --- /dev/null +++ b/Models/CubeVisibility/metadata.json @@ -0,0 +1,24 @@ +{ + "version": 2, + "legal": [ + { + "license": "CC0", + "licenseUrl": "https://creativecommons.org/publicdomain/zero/1.0/legalcode", + "artist": "Aaron Franke", + "year": "2025", + "owner": "Khronos Group", + "what": "Everything", + "text": "CC0 1.0 Universal", + "spdx": "CC0-1.0", + "icon": "https://licensebuttons.net/p/zero/1.0/88x31.png" + } + ], + "tags": [ + "testing" + ], + "screenshot": "screenshot/screenshot_animated.webp", + "name": "Cube Visiblity test for KHR_node_visibility", + "path": "./Models/CubeVisibility", + "summary": "This model demonstrates the `KHR_node_visibility` extension and its interaction with `KHR_animation_pointer`.", + "createReadme": true +} \ No newline at end of file diff --git a/Models/CubeVisibility/screenshot/screenshot_animated.webp b/Models/CubeVisibility/screenshot/screenshot_animated.webp new file mode 100644 index 00000000..6e43e046 Binary files /dev/null and b/Models/CubeVisibility/screenshot/screenshot_animated.webp differ diff --git a/Models/LightVisibility/README.body.md b/Models/LightVisibility/README.body.md new file mode 100644 index 00000000..9476339e --- /dev/null +++ b/Models/LightVisibility/README.body.md @@ -0,0 +1,9 @@ +This model demonstrates the `KHR_node_visibility` extension and its interaction with `KHR_animation_pointer`. + +- If your implementation shows either of the red spotlights, it is not compliant with `KHR_node_visibility`. + +- If your implementation does not have the blue spotlight hiding and showing every 0.5 seconds, either the animation is not playing, or it does not support using `KHR_animation_pointer` to animate the `KHR_node_visibility` visible property. + +Animated screenshot of the test model in action: + +![Light Visibility](screenshot/screenshot_animated.webp) diff --git a/Models/LightVisibility/glTF-Binary/LightVisibility.glb b/Models/LightVisibility/glTF-Binary/LightVisibility.glb new file mode 100644 index 00000000..861a5235 Binary files /dev/null and b/Models/LightVisibility/glTF-Binary/LightVisibility.glb differ diff --git a/Models/LightVisibility/glTF/LightVisibility.gltf b/Models/LightVisibility/glTF/LightVisibility.gltf new file mode 100644 index 00000000..0563b026 --- /dev/null +++ b/Models/LightVisibility/glTF/LightVisibility.gltf @@ -0,0 +1,56 @@ +{ + "accessors": [ + { "bufferView": 0, "componentType": 5126, "count": 4, "max": [3.0, 1.5, 0.0], "min": [-3.0, -1.5, 0.0], "normalized": false, "type": "VEC3" }, + { + "bufferView": 1, + "componentType": 5126, + "count": 4, + "max": [-1.5259254723787308e-5, -1.5259254723787308e-5, 1.0], + "min": [-1.5259254723787308e-5, -1.5259254723787308e-5, 1.0], + "normalized": false, + "type": "VEC3" + }, + { "bufferView": 2, "componentType": 5121, "count": 6, "max": [3], "min": [0], "normalized": false, "type": "SCALAR" }, + { "bufferView": 3, "componentType": 5126, "count": 11, "max": [5.0], "min": [0.0], "normalized": false, "type": "SCALAR" }, + { "bufferView": 4, "componentType": 5121, "count": 11, "max": [1], "min": [0], "normalized": false, "type": "SCALAR" } + ], + "animations": [ + { + "channels": [{ "sampler": 0, "target": { "extensions": { "KHR_animation_pointer": { "pointer": "/nodes/5/extensions/KHR_node_visibility/visible" } }, "path": "pointer" } }], + "name": "BlinkingBlueLight", + "samplers": [{ "input": 3, "interpolation": "STEP", "output": 4 }] + } + ], + "asset": { "copyright": "2025 The Khronos Group", "generator": "Godot Engine v4.6.dev.custom_build", "version": "2.0" }, + "bufferViews": [ + { "buffer": 0, "byteLength": 48, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 48, "byteOffset": 48, "byteStride": 12, "target": 34962 }, + { "buffer": 0, "byteLength": 6, "byteOffset": 96, "target": 34963 }, + { "buffer": 0, "byteLength": 44, "byteOffset": 104 }, + { "buffer": 0, "byteLength": 11, "byteOffset": 148 } + ], + "buffers": [{ "byteLength": 159, "uri": "LightVisibility0.bin" }], + "extensions": { + "KHR_lights_punctual": { + "lights": [ + { "color": [1.0, 0.0, 0.0], "intensity": 5.0, "range": 5.0, "spot": { "innerConeAngle": 0.65, "outerConeAngle": 0.8 }, "type": "spot" }, + { "color": [0.0, 1.0, 0.0], "intensity": 5.0, "range": 5.0, "spot": { "innerConeAngle": 0.65, "outerConeAngle": 0.8 }, "type": "spot" }, + { "color": [0.0, 0.125, 1.0], "intensity": 6.0, "range": 5.0, "spot": { "innerConeAngle": 0.65, "outerConeAngle": 0.8 }, "type": "spot" } + ] + } + }, + "extensionsRequired": ["KHR_lights_punctual", "KHR_node_visibility"], + "extensionsUsed": ["KHR_animation_pointer", "KHR_lights_punctual", "KHR_node_visibility"], + "meshes": [{ "primitives": [{ "attributes": { "NORMAL": 1, "POSITION": 0 }, "indices": 2, "mode": 4 }] }], + "nodes": [ + { "children": [1, 4, 5, 6], "name": "LightVisibility" }, + { "children": [2], "extensions": { "KHR_lights_punctual": { "light": 0 }, "KHR_node_visibility": { "visible": false } }, "name": "InvisibleLight", "translation": [-1.5, 0.0, 1.0] }, + { "children": [3], "extensions": { "KHR_lights_punctual": { "light": 0 } }, "name": "ChildOfInvisibleShouldBeInvisible" }, + { "extensions": { "KHR_lights_punctual": { "light": 0 } }, "name": "DescendantOfInvisibleShouldBeInvisible" }, + { "extensions": { "KHR_lights_punctual": { "light": 1 } }, "name": "VisibleLight", "translation": [0.0, 0.0, 1.0] }, + { "extensions": { "KHR_lights_punctual": { "light": 2 }, "KHR_node_visibility": { "visible": true } }, "name": "AnimatedVisibility", "translation": [1.5, 0.0, 1.0] }, + { "mesh": 0, "name": "QuadMeshNode" } + ], + "scene": 0, + "scenes": [{ "nodes": [0] }] +} diff --git a/Models/LightVisibility/glTF/LightVisibility0.bin b/Models/LightVisibility/glTF/LightVisibility0.bin new file mode 100644 index 00000000..e538302e Binary files /dev/null and b/Models/LightVisibility/glTF/LightVisibility0.bin differ diff --git a/Models/LightVisibility/metadata.json b/Models/LightVisibility/metadata.json new file mode 100644 index 00000000..0e50024f --- /dev/null +++ b/Models/LightVisibility/metadata.json @@ -0,0 +1,24 @@ +{ + "version": 2, + "legal": [ + { + "license": "CC0", + "licenseUrl": "https://creativecommons.org/publicdomain/zero/1.0/legalcode", + "artist": "Aaron Franke", + "year": "2025", + "owner": "Khronos Group", + "what": "Everything", + "text": "CC0 1.0 Universal", + "spdx": "CC0-1.0", + "icon": "https://licensebuttons.net/p/zero/1.0/88x31.png" + } + ], + "tags": [ + "testing" + ], + "screenshot": "screenshot/screenshot_animated.webp", + "name": "Light Visiblity test for KHR_node_visibility", + "path": "./Models/LightVisibility", + "summary": "This model demonstrates the `KHR_node_visibility` extension and its interaction with `KHR_animation_pointer`.", + "createReadme": true +} \ No newline at end of file diff --git a/Models/LightVisibility/screenshot/screenshot_animated.webp b/Models/LightVisibility/screenshot/screenshot_animated.webp new file mode 100644 index 00000000..168363fd Binary files /dev/null and b/Models/LightVisibility/screenshot/screenshot_animated.webp differ