diff --git a/.github/scripts/file_format.sh b/.github/scripts/file_format.sh deleted file mode 100755 index 1a86b2d..0000000 --- a/.github/scripts/file_format.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash - -# This script ensures proper POSIX text file formatting and a few other things. - -# We need dos2unix and isutf8. -if [ ! -x "$(command -v dos2unix)" -o ! -x "$(command -v isutf8)" ]; then - printf "Install 'dos2unix' and 'isutf8' (moreutils package) to use this script.\n" - exit 1 -fi - -set -uo pipefail -IFS=$'\n\t' - -# Loops through all text files tracked by Git. -git grep -zIl '' | -while IFS= read -rd '' f; do - # Ensure that files are UTF-8 formatted. - isutf8 "$f" >> utf8-validation.txt 2>&1 - # Ensure that files have LF line endings and do not contain a BOM. - dos2unix "$f" 2> /dev/null - # Remove trailing space characters and ensures that files end - # with newline characters. -l option handles newlines conveniently. - perl -i -ple 's/\s*$//g' "$f" - # Disallow empty lines after the opening brace. - sed -z -i 's/\x7B\x0A\x0A/\x7B\x0A/g' "$f" - # Disallow some empty lines before the closing brace. - sed -z -i 's/\x0A\x0A\x7D/\x0A\x7D/g' "$f" -done - -diff=$(git diff --color) - -if [ ! -s utf8-validation.txt ] && [ -z "$diff" ] ; then - # If no UTF-8 violations were collected (the file is empty) and - # no diff has been generated all is OK, clean up, and exit. - printf "\e[1;32m*** Files in this commit comply with the file formatting rules.\e[0m\n" - rm -f utf8-validation.txt - exit 0 -fi - -if [ -s utf8-validation.txt ] -then - # If the file has content and is not empty, violations - # detected, notify the user, clean up, and exit. - printf "\n\e[1;33m*** The following files contain invalid UTF-8 character sequences:\e[0m\n\n" - cat utf8-validation.txt -fi - -rm -f utf8-validation.txt - -if [ ! -z "$diff" ] -then - # A diff has been created, notify the user, clean up, and exit. - printf "\n\e[1;33m*** The following changes must be made to comply with the formatting rules:\e[0m\n\n" - # Perl commands replace trailing spaces with `·` and tabs with ``. - printf "$diff\n" | perl -pe 's/(.*[^ ])( +)(\e\[m)$/my $spaces="·" x length($2); sprintf("$1$spaces$3")/ge' | perl -pe 's/(.*[^\t])(\t+)(\e\[m)$/my $tabs="" x length($2); sprintf("$1$tabs$3")/ge' -fi - -printf "\n\e[1;91m*** Please fix your commit(s) with 'git commit --amend' or 'git rebase -i '\e[0m\n" -exit 1 diff --git a/.github/workflows/file_format.py b/.github/workflows/file_format.py new file mode 100644 index 0000000..d74589c --- /dev/null +++ b/.github/workflows/file_format.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys + +if len(sys.argv) < 2: + print("Invalid usage of file_format.py, it should be called with a path to one or multiple files.") + sys.exit(1) + +BOM = b"\xef\xbb\xbf" + +changed = [] +invalid = [] + +for file in sys.argv[1:]: + try: + with open(file, "rt", encoding="utf-8") as f: + original = f.read() + except UnicodeDecodeError: + invalid.append(file) + continue + + if original == "": + continue + + EOL = "\n" + revamp = EOL.join([line.rstrip("\n\r\t ") for line in original.splitlines(True)]).rstrip(EOL) + EOL + + new_raw = revamp.encode(encoding="utf-8") + if new_raw.startswith(BOM): + new_raw = new_raw[len(BOM) :] + + with open(file, "rb") as f: + old_raw = f.read() + + if old_raw != new_raw: + changed.append(file) + with open(file, "wb") as f: + f.write(new_raw) + +if changed: + for file in changed: + print(f"FIXED: {file}") + +if invalid: + for file in invalid: + print(f"REQUIRES MANUAL CHANGES: {file}") + sys.exit(1) diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml index ac6728a..9227d2c 100644 --- a/.github/workflows/static_checks.yml +++ b/.github/workflows/static_checks.yml @@ -1,19 +1,24 @@ name: 📊 Static Checks on: [push, pull_request] +concurrency: + group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}-static + jobs: - format: - name: File formatting (file_format.sh) - runs-on: ubuntu-22.04 + static-checks: + name: Code style and file formatting + runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4 - - - name: Install APT dependencies - uses: awalsh128/cache-apt-pkgs-action@latest with: - packages: dos2unix moreutils + fetch-depth: 2 - - name: File formatting checks (file_format.sh) + - name: General setup run: | - bash ./.github/scripts/file_format.sh + git config diff.wsErrorHighlight all + + - name: Style checks via pre-commit + uses: pre-commit/action@v3.0.1 + with: + extra_args: --all-files diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..e20d09c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,23 @@ +default_language_version: + python: python3 + +exclude: | + (?x)^( + CODE_OF_CONDUCT.md | + extensions/2.0/OMI_seat/examples/simple_chair_what.gltf + ) + +repos: + - repo: https://github.com/codespell-project/codespell + rev: v2.3.0 + hooks: + - id: codespell + additional_dependencies: [tomli] + + - repo: local + hooks: + - id: file-format + name: file-format + language: python + entry: python .github/workflows/file_format.py + types_or: [text] diff --git a/README.md b/README.md index 73d2c5d..523941c 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,13 @@ A draft proposal has been submitted to the working group and is receiving feedba ### Stage 2 -The draft proposal should precisely describe the extension in it's initial form and there should be at least one metaverse implementation of the extension in development and valid sample assets for testing by other potential implementors. The proposal should contain valid a JSON schema describing the extension in its entirety as well as a markdown document explaining the purpose, features, and properties of the extension. This implementation will be used to test the viability of the extension and provide an example for other implementors. Edits to the extension should be voted on and decided by consensus in weekly OMI glTF Working Group meetings. +The draft proposal should precisely describe the extension in it's initial form and there should be at least one metaverse implementation of the extension in development and valid sample assets for testing by other potential implementers. The proposal should contain valid a JSON schema describing the extension in its entirety as well as a markdown document explaining the purpose, features, and properties of the extension. This implementation will be used to test the viability of the extension and provide an example for other implementers. Edits to the extension should be voted on and decided by consensus in weekly OMI glTF Working Group meetings. #### Requirements - [ ] Previous requirements from Stage 1 - [ ] One metaverse implementation of the extension in development. -- [ ] Valid and publicly acessible sample assets +- [ ] Valid and publicly accessible sample assets - [ ] Valid JSON schema describing the extension in its entirety - [ ] Markdown document explaining the purpose, features, and properties of the extension @@ -58,7 +58,7 @@ The extension has multiple metaverse implementations, a glTF Validator implement - [ ] Previous requirements from Stage 2 - [ ] Two or more metaverse implementations - [ ] glTF Validator implementation -- [ ] Publicly availible content creation tool for generating assets for this extension +- [ ] Publicly available content creation tool for generating assets for this extension - [ ] All implementations, sample assets, and content creation tools should consume or produce assets that pass validation. ### Stage 4 diff --git a/extensions/2.0/KHR_audio_emitter/README.md b/extensions/2.0/KHR_audio_emitter/README.md index 7751c2a..a463360 100644 --- a/extensions/2.0/KHR_audio_emitter/README.md +++ b/extensions/2.0/KHR_audio_emitter/README.md @@ -134,7 +134,7 @@ The extension must be added to the file's `extensionsUsed` array and because it Audio data objects define where audio data is located and what format the data is in. The data is either accessed via a bufferView or uri. -When storing audio data in a buffer view, the `mimeType` field must be specified. The base specification supports `audio/mpeg` and `audio/wav` MIME types. These were chosen with consideration for the wide support for these types acrosss 3D engines and common use cases. Other supported audio formats may be added via extensions. +When storing audio data in a buffer view, the `mimeType` field must be specified. The base specification supports `audio/mpeg` and `audio/wav` MIME types. These were chosen with consideration for the wide support for these types across 3D engines and common use cases. Other supported audio formats may be added via extensions. Note that in tools that process glTF files, but do not implement the `KHR_audio_emitter` extension, external files referenced via the `uri` field may not be properly copied to their final destination or baked into the final binary glTF file. In these cases, using the `bufferView` property may be a better choice assuming the referenced `bufferView` index is not changed by the tool. The `uri` field might be a better choice when you want to be able to quickly change the referenced audio asset. @@ -230,16 +230,16 @@ When the audio emitter type is set to `positional`, additional properties may be #### Property Summary -| | Type | Description | Default value | -| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------- | ----------------------------------- | -| **shapeType** | `string` | The shape of the audio emitter. May be `omnidirectional`, `cone`, or a value specified by another extension. | `"omnidirectional"` | -| **coneInnerAngle** | `number` | The anglular diameter of a cone inside of which there will be no angular volume reduction. | 6.2831853... (τ or 2π rad, 360 deg) | -| **coneOuterAngle** | `number` | The anglular diameter of a cone outside of which the volume will be reduced to a constant value of `coneOuterGain`. | 6.2831853... (τ or 2π rad, 360 deg) | -| **coneOuterGain** | `number` | The linear volume gain of the audio emitter set when outside the cone defined by the `coneOuterAngle` property. | 0.0 | -| **distanceModel** | `string` | Specifies the distance model for the audio emitter. | `"inverse"` | -| **maxDistance** | `number` | The maximum distance between the emitter and listener, beyond which the audio cannot be heard. | 0.0 | -| **refDistance** | `number` | A reference distance for reducing volume as the emitter moves further from the listener. | 1.0 | -| **rolloffFactor** | `number` | Describes how quickly the volume is reduced as the emitter moves away from listener. | 1.0 | +| | Type | Description | Default value | +| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------ | ----------------------------------- | +| **shapeType** | `string` | The shape of the audio emitter. May be `omnidirectional`, `cone`, or a value specified by another extension. | `"omnidirectional"` | +| **coneInnerAngle** | `number` | The angular diameter of a cone inside of which there will be no angular volume reduction. | 6.2831853... (τ or 2π rad, 360 deg) | +| **coneOuterAngle** | `number` | The angular diameter of a cone outside of which the volume will be reduced to a constant value of `coneOuterGain`. | 6.2831853... (τ or 2π rad, 360 deg) | +| **coneOuterGain** | `number` | The linear volume gain of the audio emitter set when outside the cone defined by the `coneOuterAngle` property. | 0.0 | +| **distanceModel** | `string` | Specifies the distance model for the audio emitter. | `"inverse"` | +| **maxDistance** | `number` | The maximum distance between the emitter and listener, beyond which the audio cannot be heard. | 0.0 | +| **refDistance** | `number` | A reference distance for reducing volume as the emitter moves further from the listener. | 1.0 | +| **rolloffFactor** | `number` | Describes how quickly the volume is reduced as the emitter moves away from listener. | 1.0 | #### Shape Type @@ -340,7 +340,7 @@ Note that multiple global audio emitters are allowed on the scene, but only a si The Audio Rolloff range is `(0.0, +∞)`. The default is `1.0`. -The rolloff formula is dependant on the distance model defined. The available distance models are `linear`, `inverse`, and `exponential`. +The rolloff formula is dependent on the distance model defined. The available distance models are `linear`, `inverse`, and `exponential`. - linear formula: `1.0 - rolloffFactor * (distance - refDistance) / (maxDistance - refDistance)` - inverse formula: `refDistance / (refDistance + rolloffFactor * (Math.max(distance, refDistance) - refDistance))` @@ -352,7 +352,7 @@ The gain unit range is `(0.0, +∞)`. The default is `1.0`. - gain formula: `originalVolume * gain` -### Audio Cone Vizualized +### Audio Cone Visualized Audio cone showing how cone parameters impact volume based on relative distance to the source. diff --git a/extensions/2.0/KHR_audio_emitter/figures/cone-diagram.svg b/extensions/2.0/KHR_audio_emitter/figures/cone-diagram.svg index 92cc7fe..a2f038d 100644 --- a/extensions/2.0/KHR_audio_emitter/figures/cone-diagram.svg +++ b/extensions/2.0/KHR_audio_emitter/figures/cone-diagram.svg @@ -17,7 +17,7 @@ Listener - Example Values + Example Values coneInnerAngle : 0.872665 ( 50° ) coneOuterAngle diff --git a/extensions/2.0/OMI_personality/README.md b/extensions/2.0/OMI_personality/README.md index be24f08..be78454 100644 --- a/extensions/2.0/OMI_personality/README.md +++ b/extensions/2.0/OMI_personality/README.md @@ -88,7 +88,7 @@ The OMI_personality extension is defined by the following JSON schema: The OMI_personality extension allows users to inject a unique personality into their virtual representations and adheres to a simple set of properties that aim to be compatible with lots of AI software to come. In the below example implementation, the data for personality is used to combine with the input from the user talking to the NPC. The final prompt is being sent to the OpenAI Davinci model to allow for completion of the agent's response. ```js - // Request coming from three.js frontend that is querying this endpoint making a call to the GPT-3 model. Contains the Personality data embeded in the NPC file. + // Request coming from three.js frontend that is querying this endpoint making a call to the GPT-3 model. Contains the Personality data embedded in the NPC file. const data = await request.json(); let prompt = data.inputs.personality; let prompt = data.Input.personality; @@ -124,7 +124,7 @@ The OMI_personality extension allows users to inject a unique personality into t The final prompt in this examples follows a structure of: ``` -Agent is cheerful and always willing to help with programming tasks. They are an entity that lives in a virtual world always looking for new and intersting ways to help humans create content in the metaverse. +Agent is cheerful and always willing to help with programming tasks. They are an entity that lives in a virtual world always looking for new and interesting ways to help humans create content in the metaverse. Speaker: Hello agent! Tell me about yourself Agent: ``` diff --git a/extensions/2.0/OMI_physics_shape/README.md b/extensions/2.0/OMI_physics_shape/README.md index 480d340..2dd40a6 100644 --- a/extensions/2.0/OMI_physics_shape/README.md +++ b/extensions/2.0/OMI_physics_shape/README.md @@ -20,7 +20,7 @@ Does nothing on its own. Designed to be used together with the `OMI_physics_body This extension allows specifying physics shapes to be used in glTF scenes. -All types of physics shapes defined in this extension are intended to be used for physics simulations and to be portable between many engines. Without another extension using it, this extension does not mandate any particular behavior for the shapes aside from their geometric properties. The precise usage of these physics shape primitives SHOULD be specified by the extenions which utilize them. In general, these physics shapes are used to specify geometry which can be used for collision detection. +All types of physics shapes defined in this extension are intended to be used for physics simulations and to be portable between many engines. Without another extension using it, this extension does not mandate any particular behavior for the shapes aside from their geometric properties. The precise usage of these physics shape primitives SHOULD be specified by the extensions which utilize them. In general, these physics shapes are used to specify geometry which can be used for collision detection. The `OMI_physics_shape` extension is intended to be used together with the `OMI_physics_body` extension, which allows attaching shapes to glTF nodes and specifying their behavior, including static, kinematic, dynamic, and non-solid triggers. The `OMI_physics_body` extension refers to a shape using an index of a shape in the `OMI_physics_shape` document-level shapes array. diff --git a/extensions/2.0/OMI_vehicle_body/mappings.md b/extensions/2.0/OMI_vehicle_body/mappings.md index a1e14be..534c1c1 100644 --- a/extensions/2.0/OMI_vehicle_body/mappings.md +++ b/extensions/2.0/OMI_vehicle_body/mappings.md @@ -107,7 +107,7 @@ Hyperfy vehicles are strictly cars, not aircraft, spacecraft, etc. | glTF mesh, shapes, etc. | Model & Size | The appearance and size are determined by the meshes etc in the glTF file. | | Not available | On Enter & On Exit | Needs to wait for KHR_interactivity. | | glTF body node position/rotation | Position & Rotation | Use glTF nodes for all transforms. | -| Not available | Prefab | Configure properties of specific parts intead. | +| Not available | Prefab | Configure properties of specific parts instead. | | Not available | Reset Time | Reset functionality is not specified in the OMI extensions. | | glTF node position of pilot seat | Seat #1 Position X/Y/Z | Use glTF nodes for all transforms. Use OMI_seat for seats. | | glTF node rotation of pilot seat | Seat #1 Rotation | Use glTF nodes for all transforms. Use OMI_seat for seats. |