mirror of
https://github.com/godotengine/godot-cpp.git
synced 2026-01-03 18:09:13 +03:00
Compare commits
55 Commits
3.1
...
godot-3.2-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aba8766618 | ||
|
|
45e6801016 | ||
|
|
3861ff3018 | ||
|
|
9a08d1bb40 | ||
|
|
81783c6045 | ||
|
|
9e573b6947 | ||
|
|
7cbb846417 | ||
|
|
e8488656e5 | ||
|
|
3ee07f652b | ||
|
|
95feb486c9 | ||
|
|
f314b47843 | ||
|
|
91e9262210 | ||
|
|
9560cbff09 | ||
|
|
123d9f0e92 | ||
|
|
3352abf79e | ||
|
|
7482074779 | ||
|
|
77cde5bb3a | ||
|
|
8443486a19 | ||
|
|
93df07289c | ||
|
|
d0a4ddfd9f | ||
|
|
fc1fe720c3 | ||
|
|
c2ec46f64a | ||
|
|
b895d3c326 | ||
|
|
cdd50260d0 | ||
|
|
659a19b9a4 | ||
|
|
743100b401 | ||
|
|
5bdcecfc20 | ||
|
|
0220045268 | ||
|
|
e080c5391e | ||
|
|
73c588456c | ||
|
|
bb4a837ad3 | ||
|
|
041b97e5b2 | ||
|
|
04548011e3 | ||
|
|
c476d24b49 | ||
|
|
12732b5391 | ||
|
|
7defa6f77e | ||
|
|
877de75d8b | ||
|
|
2d9d4be655 | ||
|
|
3ffaada12a | ||
|
|
ca85ab244f | ||
|
|
e4fb5ca2a5 | ||
|
|
761d62c9c8 | ||
|
|
971adbd955 | ||
|
|
834d88a0cd | ||
|
|
51233fa1a9 | ||
|
|
7c8e42b56a | ||
|
|
0b4be7bbfa | ||
|
|
c5199a2fbf | ||
|
|
eb7a75b71e | ||
|
|
4be7fcdde5 | ||
|
|
01606fa212 | ||
|
|
f0fe88bd36 | ||
|
|
65b3bcc833 | ||
|
|
abccf9a050 | ||
|
|
976a188837 |
76
.travis.yml
Normal file
76
.travis.yml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
language: cpp
|
||||||
|
dist: xenial
|
||||||
|
osx_image: xcode10.1
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- SCONS_CACHE="$HOME/.scons_cache"
|
||||||
|
- SCONS_CACHE_LIMIT=1024
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $SCONS_CACHE
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: Linux Debug + Static Checks
|
||||||
|
os: linux
|
||||||
|
compiler: gcc
|
||||||
|
env: TARGET=debug STATIC_CHECKS=yes
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources:
|
||||||
|
- llvm-toolchain-xenial-6.0
|
||||||
|
packages:
|
||||||
|
[scons, pkg-config, build-essential, p7zip-full, clang-format-6.0]
|
||||||
|
|
||||||
|
- name: Linux Release
|
||||||
|
os: linux
|
||||||
|
compiler: gcc
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
[scons, pkg-config, build-essential, p7zip-full]
|
||||||
|
env: TARGET=release
|
||||||
|
|
||||||
|
- name: macOS Debug
|
||||||
|
os: osx
|
||||||
|
compiler: clang
|
||||||
|
env: TARGET=debug
|
||||||
|
|
||||||
|
- name: macOS Release
|
||||||
|
os: osx
|
||||||
|
compiler: clang
|
||||||
|
env: TARGET=release
|
||||||
|
|
||||||
|
- name: Windows MSVC Debug
|
||||||
|
os: windows
|
||||||
|
env: TARGET=debug
|
||||||
|
|
||||||
|
- name: Windows MSVC Release
|
||||||
|
os: windows
|
||||||
|
env: TARGET=release
|
||||||
|
|
||||||
|
install:
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||||
|
brew update;
|
||||||
|
brew install scons p7zip;
|
||||||
|
fi
|
||||||
|
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then
|
||||||
|
curl -LO https://downloads.sourceforge.net/project/scons/scons-local/3.0.5/scons-local-3.0.5.zip;
|
||||||
|
unzip scons-local-3.0.5.zip;
|
||||||
|
fi
|
||||||
|
|
||||||
|
script:
|
||||||
|
- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then
|
||||||
|
export SCONS="./scons.bat";
|
||||||
|
else
|
||||||
|
export SCONS="scons";
|
||||||
|
fi
|
||||||
|
|
||||||
|
- $SCONS target="$TARGET" bits=64 generate_bindings=yes $SCONS_FLAGS;
|
||||||
|
|
||||||
|
- if [[ "$STATIC_CHECKS" == "yes" ]]; then
|
||||||
|
sh ./misc/travis/clang-format.sh;
|
||||||
|
fi
|
||||||
@@ -133,7 +133,7 @@ endif()
|
|||||||
# Generate source from the bindings file
|
# Generate source from the bindings file
|
||||||
message(STATUS "Generating Bindings")
|
message(STATUS "Generating Bindings")
|
||||||
execute_process(COMMAND "python" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GODOT_CUSTOM_API_FILE}\")"
|
execute_process(COMMAND "python" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GODOT_CUSTOM_API_FILE}\")"
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
RESULT_VARIABLE GENERATION_RESULT
|
RESULT_VARIABLE GENERATION_RESULT
|
||||||
OUTPUT_VARIABLE GENERATION_OUTPUT)
|
OUTPUT_VARIABLE GENERATION_OUTPUT)
|
||||||
message(STATUS ${GENERATION_RESULT} ${GENERATION_OUTPUT})
|
message(STATUS ${GENERATION_RESULT} ${GENERATION_OUTPUT})
|
||||||
@@ -145,7 +145,7 @@ file(GLOB_RECURSE HEADERS include/*.h**)
|
|||||||
# Define our godot-cpp library
|
# Define our godot-cpp library
|
||||||
add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS})
|
add_library(${PROJECT_NAME} ${SOURCES} ${HEADERS})
|
||||||
target_include_directories(${PROJECT_NAME}
|
target_include_directories(${PROJECT_NAME}
|
||||||
PRIVATE
|
PUBLIC
|
||||||
include
|
include
|
||||||
include/core
|
include/core
|
||||||
include/gen
|
include/gen
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
Copyright (c) 2017-2019 GodotNativeTools
|
Copyright (c) 2017-2020 GodotNativeTools
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
23
README.md
23
README.md
@@ -76,8 +76,16 @@ $ cd godot-cpp
|
|||||||
$ scons platform=<your platform> generate_bindings=yes
|
$ scons platform=<your platform> generate_bindings=yes
|
||||||
$ cd ..
|
$ cd ..
|
||||||
```
|
```
|
||||||
|
For android:
|
||||||
|
Download the latest [Android NDK](https://developer.android.com/ndk/downloads) from the official website and set NDK path.
|
||||||
|
```
|
||||||
|
$ scons platform=android generate_bindings=yes ANDROID_NDK_ROOT="/PATH-TO-ANDROID-NDK/" android_arch=< >
|
||||||
|
```
|
||||||
|
`android_arch` can be `armv7, arm64v8, x86, x86_64`.
|
||||||
|
`ANDROID_NDK_ROOT` can also be set in the environment variables of your computer if you do not want to include it in your Scons call.
|
||||||
|
|
||||||
> Replace `<your platform>` with either `windows`, `linux` or `osx`.
|
|
||||||
|
> Replace `<your platform>` with either `windows`, `linux`, `osx` or `android`.
|
||||||
|
|
||||||
> Include `use_llvm=yes` for using clang++
|
> Include `use_llvm=yes` for using clang++
|
||||||
|
|
||||||
@@ -189,6 +197,19 @@ $ link /nologo /dll /out:bin\libtest.dll /implib:bin\libsimple.lib src\init.obj
|
|||||||
*macOS*
|
*macOS*
|
||||||
For OSX you need to find out what compiler flags need to be used.
|
For OSX you need to find out what compiler flags need to be used.
|
||||||
|
|
||||||
|
*Android*
|
||||||
|
```
|
||||||
|
$ cd SimpleLibrary
|
||||||
|
$ aarch64-linux-android29-clang -fPIC -o src/init.os -c src/init.cpp -g -O3 -std=c++14 -Igodot-cpp/include -Igodot-cpp/include/core -Igodot-cpp/include/gen -Igodot-cpp/godot_headers
|
||||||
|
$ aarch64-linux-android29-clang -o bin/libtest.so -shared src/init.os -Lgodot-cpp/bin -l<name of the godot-cpp>
|
||||||
|
```
|
||||||
|
> use `armv7a-linux-androideabi29-clang` for 32 bit armeabi-v7a library
|
||||||
|
|
||||||
|
> This creates the file `libtest.so` in your `SimpleLibrary/bin` directory.
|
||||||
|
|
||||||
|
> You will need to replace `<name of the godot-cpp>` with the file that was created in [**Compiling the cpp bindings library**](#compiling-the-cpp-bindings-library)
|
||||||
|
|
||||||
|
|
||||||
### Creating `.gdnlib` and `.gdns` files
|
### Creating `.gdnlib` and `.gdns` files
|
||||||
follow [godot_header/README.md](https://github.com/GodotNativeTools/godot_headers/blob/master/README.md#how-do-i-use-native-scripts-from-the-editor) to create the `.gdns`
|
follow [godot_header/README.md](https://github.com/GodotNativeTools/godot_headers/blob/master/README.md#how-do-i-use-native-scripts-from-the-editor) to create the `.gdns`
|
||||||
|
|
||||||
|
|||||||
346
SConstruct
346
SConstruct
@@ -1,66 +1,176 @@
|
|||||||
#!python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os, subprocess, platform, sys
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
if sys.version_info < (3,):
|
||||||
|
def decode_utf8(x):
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
import codecs
|
||||||
|
def decode_utf8(x):
|
||||||
|
return codecs.utf_8_decode(x)[0]
|
||||||
|
|
||||||
|
# Workaround for MinGW. See:
|
||||||
|
# http://www.scons.org/wiki/LongCmdLinesOnWin32
|
||||||
|
if (os.name=="nt"):
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def mySubProcess(cmdline,env):
|
||||||
|
#print "SPAWNED : " + cmdline
|
||||||
|
startupinfo = subprocess.STARTUPINFO()
|
||||||
|
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
|
||||||
|
proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env)
|
||||||
|
data, err = proc.communicate()
|
||||||
|
rv = proc.wait()
|
||||||
|
if rv:
|
||||||
|
print("=====")
|
||||||
|
print(err.decode("utf-8"))
|
||||||
|
print("=====")
|
||||||
|
return rv
|
||||||
|
|
||||||
|
def mySpawn(sh, escape, cmd, args, env):
|
||||||
|
|
||||||
|
newargs = ' '.join(args[1:])
|
||||||
|
cmdline = cmd + " " + newargs
|
||||||
|
|
||||||
|
rv=0
|
||||||
|
if len(cmdline) > 32000 and cmd.endswith("ar") :
|
||||||
|
cmdline = cmd + " " + args[1] + " " + args[2] + " "
|
||||||
|
for i in range(3,len(args)) :
|
||||||
|
rv = mySubProcess( cmdline + args[i], env )
|
||||||
|
if rv :
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
rv = mySubProcess( cmdline, env )
|
||||||
|
|
||||||
|
return rv
|
||||||
|
|
||||||
def add_sources(sources, dir, extension):
|
def add_sources(sources, dir, extension):
|
||||||
for f in os.listdir(dir):
|
for f in os.listdir(dir):
|
||||||
if f.endswith('.' + extension):
|
if f.endswith('.' + extension):
|
||||||
sources.append(dir + '/' + f)
|
sources.append(dir + '/' + f)
|
||||||
|
|
||||||
# Try to detect the host platform automatically
|
|
||||||
|
# Try to detect the host platform automatically.
|
||||||
# This is used if no `platform` argument is passed
|
# This is used if no `platform` argument is passed
|
||||||
if sys.platform.startswith('linux'):
|
if sys.platform.startswith('linux'):
|
||||||
host_platform = 'linux'
|
host_platform = 'linux'
|
||||||
elif sys.platform == 'darwin':
|
elif sys.platform == 'darwin':
|
||||||
host_platform = 'osx'
|
host_platform = 'osx'
|
||||||
elif sys.platform == 'win32':
|
elif sys.platform == 'win32' or sys.platform == 'msys':
|
||||||
host_platform = 'windows'
|
host_platform = 'windows'
|
||||||
else:
|
else:
|
||||||
raise ValueError('Could not detect platform automatically, please specify with platform=<platform>')
|
raise ValueError(
|
||||||
|
'Could not detect platform automatically, please specify with '
|
||||||
|
'platform=<platform>'
|
||||||
|
)
|
||||||
|
|
||||||
opts = Variables([], ARGUMENTS)
|
opts = Variables([], ARGUMENTS)
|
||||||
|
opts.Add(EnumVariable(
|
||||||
opts.Add(EnumVariable('platform', 'Target platform', host_platform,
|
'platform',
|
||||||
allowed_values=('linux', 'osx', 'windows'),
|
'Target platform',
|
||||||
ignorecase=2))
|
host_platform,
|
||||||
opts.Add(EnumVariable('bits', 'Target platform bits', 'default', ('default', '32', '64')))
|
allowed_values=('linux', 'osx', 'windows', 'android', 'ios'),
|
||||||
opts.Add(BoolVariable('use_llvm', 'Use the LLVM compiler - only effective when targeting Linux', False))
|
ignorecase=2
|
||||||
opts.Add(BoolVariable('use_mingw', 'Use the MinGW compiler - only effective on Windows', False))
|
))
|
||||||
|
opts.Add(EnumVariable(
|
||||||
|
'bits',
|
||||||
|
'Target platform bits',
|
||||||
|
'default',
|
||||||
|
('default', '32', '64')
|
||||||
|
))
|
||||||
|
opts.Add(BoolVariable(
|
||||||
|
'use_llvm',
|
||||||
|
'Use the LLVM compiler - only effective when targeting Linux',
|
||||||
|
False
|
||||||
|
))
|
||||||
|
opts.Add(BoolVariable(
|
||||||
|
'use_mingw',
|
||||||
|
'Use the MinGW compiler instead of MSVC - only effective on Windows',
|
||||||
|
False
|
||||||
|
))
|
||||||
# Must be the same setting as used for cpp_bindings
|
# Must be the same setting as used for cpp_bindings
|
||||||
opts.Add(EnumVariable('target', 'Compilation target', 'debug',
|
opts.Add(EnumVariable(
|
||||||
allowed_values=('debug', 'release'),
|
'target',
|
||||||
ignorecase=2))
|
'Compilation target',
|
||||||
opts.Add(PathVariable('headers_dir', 'Path to the directory containing Godot headers', 'godot_headers', PathVariable.PathIsDir))
|
'debug',
|
||||||
opts.Add(BoolVariable('use_custom_api_file', 'Use a custom JSON API file', False))
|
allowed_values=('debug', 'release'),
|
||||||
opts.Add(PathVariable('custom_api_file', 'Path to the custom JSON API file', None, PathVariable.PathIsFile))
|
ignorecase=2
|
||||||
opts.Add(BoolVariable('generate_bindings', 'Generate GDNative API bindings', False))
|
))
|
||||||
|
opts.Add(PathVariable(
|
||||||
|
'headers_dir',
|
||||||
|
'Path to the directory containing Godot headers',
|
||||||
|
'godot_headers',
|
||||||
|
PathVariable.PathIsDir
|
||||||
|
))
|
||||||
|
opts.Add(PathVariable(
|
||||||
|
'custom_api_file',
|
||||||
|
'Path to a custom JSON API file',
|
||||||
|
None,
|
||||||
|
PathVariable.PathIsFile
|
||||||
|
))
|
||||||
|
opts.Add(BoolVariable(
|
||||||
|
'generate_bindings',
|
||||||
|
'Generate GDNative API bindings',
|
||||||
|
False
|
||||||
|
))
|
||||||
|
opts.Add(EnumVariable(
|
||||||
|
'android_arch',
|
||||||
|
'Target Android architecture',
|
||||||
|
'armv7',
|
||||||
|
['armv7','arm64v8','x86','x86_64']
|
||||||
|
))
|
||||||
|
opts.Add(EnumVariable(
|
||||||
|
'ios_arch',
|
||||||
|
'Target iOS architecture',
|
||||||
|
'arm64',
|
||||||
|
['armv7', 'arm64', 'x86_64']
|
||||||
|
))
|
||||||
|
opts.Add(
|
||||||
|
'IPHONEPATH',
|
||||||
|
'Path to iPhone toolchain',
|
||||||
|
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain',
|
||||||
|
)
|
||||||
|
opts.Add(
|
||||||
|
'android_api_level',
|
||||||
|
'Target Android API level',
|
||||||
|
'18' if ARGUMENTS.get("android_arch", 'armv7') in ['armv7', 'x86'] else '21'
|
||||||
|
)
|
||||||
|
opts.Add(
|
||||||
|
'ANDROID_NDK_ROOT',
|
||||||
|
'Path to your Android NDK installation. By default, uses ANDROID_NDK_ROOT from your defined environment variables.',
|
||||||
|
os.environ.get("ANDROID_NDK_ROOT", None)
|
||||||
|
)
|
||||||
|
|
||||||
unknown = opts.UnknownVariables()
|
env = Environment(ENV = os.environ)
|
||||||
if unknown:
|
|
||||||
print("Unknown variables:" + unknown.keys())
|
|
||||||
Exit(1)
|
|
||||||
|
|
||||||
env = Environment()
|
|
||||||
opts.Update(env)
|
opts.Update(env)
|
||||||
Help(opts.GenerateHelpText(env))
|
Help(opts.GenerateHelpText(env))
|
||||||
|
|
||||||
# This makes sure to keep the session environment variables on Windows
|
is64 = sys.maxsize > 2**32
|
||||||
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find all the required tools
|
if (
|
||||||
if env['platform'] == 'windows':
|
env['TARGET_ARCH'] == 'amd64' or
|
||||||
|
env['TARGET_ARCH'] == 'emt64' or
|
||||||
|
env['TARGET_ARCH'] == 'x86_64' or
|
||||||
|
env['TARGET_ARCH'] == 'arm64-v8a'
|
||||||
|
):
|
||||||
|
is64 = True
|
||||||
|
|
||||||
|
if env['bits'] == 'default':
|
||||||
|
env['bits'] = '64' if is64 else '32'
|
||||||
|
|
||||||
|
# This makes sure to keep the session environment variables on Windows.
|
||||||
|
# This way, you can run SCons in a Visual Studio 2017 prompt and it will find
|
||||||
|
# all the required tools
|
||||||
|
if host_platform == 'windows' and env['platform'] != 'android':
|
||||||
if env['bits'] == '64':
|
if env['bits'] == '64':
|
||||||
env = Environment(TARGET_ARCH='amd64')
|
env = Environment(TARGET_ARCH='amd64')
|
||||||
elif env['bits'] == '32':
|
elif env['bits'] == '32':
|
||||||
env = Environment(TARGET_ARCH='x86')
|
env = Environment(TARGET_ARCH='x86')
|
||||||
else:
|
|
||||||
print("Warning: bits argument not specified, target arch is=" + env['TARGET_ARCH'])
|
|
||||||
opts.Update(env)
|
|
||||||
|
|
||||||
is64 = False
|
opts.Update(env)
|
||||||
if (env['platform'] == 'osx' or env['TARGET_ARCH'] == 'amd64' or env['TARGET_ARCH'] == 'emt64' or env['TARGET_ARCH'] == 'x86_64'):
|
|
||||||
is64 = True
|
|
||||||
if env['bits'] == 'default':
|
|
||||||
env['bits'] = '64' if is64 else '32'
|
|
||||||
|
|
||||||
if env['platform'] == 'linux':
|
if env['platform'] == 'linux':
|
||||||
if env['use_llvm']:
|
if env['use_llvm']:
|
||||||
@@ -82,11 +192,59 @@ if env['platform'] == 'linux':
|
|||||||
env.Append(LINKFLAGS=['-m32'])
|
env.Append(LINKFLAGS=['-m32'])
|
||||||
|
|
||||||
elif env['platform'] == 'osx':
|
elif env['platform'] == 'osx':
|
||||||
|
# Use Clang on macOS by default
|
||||||
|
env['CXX'] = 'clang++'
|
||||||
|
|
||||||
if env['bits'] == '32':
|
if env['bits'] == '32':
|
||||||
raise ValueError('Only 64-bit builds are supported for the macOS target.')
|
raise ValueError(
|
||||||
|
'Only 64-bit builds are supported for the macOS target.'
|
||||||
|
)
|
||||||
|
|
||||||
env.Append(CCFLAGS=['-g', '-std=c++14', '-arch', 'x86_64'])
|
env.Append(CCFLAGS=['-g', '-std=c++14', '-arch', 'x86_64'])
|
||||||
env.Append(LINKFLAGS=['-arch', 'x86_64', '-framework', 'Cocoa', '-Wl,-undefined,dynamic_lookup'])
|
env.Append(LINKFLAGS=[
|
||||||
|
'-arch',
|
||||||
|
'x86_64',
|
||||||
|
'-framework',
|
||||||
|
'Cocoa',
|
||||||
|
'-Wl,-undefined,dynamic_lookup',
|
||||||
|
])
|
||||||
|
|
||||||
|
if env['target'] == 'debug':
|
||||||
|
env.Append(CCFLAGS=['-Og'])
|
||||||
|
elif env['target'] == 'release':
|
||||||
|
env.Append(CCFLAGS=['-O3'])
|
||||||
|
|
||||||
|
elif env['platform'] == 'ios':
|
||||||
|
if env['ios_arch'] == 'x86_64':
|
||||||
|
sdk_name = 'iphonesimulator'
|
||||||
|
env.Append(CCFLAGS=['-mios-simulator-version-min=10.0'])
|
||||||
|
else:
|
||||||
|
sdk_name = 'iphoneos'
|
||||||
|
env.Append(CCFLAGS=['-miphoneos-version-min=10.0'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
sdk_path = decode_utf8(subprocess.check_output(['xcrun', '--sdk', sdk_name, '--show-sdk-path']).strip())
|
||||||
|
except (subprocess.CalledProcessError, OSError):
|
||||||
|
raise ValueError("Failed to find SDK path while running xcrun --sdk {} --show-sdk-path.".format(sdk_name))
|
||||||
|
|
||||||
|
compiler_path = env['IPHONEPATH'] + '/usr/bin/'
|
||||||
|
env['ENV']['PATH'] = env['IPHONEPATH'] + "/Developer/usr/bin/:" + env['ENV']['PATH']
|
||||||
|
|
||||||
|
env['CC'] = compiler_path + 'clang'
|
||||||
|
env['CXX'] = compiler_path + 'clang++'
|
||||||
|
env['AR'] = compiler_path + 'ar'
|
||||||
|
env['RANLIB'] = compiler_path + 'ranlib'
|
||||||
|
|
||||||
|
env.Append(CCFLAGS=['-g', '-std=c++14', '-arch', env['ios_arch'], '-isysroot', sdk_path])
|
||||||
|
env.Append(LINKFLAGS=[
|
||||||
|
'-arch',
|
||||||
|
env['ios_arch'],
|
||||||
|
'-framework',
|
||||||
|
'Cocoa',
|
||||||
|
'-Wl,-undefined,dynamic_lookup',
|
||||||
|
'-isysroot', sdk_path,
|
||||||
|
'-F' + sdk_path
|
||||||
|
])
|
||||||
|
|
||||||
if env['target'] == 'debug':
|
if env['target'] == 'debug':
|
||||||
env.Append(CCFLAGS=['-Og'])
|
env.Append(CCFLAGS=['-Og'])
|
||||||
@@ -98,43 +256,131 @@ elif env['platform'] == 'windows':
|
|||||||
# MSVC
|
# MSVC
|
||||||
env.Append(LINKFLAGS=['/WX'])
|
env.Append(LINKFLAGS=['/WX'])
|
||||||
if env['target'] == 'debug':
|
if env['target'] == 'debug':
|
||||||
env.Append(CCFLAGS=['/EHsc', '/D_DEBUG', '/MDd'])
|
env.Append(CCFLAGS=['/Z7', '/Od', '/EHsc', '/D_DEBUG', '/MDd'])
|
||||||
elif env['target'] == 'release':
|
elif env['target'] == 'release':
|
||||||
env.Append(CCFLAGS=['/O2', '/EHsc', '/DNDEBUG', '/MD'])
|
env.Append(CCFLAGS=['/O2', '/EHsc', '/DNDEBUG', '/MD'])
|
||||||
else:
|
|
||||||
# MinGW
|
elif host_platform == 'linux' or host_platform == 'osx':
|
||||||
|
# Cross-compilation using MinGW
|
||||||
if env['bits'] == '64':
|
if env['bits'] == '64':
|
||||||
env['CXX'] = 'x86_64-w64-mingw32-g++'
|
env['CXX'] = 'x86_64-w64-mingw32-g++'
|
||||||
|
env['AR'] = "x86_64-w64-mingw32-ar"
|
||||||
|
env['RANLIB'] = "x86_64-w64-mingw32-ranlib"
|
||||||
|
env['LINK'] = "x86_64-w64-mingw32-g++"
|
||||||
elif env['bits'] == '32':
|
elif env['bits'] == '32':
|
||||||
env['CXX'] = 'i686-w64-mingw32-g++'
|
env['CXX'] = 'i686-w64-mingw32-g++'
|
||||||
|
env['AR'] = "i686-w64-mingw32-ar"
|
||||||
|
env['RANLIB'] = "i686-w64-mingw32-ranlib"
|
||||||
|
env['LINK'] = "i686-w64-mingw32-g++"
|
||||||
|
elif host_platform == 'windows' and env['use_mingw']:
|
||||||
|
env = env.Clone(tools=['mingw'])
|
||||||
|
env["SPAWN"] = mySpawn
|
||||||
|
|
||||||
|
# Native or cross-compilation using MinGW
|
||||||
|
if host_platform == 'linux' or host_platform == 'osx' or env['use_mingw']:
|
||||||
env.Append(CCFLAGS=['-g', '-O3', '-std=c++14', '-Wwrite-strings'])
|
env.Append(CCFLAGS=['-g', '-O3', '-std=c++14', '-Wwrite-strings'])
|
||||||
env.Append(LINKFLAGS=['--static', '-Wl,--no-undefined', '-static-libgcc', '-static-libstdc++'])
|
env.Append(LINKFLAGS=[
|
||||||
|
'--static',
|
||||||
|
'-Wl,--no-undefined',
|
||||||
|
'-static-libgcc',
|
||||||
|
'-static-libstdc++',
|
||||||
|
])
|
||||||
|
elif env['platform'] == 'android':
|
||||||
|
if host_platform == 'windows':
|
||||||
|
env = env.Clone(tools=['mingw'])
|
||||||
|
env["SPAWN"] = mySpawn
|
||||||
|
|
||||||
|
# Verify NDK root
|
||||||
|
if not 'ANDROID_NDK_ROOT' in env:
|
||||||
|
raise ValueError("To build for Android, ANDROID_NDK_ROOT must be defined. Please set ANDROID_NDK_ROOT to the root folder of your Android NDK installation.")
|
||||||
|
|
||||||
env.Append(CPPPATH=['.', env['headers_dir'], 'include', 'include/gen', 'include/core'])
|
# Validate API level
|
||||||
|
api_level = int(env['android_api_level'])
|
||||||
|
if env['android_arch'] in ['x86_64', 'arm64v8'] and api_level < 21:
|
||||||
|
print("WARN: 64-bit Android architectures require an API level of at least 21; setting android_api_level=21")
|
||||||
|
env['android_api_level'] = '21'
|
||||||
|
api_level = 21
|
||||||
|
|
||||||
|
# Setup toolchain
|
||||||
|
toolchain = env['ANDROID_NDK_ROOT'] + "/toolchains/llvm/prebuilt/"
|
||||||
|
if host_platform == "windows":
|
||||||
|
toolchain += "windows"
|
||||||
|
import platform as pltfm
|
||||||
|
if pltfm.machine().endswith("64"):
|
||||||
|
toolchain += "-x86_64"
|
||||||
|
elif host_platform == "linux":
|
||||||
|
toolchain += "linux-x86_64"
|
||||||
|
elif host_platform == "osx":
|
||||||
|
toolchain += "darwin-x86_64"
|
||||||
|
env.PrependENVPath('PATH', toolchain + "/bin") # This does nothing half of the time, but we'll put it here anyways
|
||||||
|
|
||||||
|
# Get architecture info
|
||||||
|
arch_info_table = {
|
||||||
|
"armv7" : {
|
||||||
|
"march":"armv7-a", "target":"armv7a-linux-androideabi", "tool_path":"arm-linux-androideabi", "compiler_path":"armv7a-linux-androideabi",
|
||||||
|
"ccflags" : ['-mfpu=neon']
|
||||||
|
},
|
||||||
|
"arm64v8" : {
|
||||||
|
"march":"armv8-a", "target":"aarch64-linux-android", "tool_path":"aarch64-linux-android", "compiler_path":"aarch64-linux-android",
|
||||||
|
"ccflags" : []
|
||||||
|
},
|
||||||
|
"x86" : {
|
||||||
|
"march":"i686", "target":"i686-linux-android", "tool_path":"i686-linux-android", "compiler_path":"i686-linux-android",
|
||||||
|
"ccflags" : ['-mstackrealign']
|
||||||
|
},
|
||||||
|
"x86_64" : {"march":"x86-64", "target":"x86_64-linux-android", "tool_path":"x86_64-linux-android", "compiler_path":"x86_64-linux-android",
|
||||||
|
"ccflags" : []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arch_info = arch_info_table[env['android_arch']]
|
||||||
|
|
||||||
|
# Setup tools
|
||||||
|
env['CC'] = toolchain + "/bin/clang"
|
||||||
|
env['CXX'] = toolchain + "/bin/clang++"
|
||||||
|
env['AR'] = toolchain + "/bin/" + arch_info['tool_path'] + "-ar"
|
||||||
|
|
||||||
|
env.Append(CCFLAGS=['--target=' + arch_info['target'] + env['android_api_level'], '-march=' + arch_info['march'], '-fPIC'])#, '-fPIE', '-fno-addrsig', '-Oz'])
|
||||||
|
env.Append(CCFLAGS=arch_info['ccflags'])
|
||||||
|
|
||||||
|
env.Append(CPPPATH=[
|
||||||
|
'.',
|
||||||
|
env['headers_dir'],
|
||||||
|
'include',
|
||||||
|
'include/gen',
|
||||||
|
'include/core',
|
||||||
|
])
|
||||||
|
|
||||||
# Generate bindings?
|
# Generate bindings?
|
||||||
json_api_file = ''
|
json_api_file = ''
|
||||||
|
|
||||||
if env['use_custom_api_file']:
|
if 'custom_api_file' in env:
|
||||||
json_api_file = env['custom_api_file']
|
json_api_file = env['custom_api_file']
|
||||||
else:
|
else:
|
||||||
json_api_file = os.path.join(os.getcwd(), 'godot_headers', 'api.json')
|
json_api_file = os.path.join(os.getcwd(), 'godot_headers', 'api.json')
|
||||||
|
|
||||||
if env['generate_bindings']:
|
if env['generate_bindings']:
|
||||||
# Actually create the bindings here
|
# Actually create the bindings here
|
||||||
|
|
||||||
import binding_generator
|
import binding_generator
|
||||||
|
|
||||||
binding_generator.generate_bindings(json_api_file)
|
binding_generator.generate_bindings(json_api_file)
|
||||||
|
|
||||||
# source to compile
|
# Sources to compile
|
||||||
sources = []
|
sources = []
|
||||||
add_sources(sources, 'src/core', 'cpp')
|
add_sources(sources, 'src/core', 'cpp')
|
||||||
add_sources(sources, 'src/gen', 'cpp')
|
add_sources(sources, 'src/gen', 'cpp')
|
||||||
|
|
||||||
|
arch_suffix = env['bits']
|
||||||
|
if env['platform'] == 'android':
|
||||||
|
arch_suffix = env['android_arch']
|
||||||
|
if env['platform'] == 'ios':
|
||||||
|
arch_suffix = env['ios_arch']
|
||||||
|
|
||||||
library = env.StaticLibrary(
|
library = env.StaticLibrary(
|
||||||
target='bin/' + 'libgodot-cpp.{}.{}.{}'.format(env['platform'], env['target'], env['bits']), source=sources
|
target='bin/' + 'libgodot-cpp.{}.{}.{}{}'.format(
|
||||||
|
env['platform'],
|
||||||
|
env['target'],
|
||||||
|
arch_suffix,
|
||||||
|
env['LIBSUFFIX']
|
||||||
|
), source=sources
|
||||||
)
|
)
|
||||||
Default(library)
|
Default(library)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
@@ -7,36 +7,36 @@ import json
|
|||||||
classes = []
|
classes = []
|
||||||
|
|
||||||
def generate_bindings(path):
|
def generate_bindings(path):
|
||||||
|
|
||||||
global classes
|
global classes
|
||||||
classes = json.load(open(path))
|
classes = json.load(open(path))
|
||||||
|
|
||||||
icalls = set()
|
icalls = set()
|
||||||
|
|
||||||
for c in classes:
|
for c in classes:
|
||||||
# print c['name']
|
# print c['name']
|
||||||
used_classes = get_used_classes(c)
|
used_classes = get_used_classes(c)
|
||||||
|
|
||||||
header = generate_class_header(used_classes, c)
|
header = generate_class_header(used_classes, c)
|
||||||
|
|
||||||
impl = generate_class_implementation(icalls, used_classes, c)
|
impl = generate_class_implementation(icalls, used_classes, c)
|
||||||
|
|
||||||
header_file = open("include/gen/" + strip_name(c["name"]) + ".hpp", "w+")
|
header_file = open("include/gen/" + strip_name(c["name"]) + ".hpp", "w+")
|
||||||
header_file.write(header)
|
header_file.write(header)
|
||||||
|
|
||||||
source_file = open("src/gen/" + strip_name(c["name"]) + ".cpp", "w+")
|
source_file = open("src/gen/" + strip_name(c["name"]) + ".cpp", "w+")
|
||||||
source_file.write(impl)
|
source_file.write(impl)
|
||||||
|
|
||||||
|
|
||||||
icall_header_file = open("src/gen/__icalls.hpp", "w+")
|
icall_header_file = open("include/gen/__icalls.hpp", "w+")
|
||||||
icall_header_file.write(generate_icall_header(icalls))
|
icall_header_file.write(generate_icall_header(icalls))
|
||||||
|
|
||||||
icall_source_file = open("src/gen/__icalls.cpp", "w+")
|
|
||||||
icall_source_file.write(generate_icall_implementation(icalls))
|
|
||||||
|
|
||||||
register_types_file = open("src/gen/__register_types.cpp", "w+")
|
register_types_file = open("src/gen/__register_types.cpp", "w+")
|
||||||
register_types_file.write(generate_type_registry(classes))
|
register_types_file.write(generate_type_registry(classes))
|
||||||
|
|
||||||
|
init_method_bindings_file = open("src/gen/__init_method_bindings.cpp", "w+")
|
||||||
|
init_method_bindings_file.write(generate_init_method_bindings(classes))
|
||||||
|
|
||||||
|
|
||||||
def is_reference_type(t):
|
def is_reference_type(t):
|
||||||
for c in classes:
|
for c in classes:
|
||||||
@@ -58,9 +58,10 @@ def make_gdnative_type(t):
|
|||||||
if t == "int":
|
if t == "int":
|
||||||
return "int64_t "
|
return "int64_t "
|
||||||
if t == "float" or t == "real":
|
if t == "float" or t == "real":
|
||||||
return "double "
|
return "real_t "
|
||||||
return strip_name(t) + " "
|
return strip_name(t) + " "
|
||||||
|
|
||||||
|
|
||||||
def generate_class_header(used_classes, c):
|
def generate_class_header(used_classes, c):
|
||||||
|
|
||||||
source = []
|
source = []
|
||||||
@@ -68,12 +69,12 @@ def generate_class_header(used_classes, c):
|
|||||||
source.append("#define GODOT_CPP_" + strip_name(c["name"]).upper() + "_HPP")
|
source.append("#define GODOT_CPP_" + strip_name(c["name"]).upper() + "_HPP")
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("#include <gdnative_api_struct.gen.h>")
|
source.append("#include <gdnative_api_struct.gen.h>")
|
||||||
source.append("#include <stdint.h>")
|
source.append("#include <stdint.h>")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
source.append("#include <core/CoreTypes.hpp>")
|
source.append("#include <core/CoreTypes.hpp>")
|
||||||
|
|
||||||
class_name = strip_name(c["name"])
|
class_name = strip_name(c["name"])
|
||||||
@@ -101,11 +102,11 @@ def generate_class_header(used_classes, c):
|
|||||||
source.append("#include \"" + used_class_name + ".hpp\"")
|
source.append("#include \"" + used_class_name + ".hpp\"")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
if c["base_class"] != "":
|
if c["base_class"] != "":
|
||||||
source.append("#include \"" + strip_name(c["base_class"]) + ".hpp\"")
|
source.append("#include \"" + strip_name(c["base_class"]) + ".hpp\"")
|
||||||
|
|
||||||
|
|
||||||
source.append("namespace godot {")
|
source.append("namespace godot {")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
@@ -115,19 +116,19 @@ def generate_class_header(used_classes, c):
|
|||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
source.append("class " + strip_name(used_type) + ";")
|
source.append("class " + strip_name(used_type) + ";")
|
||||||
|
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
vararg_templates = ""
|
vararg_templates = ""
|
||||||
|
|
||||||
# generate the class definition here
|
# generate the class definition here
|
||||||
source.append("class " + class_name + (" : public _Wrapped" if c["base_class"] == "" else (" : public " + strip_name(c["base_class"])) ) + " {")
|
source.append("class " + class_name + (" : public _Wrapped" if c["base_class"] == "" else (" : public " + strip_name(c["base_class"])) ) + " {")
|
||||||
|
|
||||||
if c["base_class"] == "":
|
if c["base_class"] == "":
|
||||||
source.append("public: enum { ___CLASS_IS_SCRIPT = 0, };")
|
source.append("public: enum { ___CLASS_IS_SCRIPT = 0, };")
|
||||||
source.append("private:")
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
source.append("private:")
|
||||||
|
|
||||||
if c["singleton"]:
|
if c["singleton"]:
|
||||||
source.append("\tstatic " + class_name + " *_singleton;")
|
source.append("\tstatic " + class_name + " *_singleton;")
|
||||||
@@ -135,8 +136,18 @@ def generate_class_header(used_classes, c):
|
|||||||
source.append("\t" + class_name + "();")
|
source.append("\t" + class_name + "();")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
# Generate method table
|
||||||
|
source.append("\tstruct ___method_bindings {")
|
||||||
|
|
||||||
|
for method in c["methods"]:
|
||||||
|
source.append("\t\tgodot_method_bind *mb_" + method["name"] + ";")
|
||||||
|
|
||||||
|
source.append("\t};")
|
||||||
|
source.append("\tstatic ___method_bindings ___mb;")
|
||||||
|
source.append("")
|
||||||
source.append("public:")
|
source.append("public:")
|
||||||
|
source.append("\tstatic void ___init_method_bindings();")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
@@ -168,17 +179,17 @@ def generate_class_header(used_classes, c):
|
|||||||
source.append("\t};")
|
source.append("\t};")
|
||||||
|
|
||||||
source.append("\n\t// constants")
|
source.append("\n\t// constants")
|
||||||
|
|
||||||
for name in c["constants"]:
|
for name in c["constants"]:
|
||||||
if name not in enum_values:
|
if name not in enum_values:
|
||||||
source.append("\tconst static int " + name + " = " + str(c["constants"][name]) + ";")
|
source.append("\tconst static int " + name + " = " + str(c["constants"][name]) + ";")
|
||||||
|
|
||||||
|
|
||||||
if c["instanciable"]:
|
if c["instanciable"]:
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("\tstatic " + class_name + " *_new();")
|
source.append("\tstatic " + class_name + " *_new();")
|
||||||
|
|
||||||
source.append("\n\t// methods")
|
source.append("\n\t// methods")
|
||||||
|
|
||||||
|
|
||||||
@@ -188,28 +199,28 @@ def generate_class_header(used_classes, c):
|
|||||||
source.append("\tstatic T *cast_to(const Object *obj);")
|
source.append("\tstatic T *cast_to(const Object *obj);")
|
||||||
source.append("#endif")
|
source.append("#endif")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
for method in c["methods"]:
|
for method in c["methods"]:
|
||||||
|
|
||||||
method_signature = ""
|
method_signature = ""
|
||||||
|
|
||||||
# TODO decide what to do about virtual methods
|
# TODO decide what to do about virtual methods
|
||||||
# method_signature += "virtual " if method["is_virtual"] else ""
|
# method_signature += "virtual " if method["is_virtual"] else ""
|
||||||
method_signature += make_gdnative_type(method["return_type"])
|
method_signature += make_gdnative_type(method["return_type"])
|
||||||
method_name = escape_cpp(method["name"])
|
method_name = escape_cpp(method["name"])
|
||||||
method_signature += method_name + "("
|
method_signature += method_name + "("
|
||||||
|
|
||||||
|
|
||||||
has_default_argument = False
|
has_default_argument = False
|
||||||
method_arguments = ""
|
method_arguments = ""
|
||||||
|
|
||||||
for i, argument in enumerate(method["arguments"]):
|
for i, argument in enumerate(method["arguments"]):
|
||||||
method_signature += "const " + make_gdnative_type(argument["type"])
|
method_signature += "const " + make_gdnative_type(argument["type"])
|
||||||
argument_name = escape_cpp(argument["name"])
|
argument_name = escape_cpp(argument["name"])
|
||||||
method_signature += argument_name
|
method_signature += argument_name
|
||||||
method_arguments += argument_name
|
method_arguments += argument_name
|
||||||
|
|
||||||
|
|
||||||
# default arguments
|
# default arguments
|
||||||
def escape_default_arg(_type, default_value):
|
def escape_default_arg(_type, default_value):
|
||||||
if _type == "Color":
|
if _type == "Color":
|
||||||
@@ -236,51 +247,51 @@ def generate_class_header(used_classes, c):
|
|||||||
return "\"" + default_value + "\""
|
return "\"" + default_value + "\""
|
||||||
if _type == "RID":
|
if _type == "RID":
|
||||||
return "RID()"
|
return "RID()"
|
||||||
|
|
||||||
if default_value == "Null" or default_value == "[Object:null]":
|
if default_value == "Null" or default_value == "[Object:null]":
|
||||||
return "nullptr"
|
return "nullptr"
|
||||||
|
|
||||||
return default_value
|
return default_value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if argument["has_default_value"] or has_default_argument:
|
if argument["has_default_value"] or has_default_argument:
|
||||||
method_signature += " = " + escape_default_arg(argument["type"], argument["default_value"])
|
method_signature += " = " + escape_default_arg(argument["type"], argument["default_value"])
|
||||||
has_default_argument = True
|
has_default_argument = True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if i != len(method["arguments"]) - 1:
|
if i != len(method["arguments"]) - 1:
|
||||||
method_signature += ", "
|
method_signature += ", "
|
||||||
method_arguments += ","
|
method_arguments += ","
|
||||||
|
|
||||||
if method["has_varargs"]:
|
if method["has_varargs"]:
|
||||||
if len(method["arguments"]) > 0:
|
if len(method["arguments"]) > 0:
|
||||||
method_signature += ", "
|
method_signature += ", "
|
||||||
method_arguments += ", "
|
method_arguments += ", "
|
||||||
vararg_templates += "\ttemplate <class... Args> " + method_signature + "Args... args){\n\t\treturn " + method_name + "(" + method_arguments + "Array::make(args...));\n\t}\n"""
|
vararg_templates += "\ttemplate <class... Args> " + method_signature + "Args... args){\n\t\treturn " + method_name + "(" + method_arguments + "Array::make(args...));\n\t}\n"""
|
||||||
method_signature += "const Array& __var_args = Array()"
|
method_signature += "const Array& __var_args = Array()"
|
||||||
|
|
||||||
method_signature += ")" + (" const" if method["is_const"] else "")
|
method_signature += ")" + (" const" if method["is_const"] else "")
|
||||||
|
|
||||||
|
|
||||||
source.append("\t" + method_signature + ";")
|
source.append("\t" + method_signature + ";")
|
||||||
|
|
||||||
source.append(vararg_templates)
|
source.append(vararg_templates)
|
||||||
source.append("};")
|
source.append("};")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("#endif")
|
source.append("#endif")
|
||||||
|
|
||||||
|
|
||||||
return "\n".join(source)
|
return "\n".join(source)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -291,34 +302,34 @@ def generate_class_implementation(icalls, used_classes, c):
|
|||||||
source.append("#include \"" + class_name + ".hpp\"")
|
source.append("#include \"" + class_name + ".hpp\"")
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("#include <core/GodotGlobal.hpp>")
|
source.append("#include <core/GodotGlobal.hpp>")
|
||||||
source.append("#include <core/CoreTypes.hpp>")
|
source.append("#include <core/CoreTypes.hpp>")
|
||||||
source.append("#include <core/Ref.hpp>")
|
source.append("#include <core/Ref.hpp>")
|
||||||
|
|
||||||
source.append("#include <core/Godot.hpp>")
|
source.append("#include <core/Godot.hpp>")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
source.append("#include \"__icalls.hpp\"")
|
source.append("#include \"__icalls.hpp\"")
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
for used_class in used_classes:
|
for used_class in used_classes:
|
||||||
if is_enum(used_class):
|
if is_enum(used_class):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
source.append("#include \"" + strip_name(used_class) + ".hpp\"")
|
source.append("#include \"" + strip_name(used_class) + ".hpp\"")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("namespace godot {")
|
source.append("namespace godot {")
|
||||||
|
|
||||||
|
|
||||||
core_object_name = "this"
|
core_object_name = "this"
|
||||||
|
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
@@ -326,44 +337,54 @@ def generate_class_implementation(icalls, used_classes, c):
|
|||||||
source.append("" + class_name + " *" + class_name + "::_singleton = NULL;")
|
source.append("" + class_name + " *" + class_name + "::_singleton = NULL;")
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
# FIXME Test if inlining has a huge impact on binary size
|
# FIXME Test if inlining has a huge impact on binary size
|
||||||
source.append(class_name + "::" + class_name + "() {")
|
source.append(class_name + "::" + class_name + "() {")
|
||||||
source.append("\t_owner = godot::api->godot_global_get_singleton((char *) \"" + strip_name(c["name"]) + "\");")
|
source.append("\t_owner = godot::api->godot_global_get_singleton((char *) \"" + strip_name(c["name"]) + "\");")
|
||||||
source.append("}")
|
source.append("}")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
# Method table initialization
|
||||||
|
source.append(class_name + "::___method_bindings " + class_name + "::___mb = {};")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
|
source.append("void " + class_name + "::___init_method_bindings() {")
|
||||||
|
|
||||||
|
for method in c["methods"]:
|
||||||
|
source.append("\t___mb.mb_" + method["name"] + " = godot::api->godot_method_bind_get_method(\"" + c["name"] + "\", \"" + method["name"] + "\");")
|
||||||
|
|
||||||
|
source.append("}")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
if c["instanciable"]:
|
if c["instanciable"]:
|
||||||
source.append(class_name + " *" + strip_name(c["name"]) + "::_new()")
|
source.append(class_name + " *" + strip_name(c["name"]) + "::_new()")
|
||||||
source.append("{")
|
source.append("{")
|
||||||
source.append("\treturn (" + class_name + " *) godot::nativescript_1_1_api->godot_nativescript_get_instance_binding_data(godot::_RegisterState::language_index, godot::api->godot_get_class_constructor((char *)\"" + c["name"] + "\")());")
|
source.append("\treturn (" + class_name + " *) godot::nativescript_1_1_api->godot_nativescript_get_instance_binding_data(godot::_RegisterState::language_index, godot::api->godot_get_class_constructor((char *)\"" + c["name"] + "\")());")
|
||||||
source.append("}")
|
source.append("}")
|
||||||
|
|
||||||
for method in c["methods"]:
|
for method in c["methods"]:
|
||||||
method_signature = ""
|
method_signature = ""
|
||||||
|
|
||||||
|
|
||||||
method_signature += make_gdnative_type(method["return_type"])
|
method_signature += make_gdnative_type(method["return_type"])
|
||||||
method_signature += strip_name(c["name"]) + "::" + escape_cpp(method["name"]) + "("
|
method_signature += strip_name(c["name"]) + "::" + escape_cpp(method["name"]) + "("
|
||||||
|
|
||||||
for i, argument in enumerate(method["arguments"]):
|
for i, argument in enumerate(method["arguments"]):
|
||||||
method_signature += "const " + make_gdnative_type(argument["type"])
|
method_signature += "const " + make_gdnative_type(argument["type"])
|
||||||
method_signature += escape_cpp(argument["name"])
|
method_signature += escape_cpp(argument["name"])
|
||||||
|
|
||||||
if i != len(method["arguments"]) - 1:
|
if i != len(method["arguments"]) - 1:
|
||||||
method_signature += ", "
|
method_signature += ", "
|
||||||
|
|
||||||
if method["has_varargs"]:
|
if method["has_varargs"]:
|
||||||
if len(method["arguments"]) > 0:
|
if len(method["arguments"]) > 0:
|
||||||
method_signature += ", "
|
method_signature += ", "
|
||||||
method_signature += "const Array& __var_args"
|
method_signature += "const Array& __var_args"
|
||||||
|
|
||||||
method_signature += ")" + (" const" if method["is_const"] else "")
|
method_signature += ")" + (" const" if method["is_const"] else "")
|
||||||
|
|
||||||
source.append(method_signature + " {")
|
source.append(method_signature + " {")
|
||||||
|
|
||||||
|
|
||||||
@@ -373,15 +394,9 @@ def generate_class_implementation(icalls, used_classes, c):
|
|||||||
source.append("}")
|
source.append("}")
|
||||||
source.append("")
|
source.append("")
|
||||||
continue
|
continue
|
||||||
else:
|
|
||||||
|
|
||||||
source.append("\tstatic godot_method_bind *mb = nullptr;")
|
|
||||||
source.append("\tif (mb == nullptr) {")
|
|
||||||
source.append("\t\tmb = godot::api->godot_method_bind_get_method(\"" + c["name"] +"\", \"" + method["name"] + "\");")
|
|
||||||
source.append("\t}")
|
|
||||||
|
|
||||||
return_statement = ""
|
return_statement = ""
|
||||||
|
|
||||||
if method["return_type"] != "void":
|
if method["return_type"] != "void":
|
||||||
if is_class_type(method["return_type"]):
|
if is_class_type(method["return_type"]):
|
||||||
if is_enum(method["return_type"]):
|
if is_enum(method["return_type"]):
|
||||||
@@ -392,72 +407,72 @@ def generate_class_implementation(icalls, used_classes, c):
|
|||||||
return_statement += "return " + ("(" + strip_name(method["return_type"]) + " *) " if is_class_type(method["return_type"]) else "")
|
return_statement += "return " + ("(" + strip_name(method["return_type"]) + " *) " if is_class_type(method["return_type"]) else "")
|
||||||
else:
|
else:
|
||||||
return_statement += "return "
|
return_statement += "return "
|
||||||
|
|
||||||
def get_icall_type_name(name):
|
def get_icall_type_name(name):
|
||||||
if is_enum(name):
|
if is_enum(name):
|
||||||
return "int"
|
return "int"
|
||||||
if is_class_type(name):
|
if is_class_type(name):
|
||||||
return "Object"
|
return "Object"
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if method["has_varargs"]:
|
if method["has_varargs"]:
|
||||||
|
|
||||||
if len(method["arguments"]) != 0:
|
if len(method["arguments"]) != 0:
|
||||||
source.append("\tVariant __given_args[" + str(len(method["arguments"])) + "];")
|
source.append("\tVariant __given_args[" + str(len(method["arguments"])) + "];")
|
||||||
|
|
||||||
for i, argument in enumerate(method["arguments"]):
|
for i, argument in enumerate(method["arguments"]):
|
||||||
source.append("\tgodot::api->godot_variant_new_nil((godot_variant *) &__given_args[" + str(i) + "]);")
|
source.append("\tgodot::api->godot_variant_new_nil((godot_variant *) &__given_args[" + str(i) + "]);")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
for i, argument in enumerate(method["arguments"]):
|
for i, argument in enumerate(method["arguments"]):
|
||||||
source.append("\t__given_args[" + str(i) + "] = " + escape_cpp(argument["name"]) + ";")
|
source.append("\t__given_args[" + str(i) + "] = " + escape_cpp(argument["name"]) + ";")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
size = ""
|
size = ""
|
||||||
if method["has_varargs"]:
|
if method["has_varargs"]:
|
||||||
size = "(__var_args.size() + " + str(len(method["arguments"])) + ")"
|
size = "(__var_args.size() + " + str(len(method["arguments"])) + ")"
|
||||||
else:
|
else:
|
||||||
size = "(" + str(len(method["arguments"])) + ")"
|
size = "(" + str(len(method["arguments"])) + ")"
|
||||||
|
|
||||||
source.append("\tgodot_variant **__args = (godot_variant **) alloca(sizeof(godot_variant *) * " + size + ");")
|
source.append("\tgodot_variant **__args = (godot_variant **) alloca(sizeof(godot_variant *) * " + size + ");")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
for i, argument in enumerate(method["arguments"]):
|
for i, argument in enumerate(method["arguments"]):
|
||||||
source.append("\t__args[" + str(i) + "] = (godot_variant *) &__given_args[" + str(i) + "];")
|
source.append("\t__args[" + str(i) + "] = (godot_variant *) &__given_args[" + str(i) + "];")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
if method["has_varargs"]:
|
if method["has_varargs"]:
|
||||||
source.append("\tfor (int i = 0; i < __var_args.size(); i++) {")
|
source.append("\tfor (int i = 0; i < __var_args.size(); i++) {")
|
||||||
source.append("\t\t__args[i + " + str(len(method["arguments"])) + "] = (godot_variant *) &((Array &) __var_args)[i];")
|
source.append("\t\t__args[i + " + str(len(method["arguments"])) + "] = (godot_variant *) &((Array &) __var_args)[i];")
|
||||||
source.append("\t}")
|
source.append("\t}")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("\tVariant __result;")
|
source.append("\tVariant __result;")
|
||||||
source.append("\t*(godot_variant *) &__result = godot::api->godot_method_bind_call(mb, ((const Object *) " + core_object_name + ")->_owner, (const godot_variant **) __args, " + size + ", nullptr);")
|
source.append("\t*(godot_variant *) &__result = godot::api->godot_method_bind_call(___mb.mb_" + method["name"] + ", ((const Object *) " + core_object_name + ")->_owner, (const godot_variant **) __args, " + size + ", nullptr);")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
if is_class_type(method["return_type"]):
|
if is_class_type(method["return_type"]):
|
||||||
source.append("\tObject *obj = Object::___get_from_variant(__result);")
|
source.append("\tObject *obj = Object::___get_from_variant(__result);")
|
||||||
source.append("\tif (obj->has_method(\"reference\"))")
|
source.append("\tif (obj->has_method(\"reference\"))")
|
||||||
source.append("\t\tobj->callv(\"reference\", Array());")
|
source.append("\t\tobj->callv(\"reference\", Array());")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
for i, argument in enumerate(method["arguments"]):
|
for i, argument in enumerate(method["arguments"]):
|
||||||
source.append("\tgodot::api->godot_variant_destroy((godot_variant *) &__given_args[" + str(i) + "]);")
|
source.append("\tgodot::api->godot_variant_destroy((godot_variant *) &__given_args[" + str(i) + "]);")
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
if method["return_type"] != "void":
|
if method["return_type"] != "void":
|
||||||
cast = ""
|
cast = ""
|
||||||
if is_class_type(method["return_type"]):
|
if is_class_type(method["return_type"]):
|
||||||
@@ -468,40 +483,40 @@ def generate_class_implementation(icalls, used_classes, c):
|
|||||||
else:
|
else:
|
||||||
cast += "__result;"
|
cast += "__result;"
|
||||||
source.append("\treturn " + cast)
|
source.append("\treturn " + cast)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
args = []
|
args = []
|
||||||
for arg in method["arguments"]:
|
for arg in method["arguments"]:
|
||||||
args.append(get_icall_type_name(arg["type"]))
|
args.append(get_icall_type_name(arg["type"]))
|
||||||
|
|
||||||
icall_ret_type = get_icall_type_name(method["return_type"])
|
icall_ret_type = get_icall_type_name(method["return_type"])
|
||||||
|
|
||||||
icall_sig = tuple((icall_ret_type, tuple(args)))
|
icall_sig = tuple((icall_ret_type, tuple(args)))
|
||||||
|
|
||||||
icalls.add(icall_sig)
|
icalls.add(icall_sig)
|
||||||
|
|
||||||
icall_name = get_icall_name(icall_sig)
|
icall_name = get_icall_name(icall_sig)
|
||||||
|
|
||||||
return_statement += icall_name + "(mb, (const Object *) " + core_object_name
|
return_statement += icall_name + "(___mb.mb_" + method["name"] + ", (const Object *) " + core_object_name
|
||||||
|
|
||||||
for arg in method["arguments"]:
|
for arg in method["arguments"]:
|
||||||
return_statement += ", " + escape_cpp(arg["name"]) + (".ptr()" if is_reference_type(arg["type"]) else "")
|
return_statement += ", " + escape_cpp(arg["name"]) + (".ptr()" if is_reference_type(arg["type"]) else "")
|
||||||
|
|
||||||
return_statement += ")"
|
return_statement += ")"
|
||||||
|
|
||||||
source.append("\t" + return_statement + (")" if is_reference_type(method["return_type"]) else "") + ";")
|
source.append("\t" + return_statement + (")" if is_reference_type(method["return_type"]) else "") + ";")
|
||||||
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
|
|
||||||
|
|
||||||
return "\n".join(source)
|
return "\n".join(source)
|
||||||
|
|
||||||
|
|
||||||
@@ -509,93 +524,39 @@ def generate_class_implementation(icalls, used_classes, c):
|
|||||||
|
|
||||||
|
|
||||||
def generate_icall_header(icalls):
|
def generate_icall_header(icalls):
|
||||||
|
|
||||||
source = []
|
source = []
|
||||||
source.append("#ifndef GODOT_CPP__ICALLS_HPP")
|
source.append("#ifndef GODOT_CPP__ICALLS_HPP")
|
||||||
source.append("#define GODOT_CPP__ICALLS_HPP")
|
source.append("#define GODOT_CPP__ICALLS_HPP")
|
||||||
|
|
||||||
source.append("")
|
|
||||||
|
|
||||||
source.append("#include <gdnative_api_struct.gen.h>")
|
|
||||||
source.append("#include <stdint.h>")
|
|
||||||
source.append("")
|
|
||||||
|
|
||||||
source.append("#include <core/CoreTypes.hpp>")
|
|
||||||
source.append("#include \"Object.hpp\"")
|
|
||||||
source.append("")
|
|
||||||
source.append("")
|
|
||||||
|
|
||||||
source.append("namespace godot {")
|
|
||||||
source.append("")
|
|
||||||
|
|
||||||
for icall in icalls:
|
|
||||||
ret_type = icall[0]
|
|
||||||
args = icall[1]
|
|
||||||
|
|
||||||
method_signature = ""
|
|
||||||
|
|
||||||
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
|
|
||||||
|
|
||||||
for arg in args:
|
|
||||||
method_signature += ", const "
|
|
||||||
|
|
||||||
if is_core_type(arg):
|
|
||||||
method_signature += arg + "&"
|
|
||||||
elif arg == "int":
|
|
||||||
method_signature += "int64_t "
|
|
||||||
elif arg == "float":
|
|
||||||
method_signature += "double "
|
|
||||||
elif is_primitive(arg):
|
|
||||||
method_signature += arg
|
|
||||||
else:
|
|
||||||
method_signature += "Object *"
|
|
||||||
|
|
||||||
method_signature += ");"
|
|
||||||
|
|
||||||
source.append(method_signature)
|
|
||||||
|
|
||||||
source.append("")
|
|
||||||
|
|
||||||
source.append("}")
|
|
||||||
source.append("")
|
|
||||||
|
|
||||||
source.append("#endif")
|
|
||||||
|
|
||||||
return "\n".join(source)
|
|
||||||
|
|
||||||
|
|
||||||
def generate_icall_implementation(icalls):
|
|
||||||
source = []
|
|
||||||
source.append("#include \"__icalls.hpp\"")
|
|
||||||
|
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("#include <gdnative_api_struct.gen.h>")
|
source.append("#include <gdnative_api_struct.gen.h>")
|
||||||
source.append("#include <stdint.h>")
|
source.append("#include <stdint.h>")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("#include <core/GodotGlobal.hpp>")
|
source.append("#include <core/GodotGlobal.hpp>")
|
||||||
source.append("#include <core/CoreTypes.hpp>")
|
source.append("#include <core/CoreTypes.hpp>")
|
||||||
source.append("#include \"Object.hpp\"")
|
source.append("#include \"Object.hpp\"")
|
||||||
source.append("")
|
source.append("")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("namespace godot {")
|
source.append("namespace godot {")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
for icall in icalls:
|
for icall in icalls:
|
||||||
ret_type = icall[0]
|
ret_type = icall[0]
|
||||||
args = icall[1]
|
args = icall[1]
|
||||||
|
|
||||||
method_signature = ""
|
method_signature = "static inline "
|
||||||
|
|
||||||
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
|
method_signature += get_icall_return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
|
||||||
|
|
||||||
for i, arg in enumerate(args):
|
for i, arg in enumerate(args):
|
||||||
method_signature += ", const "
|
method_signature += ", const "
|
||||||
|
|
||||||
if is_core_type(arg):
|
if is_core_type(arg):
|
||||||
method_signature += arg + "& "
|
method_signature += arg + "&"
|
||||||
elif arg == "int":
|
elif arg == "int":
|
||||||
method_signature += "int64_t "
|
method_signature += "int64_t "
|
||||||
elif arg == "float":
|
elif arg == "float":
|
||||||
@@ -604,37 +565,37 @@ def generate_icall_implementation(icalls):
|
|||||||
method_signature += arg + " "
|
method_signature += arg + " "
|
||||||
else:
|
else:
|
||||||
method_signature += "Object *"
|
method_signature += "Object *"
|
||||||
|
|
||||||
method_signature += "arg" + str(i)
|
method_signature += "arg" + str(i)
|
||||||
|
|
||||||
method_signature += ")"
|
method_signature += ")"
|
||||||
|
|
||||||
source.append(method_signature + " {")
|
source.append(method_signature + " {")
|
||||||
|
|
||||||
if ret_type != "void":
|
if ret_type != "void":
|
||||||
source.append("\t" + ("godot_object *" if is_class_type(ret_type) else return_type(ret_type)) + "ret;")
|
source.append("\t" + ("godot_object *" if is_class_type(ret_type) else get_icall_return_type(ret_type)) + "ret;")
|
||||||
if is_class_type(ret_type):
|
if is_class_type(ret_type):
|
||||||
source.append("\tret = nullptr;")
|
source.append("\tret = nullptr;")
|
||||||
|
|
||||||
|
|
||||||
source.append("\tconst void *args[" + ("1" if len(args) == 0 else "") + "] = {")
|
source.append("\tconst void *args[" + ("1" if len(args) == 0 else "") + "] = {")
|
||||||
|
|
||||||
for i, arg in enumerate(args):
|
for i, arg in enumerate(args):
|
||||||
|
|
||||||
wrapped_argument = "\t\t"
|
wrapped_argument = "\t\t"
|
||||||
if is_primitive(arg) or is_core_type(arg):
|
if is_primitive(arg) or is_core_type(arg):
|
||||||
wrapped_argument += "(void *) &arg" + str(i)
|
wrapped_argument += "(void *) &arg" + str(i)
|
||||||
else:
|
else:
|
||||||
wrapped_argument += "(void *) (arg" + str(i) + ") ? arg" + str(i) + "->_owner : nullptr"
|
wrapped_argument += "(void *) (arg" + str(i) + ") ? arg" + str(i) + "->_owner : nullptr"
|
||||||
|
|
||||||
wrapped_argument += ","
|
wrapped_argument += ","
|
||||||
source.append(wrapped_argument)
|
source.append(wrapped_argument)
|
||||||
|
|
||||||
source.append("\t};")
|
source.append("\t};")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
source.append("\tgodot::api->godot_method_bind_ptrcall(mb, inst->_owner, args, " + ("nullptr" if ret_type == "void" else "&ret") + ");")
|
source.append("\tgodot::api->godot_method_bind_ptrcall(mb, inst->_owner, args, " + ("nullptr" if ret_type == "void" else "&ret") + ");")
|
||||||
|
|
||||||
if ret_type != "void":
|
if ret_type != "void":
|
||||||
if is_class_type(ret_type):
|
if is_class_type(ret_type):
|
||||||
source.append("\tif (ret) {")
|
source.append("\tif (ret) {")
|
||||||
@@ -644,20 +605,21 @@ def generate_icall_implementation(icalls):
|
|||||||
source.append("\treturn (Object *) ret;")
|
source.append("\treturn (Object *) ret;")
|
||||||
else:
|
else:
|
||||||
source.append("\treturn ret;")
|
source.append("\treturn ret;")
|
||||||
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
source.append("}")
|
source.append("}")
|
||||||
source.append("")
|
source.append("")
|
||||||
|
|
||||||
|
source.append("#endif")
|
||||||
|
|
||||||
return "\n".join(source)
|
return "\n".join(source)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def generate_type_registry(classes):
|
def generate_type_registry(classes):
|
||||||
source = []
|
source = []
|
||||||
|
|
||||||
source.append("#include \"TagDB.hpp\"")
|
source.append("#include \"TagDB.hpp\"")
|
||||||
source.append("#include <typeinfo>")
|
source.append("#include <typeinfo>")
|
||||||
source.append("\n")
|
source.append("\n")
|
||||||
@@ -695,18 +657,34 @@ def generate_type_registry(classes):
|
|||||||
return "\n".join(source)
|
return "\n".join(source)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_init_method_bindings(classes):
|
||||||
|
source = []
|
||||||
|
|
||||||
|
for c in classes:
|
||||||
|
source.append("#include <" + strip_name(c["name"]) + ".hpp>")
|
||||||
|
|
||||||
|
source.append("")
|
||||||
|
source.append("")
|
||||||
|
|
||||||
|
source.append("namespace godot {")
|
||||||
|
|
||||||
|
source.append("void ___init_method_bindings()")
|
||||||
|
source.append("{")
|
||||||
|
|
||||||
|
for c in classes:
|
||||||
|
class_name = strip_name(c["name"])
|
||||||
|
|
||||||
|
source.append("\t" + strip_name(c["name"]) + "::___init_method_bindings();")
|
||||||
|
|
||||||
|
source.append("}")
|
||||||
|
|
||||||
|
source.append("")
|
||||||
|
source.append("}")
|
||||||
|
|
||||||
|
return "\n".join(source)
|
||||||
|
|
||||||
|
|
||||||
|
def get_icall_return_type(t):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def return_type(t):
|
|
||||||
if is_class_type(t):
|
if is_class_type(t):
|
||||||
return "Object *"
|
return "Object *"
|
||||||
if t == "int":
|
if t == "int":
|
||||||
@@ -719,12 +697,12 @@ def return_type(t):
|
|||||||
def get_icall_name(sig):
|
def get_icall_name(sig):
|
||||||
ret_type = sig[0]
|
ret_type = sig[0]
|
||||||
args = sig[1]
|
args = sig[1]
|
||||||
|
|
||||||
name = "___godot_icall_"
|
name = "___godot_icall_"
|
||||||
name += strip_name(ret_type)
|
name += strip_name(ret_type)
|
||||||
for arg in args:
|
for arg in args:
|
||||||
name += "_" + strip_name(arg)
|
name += "_" + strip_name(arg)
|
||||||
|
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
@@ -737,7 +715,7 @@ def get_used_classes(c):
|
|||||||
for method in c["methods"]:
|
for method in c["methods"]:
|
||||||
if is_class_type(method["return_type"]) and not (method["return_type"] in classes):
|
if is_class_type(method["return_type"]) and not (method["return_type"] in classes):
|
||||||
classes.append(method["return_type"])
|
classes.append(method["return_type"])
|
||||||
|
|
||||||
for arg in method["arguments"]:
|
for arg in method["arguments"]:
|
||||||
if is_class_type(arg["type"]) and not (arg["type"] in classes):
|
if is_class_type(arg["type"]) and not (arg["type"] in classes):
|
||||||
classes.append(arg["type"])
|
classes.append(arg["type"])
|
||||||
|
|||||||
Submodule godot_headers updated: 489db2761c...ddf67cc7b8
@@ -3,11 +3,46 @@
|
|||||||
|
|
||||||
#include <gdnative/array.h>
|
#include <gdnative/array.h>
|
||||||
|
|
||||||
#include "Defs.hpp"
|
|
||||||
#include "String.hpp"
|
#include "String.hpp"
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
|
namespace helpers {
|
||||||
|
template <typename T, typename ValueT>
|
||||||
|
T append_all(T appendable, ValueT value) {
|
||||||
|
appendable.append(value);
|
||||||
|
return appendable;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename ValueT, typename... Args>
|
||||||
|
T append_all(T appendable, ValueT value, Args... args) {
|
||||||
|
appendable.append(value);
|
||||||
|
return append_all(appendable, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T append_all(T appendable) {
|
||||||
|
return appendable;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename KV, typename KeyT, typename ValueT>
|
||||||
|
KV add_all(KV kv, KeyT key, ValueT value) {
|
||||||
|
kv[key] = value;
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename KV, typename KeyT, typename ValueT, typename... Args>
|
||||||
|
KV add_all(KV kv, KeyT key, ValueT value, Args... args) {
|
||||||
|
kv[key] = value;
|
||||||
|
return add_all(kv, args...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename KV>
|
||||||
|
KV add_all(KV kv) {
|
||||||
|
return kv;
|
||||||
|
}
|
||||||
|
} // namespace helpers
|
||||||
|
|
||||||
class Variant;
|
class Variant;
|
||||||
class PoolByteArray;
|
class PoolByteArray;
|
||||||
class PoolIntArray;
|
class PoolIntArray;
|
||||||
@@ -98,6 +133,19 @@ public:
|
|||||||
|
|
||||||
void sort_custom(Object *obj, const String &func);
|
void sort_custom(Object *obj, const String &func);
|
||||||
|
|
||||||
|
int bsearch(const Variant &value, const bool before = true);
|
||||||
|
|
||||||
|
int bsearch_custom(const Variant &value, const Object *obj,
|
||||||
|
const String &func, const bool before = true);
|
||||||
|
|
||||||
|
Array duplicate(const bool deep = false) const;
|
||||||
|
|
||||||
|
Variant max() const;
|
||||||
|
|
||||||
|
Variant min() const;
|
||||||
|
|
||||||
|
void shuffle();
|
||||||
|
|
||||||
~Array();
|
~Array();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef BASIS_H
|
#ifndef BASIS_H
|
||||||
#define BASIS_H
|
#define BASIS_H
|
||||||
|
|
||||||
|
#include <gdnative/basis.h>
|
||||||
|
|
||||||
#include "Defs.hpp"
|
#include "Defs.hpp"
|
||||||
|
|
||||||
#include "Vector3.hpp"
|
#include "Vector3.hpp"
|
||||||
@@ -10,12 +12,291 @@ namespace godot {
|
|||||||
class Quat;
|
class Quat;
|
||||||
|
|
||||||
class Basis {
|
class Basis {
|
||||||
|
private:
|
||||||
|
// This helper template is for mimicking the behavior difference between the engine
|
||||||
|
// and script interfaces that logically script sees matrices as column major, while
|
||||||
|
// the engine stores them in row major to efficiently take advantage of SIMD
|
||||||
|
// instructions in case of matrix-vector multiplications.
|
||||||
|
// With this helper template native scripts see the data as if it was column major
|
||||||
|
// without actually transposing the basis matrix at the script-engine boundary.
|
||||||
|
template <int column>
|
||||||
|
class ColumnVector3 {
|
||||||
|
private:
|
||||||
|
template <int column1, int component>
|
||||||
|
class ColumnVectorComponent {
|
||||||
|
private:
|
||||||
|
Vector3 elements[3];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline ColumnVectorComponent<column1, component> &operator=(const ColumnVectorComponent<column1, component> &p_value) {
|
||||||
|
return *this = real_t(p_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVectorComponent(const ColumnVectorComponent<column1, component> &p_value) {
|
||||||
|
*this = real_t(p_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVectorComponent<column1, component> &operator=(const real_t &p_value) {
|
||||||
|
elements[component][column1] = p_value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator real_t() const {
|
||||||
|
return elements[component][column1];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Axis {
|
||||||
|
AXIS_X,
|
||||||
|
AXIS_Y,
|
||||||
|
AXIS_Z,
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
ColumnVectorComponent<column, 0> x;
|
||||||
|
ColumnVectorComponent<column, 1> y;
|
||||||
|
ColumnVectorComponent<column, 2> z;
|
||||||
|
|
||||||
|
Vector3 elements[3]; // Not for direct access, use [] operator instead
|
||||||
|
};
|
||||||
|
|
||||||
|
inline ColumnVector3<column> &operator=(const ColumnVector3<column> &p_value) {
|
||||||
|
return *this = Vector3(p_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVector3(const ColumnVector3<column> &p_value) {
|
||||||
|
*this = Vector3(p_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVector3<column> &operator=(const Vector3 &p_value) {
|
||||||
|
elements[0][column] = p_value.x;
|
||||||
|
elements[1][column] = p_value.y;
|
||||||
|
elements[2][column] = p_value.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator Vector3() const {
|
||||||
|
return Vector3(elements[0][column], elements[1][column], elements[2][column]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unfortunately, we also need to replicate the other interfaces of Vector3 in
|
||||||
|
// order for being able to directly operate on these "meta-Vector3" objects without
|
||||||
|
// an explicit cast or an intermediate assignment to a real Vector3 object.
|
||||||
|
|
||||||
|
inline const real_t &operator[](int p_axis) const {
|
||||||
|
return elements[p_axis][column];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t &operator[](int p_axis) {
|
||||||
|
return elements[p_axis][column];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVector3<column> &operator+=(const Vector3 &p_v) {
|
||||||
|
return *this = *this + p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator+(const Vector3 &p_v) const {
|
||||||
|
return Vector3(*this) + p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVector3<column> &operator-=(const Vector3 &p_v) {
|
||||||
|
return *this = *this - p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator-(const Vector3 &p_v) const {
|
||||||
|
return Vector3(*this) - p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVector3<column> &operator*=(const Vector3 &p_v) {
|
||||||
|
return *this = *this * p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator*(const Vector3 &p_v) const {
|
||||||
|
return Vector3(*this) * p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVector3<column> &operator/=(const Vector3 &p_v) {
|
||||||
|
return *this = *this / p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator/(const Vector3 &p_v) const {
|
||||||
|
return Vector3(*this) / p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVector3<column> &operator*=(real_t p_scalar) {
|
||||||
|
return *this = *this * p_scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator*(real_t p_scalar) const {
|
||||||
|
return Vector3(*this) * p_scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ColumnVector3<column> &operator/=(real_t p_scalar) {
|
||||||
|
return *this = *this / p_scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator/(real_t p_scalar) const {
|
||||||
|
return Vector3(*this) / p_scalar;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 operator-() const {
|
||||||
|
return -Vector3(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const Vector3 &p_v) const {
|
||||||
|
return Vector3(*this) == p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const Vector3 &p_v) const {
|
||||||
|
return Vector3(*this) != p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<(const Vector3 &p_v) const {
|
||||||
|
return Vector3(*this) < p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<=(const Vector3 &p_v) const {
|
||||||
|
return Vector3(*this) <= p_v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 abs() const {
|
||||||
|
return Vector3(*this).abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 ceil() const {
|
||||||
|
return Vector3(*this).ceil();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 cross(const Vector3 &b) const {
|
||||||
|
return Vector3(*this).cross(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 linear_interpolate(const Vector3 &p_b, real_t p_t) const {
|
||||||
|
return Vector3(*this).linear_interpolate(p_b, p_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const {
|
||||||
|
return Vector3(*this).cubic_interpolate(b, pre_a, post_b, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 bounce(const Vector3 &p_normal) const {
|
||||||
|
return Vector3(*this).bounce(p_normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t length() const {
|
||||||
|
return Vector3(*this).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t length_squared() const {
|
||||||
|
return Vector3(*this).length_squared();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t distance_squared_to(const Vector3 &b) const {
|
||||||
|
return Vector3(*this).distance_squared_to(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t distance_to(const Vector3 &b) const {
|
||||||
|
return Vector3(*this).distance_to(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t dot(const Vector3 &b) const {
|
||||||
|
return Vector3(*this).dot(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t angle_to(const Vector3 &b) const {
|
||||||
|
return Vector3(*this).angle_to(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 floor() const {
|
||||||
|
return Vector3(*this).floor();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 inverse() const {
|
||||||
|
return Vector3(*this).inverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_normalized() const {
|
||||||
|
return Vector3(*this).is_normalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Basis outer(const Vector3 &b) const {
|
||||||
|
return Vector3(*this).outer(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int max_axis() const {
|
||||||
|
return Vector3(*this).max_axis();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int min_axis() const {
|
||||||
|
return Vector3(*this).min_axis();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void normalize() {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v.normalize();
|
||||||
|
*this = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 normalized() const {
|
||||||
|
return Vector3(*this).normalized();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 reflect(const Vector3 &by) const {
|
||||||
|
return Vector3(*this).reflect(by);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 rotated(const Vector3 &axis, const real_t phi) const {
|
||||||
|
return Vector3(*this).rotated(axis, phi);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void rotate(const Vector3 &p_axis, real_t p_phi) {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v.rotate(p_axis, p_phi);
|
||||||
|
*this = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 slide(const Vector3 &by) const {
|
||||||
|
return Vector3(*this).slide(by);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void snap(real_t p_val) {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v.snap(p_val);
|
||||||
|
*this = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 snapped(const float by) {
|
||||||
|
return Vector3(*this).snapped(by);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline operator String() const {
|
||||||
|
return String(Vector3(*this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
union {
|
union {
|
||||||
Vector3 elements[3];
|
ColumnVector3<0> x;
|
||||||
Vector3 x, y, z;
|
ColumnVector3<1> y;
|
||||||
|
ColumnVector3<2> z;
|
||||||
|
|
||||||
|
Vector3 elements[3]; // Not for direct access, use [] operator instead
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline Basis(const Basis &p_basis) {
|
||||||
|
elements[0] = p_basis.elements[0];
|
||||||
|
elements[1] = p_basis.elements[1];
|
||||||
|
elements[2] = p_basis.elements[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Basis &operator=(const Basis &p_basis) {
|
||||||
|
elements[0] = p_basis.elements[0];
|
||||||
|
elements[1] = p_basis.elements[1];
|
||||||
|
elements[2] = p_basis.elements[2];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Basis(const Quat &p_quat); // euler
|
Basis(const Quat &p_quat); // euler
|
||||||
Basis(const Vector3 &p_euler); // euler
|
Basis(const Vector3 &p_euler); // euler
|
||||||
Basis(const Vector3 &p_axis, real_t p_phi);
|
Basis(const Vector3 &p_axis, real_t p_phi);
|
||||||
@@ -26,8 +307,16 @@ public:
|
|||||||
|
|
||||||
Basis();
|
Basis();
|
||||||
|
|
||||||
const Vector3 &operator[](int axis) const;
|
const Vector3 operator[](int axis) const {
|
||||||
Vector3 &operator[](int axis);
|
return get_axis(axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnVector3<0> &operator[](int axis) {
|
||||||
|
// We need to do a little pointer magic to get this to work, because the
|
||||||
|
// ColumnVector3 template takes the axis as a template parameter.
|
||||||
|
// Don't touch this unless you're sure what you're doing!
|
||||||
|
return (reinterpret_cast<Basis *>(reinterpret_cast<real_t *>(this) + axis))->x;
|
||||||
|
}
|
||||||
|
|
||||||
void invert();
|
void invert();
|
||||||
|
|
||||||
@@ -59,6 +348,8 @@ public:
|
|||||||
|
|
||||||
Vector3 get_scale() const;
|
Vector3 get_scale() const;
|
||||||
|
|
||||||
|
Basis slerp(Basis b, float t) const;
|
||||||
|
|
||||||
Vector3 get_euler_xyz() const;
|
Vector3 get_euler_xyz() const;
|
||||||
void set_euler_xyz(const Vector3 &p_euler);
|
void set_euler_xyz(const Vector3 &p_euler);
|
||||||
Vector3 get_euler_yxz() const;
|
Vector3 get_euler_yxz() const;
|
||||||
|
|||||||
@@ -32,8 +32,26 @@ public:
|
|||||||
|
|
||||||
uint32_t to_ARGB32() const;
|
uint32_t to_ARGB32() const;
|
||||||
|
|
||||||
|
uint32_t to_ABGR32() const;
|
||||||
|
|
||||||
|
uint64_t to_ABGR64() const;
|
||||||
|
|
||||||
|
uint64_t to_ARGB64() const;
|
||||||
|
|
||||||
|
uint32_t to_RGBA32() const;
|
||||||
|
|
||||||
|
uint64_t to_RGBA64() const;
|
||||||
|
|
||||||
float gray() const;
|
float gray() const;
|
||||||
|
|
||||||
|
uint8_t get_r8() const;
|
||||||
|
|
||||||
|
uint8_t get_g8() const;
|
||||||
|
|
||||||
|
uint8_t get_b8() const;
|
||||||
|
|
||||||
|
uint8_t get_a8() const;
|
||||||
|
|
||||||
float get_h() const;
|
float get_h() const;
|
||||||
|
|
||||||
float get_s() const;
|
float get_s() const;
|
||||||
@@ -42,6 +60,12 @@ public:
|
|||||||
|
|
||||||
void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
|
void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0);
|
||||||
|
|
||||||
|
Color darkened(const float amount) const;
|
||||||
|
|
||||||
|
Color lightened(const float amount) const;
|
||||||
|
|
||||||
|
Color from_hsv(float p_h, float p_s, float p_v, float p_a = 1.0) const;
|
||||||
|
|
||||||
inline float &operator[](int idx) {
|
inline float &operator[](int idx) {
|
||||||
return components[idx];
|
return components[idx];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,45 +57,9 @@ enum class Error {
|
|||||||
ERR_WTF = ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
|
ERR_WTF = ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace helpers {
|
|
||||||
template <typename T, typename ValueT>
|
|
||||||
T append_all(T appendable, ValueT value) {
|
|
||||||
appendable.append(value);
|
|
||||||
return appendable;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename ValueT, typename... Args>
|
|
||||||
T append_all(T appendable, ValueT value, Args... args) {
|
|
||||||
appendable.append(value);
|
|
||||||
return append_all(appendable, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T append_all(T appendable) {
|
|
||||||
return appendable;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename KV, typename KeyT, typename ValueT>
|
|
||||||
KV add_all(KV kv, KeyT key, ValueT value) {
|
|
||||||
kv[key] = value;
|
|
||||||
return kv;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename KV, typename KeyT, typename ValueT, typename... Args>
|
|
||||||
KV add_all(KV kv, KeyT key, ValueT value, Args... args) {
|
|
||||||
kv[key] = value;
|
|
||||||
return add_all(kv, args...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename KV>
|
|
||||||
KV add_all(KV kv) {
|
|
||||||
return kv;
|
|
||||||
}
|
|
||||||
} // namespace helpers
|
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <GodotGlobal.hpp>
|
||||||
|
|
||||||
typedef float real_t;
|
typedef float real_t;
|
||||||
|
|
||||||
@@ -106,11 +70,28 @@ typedef float real_t;
|
|||||||
#define _PLANE_EQ_DOT_EPSILON 0.999
|
#define _PLANE_EQ_DOT_EPSILON 0.999
|
||||||
#define _PLANE_EQ_D_EPSILON 0.0001
|
#define _PLANE_EQ_D_EPSILON 0.0001
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
|
#else
|
||||||
|
#define likely(x) x
|
||||||
|
#define unlikely(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Don't use this directly; instead, use any of the CRASH_* macros
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define GENERATE_TRAP \
|
||||||
|
__debugbreak(); \
|
||||||
|
/* Avoid warning about control paths */ \
|
||||||
|
for (;;) { \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define GENERATE_TRAP __builtin_trap();
|
||||||
|
#endif
|
||||||
|
|
||||||
// ERR/WARN macros
|
// ERR/WARN macros
|
||||||
#ifndef WARN_PRINT
|
#ifndef WARN_PRINT
|
||||||
#define WARN_PRINT(msg) \
|
#define WARN_PRINT(msg) godot::Godot::print_warning(msg, __func__, __FILE__, __LINE__)
|
||||||
fprintf(stdout, "ERROR: %s\n", msg); \
|
|
||||||
fflush(stdout)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WARN_PRINTS
|
#ifndef WARN_PRINTS
|
||||||
@@ -118,62 +99,160 @@ typedef float real_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_PRINT
|
#ifndef ERR_PRINT
|
||||||
#define ERR_PRINT(x) fprintf(stderr, "ERROR: %s\n", x)
|
#define ERR_PRINT(msg) godot::Godot::print_error(msg, __func__, __FILE__, __LINE__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_PRINTS
|
#ifndef ERR_PRINTS
|
||||||
#define ERR_PRINTS(msg) ERR_PRINT((msg).utf8().get_data())
|
#define ERR_PRINTS(msg) ERR_PRINT((msg).utf8().get_data())
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL
|
#ifndef FATAL_PRINT
|
||||||
#define ERR_FAIL() ERR_PRINT("Failed")
|
#define FATAL_PRINT(msg) ERR_PRINT(godot::String("FATAL: ") + (msg))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL_V
|
#ifndef ERR_MSG_INDEX
|
||||||
#define ERR_FAIL_V(a) \
|
#define ERR_MSG_INDEX(index, size) (godot::String("Index ") + #index + "=" + godot::String::num_int64(index) + " out of size (" + #size + "=" + godot::String::num_int64(size) + ")")
|
||||||
{ \
|
|
||||||
ERR_FAIL(); \
|
|
||||||
return a; \
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL_COND
|
#ifndef ERR_MSG_NULL
|
||||||
#define ERR_FAIL_COND(a) \
|
#define ERR_MSG_NULL(param) (godot::String("Parameter '") + #param + "' is null.")
|
||||||
do { \
|
|
||||||
if (a) { \
|
|
||||||
ERR_PRINT(#a); \
|
|
||||||
return; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL_COND_V
|
#ifndef ERR_MSG_COND
|
||||||
#define ERR_FAIL_COND_V(cond, ret) \
|
#define ERR_MSG_COND(cond) (godot::String("Condition '") + #cond + "' is true.")
|
||||||
do { \
|
|
||||||
if (cond) { \
|
|
||||||
ERR_PRINT(#cond); \
|
|
||||||
return ret; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL_INDEX
|
#ifndef ERR_FAIL_INDEX
|
||||||
#define ERR_FAIL_INDEX(a, b) \
|
#define ERR_FAIL_INDEX(index, size) \
|
||||||
do { \
|
do { \
|
||||||
if (a < 0 || a >= b) { \
|
if (unlikely((index) < 0 || (index) >= (size))) { \
|
||||||
ERR_FAIL(); \
|
ERR_PRINT(ERR_MSG_INDEX(index, size)); \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ERR_FAIL_INDEX_V
|
#ifndef ERR_FAIL_INDEX_V
|
||||||
#define ERR_FAIL_INDEX_V(a, b, c) \
|
#define ERR_FAIL_INDEX_V(index, size, ret) \
|
||||||
do { \
|
do { \
|
||||||
if (a < 0 || a >= b) { \
|
if (unlikely((index) < 0 || (index) >= (size))) { \
|
||||||
ERR_FAIL(); \
|
ERR_PRINT(ERR_MSG_INDEX(index, size)); \
|
||||||
return c; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL_UNSIGNED_INDEX_V
|
||||||
|
#define ERR_FAIL_UNSIGNED_INDEX_V(index, size, ret) \
|
||||||
|
do { \
|
||||||
|
if (unlikely((index) >= (size))) { \
|
||||||
|
ERR_PRINT(ERR_MSG_INDEX(index, size)); \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRASH_BAD_INDEX
|
||||||
|
#define CRASH_BAD_INDEX(index, size) \
|
||||||
|
do { \
|
||||||
|
if (unlikely((index) < 0 || (index) >= (size))) { \
|
||||||
|
FATAL_PRINT(ERR_MSG_INDEX(index, size)); \
|
||||||
|
GENERATE_TRAP; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL_NULL
|
||||||
|
#define ERR_FAIL_NULL(param) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(!param)) { \
|
||||||
|
ERR_PRINT(ERR_MSG_NULL(param)); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL_NULL_V
|
||||||
|
#define ERR_FAIL_NULL_V(param, ret) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(!param)) { \
|
||||||
|
ERR_PRINT(ERR_MSG_NULL(param)); \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL_COND
|
||||||
|
#define ERR_FAIL_COND(cond) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(cond)) { \
|
||||||
|
ERR_PRINT(ERR_MSG_COND(cond)); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRASH_COND
|
||||||
|
#define CRASH_COND(cond) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(cond)) { \
|
||||||
|
FATAL_PRINT(ERR_MSG_COND(cond)); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL_COND_V
|
||||||
|
#define ERR_FAIL_COND_V(cond, ret) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(cond)) { \
|
||||||
|
ERR_PRINT(ERR_MSG_COND(cond)); \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_CONTINUE
|
||||||
|
#define ERR_CONTINUE(cond) \
|
||||||
|
{ \
|
||||||
|
if (unlikely(cond)) { \
|
||||||
|
ERR_PRINT(ERR_MSG_COND(cond)); \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_BREAK
|
||||||
|
#define ERR_BREAK(cond) \
|
||||||
|
{ \
|
||||||
|
if (unlikely(cond)) { \
|
||||||
|
ERR_PRINT(ERR_MSG_COND(cond)); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL
|
||||||
|
#define ERR_FAIL() \
|
||||||
|
do { \
|
||||||
|
ERR_PRINT("Method/Function Failed."); \
|
||||||
|
return; \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ERR_FAIL_V
|
||||||
|
#define ERR_FAIL_V(ret) \
|
||||||
|
do { \
|
||||||
|
ERR_PRINT("Method/Function Failed."); \
|
||||||
|
return ret; \
|
||||||
|
} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CRASH_NOW
|
||||||
|
#define CRASH_NOW() \
|
||||||
|
do { \
|
||||||
|
FATAL_PRINT("Method/Function Failed."); \
|
||||||
|
GENERATE_TRAP; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ public:
|
|||||||
Name *instance = godot::as<Name>(script->new_()); \
|
Name *instance = godot::as<Name>(script->new_()); \
|
||||||
return instance; \
|
return instance; \
|
||||||
} \
|
} \
|
||||||
inline static size_t ___get_id() { return typeid(Name).hash_code(); }; \
|
inline static size_t ___get_id() { return typeid(Name).hash_code(); } \
|
||||||
inline static size_t ___get_base_id() { return typeid(Base).hash_code(); }; \
|
inline static size_t ___get_base_id() { return typeid(Base).hash_code(); } \
|
||||||
inline static const char *___get_base_type_name() { return Base::___get_class_name(); } \
|
inline static const char *___get_base_type_name() { return Base::___get_class_name(); } \
|
||||||
inline static Object *___get_from_variant(godot::Variant a) { return (godot::Object *)godot::as<Name>(godot::Object::___get_from_variant(a)); } \
|
inline static Object *___get_from_variant(godot::Variant a) { return (godot::Object *)godot::as<Name>(godot::Object::___get_from_variant(a)); } \
|
||||||
\
|
\
|
||||||
@@ -326,8 +326,13 @@ void register_property(const char *name, P(T::*var), P default_value, godot_meth
|
|||||||
godot_string *_hint_string = (godot_string *)&hint_string;
|
godot_string *_hint_string = (godot_string *)&hint_string;
|
||||||
|
|
||||||
godot_property_attributes attr = {};
|
godot_property_attributes attr = {};
|
||||||
attr.type = def_val.get_type();
|
if (def_val.get_type() == Variant::NIL) {
|
||||||
attr.default_value = *(godot_variant *)&def_val;
|
attr.type = Variant::OBJECT;
|
||||||
|
} else {
|
||||||
|
attr.type = def_val.get_type();
|
||||||
|
attr.default_value = *(godot_variant *)&def_val;
|
||||||
|
}
|
||||||
|
|
||||||
attr.hint = hint;
|
attr.hint = hint;
|
||||||
attr.rset_type = rpc_mode;
|
attr.rset_type = rpc_mode;
|
||||||
attr.usage = usage;
|
attr.usage = usage;
|
||||||
@@ -356,12 +361,19 @@ template <class T, class P>
|
|||||||
void register_property(const char *name, void (T::*setter)(P), P (T::*getter)(), P default_value, godot_method_rpc_mode rpc_mode = GODOT_METHOD_RPC_MODE_DISABLED, godot_property_usage_flags usage = GODOT_PROPERTY_USAGE_DEFAULT, godot_property_hint hint = GODOT_PROPERTY_HINT_NONE, String hint_string = "") {
|
void register_property(const char *name, void (T::*setter)(P), P (T::*getter)(), P default_value, godot_method_rpc_mode rpc_mode = GODOT_METHOD_RPC_MODE_DISABLED, godot_property_usage_flags usage = GODOT_PROPERTY_USAGE_DEFAULT, godot_property_hint hint = GODOT_PROPERTY_HINT_NONE, String hint_string = "") {
|
||||||
Variant def_val = default_value;
|
Variant def_val = default_value;
|
||||||
|
|
||||||
|
godot_string *_hint_string = (godot_string *)&hint_string;
|
||||||
|
|
||||||
godot_property_attributes attr = {};
|
godot_property_attributes attr = {};
|
||||||
attr.type = def_val.get_type();
|
if (def_val.get_type() == Variant::NIL) {
|
||||||
attr.default_value = *(godot_variant *)&def_val;
|
attr.type = Variant::OBJECT;
|
||||||
|
} else {
|
||||||
|
attr.type = def_val.get_type();
|
||||||
|
attr.default_value = *(godot_variant *)&def_val;
|
||||||
|
}
|
||||||
attr.hint = hint;
|
attr.hint = hint;
|
||||||
attr.rset_type = rpc_mode;
|
attr.rset_type = rpc_mode;
|
||||||
attr.usage = usage;
|
attr.usage = usage;
|
||||||
|
attr.hint_string = *_hint_string;
|
||||||
|
|
||||||
_PropertySetFunc<T, P> *wrapped_set = (_PropertySetFunc<T, P> *)godot::api->godot_alloc(sizeof(_PropertySetFunc<T, P>));
|
_PropertySetFunc<T, P> *wrapped_set = (_PropertySetFunc<T, P> *)godot::api->godot_alloc(sizeof(_PropertySetFunc<T, P>));
|
||||||
wrapped_set->f = setter;
|
wrapped_set->f = setter;
|
||||||
|
|||||||
@@ -8,8 +8,17 @@
|
|||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
extern "C" const godot_gdnative_core_api_struct *api;
|
extern "C" const godot_gdnative_core_api_struct *api;
|
||||||
|
extern "C" const godot_gdnative_core_1_1_api_struct *core_1_1_api;
|
||||||
|
extern "C" const godot_gdnative_core_1_2_api_struct *core_1_2_api;
|
||||||
|
|
||||||
extern "C" const godot_gdnative_ext_nativescript_api_struct *nativescript_api;
|
extern "C" const godot_gdnative_ext_nativescript_api_struct *nativescript_api;
|
||||||
extern "C" const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api;
|
extern "C" const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api;
|
||||||
|
extern "C" const godot_gdnative_ext_pluginscript_api_struct *pluginscript_api;
|
||||||
|
extern "C" const godot_gdnative_ext_android_api_struct *android_api;
|
||||||
|
extern "C" const godot_gdnative_ext_arvr_api_struct *arvr_api;
|
||||||
|
extern "C" const godot_gdnative_ext_videodecoder_api_struct *videodecoder_api;
|
||||||
|
extern "C" const godot_gdnative_ext_net_api_struct *net_api;
|
||||||
|
extern "C" const godot_gdnative_ext_net_3_2_api_struct *net_3_2_api;
|
||||||
|
|
||||||
extern "C" const void *gdnlib;
|
extern "C" const void *gdnlib;
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ public:
|
|||||||
|
|
||||||
bool is_empty() const;
|
bool is_empty() const;
|
||||||
|
|
||||||
|
NodePath get_as_property_path() const;
|
||||||
|
|
||||||
|
String get_concatenated_subnames() const;
|
||||||
|
|
||||||
operator String() const;
|
operator String() const;
|
||||||
|
|
||||||
void operator=(const NodePath &other);
|
void operator=(const NodePath &other);
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ public:
|
|||||||
|
|
||||||
Quat normalized() const;
|
Quat normalized() const;
|
||||||
|
|
||||||
|
bool is_normalized() const;
|
||||||
|
|
||||||
Quat inverse() const;
|
Quat inverse() const;
|
||||||
|
|
||||||
void set_euler_xyz(const Vector3 &p_euler);
|
void set_euler_xyz(const Vector3 &p_euler);
|
||||||
@@ -40,6 +42,8 @@ public:
|
|||||||
|
|
||||||
void get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const;
|
void get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const;
|
||||||
|
|
||||||
|
void set_axis_angle(const Vector3 &axis, const float angle);
|
||||||
|
|
||||||
void operator*=(const Quat &q);
|
void operator*=(const Quat &q);
|
||||||
Quat operator*(const Quat &q) const;
|
Quat operator*(const Quat &q) const;
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,11 @@ public:
|
|||||||
signed char casecmp_to(String p_str) const;
|
signed char casecmp_to(String p_str) const;
|
||||||
signed char nocasecmp_to(String p_str) const;
|
signed char nocasecmp_to(String p_str) const;
|
||||||
signed char naturalnocasecmp_to(String p_str) const;
|
signed char naturalnocasecmp_to(String p_str) const;
|
||||||
|
String dedent() const;
|
||||||
|
PoolStringArray rsplit(const String &divisor, const bool allow_empty = true, const int maxsplit = 0) const;
|
||||||
|
String rstrip(const String &chars) const;
|
||||||
|
String trim_prefix(const String &prefix) const;
|
||||||
|
String trim_suffix(const String &suffix) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
String operator+(const char *a, const String &b);
|
String operator+(const char *a, const String &b);
|
||||||
|
|||||||
@@ -58,6 +58,13 @@ public:
|
|||||||
void operator*=(const Transform &p_transform);
|
void operator*=(const Transform &p_transform);
|
||||||
Transform operator*(const Transform &p_transform) const;
|
Transform operator*(const Transform &p_transform) const;
|
||||||
|
|
||||||
|
inline Vector3 operator*(const Vector3 &p_vector) const {
|
||||||
|
return Vector3(
|
||||||
|
basis.elements[0].dot(p_vector) + origin.x,
|
||||||
|
basis.elements[1].dot(p_vector) + origin.y,
|
||||||
|
basis.elements[2].dot(p_vector) + origin.z);
|
||||||
|
}
|
||||||
|
|
||||||
Transform interpolate_with(const Transform &p_transform, real_t p_c) const;
|
Transform interpolate_with(const Transform &p_transform, real_t p_c) const;
|
||||||
|
|
||||||
Transform inverse_xform(const Transform &t) const;
|
Transform inverse_xform(const Transform &t) const;
|
||||||
|
|||||||
@@ -226,6 +226,7 @@ public:
|
|||||||
operator NodePath() const;
|
operator NodePath() const;
|
||||||
operator RID() const;
|
operator RID() const;
|
||||||
operator godot_object *() const;
|
operator godot_object *() const;
|
||||||
|
template <typename T> operator T*() const { return static_cast<T*>(T::___get_from_variant(*this)); }
|
||||||
|
|
||||||
operator Dictionary() const;
|
operator Dictionary() const;
|
||||||
operator Array() const;
|
operator Array() const;
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "Defs.hpp"
|
#include "Defs.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
class String;
|
class String;
|
||||||
@@ -20,36 +22,75 @@ struct Vector2 {
|
|||||||
real_t height;
|
real_t height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline Vector2(real_t p_x, real_t p_y) {
|
||||||
|
x = p_x;
|
||||||
|
y = p_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2() {
|
||||||
|
x = 0;
|
||||||
|
y = 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline real_t &operator[](int p_idx) {
|
inline real_t &operator[](int p_idx) {
|
||||||
return p_idx ? y : x;
|
return p_idx ? y : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const real_t &operator[](int p_idx) const {
|
inline const real_t &operator[](int p_idx) const {
|
||||||
return p_idx ? y : x;
|
return p_idx ? y : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 operator+(const Vector2 &p_v) const;
|
inline Vector2 operator+(const Vector2 &p_v) const {
|
||||||
|
return Vector2(x + p_v.x, y + p_v.y);
|
||||||
|
}
|
||||||
|
|
||||||
void operator+=(const Vector2 &p_v);
|
inline void operator+=(const Vector2 &p_v) {
|
||||||
|
x += p_v.x;
|
||||||
|
y += p_v.y;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 operator-(const Vector2 &p_v) const;
|
inline Vector2 operator-(const Vector2 &p_v) const {
|
||||||
|
return Vector2(x - p_v.x, y - p_v.y);
|
||||||
|
}
|
||||||
|
|
||||||
void operator-=(const Vector2 &p_v);
|
inline void operator-=(const Vector2 &p_v) {
|
||||||
|
x -= p_v.x;
|
||||||
|
y -= p_v.y;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 operator*(const Vector2 &p_v1) const;
|
inline Vector2 operator*(const Vector2 &p_v1) const {
|
||||||
|
return Vector2(x * p_v1.x, y * p_v1.y);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 operator*(const real_t &rvalue) const;
|
inline Vector2 operator*(const real_t &rvalue) const {
|
||||||
|
return Vector2(x * rvalue, y * rvalue);
|
||||||
|
}
|
||||||
|
|
||||||
void operator*=(const real_t &rvalue);
|
inline void operator*=(const real_t &rvalue) {
|
||||||
|
x *= rvalue;
|
||||||
|
y *= rvalue;
|
||||||
|
}
|
||||||
|
|
||||||
inline void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
|
inline void operator*=(const Vector2 &rvalue) {
|
||||||
|
*this = *this * rvalue;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 operator/(const Vector2 &p_v1) const;
|
inline Vector2 operator/(const Vector2 &p_v1) const {
|
||||||
|
return Vector2(x / p_v1.x, y / p_v1.y);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 operator/(const real_t &rvalue) const;
|
inline Vector2 operator/(const real_t &rvalue) const {
|
||||||
|
return Vector2(x / rvalue, y / rvalue);
|
||||||
|
}
|
||||||
|
|
||||||
void operator/=(const real_t &rvalue);
|
inline void operator/=(const real_t &rvalue) {
|
||||||
|
x /= rvalue;
|
||||||
|
y /= rvalue;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 operator-() const;
|
inline Vector2 operator-() const {
|
||||||
|
return Vector2(-x, -y);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const Vector2 &p_vec2) const;
|
bool operator==(const Vector2 &p_vec2) const;
|
||||||
|
|
||||||
@@ -58,23 +99,56 @@ struct Vector2 {
|
|||||||
inline bool operator<(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
|
inline bool operator<(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
|
||||||
inline bool operator<=(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y <= p_vec2.y) : (x <= p_vec2.x); }
|
inline bool operator<=(const Vector2 &p_vec2) const { return (x == p_vec2.x) ? (y <= p_vec2.y) : (x <= p_vec2.x); }
|
||||||
|
|
||||||
void normalize();
|
inline void normalize() {
|
||||||
|
real_t l = x * x + y * y;
|
||||||
|
if (l != 0) {
|
||||||
|
l = sqrt(l);
|
||||||
|
x /= l;
|
||||||
|
y /= l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 normalized() const;
|
inline Vector2 normalized() const {
|
||||||
|
Vector2 v = *this;
|
||||||
|
v.normalize();
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
real_t length() const;
|
inline real_t length() const {
|
||||||
real_t length_squared() const;
|
return sqrt(x * x + y * y);
|
||||||
|
}
|
||||||
|
|
||||||
real_t distance_to(const Vector2 &p_vector2) const;
|
inline real_t length_squared() const {
|
||||||
real_t distance_squared_to(const Vector2 &p_vector2) const;
|
return x * x + y * y;
|
||||||
|
}
|
||||||
|
|
||||||
real_t angle_to(const Vector2 &p_vector2) const;
|
inline real_t distance_to(const Vector2 &p_vector2) const {
|
||||||
real_t angle_to_point(const Vector2 &p_vector2) const;
|
return sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y));
|
||||||
|
}
|
||||||
|
|
||||||
real_t dot(const Vector2 &p_other) const;
|
inline real_t distance_squared_to(const Vector2 &p_vector2) const {
|
||||||
|
return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y);
|
||||||
|
}
|
||||||
|
|
||||||
real_t cross(const Vector2 &p_other) const;
|
inline real_t angle_to(const Vector2 &p_vector2) const {
|
||||||
Vector2 cross(real_t p_other) const;
|
return atan2(cross(p_vector2), dot(p_vector2));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t angle_to_point(const Vector2 &p_vector2) const {
|
||||||
|
return atan2(y - p_vector2.y, x - p_vector2.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t dot(const Vector2 &p_other) const {
|
||||||
|
return x * p_other.x + y * p_other.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline real_t cross(const Vector2 &p_other) const {
|
||||||
|
return x * p_other.y - y * p_other.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 cross(real_t p_other) const {
|
||||||
|
return Vector2(p_other * y, -p_other * x);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 project(const Vector2 &p_vec) const;
|
Vector2 project(const Vector2 &p_vec) const;
|
||||||
|
|
||||||
@@ -82,39 +156,71 @@ struct Vector2 {
|
|||||||
|
|
||||||
Vector2 clamped(real_t p_len) const;
|
Vector2 clamped(real_t p_len) const;
|
||||||
|
|
||||||
static Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t);
|
static inline Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t) {
|
||||||
|
Vector2 res = p_a;
|
||||||
|
res.x += (p_t * (p_b.x - p_a.x));
|
||||||
|
res.y += (p_t * (p_b.y - p_a.y));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 linear_interpolate(const Vector2 &p_b, real_t p_t) const {
|
||||||
|
Vector2 res = *this;
|
||||||
|
res.x += (p_t * (p_b.x - x));
|
||||||
|
res.y += (p_t * (p_b.y - y));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 linear_interpolate(const Vector2 &p_b, real_t p_t) const;
|
|
||||||
Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const;
|
Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const;
|
||||||
|
|
||||||
Vector2 slide(const Vector2 &p_vec) const;
|
inline Vector2 slide(const Vector2 &p_vec) const {
|
||||||
|
return p_vec - *this * this->dot(p_vec);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 reflect(const Vector2 &p_vec) const;
|
inline Vector2 bounce(const Vector2 &p_normal) const {
|
||||||
|
return -reflect(p_normal);
|
||||||
|
}
|
||||||
|
|
||||||
real_t angle() const;
|
inline Vector2 reflect(const Vector2 &p_vec) const {
|
||||||
|
return p_vec - *this * this->dot(p_vec) * 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
void set_rotation(real_t p_radians);
|
inline real_t angle() const {
|
||||||
|
return atan2(y, x);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 abs() const;
|
inline void set_rotation(real_t p_radians) {
|
||||||
Vector2 rotated(real_t p_by) const;
|
x = cosf(p_radians);
|
||||||
|
y = sinf(p_radians);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 tangent() const;
|
inline Vector2 abs() const {
|
||||||
|
return Vector2(fabs(x), fabs(y));
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 floor() const;
|
inline Vector2 rotated(real_t p_by) const {
|
||||||
|
Vector2 v;
|
||||||
|
v.set_rotation(angle() + p_by);
|
||||||
|
v *= length();
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 tangent() const {
|
||||||
|
return Vector2(y, -x);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 floor() const {
|
||||||
|
return Vector2(::floor(x), ::floor(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector2 snapped(const Vector2 &p_by) const {
|
||||||
|
return Vector2(
|
||||||
|
p_by.x != 0 ? ::floor(x / p_by.x + 0.5) * p_by.x : x,
|
||||||
|
p_by.y != 0 ? ::floor(y / p_by.y + 0.5) * p_by.y : y);
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 snapped(const Vector2 &p_by) const;
|
|
||||||
inline real_t aspect() const { return width / height; }
|
inline real_t aspect() const { return width / height; }
|
||||||
|
|
||||||
operator String() const;
|
operator String() const;
|
||||||
|
|
||||||
inline Vector2(real_t p_x, real_t p_y) {
|
|
||||||
x = p_x;
|
|
||||||
y = p_y;
|
|
||||||
}
|
|
||||||
inline Vector2() {
|
|
||||||
x = 0;
|
|
||||||
y = 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) {
|
inline Vector2 operator*(real_t p_scalar, const Vector2 &p_vec) {
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
#ifndef VECTOR3_H
|
#ifndef VECTOR3_H
|
||||||
#define VECTOR3_H
|
#define VECTOR3_H
|
||||||
|
|
||||||
|
#include <gdnative/vector3.h>
|
||||||
|
|
||||||
#include "Defs.hpp"
|
#include "Defs.hpp"
|
||||||
|
|
||||||
#include "String.hpp"
|
#include "String.hpp"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
class Basis;
|
class Basis;
|
||||||
@@ -24,80 +28,192 @@ struct Vector3 {
|
|||||||
real_t z;
|
real_t z;
|
||||||
};
|
};
|
||||||
|
|
||||||
real_t coord[3];
|
real_t coord[3]; // Not for direct access, use [] operator instead
|
||||||
};
|
};
|
||||||
|
|
||||||
Vector3(real_t x, real_t y, real_t z);
|
inline Vector3(real_t x, real_t y, real_t z) {
|
||||||
|
this->x = x;
|
||||||
|
this->y = y;
|
||||||
|
this->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3();
|
inline Vector3() {
|
||||||
|
this->x = 0;
|
||||||
|
this->y = 0;
|
||||||
|
this->z = 0;
|
||||||
|
}
|
||||||
|
|
||||||
const real_t &operator[](int p_axis) const;
|
inline const real_t &operator[](int p_axis) const {
|
||||||
|
return coord[p_axis];
|
||||||
|
}
|
||||||
|
|
||||||
real_t &operator[](int p_axis);
|
inline real_t &operator[](int p_axis) {
|
||||||
|
return coord[p_axis];
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 &operator+=(const Vector3 &p_v);
|
inline Vector3 &operator+=(const Vector3 &p_v) {
|
||||||
|
x += p_v.x;
|
||||||
|
y += p_v.y;
|
||||||
|
z += p_v.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 operator+(const Vector3 &p_v) const;
|
inline Vector3 operator+(const Vector3 &p_v) const {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v += p_v;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 &operator-=(const Vector3 &p_v);
|
inline Vector3 &operator-=(const Vector3 &p_v) {
|
||||||
|
x -= p_v.x;
|
||||||
|
y -= p_v.y;
|
||||||
|
z -= p_v.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 operator-(const Vector3 &p_v) const;
|
inline Vector3 operator-(const Vector3 &p_v) const {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v -= p_v;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 &operator*=(const Vector3 &p_v);
|
inline Vector3 &operator*=(const Vector3 &p_v) {
|
||||||
|
x *= p_v.x;
|
||||||
|
y *= p_v.y;
|
||||||
|
z *= p_v.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 operator*(const Vector3 &p_v) const;
|
inline Vector3 operator*(const Vector3 &p_v) const {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v *= p_v;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 &operator/=(const Vector3 &p_v);
|
inline Vector3 &operator/=(const Vector3 &p_v) {
|
||||||
|
x /= p_v.x;
|
||||||
|
y /= p_v.y;
|
||||||
|
z /= p_v.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 operator/(const Vector3 &p_v) const;
|
inline Vector3 operator/(const Vector3 &p_v) const {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v /= p_v;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 &operator*=(real_t p_scalar);
|
inline Vector3 &operator*=(real_t p_scalar) {
|
||||||
|
*this *= Vector3(p_scalar, p_scalar, p_scalar);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 operator*(real_t p_scalar) const;
|
inline Vector3 operator*(real_t p_scalar) const {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v *= p_scalar;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 &operator/=(real_t p_scalar);
|
inline Vector3 &operator/=(real_t p_scalar) {
|
||||||
|
*this /= Vector3(p_scalar, p_scalar, p_scalar);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 operator/(real_t p_scalar) const;
|
inline Vector3 operator/(real_t p_scalar) const {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v /= p_scalar;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 operator-() const;
|
inline Vector3 operator-() const {
|
||||||
|
return Vector3(-x, -y, -z);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const Vector3 &p_v) const;
|
inline bool operator==(const Vector3 &p_v) const {
|
||||||
|
return (x == p_v.x && y == p_v.y && z == p_v.z);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator!=(const Vector3 &p_v) const;
|
inline bool operator!=(const Vector3 &p_v) const {
|
||||||
|
return (x != p_v.x || y != p_v.y || z != p_v.z);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator<(const Vector3 &p_v) const;
|
bool operator<(const Vector3 &p_v) const;
|
||||||
|
|
||||||
bool operator<=(const Vector3 &p_v) const;
|
bool operator<=(const Vector3 &p_v) const;
|
||||||
|
|
||||||
Vector3 abs() const;
|
inline Vector3 abs() const {
|
||||||
|
return Vector3(::fabs(x), ::fabs(y), ::fabs(z));
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 ceil() const;
|
inline Vector3 ceil() const {
|
||||||
|
return Vector3(::ceil(x), ::ceil(y), ::ceil(z));
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 cross(const Vector3 &b) const;
|
inline Vector3 cross(const Vector3 &b) const {
|
||||||
|
Vector3 ret(
|
||||||
|
(y * b.z) - (z * b.y),
|
||||||
|
(z * b.x) - (x * b.z),
|
||||||
|
(x * b.y) - (y * b.x));
|
||||||
|
|
||||||
Vector3 linear_interpolate(const Vector3 &p_b, real_t p_t) const;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 linear_interpolate(const Vector3 &p_b, real_t p_t) const {
|
||||||
|
return Vector3(
|
||||||
|
x + (p_t * (p_b.x - x)),
|
||||||
|
y + (p_t * (p_b.y - y)),
|
||||||
|
z + (p_t * (p_b.z - z)));
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const;
|
Vector3 cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const;
|
||||||
|
|
||||||
Vector3 bounce(const Vector3 &p_normal) const;
|
Vector3 bounce(const Vector3 &p_normal) const {
|
||||||
|
return -reflect(p_normal);
|
||||||
|
}
|
||||||
|
|
||||||
real_t length() const;
|
inline real_t length() const {
|
||||||
|
real_t x2 = x * x;
|
||||||
|
real_t y2 = y * y;
|
||||||
|
real_t z2 = z * z;
|
||||||
|
|
||||||
real_t length_squared() const;
|
return ::sqrt(x2 + y2 + z2);
|
||||||
|
}
|
||||||
|
|
||||||
real_t distance_squared_to(const Vector3 &b) const;
|
inline real_t length_squared() const {
|
||||||
|
real_t x2 = x * x;
|
||||||
|
real_t y2 = y * y;
|
||||||
|
real_t z2 = z * z;
|
||||||
|
|
||||||
real_t distance_to(const Vector3 &b) const;
|
return x2 + y2 + z2;
|
||||||
|
}
|
||||||
|
|
||||||
real_t dot(const Vector3 &b) const;
|
inline real_t distance_squared_to(const Vector3 &b) const {
|
||||||
|
return (b - *this).length_squared();
|
||||||
|
}
|
||||||
|
|
||||||
real_t angle_to(const Vector3 &b) const;
|
inline real_t distance_to(const Vector3 &b) const {
|
||||||
|
return (b - *this).length();
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 floor() const;
|
inline real_t dot(const Vector3 &b) const {
|
||||||
|
return x * b.x + y * b.y + z * b.z;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 inverse() const;
|
inline real_t angle_to(const Vector3 &b) const {
|
||||||
|
return std::atan2(cross(b).length(), dot(b));
|
||||||
|
}
|
||||||
|
|
||||||
bool is_normalized() const;
|
inline Vector3 floor() const {
|
||||||
|
return Vector3(::floor(x), ::floor(y), ::floor(z));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Vector3 inverse() const {
|
||||||
|
return Vector3(1.f / x, 1.f / y, 1.f / z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool is_normalized() const {
|
||||||
|
return std::abs(length_squared() - 1.f) < 0.00001f;
|
||||||
|
}
|
||||||
|
|
||||||
Basis outer(const Vector3 &b) const;
|
Basis outer(const Vector3 &b) const;
|
||||||
|
|
||||||
@@ -105,21 +221,46 @@ struct Vector3 {
|
|||||||
|
|
||||||
int min_axis() const;
|
int min_axis() const;
|
||||||
|
|
||||||
void normalize();
|
inline void normalize() {
|
||||||
|
real_t l = length();
|
||||||
|
if (l == 0) {
|
||||||
|
x = y = z = 0;
|
||||||
|
} else {
|
||||||
|
x /= l;
|
||||||
|
y /= l;
|
||||||
|
z /= l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 normalized() const;
|
inline Vector3 normalized() const {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v.normalize();
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 reflect(const Vector3 &by) const;
|
inline Vector3 reflect(const Vector3 &by) const {
|
||||||
|
return by - *this * this->dot(by) * 2.f;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 rotated(const Vector3 &axis, const real_t phi) const;
|
inline Vector3 rotated(const Vector3 &axis, const real_t phi) const {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v.rotate(axis, phi);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
void rotate(const Vector3 &p_axis, real_t p_phi);
|
void rotate(const Vector3 &p_axis, real_t p_phi);
|
||||||
|
|
||||||
Vector3 slide(const Vector3 &by) const;
|
inline Vector3 slide(const Vector3 &by) const {
|
||||||
|
return by - *this * this->dot(by);
|
||||||
|
}
|
||||||
|
|
||||||
void snap(real_t p_val);
|
void snap(real_t p_val);
|
||||||
|
|
||||||
Vector3 snapped(const float by);
|
inline Vector3 snapped(const float by) {
|
||||||
|
Vector3 v = *this;
|
||||||
|
v.snap(by);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
operator String() const;
|
operator String() const;
|
||||||
};
|
};
|
||||||
|
|||||||
40
misc/travis/clang-format.sh
Executable file
40
misc/travis/clang-format.sh
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
CLANG_FORMAT=clang-format-6.0
|
||||||
|
|
||||||
|
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
|
||||||
|
# Check the whole commit range against $TRAVIS_BRANCH, the base merge branch
|
||||||
|
# We could use $TRAVIS_COMMIT_RANGE but it doesn't play well with force pushes
|
||||||
|
RANGE="$(git rev-parse $TRAVIS_BRANCH) HEAD"
|
||||||
|
else
|
||||||
|
# Test only the last commit
|
||||||
|
RANGE=HEAD
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILES=$(git diff-tree --no-commit-id --name-only -r $RANGE | grep -v thirdparty/ | grep -E "\.(c|h|cpp|hpp|cc|hh|cxx|m|mm|inc|java|glsl)$")
|
||||||
|
echo "Checking files:\n$FILES"
|
||||||
|
|
||||||
|
# create a random filename to store our generated patch
|
||||||
|
prefix="static-check-clang-format"
|
||||||
|
suffix="$(date +%s)"
|
||||||
|
patch="/tmp/$prefix-$suffix.patch"
|
||||||
|
|
||||||
|
for file in $FILES; do
|
||||||
|
"$CLANG_FORMAT" -style=file "$file" | \
|
||||||
|
diff -u "$file" - | \
|
||||||
|
sed -e "1s|--- |--- a/|" -e "2s|+++ -|+++ b/$file|" >> "$patch"
|
||||||
|
done
|
||||||
|
|
||||||
|
# if no patch has been generated all is ok, clean up the file stub and exit
|
||||||
|
if [ ! -s "$patch" ] ; then
|
||||||
|
printf "Files in this commit comply with the clang-format rules.\n"
|
||||||
|
rm -f "$patch"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# a patch has been created, notify the user and exit
|
||||||
|
printf "\n*** The following differences were found between the code to commit "
|
||||||
|
printf "and the clang-format rules:\n\n"
|
||||||
|
cat "$patch"
|
||||||
|
printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
|
||||||
|
exit 1
|
||||||
@@ -158,6 +158,35 @@ void Array::sort_custom(Object *obj, const String &func) {
|
|||||||
godot::api->godot_array_sort_custom(&_godot_array, (godot_object *)obj, (godot_string *)&func);
|
godot::api->godot_array_sort_custom(&_godot_array, (godot_object *)obj, (godot_string *)&func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Array::bsearch(const Variant &value, const bool before) {
|
||||||
|
return godot::api->godot_array_bsearch(&_godot_array, (godot_variant *)&value, before);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Array::bsearch_custom(const Variant &value, const Object *obj,
|
||||||
|
const String &func, const bool before) {
|
||||||
|
return godot::api->godot_array_bsearch_custom(&_godot_array, (godot_variant *)&value,
|
||||||
|
(godot_object *)obj, (godot_string *)&func, before);
|
||||||
|
}
|
||||||
|
|
||||||
|
Array Array::duplicate(const bool deep) const {
|
||||||
|
godot_array arr = godot::core_1_1_api->godot_array_duplicate(&_godot_array, deep);
|
||||||
|
return *(Array *)&arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant Array::max() const {
|
||||||
|
godot_variant v = godot::core_1_1_api->godot_array_max(&_godot_array);
|
||||||
|
return *(Variant *)&v;
|
||||||
|
}
|
||||||
|
|
||||||
|
Variant Array::min() const {
|
||||||
|
godot_variant v = godot::core_1_1_api->godot_array_min(&_godot_array);
|
||||||
|
return *(Variant *)&v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Array::shuffle() {
|
||||||
|
godot::core_1_1_api->godot_array_shuffle(&_godot_array);
|
||||||
|
}
|
||||||
|
|
||||||
Array::~Array() {
|
Array::~Array() {
|
||||||
godot::api->godot_array_destroy(&_godot_array);
|
godot::api->godot_array_destroy(&_godot_array);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,15 +31,6 @@ Basis::Basis() {
|
|||||||
elements[2][2] = 1;
|
elements[2][2] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector3 &Basis::operator[](int axis) const {
|
|
||||||
|
|
||||||
return elements[axis];
|
|
||||||
}
|
|
||||||
Vector3 &Basis::operator[](int axis) {
|
|
||||||
|
|
||||||
return elements[axis];
|
|
||||||
}
|
|
||||||
|
|
||||||
#define cofac(row1, col1, row2, col2) \
|
#define cofac(row1, col1, row2, col2) \
|
||||||
(elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1])
|
(elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1])
|
||||||
|
|
||||||
@@ -158,6 +149,15 @@ Vector3 Basis::get_scale() const {
|
|||||||
Vector3(elements[0][2], elements[1][2], elements[2][2]).length());
|
Vector3(elements[0][2], elements[1][2], elements[2][2]).length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: implement this directly without using quaternions to make it more efficient
|
||||||
|
Basis Basis::slerp(Basis b, float t) const {
|
||||||
|
ERR_FAIL_COND_V(!is_rotation(), Basis());
|
||||||
|
ERR_FAIL_COND_V(!b.is_rotation(), Basis());
|
||||||
|
Quat from(*this);
|
||||||
|
Quat to(b);
|
||||||
|
return Basis(from.slerp(to, t));
|
||||||
|
}
|
||||||
|
|
||||||
// get_euler_xyz returns a vector containing the Euler angles in the format
|
// get_euler_xyz returns a vector containing the Euler angles in the format
|
||||||
// (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last
|
// (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last
|
||||||
// (following the convention they are commonly defined in the literature).
|
// (following the convention they are commonly defined in the literature).
|
||||||
|
|||||||
@@ -67,10 +67,86 @@ uint32_t Color::to_ARGB32() const {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Color::to_ABGR32() const {
|
||||||
|
uint32_t c = (uint8_t)(a * 255);
|
||||||
|
c <<= 8;
|
||||||
|
c |= (uint8_t)(b * 255);
|
||||||
|
c <<= 8;
|
||||||
|
c |= (uint8_t)(g * 255);
|
||||||
|
c <<= 8;
|
||||||
|
c |= (uint8_t)(r * 255);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Color::to_ABGR64() const {
|
||||||
|
uint64_t c = (uint16_t)(a * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(b * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(g * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(r * 65535);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Color::to_ARGB64() const {
|
||||||
|
uint64_t c = (uint16_t)(a * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(r * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(g * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(b * 65535);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Color::to_RGBA32() const {
|
||||||
|
uint32_t c = (uint8_t)(r * 255);
|
||||||
|
c <<= 8;
|
||||||
|
c |= (uint8_t)(g * 255);
|
||||||
|
c <<= 8;
|
||||||
|
c |= (uint8_t)(b * 255);
|
||||||
|
c <<= 8;
|
||||||
|
c |= (uint8_t)(a * 255);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Color::to_RGBA64() const {
|
||||||
|
uint64_t c = (uint16_t)(r * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(g * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(b * 65535);
|
||||||
|
c <<= 16;
|
||||||
|
c |= (uint16_t)(a * 65535);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
float Color::gray() const {
|
float Color::gray() const {
|
||||||
return (r + g + b) / 3.0;
|
return (r + g + b) / 3.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t Color::get_r8() const {
|
||||||
|
return (uint8_t)(r * 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Color::get_g8() const {
|
||||||
|
return (uint8_t)(g * 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Color::get_b8() const {
|
||||||
|
return (uint8_t)(b * 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Color::get_a8() const {
|
||||||
|
return (uint8_t)(a * 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
float Color::get_h() const {
|
float Color::get_h() const {
|
||||||
|
|
||||||
float min = MIN(r, g);
|
float min = MIN(r, g);
|
||||||
@@ -167,6 +243,74 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Color Color::darkened(const float p_amount) const {
|
||||||
|
Color res = *this;
|
||||||
|
res.r = res.r * (1.0f - p_amount);
|
||||||
|
res.g = res.g * (1.0f - p_amount);
|
||||||
|
res.b = res.b * (1.0f - p_amount);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color Color::lightened(const float p_amount) const {
|
||||||
|
Color res = *this;
|
||||||
|
res.r = res.r + (1.0f - res.r) * p_amount;
|
||||||
|
res.g = res.g + (1.0f - res.g) * p_amount;
|
||||||
|
res.b = res.b + (1.0f - res.b) * p_amount;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
|
||||||
|
p_h = ::fmod(p_h * 360.0f, 360.0f);
|
||||||
|
if (p_h < 0.0)
|
||||||
|
p_h += 360.0f;
|
||||||
|
|
||||||
|
const float h_ = p_h / 60.0f;
|
||||||
|
const float c = p_v * p_s;
|
||||||
|
const float x = c * (1.0f - ::fabs(::fmod(h_, 2.0f) - 1.0f));
|
||||||
|
float r, g, b;
|
||||||
|
|
||||||
|
switch ((int)h_) {
|
||||||
|
case 0: {
|
||||||
|
r = c;
|
||||||
|
g = x;
|
||||||
|
b = 0;
|
||||||
|
} break;
|
||||||
|
case 1: {
|
||||||
|
r = x;
|
||||||
|
g = c;
|
||||||
|
b = 0;
|
||||||
|
} break;
|
||||||
|
case 2: {
|
||||||
|
r = 0;
|
||||||
|
g = c;
|
||||||
|
b = x;
|
||||||
|
} break;
|
||||||
|
case 3: {
|
||||||
|
r = 0;
|
||||||
|
g = x;
|
||||||
|
b = c;
|
||||||
|
} break;
|
||||||
|
case 4: {
|
||||||
|
r = x;
|
||||||
|
g = 0;
|
||||||
|
b = c;
|
||||||
|
} break;
|
||||||
|
case 5: {
|
||||||
|
r = c;
|
||||||
|
g = 0;
|
||||||
|
b = x;
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
r = 0;
|
||||||
|
g = 0;
|
||||||
|
b = 0;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float m = p_v - c;
|
||||||
|
return Color(m + r, m + g, m + b, p_a);
|
||||||
|
}
|
||||||
|
|
||||||
void Color::invert() {
|
void Color::invert() {
|
||||||
r = 1.0 - r;
|
r = 1.0 - r;
|
||||||
g = 1.0 - g;
|
g = 1.0 - g;
|
||||||
|
|||||||
@@ -24,9 +24,19 @@ namespace godot {
|
|||||||
|
|
||||||
void *_RegisterState::nativescript_handle;
|
void *_RegisterState::nativescript_handle;
|
||||||
int _RegisterState::language_index;
|
int _RegisterState::language_index;
|
||||||
|
|
||||||
const godot_gdnative_core_api_struct *api = nullptr;
|
const godot_gdnative_core_api_struct *api = nullptr;
|
||||||
|
const godot_gdnative_core_1_1_api_struct *core_1_1_api = nullptr;
|
||||||
|
const godot_gdnative_core_1_2_api_struct *core_1_2_api = nullptr;
|
||||||
|
|
||||||
const godot_gdnative_ext_nativescript_api_struct *nativescript_api = nullptr;
|
const godot_gdnative_ext_nativescript_api_struct *nativescript_api = nullptr;
|
||||||
const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api = nullptr;
|
const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api = nullptr;
|
||||||
|
const godot_gdnative_ext_pluginscript_api_struct *pluginscript_api = nullptr;
|
||||||
|
const godot_gdnative_ext_android_api_struct *android_api = nullptr;
|
||||||
|
const godot_gdnative_ext_arvr_api_struct *arvr_api = nullptr;
|
||||||
|
const godot_gdnative_ext_videodecoder_api_struct *videodecoder_api = nullptr;
|
||||||
|
const godot_gdnative_ext_net_api_struct *net_api = nullptr;
|
||||||
|
const godot_gdnative_ext_net_3_2_api_struct *net_3_2_api = nullptr;
|
||||||
|
|
||||||
const void *gdnlib = NULL;
|
const void *gdnlib = NULL;
|
||||||
|
|
||||||
@@ -67,11 +77,23 @@ void Godot::print_error(const String &description, const String &function, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ___register_types();
|
void ___register_types();
|
||||||
|
void ___init_method_bindings();
|
||||||
|
|
||||||
void Godot::gdnative_init(godot_gdnative_init_options *options) {
|
void Godot::gdnative_init(godot_gdnative_init_options *options) {
|
||||||
godot::api = options->api_struct;
|
godot::api = options->api_struct;
|
||||||
godot::gdnlib = options->gd_native_library;
|
godot::gdnlib = options->gd_native_library;
|
||||||
|
|
||||||
|
const godot_gdnative_api_struct *core_extension = godot::api->next;
|
||||||
|
|
||||||
|
while (core_extension) {
|
||||||
|
if (core_extension->version.major == 1 && core_extension->version.minor == 1) {
|
||||||
|
godot::core_1_1_api = (const godot_gdnative_core_1_1_api_struct *)core_extension;
|
||||||
|
} else if (core_extension->version.major == 1 && core_extension->version.minor == 2) {
|
||||||
|
godot::core_1_2_api = (const godot_gdnative_core_1_2_api_struct *)core_extension;
|
||||||
|
}
|
||||||
|
core_extension = core_extension->next;
|
||||||
|
}
|
||||||
|
|
||||||
// now find our extensions
|
// now find our extensions
|
||||||
for (int i = 0; i < godot::api->num_extensions; i++) {
|
for (int i = 0; i < godot::api->num_extensions; i++) {
|
||||||
switch (godot::api->extensions[i]->type) {
|
switch (godot::api->extensions[i]->type) {
|
||||||
@@ -88,9 +110,39 @@ void Godot::gdnative_init(godot_gdnative_init_options *options) {
|
|||||||
extension = extension->next;
|
extension = extension->next;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case GDNATIVE_EXT_PLUGINSCRIPT: {
|
||||||
|
godot::pluginscript_api = (const godot_gdnative_ext_pluginscript_api_struct *)godot::api->extensions[i];
|
||||||
|
} break;
|
||||||
|
case GDNATIVE_EXT_ANDROID: {
|
||||||
|
godot::android_api = (const godot_gdnative_ext_android_api_struct *)godot::api->extensions[i];
|
||||||
|
} break;
|
||||||
|
case GDNATIVE_EXT_ARVR: {
|
||||||
|
godot::arvr_api = (const godot_gdnative_ext_arvr_api_struct *)godot::api->extensions[i];
|
||||||
|
} break;
|
||||||
|
case GDNATIVE_EXT_VIDEODECODER: {
|
||||||
|
godot::videodecoder_api = (const godot_gdnative_ext_videodecoder_api_struct *)godot::api->extensions[i];
|
||||||
|
} break;
|
||||||
|
case GDNATIVE_EXT_NET: {
|
||||||
|
godot::net_api = (const godot_gdnative_ext_net_api_struct *)godot::api->extensions[i];
|
||||||
|
|
||||||
|
const godot_gdnative_api_struct *extension = godot::net_api->next;
|
||||||
|
|
||||||
|
while (extension) {
|
||||||
|
if (extension->version.major == 3 && extension->version.minor == 2) {
|
||||||
|
godot::net_3_2_api = (const godot_gdnative_ext_net_3_2_api_struct *)extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension = extension->next;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// register these now
|
||||||
|
___register_types();
|
||||||
|
___init_method_bindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Godot::gdnative_terminate(godot_gdnative_terminate_options *options) {
|
void Godot::gdnative_terminate(godot_gdnative_terminate_options *options) {
|
||||||
@@ -109,8 +161,6 @@ void Godot::nativescript_init(void *handle) {
|
|||||||
binding_funcs.free_instance_binding_data = wrapper_destroy;
|
binding_funcs.free_instance_binding_data = wrapper_destroy;
|
||||||
|
|
||||||
godot::_RegisterState::language_index = godot::nativescript_1_1_api->godot_nativescript_register_instance_binding_data_functions(binding_funcs);
|
godot::_RegisterState::language_index = godot::nativescript_1_1_api->godot_nativescript_register_instance_binding_data_functions(binding_funcs);
|
||||||
|
|
||||||
___register_types();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Godot::nativescript_terminate(void *handle) {
|
void Godot::nativescript_terminate(void *handle) {
|
||||||
|
|||||||
@@ -52,6 +52,15 @@ bool NodePath::is_empty() const {
|
|||||||
return godot::api->godot_node_path_is_empty(&_node_path);
|
return godot::api->godot_node_path_is_empty(&_node_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodePath NodePath::get_as_property_path() const {
|
||||||
|
godot_node_path path = godot::core_1_1_api->godot_node_path_get_as_property_path(&_node_path);
|
||||||
|
return *(NodePath *)&path;
|
||||||
|
}
|
||||||
|
String NodePath::get_concatenated_subnames() const {
|
||||||
|
godot_string str = godot::api->godot_node_path_get_concatenated_subnames(&_node_path);
|
||||||
|
return *(String *)&str;
|
||||||
|
}
|
||||||
|
|
||||||
NodePath::operator String() const {
|
NodePath::operator String() const {
|
||||||
godot_string str = godot::api->godot_node_path_as_string(&_node_path);
|
godot_string str = godot::api->godot_node_path_as_string(&_node_path);
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,10 @@ Quat Quat::normalized() const {
|
|||||||
return *this / length();
|
return *this / length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Quat::is_normalized() const {
|
||||||
|
return std::abs(length_squared() - 1.0) < 0.00001;
|
||||||
|
}
|
||||||
|
|
||||||
Quat Quat::inverse() const {
|
Quat Quat::inverse() const {
|
||||||
return Quat(-x, -y, -z, w);
|
return Quat(-x, -y, -z, w);
|
||||||
}
|
}
|
||||||
@@ -171,6 +175,21 @@ void Quat::get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const {
|
|||||||
r_axis.z = z / ::sqrt(1 - w * w);
|
r_axis.z = z / ::sqrt(1 - w * w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Quat::set_axis_angle(const Vector3 &axis, const float angle) {
|
||||||
|
ERR_FAIL_COND(!axis.is_normalized());
|
||||||
|
|
||||||
|
real_t d = axis.length();
|
||||||
|
if (d == 0)
|
||||||
|
set(0, 0, 0, 0);
|
||||||
|
else {
|
||||||
|
real_t sin_angle = ::sin(angle * 0.5);
|
||||||
|
real_t cos_angle = ::cos(angle * 0.5);
|
||||||
|
real_t s = sin_angle / d;
|
||||||
|
set(axis.x * s, axis.y * s, axis.z * s,
|
||||||
|
cos_angle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Quat Quat::operator*(const Vector3 &v) const {
|
Quat Quat::operator*(const Vector3 &v) const {
|
||||||
return Quat(w * v.x + y * v.z - z * v.y,
|
return Quat(w * v.x + y * v.z - z * v.y,
|
||||||
w * v.y + z * v.x - x * v.z,
|
w * v.y + z * v.x - x * v.z,
|
||||||
@@ -247,10 +266,10 @@ void Quat::operator-=(const Quat &q) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Quat::operator*=(const Quat &q) {
|
void Quat::operator*=(const Quat &q) {
|
||||||
x *= q.x;
|
set(w * q.x + x * q.w + y * q.z - z * q.y,
|
||||||
y *= q.y;
|
w * q.y + y * q.w + z * q.x - x * q.z,
|
||||||
z *= q.z;
|
w * q.z + z * q.w + x * q.y - y * q.x,
|
||||||
w *= q.w;
|
w * q.w - x * q.x - y * q.y - z * q.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quat::operator*=(const real_t &s) {
|
void Quat::operator*=(const real_t &s) {
|
||||||
|
|||||||
@@ -124,8 +124,8 @@ bool String::operator!=(const String &s) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String String::operator+(const String &s) const {
|
String String::operator+(const String &s) const {
|
||||||
String new_string = *this;
|
String new_string;
|
||||||
new_string._godot_string = godot::api->godot_string_operator_plus(&new_string._godot_string, &s._godot_string);
|
new_string._godot_string = godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string);
|
||||||
|
|
||||||
return new_string;
|
return new_string;
|
||||||
}
|
}
|
||||||
@@ -555,4 +555,34 @@ signed char String::naturalnocasecmp_to(String p_str) const {
|
|||||||
return godot::api->godot_string_naturalnocasecmp_to(&_godot_string, &p_str._godot_string);
|
return godot::api->godot_string_naturalnocasecmp_to(&_godot_string, &p_str._godot_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String String::dedent() const {
|
||||||
|
String new_string;
|
||||||
|
new_string._godot_string = godot::core_1_1_api->godot_string_dedent(&_godot_string);
|
||||||
|
return new_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolStringArray String::rsplit(const String &divisor, const bool allow_empty,
|
||||||
|
const int maxsplit) const {
|
||||||
|
godot_pool_string_array arr = godot::core_1_1_api->godot_string_rsplit(&_godot_string, &divisor._godot_string, allow_empty, maxsplit);
|
||||||
|
return *(PoolStringArray *)&arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
String String::rstrip(const String &chars) const {
|
||||||
|
String new_string;
|
||||||
|
new_string._godot_string = godot::core_1_1_api->godot_string_rstrip(&_godot_string, &chars._godot_string);
|
||||||
|
return new_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
String String::trim_prefix(const String &prefix) const {
|
||||||
|
String new_string;
|
||||||
|
new_string._godot_string = godot::core_1_1_api->godot_string_trim_prefix(&_godot_string, &prefix._godot_string);
|
||||||
|
return new_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
String String::trim_suffix(const String &suffix) const {
|
||||||
|
String new_string;
|
||||||
|
new_string._godot_string = godot::core_1_1_api->godot_string_trim_suffix(&_godot_string, &suffix._godot_string);
|
||||||
|
return new_string;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace godot
|
} // namespace godot
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ void Transform::set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_
|
|||||||
Vector3 Transform::xform(const Vector3 &p_vector) const {
|
Vector3 Transform::xform(const Vector3 &p_vector) const {
|
||||||
|
|
||||||
return Vector3(
|
return Vector3(
|
||||||
basis[0].dot(p_vector) + origin.x,
|
basis.elements[0].dot(p_vector) + origin.x,
|
||||||
basis[1].dot(p_vector) + origin.y,
|
basis.elements[1].dot(p_vector) + origin.y,
|
||||||
basis[2].dot(p_vector) + origin.z);
|
basis.elements[2].dot(p_vector) + origin.z);
|
||||||
}
|
}
|
||||||
Vector3 Transform::xform_inv(const Vector3 &p_vector) const {
|
Vector3 Transform::xform_inv(const Vector3 &p_vector) const {
|
||||||
|
|
||||||
@@ -241,7 +241,7 @@ void Transform::translate(real_t p_tx, real_t p_ty, real_t p_tz) {
|
|||||||
void Transform::translate(const Vector3 &p_translation) {
|
void Transform::translate(const Vector3 &p_translation) {
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
origin[i] += basis[i].dot(p_translation);
|
origin[i] += basis.elements[i].dot(p_translation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -205,8 +205,9 @@ Variant::operator double() const {
|
|||||||
return godot::api->godot_variant_as_real(&_godot_variant);
|
return godot::api->godot_variant_as_real(&_godot_variant);
|
||||||
}
|
}
|
||||||
Variant::operator String() const {
|
Variant::operator String() const {
|
||||||
godot_string s = godot::api->godot_variant_as_string(&_godot_variant);
|
String ret;
|
||||||
return *(String *)&s;
|
*(godot_string *)&ret = godot::api->godot_variant_as_string(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator Vector2() const {
|
Variant::operator Vector2() const {
|
||||||
godot_vector2 s = godot::api->godot_variant_as_vector2(&_godot_variant);
|
godot_vector2 s = godot::api->godot_variant_as_vector2(&_godot_variant);
|
||||||
@@ -250,8 +251,9 @@ Variant::operator Color() const {
|
|||||||
return *(Color *)&s;
|
return *(Color *)&s;
|
||||||
}
|
}
|
||||||
Variant::operator NodePath() const {
|
Variant::operator NodePath() const {
|
||||||
godot_node_path s = godot::api->godot_variant_as_node_path(&_godot_variant);
|
NodePath ret;
|
||||||
return *(NodePath *)&s;
|
*(godot_node_path *)&ret = godot::api->godot_variant_as_node_path(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator RID() const {
|
Variant::operator RID() const {
|
||||||
godot_rid s = godot::api->godot_variant_as_rid(&_godot_variant);
|
godot_rid s = godot::api->godot_variant_as_rid(&_godot_variant);
|
||||||
@@ -259,42 +261,51 @@ Variant::operator RID() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator Dictionary() const {
|
Variant::operator Dictionary() const {
|
||||||
godot_dictionary d = godot::api->godot_variant_as_dictionary(&_godot_variant);
|
Dictionary ret;
|
||||||
return *(Dictionary *)&d;
|
*(godot_dictionary *)&ret = godot::api->godot_variant_as_dictionary(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator Array() const {
|
Variant::operator Array() const {
|
||||||
godot_array s = godot::api->godot_variant_as_array(&_godot_variant);
|
Array ret;
|
||||||
return *(Array *)&s;
|
*(godot_array *)&ret = godot::api->godot_variant_as_array(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant::operator PoolByteArray() const {
|
Variant::operator PoolByteArray() const {
|
||||||
godot_pool_byte_array s = godot::api->godot_variant_as_pool_byte_array(&_godot_variant);
|
PoolByteArray ret;
|
||||||
return *(PoolByteArray *)&s;
|
*(godot_pool_byte_array *)&ret = godot::api->godot_variant_as_pool_byte_array(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator PoolIntArray() const {
|
Variant::operator PoolIntArray() const {
|
||||||
godot_pool_int_array s = godot::api->godot_variant_as_pool_int_array(&_godot_variant);
|
PoolIntArray ret;
|
||||||
return *(PoolIntArray *)&s;
|
*(godot_pool_int_array *)&ret = godot::api->godot_variant_as_pool_int_array(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator PoolRealArray() const {
|
Variant::operator PoolRealArray() const {
|
||||||
godot_pool_real_array s = godot::api->godot_variant_as_pool_real_array(&_godot_variant);
|
PoolRealArray ret;
|
||||||
return *(PoolRealArray *)&s;
|
*(godot_pool_real_array *)&ret = godot::api->godot_variant_as_pool_real_array(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator PoolStringArray() const {
|
Variant::operator PoolStringArray() const {
|
||||||
godot_pool_string_array s = godot::api->godot_variant_as_pool_string_array(&_godot_variant);
|
PoolStringArray ret;
|
||||||
return *(PoolStringArray *)&s;
|
*(godot_pool_string_array *)&ret = godot::api->godot_variant_as_pool_string_array(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator PoolVector2Array() const {
|
Variant::operator PoolVector2Array() const {
|
||||||
godot_pool_vector2_array s = godot::api->godot_variant_as_pool_vector2_array(&_godot_variant);
|
PoolVector2Array ret;
|
||||||
return *(PoolVector2Array *)&s;
|
*(godot_pool_vector2_array *)&ret = godot::api->godot_variant_as_pool_vector2_array(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator PoolVector3Array() const {
|
Variant::operator PoolVector3Array() const {
|
||||||
godot_pool_vector3_array s = godot::api->godot_variant_as_pool_vector3_array(&_godot_variant);
|
PoolVector3Array ret;
|
||||||
return *(PoolVector3Array *)&s;
|
*(godot_pool_vector3_array *)&ret = godot::api->godot_variant_as_pool_vector3_array(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator PoolColorArray() const {
|
Variant::operator PoolColorArray() const {
|
||||||
godot_pool_color_array s = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
|
PoolColorArray ret;
|
||||||
return *(PoolColorArray *)&s;
|
*(godot_pool_color_array *)&ret = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
Variant::operator godot_object *() const {
|
Variant::operator godot_object *() const {
|
||||||
return godot::api->godot_variant_as_object(&_godot_variant);
|
return godot::api->godot_variant_as_object(&_godot_variant);
|
||||||
|
|||||||
@@ -1,61 +1,11 @@
|
|||||||
#include "Vector2.hpp"
|
#include "Vector2.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include <gdnative/vector2.h>
|
#include <gdnative/vector2.h>
|
||||||
|
|
||||||
#include "String.hpp"
|
#include "String.hpp"
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
Vector2 Vector2::operator+(const Vector2 &p_v) const {
|
|
||||||
return Vector2(x + p_v.x, y + p_v.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vector2::operator+=(const Vector2 &p_v) {
|
|
||||||
x += p_v.x;
|
|
||||||
y += p_v.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::operator-(const Vector2 &p_v) const {
|
|
||||||
return Vector2(x - p_v.x, y - p_v.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vector2::operator-=(const Vector2 &p_v) {
|
|
||||||
x -= p_v.x;
|
|
||||||
y -= p_v.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::operator*(const Vector2 &p_v1) const {
|
|
||||||
return Vector2(x * p_v1.x, y * p_v1.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::operator*(const real_t &rvalue) const {
|
|
||||||
return Vector2(x * rvalue, y * rvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vector2::operator*=(const real_t &rvalue) {
|
|
||||||
x *= rvalue;
|
|
||||||
y *= rvalue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::operator/(const Vector2 &p_v1) const {
|
|
||||||
return Vector2(x / p_v1.x, y / p_v1.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::operator/(const real_t &rvalue) const {
|
|
||||||
return Vector2(x / rvalue, y / rvalue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vector2::operator/=(const real_t &rvalue) {
|
|
||||||
x /= rvalue;
|
|
||||||
y /= rvalue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::operator-() const {
|
|
||||||
return Vector2(-x, -y);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Vector2::operator==(const Vector2 &p_vec2) const {
|
bool Vector2::operator==(const Vector2 &p_vec2) const {
|
||||||
return x == p_vec2.x && y == p_vec2.y;
|
return x == p_vec2.x && y == p_vec2.y;
|
||||||
}
|
}
|
||||||
@@ -64,56 +14,6 @@ bool Vector2::operator!=(const Vector2 &p_vec2) const {
|
|||||||
return x != p_vec2.x || y != p_vec2.y;
|
return x != p_vec2.x || y != p_vec2.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector2::normalize() {
|
|
||||||
real_t l = x * x + y * y;
|
|
||||||
if (l != 0) {
|
|
||||||
l = sqrt(l);
|
|
||||||
x /= l;
|
|
||||||
y /= l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::normalized() const {
|
|
||||||
Vector2 v = *this;
|
|
||||||
v.normalize();
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector2::length() const {
|
|
||||||
return sqrt(x * x + y * y);
|
|
||||||
}
|
|
||||||
real_t Vector2::length_squared() const {
|
|
||||||
return x * x + y * y;
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector2::distance_to(const Vector2 &p_vector2) const {
|
|
||||||
return sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector2::distance_squared_to(const Vector2 &p_vector2) const {
|
|
||||||
return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector2::angle_to(const Vector2 &p_vector2) const {
|
|
||||||
return atan2(cross(p_vector2), dot(p_vector2));
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector2::angle_to_point(const Vector2 &p_vector2) const {
|
|
||||||
return atan2(y - p_vector2.y, x - p_vector2.x);
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector2::dot(const Vector2 &p_other) const {
|
|
||||||
return x * p_other.x + y * p_other.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector2::cross(const Vector2 &p_other) const {
|
|
||||||
return x * p_other.y - y * p_other.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::cross(real_t p_other) const {
|
|
||||||
return Vector2(p_other * y, -p_other * x);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::project(const Vector2 &p_vec) const {
|
Vector2 Vector2::project(const Vector2 &p_vec) const {
|
||||||
Vector2 v1 = p_vec;
|
Vector2 v1 = p_vec;
|
||||||
Vector2 v2 = *this;
|
Vector2 v2 = *this;
|
||||||
@@ -134,19 +34,6 @@ Vector2 Vector2::clamped(real_t p_len) const {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 Vector2::linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t) {
|
|
||||||
Vector2 res = p_a;
|
|
||||||
res.x += (p_t * (p_b.x - p_a.x));
|
|
||||||
res.y += (p_t * (p_b.y - p_a.y));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const {
|
|
||||||
Vector2 res = *this;
|
|
||||||
res.x += (p_t * (p_b.x - x));
|
|
||||||
res.y += (p_t * (p_b.y - y));
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const {
|
Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const {
|
||||||
Vector2 p0 = p_pre_a;
|
Vector2 p0 = p_pre_a;
|
||||||
Vector2 p1 = *this;
|
Vector2 p1 = *this;
|
||||||
@@ -167,51 +54,6 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 Vector2::slide(const Vector2 &p_vec) const {
|
|
||||||
return p_vec - *this * this->dot(p_vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::reflect(const Vector2 &p_vec) const {
|
|
||||||
return p_vec - *this * this->dot(p_vec) * 2.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector2::angle() const {
|
|
||||||
return atan2(y, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vector2::set_rotation(real_t p_radians) {
|
|
||||||
|
|
||||||
x = cosf(p_radians);
|
|
||||||
y = sinf(p_radians);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::abs() const {
|
|
||||||
|
|
||||||
return Vector2(fabs(x), fabs(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::rotated(real_t p_by) const {
|
|
||||||
Vector2 v;
|
|
||||||
v.set_rotation(angle() + p_by);
|
|
||||||
v *= length();
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::tangent() const {
|
|
||||||
|
|
||||||
return Vector2(y, -x);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::floor() const {
|
|
||||||
return Vector2(::floor(x), ::floor(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 Vector2::snapped(const Vector2 &p_by) const {
|
|
||||||
return Vector2(
|
|
||||||
p_by.x != 0 ? ::floor(x / p_by.x + 0.5) * p_by.x : x,
|
|
||||||
p_by.y != 0 ? ::floor(y / p_by.y + 0.5) * p_by.y : y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2::operator String() const {
|
Vector2::operator String() const {
|
||||||
return String::num(x) + ", " + String::num(y);
|
return String::num(x) + ", " + String::num(y);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,118 +4,10 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "Basis.hpp"
|
#include "Basis.hpp"
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
Vector3::Vector3(real_t x, real_t y, real_t z) {
|
|
||||||
this->x = x;
|
|
||||||
this->y = y;
|
|
||||||
this->z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3::Vector3() {
|
|
||||||
this->x = 0;
|
|
||||||
this->y = 0;
|
|
||||||
this->z = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const real_t &Vector3::operator[](int p_axis) const {
|
|
||||||
return coord[p_axis];
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t &Vector3::operator[](int p_axis) {
|
|
||||||
return coord[p_axis];
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 &Vector3::operator+=(const Vector3 &p_v) {
|
|
||||||
x += p_v.x;
|
|
||||||
y += p_v.y;
|
|
||||||
z += p_v.z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::operator+(const Vector3 &p_v) const {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v += p_v;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 &Vector3::operator-=(const Vector3 &p_v) {
|
|
||||||
x -= p_v.x;
|
|
||||||
y -= p_v.y;
|
|
||||||
z -= p_v.z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::operator-(const Vector3 &p_v) const {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v -= p_v;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 &Vector3::operator*=(const Vector3 &p_v) {
|
|
||||||
x *= p_v.x;
|
|
||||||
y *= p_v.y;
|
|
||||||
z *= p_v.z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::operator*(const Vector3 &p_v) const {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v *= p_v;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 &Vector3::operator/=(const Vector3 &p_v) {
|
|
||||||
x /= p_v.x;
|
|
||||||
y /= p_v.y;
|
|
||||||
z /= p_v.z;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::operator/(const Vector3 &p_v) const {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v /= p_v;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 &Vector3::operator*=(real_t p_scalar) {
|
|
||||||
*this *= Vector3(p_scalar, p_scalar, p_scalar);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::operator*(real_t p_scalar) const {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v *= p_scalar;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 &Vector3::operator/=(real_t p_scalar) {
|
|
||||||
*this /= Vector3(p_scalar, p_scalar, p_scalar);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::operator/(real_t p_scalar) const {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v /= p_scalar;
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::operator-() const {
|
|
||||||
return Vector3(-x, -y, -z);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Vector3::operator==(const Vector3 &p_v) const {
|
|
||||||
return (x == p_v.x && y == p_v.y && z == p_v.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Vector3::operator!=(const Vector3 &p_v) const {
|
|
||||||
return (x != p_v.x || y != p_v.y || z != p_v.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Vector3::operator<(const Vector3 &p_v) const {
|
bool Vector3::operator<(const Vector3 &p_v) const {
|
||||||
if (x == p_v.x) {
|
if (x == p_v.x) {
|
||||||
if (y == p_v.y)
|
if (y == p_v.y)
|
||||||
@@ -138,30 +30,6 @@ bool Vector3::operator<=(const Vector3 &p_v) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3::abs() const {
|
|
||||||
return Vector3(::fabs(x), ::fabs(y), ::fabs(z));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::ceil() const {
|
|
||||||
return Vector3(::ceil(x), ::ceil(y), ::ceil(z));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::cross(const Vector3 &b) const {
|
|
||||||
Vector3 ret(
|
|
||||||
(y * b.z) - (z * b.y),
|
|
||||||
(z * b.x) - (x * b.z),
|
|
||||||
(x * b.y) - (y * b.x));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::linear_interpolate(const Vector3 &p_b, real_t p_t) const {
|
|
||||||
return Vector3(
|
|
||||||
x + (p_t * (p_b.x - x)),
|
|
||||||
y + (p_t * (p_b.y - y)),
|
|
||||||
z + (p_t * (p_b.z - z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const {
|
Vector3 Vector3::cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const Vector3 &post_b, const real_t t) const {
|
||||||
Vector3 p0 = pre_a;
|
Vector3 p0 = pre_a;
|
||||||
Vector3 p1 = *this;
|
Vector3 p1 = *this;
|
||||||
@@ -180,54 +48,6 @@ Vector3 Vector3::cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3::bounce(const Vector3 &p_normal) const {
|
|
||||||
return -reflect(p_normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector3::length() const {
|
|
||||||
real_t x2 = x * x;
|
|
||||||
real_t y2 = y * y;
|
|
||||||
real_t z2 = z * z;
|
|
||||||
|
|
||||||
return ::sqrt(x2 + y2 + z2);
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector3::length_squared() const {
|
|
||||||
real_t x2 = x * x;
|
|
||||||
real_t y2 = y * y;
|
|
||||||
real_t z2 = z * z;
|
|
||||||
|
|
||||||
return x2 + y2 + z2;
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector3::distance_squared_to(const Vector3 &b) const {
|
|
||||||
return (b - *this).length_squared();
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector3::distance_to(const Vector3 &b) const {
|
|
||||||
return (b - *this).length();
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector3::dot(const Vector3 &b) const {
|
|
||||||
return x * b.x + y * b.y + z * b.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
real_t Vector3::angle_to(const Vector3 &b) const {
|
|
||||||
return std::atan2(cross(b).length(), dot(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::floor() const {
|
|
||||||
return Vector3(::floor(x), ::floor(y), ::floor(z));
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::inverse() const {
|
|
||||||
return Vector3(1.0 / x, 1.0 / y, 1.0 / z);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Vector3::is_normalized() const {
|
|
||||||
return std::abs(length_squared() - 1.0) < 0.00001;
|
|
||||||
}
|
|
||||||
|
|
||||||
Basis Vector3::outer(const Vector3 &b) const {
|
Basis Vector3::outer(const Vector3 &b) const {
|
||||||
Vector3 row0(x * b.x, x * b.y, x * b.z);
|
Vector3 row0(x * b.x, x * b.y, x * b.z);
|
||||||
Vector3 row1(y * b.x, y * b.y, y * b.z);
|
Vector3 row1(y * b.x, y * b.y, y * b.z);
|
||||||
@@ -243,41 +63,10 @@ int Vector3::min_axis() const {
|
|||||||
return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
|
return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vector3::normalize() {
|
|
||||||
real_t l = length();
|
|
||||||
if (l == 0) {
|
|
||||||
x = y = z = 0;
|
|
||||||
} else {
|
|
||||||
x /= l;
|
|
||||||
y /= l;
|
|
||||||
z /= l;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::normalized() const {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v.normalize();
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::reflect(const Vector3 &by) const {
|
|
||||||
return by - *this * this->dot(by) * 2.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 Vector3::rotated(const Vector3 &axis, const real_t phi) const {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v.rotate(axis, phi);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Vector3::rotate(const Vector3 &p_axis, real_t p_phi) {
|
void Vector3::rotate(const Vector3 &p_axis, real_t p_phi) {
|
||||||
*this = Basis(p_axis, p_phi).xform(*this);
|
*this = Basis(p_axis, p_phi).xform(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 Vector3::slide(const Vector3 &by) const {
|
|
||||||
return by - *this * this->dot(by);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is ugly as well, but hey, I'm a simple man
|
// this is ugly as well, but hey, I'm a simple man
|
||||||
#define _ugly_stepify(val, step) (step != 0 ? ::floor(val / step + 0.5) * step : val)
|
#define _ugly_stepify(val, step) (step != 0 ? ::floor(val / step + 0.5) * step : val)
|
||||||
|
|
||||||
@@ -289,12 +78,6 @@ void Vector3::snap(real_t p_val) {
|
|||||||
|
|
||||||
#undef _ugly_stepify
|
#undef _ugly_stepify
|
||||||
|
|
||||||
Vector3 Vector3::snapped(const float by) {
|
|
||||||
Vector3 v = *this;
|
|
||||||
v.snap(by);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3::operator String() const {
|
Vector3::operator String() const {
|
||||||
return String::num(x) + ", " + String::num(y) + ", " + String::num(z);
|
return String::num(x) + ", " + String::num(y) + ", " + String::num(z);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user