diff --git a/.github/actions/compile_gdextension/action.yml b/.github/actions/compile_gdextension/action.yml
index 116e9d49..e591c8e7 100644
--- a/.github/actions/compile_gdextension/action.yml
+++ b/.github/actions/compile_gdextension/action.yml
@@ -33,7 +33,7 @@ inputs:
description: Secrets token
telemetry_version:
description: Telemetry version
- default: 2ed8ace3201d466c0bac4f0d40f05d2ec85a6bd3
+ default: 999c64d0e0fc4c51f64130728eec33805721f4aa
runs:
using: composite
steps:
@@ -116,9 +116,13 @@ runs:
shell: bash
run: |
if [ "$RUNNER_OS" == "macOS" ]; then
- strip -u $(find -L ${{inputs.output_libs_path}} -type f)
+ found_files=$(find -L ${{inputs.output_libs_path}} -type f -exec file {} + | grep "Mach-O universal" | cut -d: -f1)
+ echo "Found files: $found_files"
+ strip -u $found_files
else
- strip $(find -L ${{inputs.output_libs_path}} -type f)
+ found_files=$(find -L ${{inputs.output_libs_path}} -type f -exec file {} + | grep "ELF" | cut -d: -f1)
+ echo "Found files: $found_files"
+ strip $found_files
fi
- name: Prepare artifact Windows
@@ -135,7 +139,7 @@ runs:
path: ${{inputs.output_libs_path}}/*
- name: Save .scons_cache directory
- if: ${{!steps.restore_scons_cache.outputs.cache-hit && inputs.use_cache != 'false'}}
+ if: inputs.use_cache != 'false'
uses: actions/cache/save@v3
with:
path: ${{env.SCONS_CACHE}}
diff --git a/.github/actions/delete_artifact/action.yml b/.github/actions/delete_artifact/action.yml
deleted file mode 100644
index 6c5cabee..00000000
--- a/.github/actions/delete_artifact/action.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: Delete the artifact if it exists
-description: Delete an artifact by its name if it exists. 'actions/upload-artifact@v4' usually removes artifacts itself when restarting jobs.
-inputs:
- artifact:
- description: Any name of artifact
- required: true
-runs:
- using: composite
- steps:
- - name: Delete `${{inputs.artifact}}`
- shell: bash
- continue-on-error: true
- run: |
- res=$(gh api \
- -H "Accept: application/vnd.github+json" \
- -H "X-GitHub-Api-Version: 2022-11-28" \
- /repos/${{github.repository}}/actions/runs/${{github.run_id}}/artifacts?name="${{inputs.artifact}}")
-
- artifact_id=$(echo "$res" | jq -r 'if .total_count > 0 then .artifacts[0].id else 0 end')
-
- if [ "$artifact_id" == "0" ]; then
- echo "No artifact to remove was found."
- else
- echo "Found the artifact ID $artifact_id for the ${{inputs.artifact}}."
- gh api \
- --method DELETE \
- -H "Accept: application/vnd.github+json" \
- -H "X-GitHub-Api-Version: 2022-11-28" \
- /repos/${{github.repository}}/actions/artifacts/$artifact_id
- echo "The artifact with the ID $artifact_id has been removed."
- fi
diff --git a/.github/actions/setup_godot/action.yml b/.github/actions/setup_godot/action.yml
new file mode 100644
index 00000000..5c6944ce
--- /dev/null
+++ b/.github/actions/setup_godot/action.yml
@@ -0,0 +1,135 @@
+name: Download Godot Engine
+description: Download Godot Engine executable and
+inputs:
+ tag:
+ description: Release tag in the official repository (4.2.1-stable, 4.1.3-stable, 4.1-stable)
+ required: true
+ file_suffix:
+ description: The name of the file to download.
+ required: true
+ download_export_templates:
+ description: Whether export templates need to be downloaded (true|false).
+ default: "false"
+ required: false
+ is_mono:
+ description: Whether Godot and export templates support dotnet (true|false).
+ default: "false"
+ required: false
+outputs:
+ godot_folder:
+ description: Path to the Godot executable file
+ value: ${{steps.store_folder.outputs.path}}
+ godot:
+ description: Path to the Godot executable file
+ value: ${{steps.store_folder.outputs.exe}}
+runs:
+ using: composite
+ steps:
+ - name: Store Godot folder
+ id: store_folder
+ env:
+ temp: ${{runner.temp}}
+ shell: bash
+ run: |
+ tmp_path="${{env.temp}}"
+ tmp_path_unix="${{env.temp}}"
+ if [ "${{runner.os}}" == "Windows" ]; then
+ tmp_path_unix=$(cygpath -u "${{env.temp}}")
+ echo "Fixed path: $tmp_path_unix"
+ fi
+
+ echo "path=$tmp_path/godot_installation" >> $GITHUB_OUTPUT
+ echo "path_unix=$tmp_path_unix/godot_installation" >> $GITHUB_OUTPUT
+
+ if [[ "${{inputs.file_suffix}}" == *"macos"* ]]; then
+ echo "exe=$tmp_path_unix/godot_installation/Godot.app/Contents/MacOS/Godot" >> $GITHUB_OUTPUT
+ else
+ echo "exe=$tmp_path_unix/godot_installation/godot" >> $GITHUB_OUTPUT
+ fi
+
+ - name: Restore cache directory
+ id: restore_scons_cache
+ uses: actions/cache/restore@v3
+ with:
+ path: ${{steps.store_folder.outputs.path}}
+ key: godot-${{inputs.tag}}-${{inputs.file_suffix}}${{inputs.download_export_templates == 'true' && '-with_exports' || ''}}
+
+ - name: Download Godot Engine
+ uses: robinraju/release-downloader@v1.8
+ if: ${{!steps.restore_scons_cache.outputs.cache-hit}}
+ with:
+ repository: "godotengine/godot"
+ tag: "${{inputs.tag}}"
+ fileName: "*${{inputs.file_suffix}}"
+ out-file-path: "temp_download"
+ extract: true
+
+ - name: Download templates
+ uses: robinraju/release-downloader@v1.8
+ if: ${{!steps.restore_scons_cache.outputs.cache-hit && inputs.download_export_templates == 'true'}}
+ with:
+ repository: "godotengine/godot"
+ tag: "${{inputs.tag}}"
+ fileName: "*${{inputs.tag}}${{inputs.is_mono == 'true' && '_mono' || ''}}_export_templates.tpz"
+ out-file-path: "temp_download"
+
+ - name: Finish preparation
+ if: ${{!steps.restore_scons_cache.outputs.cache-hit}}
+ shell: bash
+ run: |
+ if [ "${{inputs.is_mono}}" == "true" ]; then
+ echo "Move the Mono files to the root of the temporary folder"
+ mv -f Godot*/* temp_download/ || true
+ mv -f godot*/* temp_download/ || true
+ fi
+
+ echo "Unzip templates"
+ if [ "${{inputs.download_export_templates}}" == "true" ]; then
+ templates_dir="temp_download/editor_data/export_templates"
+ mkdir -p $templates_dir
+ unzip temp_download/*_export_templates.tpz -d $templates_dir
+ version=$(cat $templates_dir/templates/version.txt)
+ mv $templates_dir/templates $templates_dir/$version
+ fi
+
+ echo "Remove archives"
+ rm -rf temp_download/*.zip
+ rm -rf temp_download/*.tpz
+
+ # Get files
+ files=$(find temp_download/ -mindepth 1 -maxdepth 1 -type f)
+ echo "Found files:"
+ echo ${files[@]}
+
+ # Rename everything to godot..
+ for file in $files; do
+ folder_basename=$(basename "$file")
+ if [[ "$folder_basename" == *"_console.exe" ]]; then
+ mv -f $file temp_download/godot_console.exe
+ elif [[ "$folder_basename" == *".exe" ]]; then
+ mv -f $file temp_download/godot.exe
+ elif [[ "$folder_basename" == "Godot"* || "$folder_basename" == "godot"* ]]; then
+ mv -f $file temp_download/godot
+ # Fix permissions on Unix
+ chmod +x temp_download/godot
+ fi
+ done
+
+ echo "Move files to installation folder"
+ mv -f temp_download/ ${{steps.store_folder.outputs.path_unix}}/
+ touch ${{steps.store_folder.outputs.path_unix}}/._sc_
+
+ echo "Final folder structure:"
+ find ${{steps.store_folder.outputs.path_unix}} -mindepth 1
+
+ if [[ "${{steps.store_folder.outputs.exe}}" == *"Godot.app"* ]]; then
+ echo "Fix permissions on macOS"
+ chmod 755 "${{steps.store_folder.outputs.exe}}"
+ fi
+
+ - name: Save cache directory
+ if: ${{!steps.restore_scons_cache.outputs.cache-hit}}
+ uses: actions/cache/save@v3
+ with:
+ path: ${{steps.store_folder.outputs.path}}
+ key: godot-${{inputs.tag}}-${{inputs.file_suffix}}${{inputs.download_export_templates == 'true' && '-with_exports' || ''}}
diff --git a/.github/workflows/gdextension_build.yml b/.github/workflows/gdextension_build.yml
index 784d8efb..3a1d7e42 100644
--- a/.github/workflows/gdextension_build.yml
+++ b/.github/workflows/gdextension_build.yml
@@ -229,6 +229,8 @@ jobs:
]
name: ๐ฆ Collect GDExtension binaries
runs-on: ubuntu-latest
+ outputs:
+ artifact_name: ${{steps.output_info.outputs.artifact_name}}
steps:
- name: Checkout
@@ -242,19 +244,102 @@ jobs:
- name: Store all libraries in one directory
run: |
- ls -R extracted_files/
+ arch_dirs=$(find extracted_files/ -mindepth 1 -maxdepth 1 -type d)
+ echo "Original structure:"
+ find extracted_files -mindepth 1
mv -f extracted_files/**/* extracted_files
- rm -rf extracted_files/**/
+ rm -rf $arch_dirs
+ echo "Final structure:"
+ find extracted_files -mindepth 1
touch extracted_files/.gdignore
- name: Output file information
+ id: output_info
run: |
cd extracted_files
echo "Total size: $(du -ch -b | grep total | cut -f1 | awk '{printf "%.2f", $1/1048576}') MB, Total number of files: $(find . -type f | wc -l)" >> $GITHUB_STEP_SUMMARY
+ echo "artifact_name=${{env.PRODUCTION_BUILD == 'true' && '.gdextension_libs_production' || '.gdextension_libs'}}" >> $GITHUB_OUTPUT
+
- name: Upload GDExtension
uses: actions/upload-artifact@v4
with:
- name: ${{env.PRODUCTION_BUILD == 'true' && '.gdextension_libs_production' || '.gdextension_libs'}}
+ name: ${{steps.output_info.outputs.artifact_name}}
retention-days: 7
path: extracted_files/*
+
+ # ============================================
+
+ test_api_integration:
+ name: "๐งช Testing API: ${{matrix.runner-os}}, Godot-${{matrix.file_suffix}}"
+ runs-on: ${{matrix.runner-os}}
+ needs: collect-gdextension
+
+ strategy:
+ fail-fast: false
+ matrix:
+ # sync with other jobs
+ runner-os: [ubuntu-20.04, macos-latest, windows-latest]
+ include:
+ - runner-os: ubuntu-20.04
+ file_suffix: "stable_linux.x86_64.zip"
+ - runner-os: macos-latest
+ file_suffix: "stable_macos.universal.zip"
+ - runner-os: windows-latest
+ file_suffix: "stable_win64.exe.zip"
+
+ env:
+ # Sync with container: image:
+ GODOT_VERSION: 4.2.1-stable
+ PROJECT_PATH: dd3d_web_build
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+ with:
+ lfs: true
+
+ - name: Delete old libs folder
+ shell: bash
+ run: |
+ rm -rf addons/debug_draw_3d/libs
+
+ - name: Download Binaries
+ uses: actions/download-artifact@v4
+ with:
+ path: addons/debug_draw_3d/libs
+ name: ${{needs.collect-gdextension.outputs.artifact_name}}
+
+ - name: Prepare Test Project
+ shell: bash
+ run: |
+ cp -r addons ${{env.PROJECT_PATH}}/addons
+ cp -r examples_dd3d ${{env.PROJECT_PATH}}/examples_dd3d
+ find ${{env.PROJECT_PATH}} -mindepth 1
+
+ - name: Setup Godot
+ uses: ./.github/actions/setup_godot
+ id: setup_godot
+ with:
+ tag: ${{env.GODOT_VERSION}}
+ file_suffix: ${{matrix.file_suffix}}
+ download_export_templates: false
+ is_mono: false
+
+ - name: Import Assets
+ shell: bash
+ run: ${{steps.setup_godot.outputs.godot}} -v -e --headless --path ${{env.PROJECT_PATH}} --quit || true
+
+ - name: Test Run
+ shell: bash
+ timeout-minutes: 2
+ run: |
+ ${{steps.setup_godot.outputs.godot}} -v --headless --path ${{env.PROJECT_PATH}} res://headless_test.tscn || true
+
+ - name: Check Results
+ shell: bash
+ run: |
+ if [ ! -f "${{env.PROJECT_PATH}}/SUCCESS" ]; then
+ echo "The file reporting success has not been created! Failed."
+ exit 1
+ fi
diff --git a/.github/workflows/util_update_libs.yml b/.github/workflows/util_update_libs.yml
index 6c0f5eab..f184b014 100644
--- a/.github/workflows/util_update_libs.yml
+++ b/.github/workflows/util_update_libs.yml
@@ -31,7 +31,7 @@ jobs:
- name: Replace with new files
shell: bash
run: |
- ls -R extracted_files
+ find extracted_files -mindepth 1
rm -rf ${{env.ADDON_LIBS_PATH}}/
mv -f extracted_files ${{env.ADDON_LIBS_PATH}}
diff --git a/.github/workflows/web_deploy.yml b/.github/workflows/web_deploy.yml
index f2dd4d49..535a3aed 100644
--- a/.github/workflows/web_deploy.yml
+++ b/.github/workflows/web_deploy.yml
@@ -9,8 +9,8 @@ on:
workflow_call:
workflow_dispatch:
inputs:
- dev_deploy:
- description: Dev deploy
+ production_build:
+ description: Production build
default: true
type: boolean
@@ -33,7 +33,7 @@ concurrency:
env:
PAGES_BRANCH: gh-pages
- DEV_DEPLOY: ${{!format('{0}', inputs.dev_deploy) && 'true' || format('{0}', inputs.dev_deploy)}} # Default true
+ DEV_DEPLOY: ${{!format('{0}', inputs.production_build) && 'true' || format('{0}', !inputs.production_build)}} # Default true
GH_TOKEN: ${{github.token}}
jobs:
@@ -43,6 +43,7 @@ jobs:
outputs:
head_sha: ${{steps.get_sha.outputs.head_sha}}
lib_version: ${{steps.get_lib_version.outputs.version}}
+ deploy_version: ${{steps.get_lib_version.outputs.deploy_version}}
domain: ${{steps.get_domain.outputs.domain}}
steps:
@@ -77,6 +78,8 @@ jobs:
- name: Get library version
id: get_lib_version
shell: bash
+ env:
+ REF: ${{github.ref_name}}
run: |
# Get DD3D version
source_file="current/src/version.h"
@@ -88,7 +91,18 @@ jobs:
version_string="$major.$minor.$patch"
echo "version=$version_string" >> $GITHUB_OUTPUT
- echo "Version found in file \`version.h\`: \`$version_string\`" >> $GITHUB_STEP_SUMMARY
+ echo "Library Version found in file \`version.h\`: \`$version_string\`" >> $GITHUB_STEP_SUMMARY
+
+ fixed_ref_name=$(echo "$REF" | tr -c [:alnum:]+[:cntrl:] [_*])
+ deploy_version=""
+ if [ "${{env.DEV_DEPLOY}}" == "true" ]; then
+ deploy_version=$fixed_ref_name
+ echo "deploy_version=$deploy_version" >> $GITHUB_OUTPUT
+ else
+ deploy_version=$version_string
+ echo "deploy_version=$deploy_version" >> $GITHUB_OUTPUT
+ fi
+ echo "Deploy version: \`$deploy_version\`" >> $GITHUB_STEP_SUMMARY
- name: Checkout CNAME
uses: actions/checkout@v4
@@ -204,17 +218,15 @@ jobs:
id: get_ref
shell: bash
env:
- REF: ${{github.ref_name}}
content_dir: docs
# dev folder name must be synced with :fix_ref_names
run: |
- fixed_ref_name=$(echo "$REF" | tr -c [:alnum:]+[:cntrl:] [_*])
new_ref_name=""
if [ "${{env.DEV_DEPLOY}}" == "true" ]; then
- new_ref_name="dev/$fixed_ref_name/$content_dir"
+ new_ref_name="dev/${{needs.data_preparation.outputs.deploy_version}}/$content_dir"
echo "new_ref_name=$new_ref_name" >> $GITHUB_OUTPUT
else
- new_ref_name="$content_dir/${{needs.data_preparation.outputs.lib_version}}"
+ new_ref_name="$content_dir/${{needs.data_preparation.outputs.deploy_version}}"
echo "new_ref_name=$new_ref_name" >> $GITHUB_OUTPUT
fi
echo "Target URL: https://${{needs.data_preparation.outputs.domain}}/$new_ref_name" >> $GITHUB_STEP_SUMMARY
@@ -237,24 +249,26 @@ jobs:
name: ๐๐ฆ Export Demo Project
runs-on: ubuntu-20.04
needs: [data_preparation, generate_docs, web-gdextension]
- container:
- image: barichello/godot-ci:4.2.1
env:
- # Sync with container: image:
- GODOT_VERSION: 4.2.1
+ GODOT_VERSION: 4.2.1-stable
PROJECT_PATH: dd3d_web_build
+ BUILD_FOLDER: demo_build
steps:
- - name: Check out code
+ - name: Checkout code
uses: actions/checkout@v4
with:
lfs: true
- - name: Setup
- run: |
- mkdir -v -p ~/.local/share/godot/export_templates
- mv /root/.local/share/godot/export_templates/${GODOT_VERSION}.stable ~/.local/share/godot/export_templates/${GODOT_VERSION}.stable
+ - name: Setup Godot
+ uses: ./.github/actions/setup_godot
+ id: setup_godot
+ with:
+ tag: ${{env.GODOT_VERSION}}
+ file_suffix: "stable_linux.x86_64.zip"
+ download_export_templates: true
+ is_mono: false
- name: Download Binaries
uses: actions/download-artifact@v4
@@ -264,23 +278,22 @@ jobs:
- name: Prepare Web Build
run: |
- ls addons/debug_draw_3d/libs
- ls ${GITHUB_WORKSPACE}/addons/debug_draw_3d/libs
- cp -r addons ${PROJECT_PATH}/addons
- cp -r examples_dd3d ${PROJECT_PATH}/examples_dd3d
+ find addons/debug_draw_3d/libs -mindepth 1
+ cp -r addons ${{env.PROJECT_PATH}}/addons
+ cp -r examples_dd3d ${{env.PROJECT_PATH}}/examples_dd3d
- name: Import Assets
- run: godot -v -e --headless --path ${PROJECT_PATH} --quit || true
+ run: ${{steps.setup_godot.outputs.godot}} -v -e --headless --path ${{env.PROJECT_PATH}} --quit || true
- name: Web Build
run: |
- mkdir ${GITHUB_WORKSPACE}/demo
- cp ${PROJECT_PATH}/coi-serviceworker.min.js ${GITHUB_WORKSPACE}/demo/coi-serviceworker.min.js
- godot -v --headless --path ${PROJECT_PATH} --export-release web ${GITHUB_WORKSPACE}/demo/index.html
+ mkdir ${{env.BUILD_FOLDER}}
+ cp ${{env.PROJECT_PATH}}/coi-serviceworker.min.js ${{env.BUILD_FOLDER}}/coi-serviceworker.min.js
+ ${{steps.setup_godot.outputs.godot}} -v --headless --path ${{env.PROJECT_PATH}} --export-release web $(pwd)/${{env.BUILD_FOLDER}}/index.html
- name: Fix Permissions
run: |
- chmod -c -R +rX "demo/" | while read line; do
+ chmod -c -R +rX "${{env.BUILD_FOLDER}}" | while read line; do
echo "::warning title=Invalid file permissions automatically fixed::$line"
done
@@ -288,17 +301,15 @@ jobs:
id: get_ref
shell: bash
env:
- REF: ${{github.ref_name}}
content_dir: demo
# dev folder name must be synced with :fix_ref_names
run: |
- fixed_ref_name=$(echo "$REF" | tr -c [:alnum:]+[:cntrl:] [_*])
new_ref_name=""
if [ "${{env.DEV_DEPLOY}}" == "true" ]; then
- new_ref_name="dev/$fixed_ref_name/$content_dir"
+ new_ref_name="dev/${{needs.data_preparation.outputs.deploy_version}}/$content_dir"
echo "new_ref_name=$new_ref_name" >> $GITHUB_OUTPUT
else
- new_ref_name="$content_dir/${{needs.data_preparation.outputs.lib_version}}"
+ new_ref_name="$content_dir/${{needs.data_preparation.outputs.deploy_version}}"
echo "new_ref_name=$new_ref_name" >> $GITHUB_OUTPUT
fi
echo "Target URL: https://${{needs.data_preparation.outputs.domain}}/$new_ref_name" >> $GITHUB_STEP_SUMMARY
@@ -307,7 +318,7 @@ jobs:
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{secrets.GITHUB_TOKEN}}
- publish_dir: demo
+ publish_dir: ${{env.BUILD_FOLDER}}
destination_dir: ${{steps.get_ref.outputs.new_ref_name}}
publish_branch: ${{env.PAGES_BRANCH}}
allow_empty_commit: true
@@ -561,8 +572,8 @@ jobs:
shell: bash
run: |
git reset --soft ${{needs.data_preparation.outputs.head_sha}}
- msg=$'Pages have been updated: ${{github.sha}}\n'
- git commit -am "${msg}$(git log --format=%B --reverse HEAD..HEAD@{1})"
+ msg=$'Pages have been updated (${{env.DEV_DEPLOY == 'true' && 'Dev' || 'Release'}}, deploy version: ${{needs.data_preparation.outputs.deploy_version}}): ${{github.sha}}\n'
+ git commit --allow-empty -am "${msg}$(git log --format=%B --reverse HEAD..HEAD@{1})"
git push -f
echo "## Changed files:" >> $GITHUB_STEP_SUMMARY
@@ -580,19 +591,11 @@ jobs:
url: ${{steps.deployment.outputs.page_url}}
steps:
- - name: Checkout Action
- uses: actions/checkout@v4
- with:
- path: temp_repo
- sparse-checkout: .github/actions/delete_artifact
-
- name: Remove `github-pages` if the action was restarted
- uses: ./temp_repo/.github/actions/delete_artifact
+ uses: geekyeggo/delete-artifact@v4
with:
- artifact: github-pages
-
- - name: Remove Action
- run: rm -rf temp_repo/
+ token: ${{secrets.GITHUB_TOKEN}}
+ name: github-pages
- name: Checkout
uses: actions/checkout@v4
diff --git a/.gitignore b/.gitignore
index 1d7e0ab4..4628dae6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,12 +36,15 @@ used_classes.json
*.scor
*.scor.*
+.scons-cache/
.import/
.mono/
obj/
bin/
src/gen/*
+src/editor/my_telemetry_modules
addons/debug_draw_3d/libs/~*
addons/debug_draw_3d/gen/*
clang_rt.asan_*
docs/images/classes/temp/
+SUCCESS
diff --git a/addons/debug_draw_3d/README.md b/addons/debug_draw_3d/README.md
index 6d1b0f99..78c74964 100644
--- a/addons/debug_draw_3d/README.md
+++ b/addons/debug_draw_3d/README.md
@@ -34,6 +34,7 @@ Your support adds motivation to develop my public projects.
* Line
* Line Path
* Line with Arrow
+* Plane
* Points
* Position 3D (3 crossing axes)
* Sphere
@@ -51,10 +52,10 @@ Overlay:
Precompiled for:
* Windows
-* Linux
-* macOS
-* Android
-* Web (WebAssembly)
+* Linux (built on Ubuntu 20.04)
+* macOS (10.14+)
+* Android (5.0+)
+* Web (Firefox not supported)
## [Interactive Web Demo](https://dd3d.dmitriysalnikov.ru/demo/)
diff --git a/addons/debug_draw_3d/debug_draw_3d.gdextension b/addons/debug_draw_3d/debug_draw_3d.gdextension
index d0f406fc..fbc1b9c6 100644
--- a/addons/debug_draw_3d/debug_draw_3d.gdextension
+++ b/addons/debug_draw_3d/debug_draw_3d.gdextension
@@ -6,9 +6,9 @@ reloadable = false
[dependencies]
-# example.x86_64 = { "relative or absolute path to the dependency" : "the path relative to the exported project", }
-
-# debug
+; example.x86_64 = { "relative or absolute path to the dependency" : "the path relative to the exported project", }
+; -------------------------------------
+; debug
macos = { }
windows.x86_64 = { }
@@ -21,7 +21,8 @@ android.arm64 = { }
android.x86_32 = { }
android.x86_64 = { }
-# release no debug draw
+; -------------------------------------
+; release no debug draw
macos.template_release = { }
windows.template_release.x86_64 = { }
@@ -34,7 +35,8 @@ android.template_release.arm64 = { }
android.template_release.x86_32 = { }
android.template_release.x86_64 = { }
-# release forced debug draw
+; -------------------------------------
+; release forced debug draw
macos.template_release.forced_dd3d = { }
windows.template_release.x86_64.forced_dd3d = { }
@@ -44,9 +46,10 @@ web.template_release.wasm32.forced_dd3d = { }
[libraries]
-# debug
+; -------------------------------------
+; debug
-macos = "libs/libdd3d.macos.editor.universal.dylib"
+macos = "libs/libdd3d.macos.editor.universal.framework"
windows.x86_64 = "libs/libdd3d.windows.editor.x86_64.dll"
linux.x86_64 = "libs/libdd3d.linux.editor.x86_64.so"
@@ -57,9 +60,10 @@ android.arm64 = "libs/libdd3d.android.template_debug.arm64.so"
android.x86_32 = "libs/libdd3d.android.template_debug.x86_32.so"
android.x86_64 = "libs/libdd3d.android.template_debug.x86_64.so"
-# release no debug draw
+; -------------------------------------
+; release no debug draw
-macos.template_release = "libs/libdd3d.macos.template_release.universal.dylib"
+macos.template_release = "libs/libdd3d.macos.template_release.universal.framework"
windows.template_release.x86_64 = "libs/libdd3d.windows.template_release.x86_64.dll"
linux.template_release.x86_64 = "libs/libdd3d.linux.template_release.x86_64.so"
@@ -70,9 +74,10 @@ android.template_release.arm64 = "libs/libdd3d.android.template_release.arm64.so
android.template_release.x86_32 = "libs/libdd3d.android.template_release.x86_32.so"
android.template_release.x86_64 = "libs/libdd3d.android.template_release.x86_64.so"
-# release forced debug draw
+; -------------------------------------
+; release forced debug draw
-macos.template_release.forced_dd3d = "libs/libdd3d.macos.template_release.universal.enabled.dylib"
+macos.template_release.forced_dd3d = "libs/libdd3d.macos.template_release.universal.enabled.framework"
windows.template_release.x86_64.forced_dd3d = "libs/libdd3d.windows.template_release.x86_64.enabled.dll"
linux.template_release.x86_64.forced_dd3d = "libs/libdd3d.linux.template_release.x86_64.enabled.so"
diff --git a/dd3d_web_build/headless_test.tscn b/dd3d_web_build/headless_test.tscn
new file mode 100644
index 00000000..104ea0cd
--- /dev/null
+++ b/dd3d_web_build/headless_test.tscn
@@ -0,0 +1,68 @@
+[gd_scene load_steps=3 format=3 uid="uid://cnv87ogp7t43e"]
+
+[sub_resource type="GDScript" id="GDScript_wbn2v"]
+script/source = "extends Node3D
+
+
+func _ready():
+ if FileAccess.file_exists(\"SUCCESS\"):
+ DirAccess.remove_absolute(\"SUCCESS\")
+
+ print(\"DD3D Version: \", ProjectSettings.get_setting(\"debug_draw_3d/settings/updates/addon_version\"))
+ print(\"Engine Version: \", Engine.get_version_info())
+ print(\"Distribution: \", OS.get_distribution_name())
+ print(\"OS Name: \", OS.get_name())
+ print(\"OS Version: \", OS.get_version())
+ print(\"CPU: \", OS.get_processor_name())
+ print(\"CPU Count: \", OS.get_processor_count())
+ print(\"CPU Architecture: \", Engine.get_architecture_name())
+
+ var res = await $Runner.call(&\"start\") if $Runner.has_method(&\"start\") else false
+ print(\"Headless runner returns: \", res)
+
+ if res:
+ var f = FileAccess.open(\"SUCCESS\", FileAccess.WRITE)
+ f.store_8(1)
+
+ print()
+ get_tree().quit(0 if res == true else 1)
+"
+
+[sub_resource type="GDScript" id="GDScript_7yy7l"]
+script/source = "extends Node3D
+
+
+# Some API calls to test library integration
+func start() -> bool:
+ print()
+ print(\"Start of testing.\")
+
+ if true:
+ var _s = DebugDraw3D.new_scoped_config().set_thickness(0.3)
+ DebugDraw3D.draw_box(Vector3.ZERO, Quaternion.IDENTITY, Vector3.ONE)
+ DebugDraw3D.draw_sphere(Vector3.ZERO)
+ DebugDraw2D.set_text(\"FPS\", \"0\")
+ DebugDraw2D.begin_text_group(\"Info\")
+
+ await get_tree().process_frame
+
+ DebugDraw3D.draw_sphere(Vector3.ZERO)
+ DebugDraw3D.config.culling_distance = 50
+ print(\"culling_distance: \", DebugDraw3D.config.culling_distance)
+
+ await get_tree().process_frame
+
+ DebugDrawManager.clear_all()
+
+ await get_tree().process_frame
+
+ print(\"End of testing.\")
+
+ return true
+"
+
+[node name="HeadlessTest" type="Node3D"]
+script = SubResource("GDScript_wbn2v")
+
+[node name="Runner" type="Node3D" parent="."]
+script = SubResource("GDScript_7yy7l")
diff --git a/lib_utils.py b/lib_utils.py
index ede79084..637ec40a 100644
--- a/lib_utils.py
+++ b/lib_utils.py
@@ -2,8 +2,10 @@
import os
import json
+import re
from patches import unity_tools
+lib_readable_name = "Debug Draw 3D"
lib_name = "dd3d"
output_dir = os.path.join("addons", "debug_draw_3d", "libs")
src_folder = "src"
@@ -54,66 +56,12 @@ def setup_defines_and_flags(env, src_out):
print()
-# A utility function for getting the name of an unblocked file
-def _get_unblocked_file_name(original_file_path, new_file_ext, max_files=256, keep_newest_one=True):
- lib_dir = os.path.normpath(os.path.dirname(original_file_path))
- lib_name = os.path.splitext(os.path.basename(original_file_path))[0]
-
- # Collect all matching files
- found_files = [
- f
- for f in os.listdir(lib_dir)
- if os.path.isfile(os.path.join(lib_dir, f)) and f.startswith(lib_name) and f.endswith("." + new_file_ext)
- ]
- found_files = sorted(found_files, key=lambda x: os.path.getmtime(os.path.join(lib_dir, x)))
-
- # Clean up the old files if possible, except for the newest one
- if found_files:
- if keep_newest_one:
- found_files.pop()
- for f in found_files:
- try:
- os.remove(os.path.join(lib_dir, f))
- except:
- pass
-
- # Search for a unblocked file name
- file_name = ""
- for s in range(max_files):
- file_name = "{}_{}.{}".format(os.path.join(lib_dir, lib_name), s, new_file_ext)
- if not os.path.exists(file_name):
- break
- try:
- with open(file_name, "a") as f:
- pass
- except IOError:
- continue
- break
-
- return file_name
-
-
-# This is necessary to support debugging and Hot-Reload at the same time when building using MSVC
-def msvc_pdb_rename(env, full_lib_path):
- pdb_name = _get_unblocked_file_name(full_lib_path, "pdb")
- print("New path to the PDB: " + pdb_name)
- # explicit assignment of the PDB name
- env.Append(LINKFLAGS=["/PDB:" + pdb_name])
-
-
def get_sources(src):
res = [src_folder + "/" + file for file in src]
res = unity_tools.generate_unity_build(res, "dd3d_")
-
return res
-def replace_flag(arr, flag, new_flag):
- if flag in arr:
- arr.remove(flag)
- arr.append(new_flag)
-
-
def get_library_object(env, arguments=None, gen_help=None):
if arguments != None and gen_help:
setup_options(env, arguments, gen_help)
@@ -125,8 +73,10 @@ def get_library_object(env, arguments=None, gen_help=None):
with open(src_folder + "/default_sources.json") as f:
src = json.load(f)
- # store all obj's in a dedicated folder
- env["SHOBJPREFIX"] = "#obj/"
+ scons_cache_path = os.environ.get("SCONS_CACHE")
+ if scons_cache_path is None:
+ # store all obj's in a dedicated folder
+ env["SHOBJPREFIX"] = "#obj/"
generate_sources_for_resources(env, src)
@@ -136,20 +86,30 @@ def get_library_object(env, arguments=None, gen_help=None):
additional_tags += ".enabled"
library_name = "lib{}.{}.{}.{}{}".format(lib_name, env["platform"], env["target"], env["arch"], additional_tags)
- library_full_path = os.path.join(env["addon_output_dir"], (library_name + env["SHLIBSUFFIX"]))
+ library_full_path = os.path.join(env["addon_output_dir"], library_name + env["SHLIBSUFFIX"])
# using the library with `reloadable = true` and with the debugger block the PDB file,
# so it needs to be renamed to something not blocked
if env.get("is_msvc", False) and env["target"] != "template_release":
msvc_pdb_rename(env, library_full_path)
- env.Default(
- env.SharedLibrary(
- target=env.File(library_full_path),
- source=additional_src + get_sources(src),
- SHLIBSUFFIX=env["SHLIBSUFFIX"],
+ if env["platform"] != "macos":
+ env.Default(
+ env.SharedLibrary(
+ target=env.File(library_full_path),
+ source=additional_src + get_sources(src),
+ SHLIBSUFFIX=env["SHLIBSUFFIX"],
+ )
+ )
+ else:
+ generate_framework_folder(env, library_name)
+ env.Default(
+ env.SharedLibrary(
+ target=env.File(os.path.join(env["addon_output_dir"], library_name + ".framework", library_name)),
+ source=additional_src + get_sources(src),
+ SHLIBSUFFIX="",
+ )
)
- )
# Needed for easy reuse of this library in other build scripts
# TODO: not tested at the moment. Probably need some changes in the C++ code
@@ -163,6 +123,32 @@ def get_library_object(env, arguments=None, gen_help=None):
return env
+def get_library_version():
+ with open("src/version.h", "r") as f:
+ header_content = f.read()
+
+ major_match = re.search(r"#define .*_MAJOR (\d+)", header_content)
+ minor_match = re.search(r"#define .*_MINOR (\d+)", header_content)
+ patch_match = re.search(r"#define .*_PATCH (\d+)", header_content)
+
+ if major_match:
+ major_value = int(major_match.group(1))
+ else:
+ major_value = 0
+
+ if minor_match:
+ minor_value = int(minor_match.group(1))
+ else:
+ minor_value = 0
+
+ if patch_match:
+ patch_value = int(patch_match.group(1))
+ else:
+ patch_value = 0
+
+ return f"{major_value}.{minor_value}.{patch_value}"
+
+
def generate_sources_for_resources(env, src_out):
# Array of (path, is_text)
editor_files = [
@@ -255,3 +241,101 @@ def generate_resources_cpp_h_files(input_files, namespace, output_no_ext, src_ou
h_file.write("}\n")
cpp_file.write("}\n")
+
+
+def generate_framework_folder(env, library_name):
+ min_version = env.get("macos_deployment_target", "10.14")
+ lib_version = get_library_version()
+
+ info_plist = f"""
+
+
+
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ {library_name}
+ CFBundleName
+ {lib_readable_name}
+ CFBundleDisplayName
+ {lib_readable_name}
+ CFBundleIdentifier
+ ru.dmitriysalnikov.{lib_name}
+ NSHumanReadableCopyright
+ Copyright (c) Dmitriy Salnikov.
+ CFBundleVersion
+ {lib_version}
+ CFBundleShortVersionString
+ {lib_version}
+ CFBundlePackageType
+ FMWK
+ CSResourcesFileMapped
+
+ DTPlatformName
+ macosx
+ LSMinimumSystemVersion
+ {min_version}
+
+
+ """
+
+ res_folder = os.path.join(env["addon_output_dir"], library_name + ".framework", "Resources")
+ os.makedirs(res_folder, exist_ok=True)
+
+ with open(os.path.join(res_folder, "Info.plist"), "w") as info_plist_file:
+ info_plist_file.write(info_plist)
+
+
+def replace_flag(arr, flag, new_flag):
+ if flag in arr:
+ arr.remove(flag)
+ arr.append(new_flag)
+
+
+# A utility function for getting the name of an unblocked file
+def get_unblocked_file_name(original_file_path, new_file_ext, max_files=256, keep_newest_one=True):
+ lib_dir = os.path.normpath(os.path.dirname(original_file_path))
+ lib_name = os.path.splitext(os.path.basename(original_file_path))[0]
+
+ # Collect all matching files
+ found_files = [
+ f
+ for f in os.listdir(lib_dir)
+ if os.path.isfile(os.path.join(lib_dir, f)) and f.startswith(lib_name) and f.endswith("." + new_file_ext)
+ ]
+ found_files = sorted(found_files, key=lambda x: os.path.getmtime(os.path.join(lib_dir, x)))
+
+ # Clean up the old files if possible, except for the newest one
+ if found_files:
+ if keep_newest_one:
+ found_files.pop()
+ for f in found_files:
+ try:
+ os.remove(os.path.join(lib_dir, f))
+ except:
+ pass
+
+ # Search for a unblocked file name
+ file_name = ""
+ for s in range(max_files):
+ file_name = "{}_{}.{}".format(os.path.join(lib_dir, lib_name), s, new_file_ext)
+ if not os.path.exists(file_name):
+ break
+ try:
+ with open(file_name, "a") as f:
+ pass
+ except IOError:
+ continue
+ break
+
+ return file_name
+
+
+# This is necessary to support debugging and Hot-Reload at the same time when building using MSVC
+def msvc_pdb_rename(env, full_lib_path):
+ pdb_name = get_unblocked_file_name(full_lib_path, "pdb")
+ print("New path to the PDB: " + pdb_name)
+ # explicit assignment of the PDB name
+ env.Append(LINKFLAGS=["/PDB:" + pdb_name])
diff --git a/src/3d/config_scope_3d.cpp b/src/3d/config_scope_3d.cpp
index 94b78ea3..a68df8c0 100644
--- a/src/3d/config_scope_3d.cpp
+++ b/src/3d/config_scope_3d.cpp
@@ -28,39 +28,39 @@ void DebugDraw3DScopeConfig::_manual_unregister() {
}
Ref DebugDraw3DScopeConfig::set_thickness(real_t value) {
- thickness = Math::clamp(value, (real_t)0, (real_t)100);
+ data->thickness = Math::clamp(value, (real_t)0, (real_t)100);
return Ref(this);
}
real_t DebugDraw3DScopeConfig::get_thickness() {
- return thickness;
+ return data->thickness;
}
Ref DebugDraw3DScopeConfig::set_center_brightness(real_t value) {
- center_brightness = Math::clamp(value, (real_t)0, (real_t)1);
+ data->center_brightness = Math::clamp(value, (real_t)0, (real_t)1);
return Ref(this);
}
real_t DebugDraw3DScopeConfig::get_center_brightness() {
- return center_brightness;
+ return data->center_brightness;
}
Ref DebugDraw3DScopeConfig::set_hd_sphere(bool value) {
- hd_sphere = value;
+ data->hd_sphere = value;
return this;
}
bool DebugDraw3DScopeConfig::is_hd_sphere() {
- return hd_sphere;
+ return data->hd_sphere;
}
Ref DebugDraw3DScopeConfig::set_plane_size(real_t value) {
- plane_size = value;
+ data->plane_size = value;
return this;
}
real_t DebugDraw3DScopeConfig::get_plane_size() {
- return plane_size;
+ return data->plane_size;
}
DebugDraw3DScopeConfig::DebugDraw3DScopeConfig() {
@@ -68,18 +68,26 @@ DebugDraw3DScopeConfig::DebugDraw3DScopeConfig() {
thread_id = 0;
guard_id = 0;
+ data = std::make_shared();
+}
+
+DebugDraw3DScopeConfig::Data::Data() {
thickness = 0;
center_brightness = 0;
hd_sphere = false;
plane_size = INFINITY;
}
-DebugDraw3DScopeConfig::DebugDraw3DScopeConfig(const uint64_t &p_thread_id, const uint64_t &p_guard_id, const DebugDraw3DScopeConfig *parent, const unregister_func p_unreg) {
+DebugDraw3DScopeConfig::DebugDraw3DScopeConfig(const uint64_t &p_thread_id, const uint64_t &p_guard_id, const std::shared_ptr &parent, const unregister_func p_unreg) {
unregister_action = p_unreg;
thread_id = p_thread_id;
guard_id = p_guard_id;
+ data = std::make_shared(parent);
+}
+
+DebugDraw3DScopeConfig::Data::Data(const std::shared_ptr &parent) {
thickness = parent->thickness;
center_brightness = parent->center_brightness;
hd_sphere = parent->hd_sphere;
diff --git a/src/3d/config_scope_3d.h b/src/3d/config_scope_3d.h
index 938a1c94..03bb0386 100644
--- a/src/3d/config_scope_3d.h
+++ b/src/3d/config_scope_3d.h
@@ -3,6 +3,7 @@
#include "utils/compiler.h"
#include
+#include
GODOT_WARNING_DISABLE()
#include
@@ -15,10 +16,33 @@ using namespace godot;
*
* `Scope` means that these overridden parameters will affect the drawn geometry until it exits the current scope.
*
- * To create it, use DebugDraw3D.new_scoped_config. Immediately after creation, you can change the values and save the reference to a variable.
+ * To create it, use DebugDraw3D.new_scoped_config.
+ * Immediately after creation, you can change the values and save the reference in a variable.
*
- * But the main thing is not to save it outside the method or in other objects. After leaving the scope, this object should be deleted.
+ * @warning
+ * But the main thing is not to save it outside the method or in other objects.
+ * After leaving the scope, this object should be deleted.
*
+ * ---
+ * @warning
+ * Also, you can't use scope config between `await`s unless this object is freed before `await`.
+ * So, narrow the scope if you want to use `await` and DebugDraw3DScopeConfig in the same method.
+ * ```python
+ * # Bad example
+ * var _s = DebugDraw3D.new_scoped_config().set_thickness(0.3)
+ * DebugDraw3D.draw_box(Vector3.ZERO, Quaternion.IDENTITY, Vector3.ONE)
+ * await get_tree().process_frame
+ * # your code...
+ *
+ * # Good example
+ * if true:
+ * var _s = DebugDraw3D.new_scoped_config().set_thickness(0.3)
+ * DebugDraw3D.draw_box(Vector3.ZERO, Quaternion.IDENTITY, Vector3.ONE)
+ * await get_tree().process_frame
+ * # your code...
+ * ```
+ *
+ * ### Examples:
* ```python
* var _s = DebugDraw3D.new_scoped_config().set_thickness(0.025).set_center_brightness(0.7)
* DebugDraw3D.draw_grid_xf(%Grid.global_transform, Vector2i(10,10), Color.LIGHT_GRAY)
@@ -40,16 +64,24 @@ class DebugDraw3DScopeConfig : public RefCounted {
uint64_t thread_id;
uint64_t guard_id;
- typedef std::function unregister_func;
+ typedef std::function unregister_func;
unregister_func unregister_action;
- // Update constructor!
- real_t thickness;
- real_t center_brightness;
- bool hd_sphere;
- real_t plane_size;
-
public:
+ /// @private
+ struct Data {
+ // Update constructor!
+ real_t thickness;
+ real_t center_brightness;
+ bool hd_sphere;
+ real_t plane_size;
+
+ Data();
+ Data(const std::shared_ptr &parent);
+ };
+ /// @private
+ std::shared_ptr data = nullptr;
+
/// @private
// It can be used for example in C#
void _manual_unregister();
@@ -91,6 +123,6 @@ class DebugDraw3DScopeConfig : public RefCounted {
// `DDScopedConfig3D` is passed as Ref to avoid a random unreference
/// @private
- DebugDraw3DScopeConfig(const uint64_t &p_thread_id, const uint64_t &p_guard_id, const DebugDraw3DScopeConfig *parent, const unregister_func p_unreg);
+ DebugDraw3DScopeConfig(const uint64_t &p_thread_id, const uint64_t &p_guard_id, const std::shared_ptr &parent, const unregister_func p_unreg);
~DebugDraw3DScopeConfig();
};
diff --git a/src/3d/debug_draw_3d.cpp b/src/3d/debug_draw_3d.cpp
index f1d9dde4..1ec35728 100644
--- a/src/3d/debug_draw_3d.cpp
+++ b/src/3d/debug_draw_3d.cpp
@@ -166,48 +166,48 @@ void DebugDraw3D::physics_process_end(double delta) {
}
#ifndef DISABLE_DEBUG_RENDERING
-DebugDraw3DScopeConfig *DebugDraw3D::scoped_config_for_current_thread() {
+const DebugDraw3D::DebugDraw3DScopeConfig_Data DebugDraw3D::scoped_config_for_current_thread() {
ZoneScoped;
LOCK_GUARD(datalock);
uint64_t thread = OS::get_singleton()->get_thread_caller_id();
- auto it = cached_scoped_configs.find(thread);
- if (it != cached_scoped_configs.end()) {
+ const auto &it = cached_scoped_configs.find(thread);
+ if (it != cached_scoped_configs.cend()) {
return it->second;
}
- auto it_v = scoped_configs.find(thread);
- if (it_v != scoped_configs.end()) {
+ const auto &it_v = scoped_configs.find(thread);
+ if (it_v != scoped_configs.cend()) {
const auto &cfgs = it_v->second;
if (!cfgs.empty()) {
DebugDraw3DScopeConfig *tmp = cfgs.back().second;
- cached_scoped_configs[thread] = tmp;
- return tmp;
+ cached_scoped_configs[thread] = tmp->data;
+ return tmp->data;
}
}
- cached_scoped_configs[thread] = default_scoped_config.ptr();
- return default_scoped_config.ptr();
+ cached_scoped_configs[thread] = default_scoped_config.ptr()->data;
+ return default_scoped_config.ptr()->data;
}
-DebugDraw3D::GeometryType DebugDraw3D::_scoped_config_get_geometry_type(DebugDraw3DScopeConfig *cfg) {
+DebugDraw3D::GeometryType DebugDraw3D::_scoped_config_get_geometry_type(const DebugDraw3DScopeConfig_Data &cfg) {
ZoneScoped;
- if (cfg->get_thickness() != 0) {
+ if (cfg->thickness != 0) {
return GeometryType::Volumetric;
}
// TODO solid
return GeometryType::Wireframe;
}
-Color DebugDraw3D::_scoped_config_to_custom(DebugDraw3DScopeConfig *cfg) {
+Color DebugDraw3D::_scoped_config_to_custom(const DebugDraw3DScopeConfig_Data &cfg) {
ZoneScoped;
if (_scoped_config_get_geometry_type(cfg) == GeometryType::Volumetric)
- return Color(cfg->get_thickness(), cfg->get_center_brightness(), 0, 0);
+ return Color(cfg->thickness, cfg->center_brightness, 0, 0);
return Color();
}
-InstanceType DebugDraw3D::_scoped_config_type_convert(ConvertableInstanceType type, DebugDraw3DScopeConfig *cfg) {
+InstanceType DebugDraw3D::_scoped_config_type_convert(ConvertableInstanceType type, const DebugDraw3DScopeConfig_Data &cfg) {
ZoneScoped;
switch (_scoped_config_get_geometry_type(cfg)) {
case GeometryType::Wireframe: {
@@ -272,7 +272,7 @@ void DebugDraw3D::_register_scoped_config(uint64_t thread_id, uint64_t guard_id,
scoped_configs[thread_id].push_back(ScopedPairIdConfig(guard_id, cfg));
// Update cached value
- cached_scoped_configs[thread] = cfg;
+ cached_scoped_configs[thread] = cfg->data;
}
void DebugDraw3D::_unregister_scoped_config(uint64_t thread_id, uint64_t guard_id) {
@@ -287,9 +287,9 @@ void DebugDraw3D::_unregister_scoped_config(uint64_t thread_id, uint64_t guard_i
// Update cached value
if (!cfgs.empty()) {
- cached_scoped_configs[thread_id] = cfgs.back().second;
+ cached_scoped_configs[thread_id] = (DebugDraw3DScopeConfig_Data)(cfgs.back().second->data);
} else {
- cached_scoped_configs[thread_id] = default_scoped_config.ptr();
+ cached_scoped_configs[thread_id] = default_scoped_config.ptr()->data;
}
}
}
@@ -327,12 +327,14 @@ Ref DebugDraw3D::new_scoped_config() {
create_counter++;
uint64_t thread = OS::get_singleton()->get_thread_caller_id();
- Ref res = memnew(
+ Ref res(memnew(
DebugDraw3DScopeConfig(
thread,
create_counter,
scoped_config_for_current_thread(),
- std::bind(&DebugDraw3D::_unregister_scoped_config, this, std::placeholders::_1, std::placeholders::_2)));
+ [this](const uint64_t &p_thread_id, const uint64_t &p_guard_id) {
+ _unregister_scoped_config(p_thread_id, p_guard_id);
+ })));
_register_scoped_config(thread, create_counter, res.ptr());
create_scoped_configs++;
@@ -527,9 +529,9 @@ void DebugDraw3D::add_or_update_line_with_thickness(real_t _exp_time, std::uniqu
ZoneScoped;
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
- if (!scfg->get_thickness()) {
+ if (!scfg->thickness) {
dgc->geometry_pool.add_or_update_line(_exp_time, GET_PROC_TYPE(), std::move(_lines), _line_count, _col);
} else {
for (int i = 0; i < _line_count; i += 2) {
@@ -557,10 +559,10 @@ void DebugDraw3D::draw_sphere_base(const Transform3D &transform, const Color &co
CHECK_BEFORE_CALL();
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
dgc->geometry_pool.add_or_update_instance(
- _scoped_config_type_convert(scfg->is_hd_sphere() ? ConvertableInstanceType::SPHERE_HD : ConvertableInstanceType::SPHERE, scfg),
+ _scoped_config_type_convert(scfg->hd_sphere ? ConvertableInstanceType::SPHERE_HD : ConvertableInstanceType::SPHERE, scfg),
duration,
GET_PROC_TYPE(),
transform,
@@ -589,7 +591,7 @@ void DebugDraw3D::draw_cylinder(const Transform3D &transform, const Color &color
CHECK_BEFORE_CALL();
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
dgc->geometry_pool.add_or_update_instance(
_scoped_config_type_convert(ConvertableInstanceType::CYLINDER, scfg),
@@ -614,7 +616,7 @@ void DebugDraw3D::draw_cylinder_ab(const Vector3 &a, const Vector3 &b, const rea
Transform3D t = Transform3D(Basis().looking_at(half_center, up).scaled_local(Vector3(diameter, diameter, len)), a + half_center);
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
dgc->geometry_pool.add_or_update_instance(
_scoped_config_type_convert(ConvertableInstanceType::CYLINDER_AB, scfg),
@@ -656,7 +658,7 @@ void DebugDraw3D::draw_box_ab(const Vector3 &a, const Vector3 &b, const Vector3
SphereBounds sb(t.origin + half_center_orig, MathUtils::get_max_basis_length(t.basis) * MathUtils::CubeRadiusForSphere);
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
dgc->geometry_pool.add_or_update_instance(
_scoped_config_type_convert(ConvertableInstanceType::CUBE, scfg),
@@ -688,7 +690,7 @@ void DebugDraw3D::draw_box_xf(const Transform3D &transform, const Color &color,
}
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
dgc->geometry_pool.add_or_update_instance(
_scoped_config_type_convert(is_box_centered ? ConvertableInstanceType::CUBE_CENTERED : ConvertableInstanceType::CUBE, scfg),
@@ -833,7 +835,7 @@ void DebugDraw3D::create_arrow(const Vector3 &a, const Vector3 &b, const Color &
Vector3 up = get_up_vector(dir);
Transform3D t = Transform3D(Basis().looking_at(dir, up).scaled(Vector3(size, size, size)), b);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
LOCK_GUARD(datalock);
dgc->geometry_pool.add_or_update_instance(
@@ -851,7 +853,7 @@ void DebugDraw3D::draw_arrowhead(const Transform3D &transform, const Color &colo
CHECK_BEFORE_CALL();
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
dgc->geometry_pool.add_or_update_instance(
_scoped_config_type_convert(ConvertableInstanceType::ARROWHEAD, scfg),
@@ -918,7 +920,7 @@ void DebugDraw3D::draw_square(const Vector3 &position, const real_t &size, const
Transform3D t(Basis().scaled(Vector3_ONE * size), position);
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
dgc->geometry_pool.add_or_update_instance(
InstanceType::BILLBOARD_SQUARE,
@@ -938,9 +940,9 @@ void DebugDraw3D::draw_plane(const Plane &plane, const Color &color, const Vecto
Color front_color = IS_DEFAULT_COLOR(color) ? Colors::plane_light_sky_blue : color;
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
- float plane_size = scfg->get_plane_size() != INFINITY ? scfg->get_plane_size() : (float)previous_camera_far_plane;
+ float plane_size = scfg->plane_size != INFINITY ? scfg->plane_size : (float)previous_camera_far_plane;
Transform3D t(Basis(), center_pos);
t = t.looking_at(center_pos + plane.normal, get_up_vector(plane.normal)).scaled_local(Vector3_ONE * plane_size);
@@ -976,7 +978,7 @@ void DebugDraw3D::draw_position(const Transform3D &transform, const Color &color
CHECK_BEFORE_CALL();
LOCK_GUARD(datalock);
- DebugDraw3DScopeConfig *scfg = scoped_config_for_current_thread();
+ auto scfg = scoped_config_for_current_thread();
dgc->geometry_pool.add_or_update_instance(
_scoped_config_type_convert(ConvertableInstanceType::POSITION, scfg),
@@ -1024,7 +1026,7 @@ void DebugDraw3D::draw_grid_xf(const Transform3D &transform, const Vector2i &p_s
ZoneScoped;
CHECK_BEFORE_CALL();
-#define MAX_SUBDIVISIONS 1024 * 1024
+ const int MAX_SUBDIVISIONS = 1024 * 1024;
ERR_FAIL_COND(p_subdivision.x > MAX_SUBDIVISIONS);
ERR_FAIL_COND(p_subdivision.y > MAX_SUBDIVISIONS);
diff --git a/src/3d/debug_draw_3d.h b/src/3d/debug_draw_3d.h
index 5eb9da34..a2052262 100644
--- a/src/3d/debug_draw_3d.h
+++ b/src/3d/debug_draw_3d.h
@@ -71,7 +71,7 @@ enum class ConvertableInstanceType : char;
* # some DD3D logic
* ```
*/
-class DebugDraw3D : public Object, public IScopeStorage {
+class DebugDraw3D : public Object, public IScopeStorage {
GDCLASS(DebugDraw3D, Object)
friend DebugDrawManager;
@@ -117,14 +117,15 @@ class DebugDraw3D : public Object, public IScopeStorage
ProfiledMutex(std::recursive_mutex, datalock, "3D Geometry lock");
typedef std::pair ScopedPairIdConfig;
+ typedef std::shared_ptr DebugDraw3DScopeConfig_Data;
// stores thread id and array of id's with ptrs
std::unordered_map > scoped_configs;
// stores thread id and most recent config
- std::unordered_map cached_scoped_configs;
+ std::unordered_map cached_scoped_configs;
uint64_t create_scoped_configs = 0;
// Inherited via IScopeStorage
- DebugDraw3DScopeConfig *scoped_config_for_current_thread() override;
+ const DebugDraw3DScopeConfig_Data scoped_config_for_current_thread() override;
// Meshes
std::unique_ptr dgc;
@@ -151,9 +152,9 @@ class DebugDraw3D : public Object, public IScopeStorage
void _clear_scoped_configs() override;
// Internal use of raw pointer to avoid ref/unref
- Color _scoped_config_to_custom(DebugDraw3DScopeConfig *cfg);
- InstanceType _scoped_config_type_convert(ConvertableInstanceType type, DebugDraw3DScopeConfig *cfg);
- GeometryType _scoped_config_get_geometry_type(DebugDraw3DScopeConfig *cfg);
+ Color _scoped_config_to_custom(const DebugDraw3DScopeConfig_Data &cfg);
+ InstanceType _scoped_config_type_convert(ConvertableInstanceType type, const DebugDraw3DScopeConfig_Data &cfg);
+ GeometryType _scoped_config_get_geometry_type(const DebugDraw3DScopeConfig_Data &cfg);
_FORCE_INLINE_ Vector3 get_up_vector(const Vector3 &dir);
void add_or_update_line_with_thickness(real_t _exp_time, std::unique_ptr _lines, const size_t _line_count, const Color &_col, const std::function _custom_upd = nullptr);
diff --git a/src/common/i_scope_storage.h b/src/common/i_scope_storage.h
index dad71057..a59f88c0 100644
--- a/src/common/i_scope_storage.h
+++ b/src/common/i_scope_storage.h
@@ -3,13 +3,14 @@
#include "utils/compiler.h"
#include
+#include
GODOT_WARNING_DISABLE()
#include
GODOT_WARNING_RESTORE()
using namespace godot;
-template
+template
class IScopeStorage {
private:
#ifndef DISABLE_DEBUG_RENDERING
@@ -17,7 +18,7 @@ class IScopeStorage {
virtual void _unregister_scoped_config(uint64_t thread_id, uint64_t guard_id) = 0;
virtual void _clear_scoped_configs() = 0;
- virtual TCfgStorage *scoped_config_for_current_thread() = 0;
+ virtual const std::shared_ptr scoped_config_for_current_thread() = 0;
#endif
public:
diff --git a/src/debug_draw_manager.cpp b/src/debug_draw_manager.cpp
index 928193c4..46c54bd8 100644
--- a/src/debug_draw_manager.cpp
+++ b/src/debug_draw_manager.cpp
@@ -4,6 +4,7 @@
#include "2d/grouped_text.h"
#include "3d/debug_draw_3d.h"
#include "utils/utils.h"
+#include "version.h"
#ifdef TOOLS_ENABLED
#include "editor/generate_csharp_bindings.h"
@@ -250,7 +251,6 @@ void DebugDrawManager::_integrate_into_engine() {
if (is_headless) {
set_debug_enabled(false);
- return;
}
// Draw everything after calls from scripts to avoid lagging
@@ -352,7 +352,9 @@ void DebugDrawManager::_integrate_into_engine() {
_try_to_update_cs_bindings();
#ifdef TELEMETRY_ENABLED
- time_usage_reporter = std::make_unique([&]() { call_deferred(NAMEOF(_on_telemetry_sending_completed)); });
+ if (!is_headless) {
+ time_usage_reporter = std::make_unique(DD3D_VERSION_STR, [&]() { call_deferred(NAMEOF(_on_telemetry_sending_completed)); });
+ }
#endif
}
#endif
@@ -423,7 +425,9 @@ void DebugDrawManager::_try_to_update_cs_bindings() {
#ifdef TELEMETRY_ENABLED
void DebugDrawManager::_on_telemetry_sending_completed() {
- time_usage_reporter->stop_thread();
+ if (time_usage_reporter) {
+ time_usage_reporter->stop_thread();
+ }
}
#endif
#endif
diff --git a/src/version.h b/src/version.h
index fe7b641c..9fffaef9 100644
--- a/src/version.h
+++ b/src/version.h
@@ -2,7 +2,7 @@
#define DD3D_MAJOR 1
#define DD3D_MINOR 3
-#define DD3D_PATCH 0
+#define DD3D_PATCH 1
#define DD3D_VERSION ((DD3D_MAJOR << (8 * 3)) + (DD3D_MINOR << (8 * 2)) + (DD3D_PATCH << (8 * 1)))
#define _DD3D_VERSION_STR_TEXT(text) #text