Compare commits

..

6 Commits

Author SHA1 Message Date
Rémi Verschelde
290d629f14 headers: Sync with Godot 3.1.2
Commit authored long after 3.1.2 was released, just adding this here for the
sake of not having missed a release, if anyone needs its headers.
2021-09-27 13:06:11 +02:00
Rémi Verschelde
2fb605531a Update godot_headers URL after repo move 2021-09-27 13:02:54 +02:00
Bastiaan Olij
e4ad265339 Update godot_headers after we discovered an upstream issue 2019-05-02 22:55:31 +10:00
Bastiaan Olij
9bebf4feb7 Using godot_headers that is in sync with Godot 3.1.1 2019-05-02 21:43:14 +10:00
Bastiaan Olij
7e8c24f0ac Merge pull request #263 from underdoeg/patch-1
changes to cmake file so it can be used as a subdirectory
2019-04-12 22:25:12 +10:00
Philip Whitfield
468dab8f01 Update CMakeLists.txt
changes so this cmake file can be used as a subdirectory
```
add_subdirectory(godot-cpp)

project(project-name)
add_library(project-name SHARED src/init.cpp)
target_link_libraries(project-name godot-cpp)
```
2019-04-11 11:56:42 +02:00
32 changed files with 869 additions and 1878 deletions

2
.gitmodules vendored
View File

@@ -1,3 +1,3 @@
[submodule "godot_headers"]
path = godot_headers
url = https://github.com/GodotNativeTools/godot_headers
url = https://github.com/godotengine/godot-headers

View File

@@ -1,76 +0,0 @@
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

View File

@@ -1,6 +1,6 @@
# MIT License
Copyright (c) 2017-2020 GodotNativeTools
Copyright (c) 2017-2019 GodotNativeTools
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -76,16 +76,8 @@ $ cd godot-cpp
$ scons platform=<your platform> generate_bindings=yes
$ 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`, `osx` or `android`.
> Replace `<your platform>` with either `windows`, `linux` or `osx`.
> Include `use_llvm=yes` for using clang++
@@ -197,19 +189,6 @@ $ link /nologo /dll /out:bin\libtest.dll /implib:bin\libsimple.lib src\init.obj
*macOS*
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
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`

View File

@@ -1,177 +1,67 @@
#!/usr/bin/env python
#!python
import os
import sys
import subprocess
import os, subprocess, platform, sys
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):
for f in os.listdir(dir):
if f.endswith('.' + extension):
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
if sys.platform.startswith('linux'):
host_platform = 'linux'
elif sys.platform == 'darwin':
host_platform = 'osx'
elif sys.platform == 'win32' or sys.platform == 'msys':
elif sys.platform == 'win32':
host_platform = 'windows'
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.Add(EnumVariable(
'platform',
'Target platform',
host_platform,
allowed_values=('linux', 'osx', 'windows', 'android', 'ios'),
ignorecase=2
))
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
opts.Add(EnumVariable(
'target',
'Compilation target',
'debug',
allowed_values=('debug', 'release'),
ignorecase=2
))
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)
)
env = Environment(ENV = os.environ)
opts.Add(EnumVariable('platform', 'Target platform', host_platform,
allowed_values=('linux', 'osx', 'windows'),
ignorecase=2))
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 - only effective on Windows', False))
# Must be the same setting as used for cpp_bindings
opts.Add(EnumVariable('target', 'Compilation target', 'debug',
allowed_values=('debug', 'release'),
ignorecase=2))
opts.Add(PathVariable('headers_dir', 'Path to the directory containing Godot headers', 'godot_headers', PathVariable.PathIsDir))
opts.Add(BoolVariable('use_custom_api_file', 'Use a custom JSON API file', False))
opts.Add(PathVariable('custom_api_file', 'Path to the custom JSON API file', None, PathVariable.PathIsFile))
opts.Add(BoolVariable('generate_bindings', 'Generate GDNative API bindings', False))
unknown = opts.UnknownVariables()
if unknown:
print("Unknown variables:" + unknown.keys())
Exit(1)
env = Environment()
opts.Update(env)
Help(opts.GenerateHelpText(env))
is64 = sys.maxsize > 2**32
if (
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':
# 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 env['platform'] == 'windows':
if env['bits'] == '64':
env = Environment(TARGET_ARCH='amd64')
elif env['bits'] == '32':
env = Environment(TARGET_ARCH='x86')
else:
print("Warning: bits argument not specified, target arch is=" + env['TARGET_ARCH'])
opts.Update(env)
is64 = False
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['use_llvm']:
env['CXX'] = 'clang++'
@@ -192,59 +82,11 @@ if env['platform'] == 'linux':
env.Append(LINKFLAGS=['-m32'])
elif env['platform'] == 'osx':
# Use Clang on macOS by default
env['CXX'] = 'clang++'
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(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
])
env.Append(LINKFLAGS=['-arch', 'x86_64', '-framework', 'Cocoa', '-Wl,-undefined,dynamic_lookup'])
if env['target'] == 'debug':
env.Append(CCFLAGS=['-Og'])
@@ -256,131 +98,43 @@ elif env['platform'] == 'windows':
# MSVC
env.Append(LINKFLAGS=['/WX'])
if env['target'] == 'debug':
env.Append(CCFLAGS=['/Z7', '/Od', '/EHsc', '/D_DEBUG', '/MDd'])
env.Append(CCFLAGS=['/EHsc', '/D_DEBUG', '/MDd'])
elif env['target'] == 'release':
env.Append(CCFLAGS=['/O2', '/EHsc', '/DNDEBUG', '/MD'])
elif host_platform == 'linux' or host_platform == 'osx':
# Cross-compilation using MinGW
else:
# MinGW
if env['bits'] == '64':
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':
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(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
env.Append(LINKFLAGS=['--static', '-Wl,--no-undefined', '-static-libgcc', '-static-libstdc++'])
# 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.")
# 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',
])
env.Append(CPPPATH=['.', env['headers_dir'], 'include', 'include/gen', 'include/core'])
# Generate bindings?
json_api_file = ''
if 'custom_api_file' in env:
if env['use_custom_api_file']:
json_api_file = env['custom_api_file']
else:
json_api_file = os.path.join(os.getcwd(), 'godot_headers', 'api.json')
if env['generate_bindings']:
# Actually create the bindings here
import binding_generator
binding_generator.generate_bindings(json_api_file)
# Sources to compile
# source to compile
sources = []
add_sources(sources, 'src/core', '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(
target='bin/' + 'libgodot-cpp.{}.{}.{}{}'.format(
env['platform'],
env['target'],
arch_suffix,
env['LIBSUFFIX']
), source=sources
target='bin/' + 'libgodot-cpp.{}.{}.{}'.format(env['platform'], env['target'], env['bits']), source=sources
)
Default(library)

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!python
import json
@@ -28,15 +28,15 @@ def generate_bindings(path):
source_file.write(impl)
icall_header_file = open("include/gen/__icalls.hpp", "w+")
icall_header_file = open("src/gen/__icalls.hpp", "w+")
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.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):
for c in classes:
@@ -58,10 +58,9 @@ def make_gdnative_type(t):
if t == "int":
return "int64_t "
if t == "float" or t == "real":
return "real_t "
return "double "
return strip_name(t) + " "
def generate_class_header(used_classes, c):
source = []
@@ -127,8 +126,8 @@ def generate_class_header(used_classes, c):
if c["base_class"] == "":
source.append("public: enum { ___CLASS_IS_SCRIPT = 0, };")
source.append("")
source.append("private:")
source.append("")
if c["singleton"]:
source.append("\tstatic " + class_name + " *_singleton;")
@@ -136,18 +135,8 @@ def generate_class_header(used_classes, c):
source.append("\t" + class_name + "();")
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("\tstatic void ___init_method_bindings();")
source.append("")
@@ -346,17 +335,7 @@ def generate_class_implementation(icalls, used_classes, c):
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"]:
source.append(class_name + " *" + strip_name(c["name"]) + "::_new()")
@@ -394,6 +373,12 @@ def generate_class_implementation(icalls, used_classes, c):
source.append("}")
source.append("")
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 = ""
@@ -456,7 +441,7 @@ def generate_class_implementation(icalls, used_classes, c):
source.append("")
source.append("\tVariant __result;")
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("\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("")
@@ -500,7 +485,7 @@ def generate_class_implementation(icalls, used_classes, c):
icall_name = get_icall_name(icall_sig)
return_statement += icall_name + "(___mb.mb_" + method["name"] + ", (const Object *) " + core_object_name
return_statement += icall_name + "(mb, (const Object *) " + core_object_name
for arg in method["arguments"]:
return_statement += ", " + escape_cpp(arg["name"]) + (".ptr()" if is_reference_type(arg["type"]) else "")
@@ -535,6 +520,60 @@ def generate_icall_header(icalls):
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("#include <gdnative_api_struct.gen.h>")
source.append("#include <stdint.h>")
source.append("")
source.append("#include <core/GodotGlobal.hpp>")
source.append("#include <core/CoreTypes.hpp>")
source.append("#include \"Object.hpp\"")
@@ -548,9 +587,9 @@ def generate_icall_header(icalls):
ret_type = icall[0]
args = icall[1]
method_signature = "static inline "
method_signature = ""
method_signature += get_icall_return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
method_signature += return_type(ret_type) + get_icall_name(icall) + "(godot_method_bind *mb, const Object *inst"
for i, arg in enumerate(args):
method_signature += ", const "
@@ -573,7 +612,7 @@ def generate_icall_header(icalls):
source.append(method_signature + " {")
if ret_type != "void":
source.append("\t" + ("godot_object *" if is_class_type(ret_type) else get_icall_return_type(ret_type)) + "ret;")
source.append("\t" + ("godot_object *" if is_class_type(ret_type) else return_type(ret_type)) + "ret;")
if is_class_type(ret_type):
source.append("\tret = nullptr;")
@@ -607,16 +646,15 @@ def generate_icall_header(icalls):
source.append("\treturn ret;")
source.append("}")
source.append("")
source.append("}")
source.append("")
source.append("#endif")
return "\n".join(source)
def generate_type_registry(classes):
source = []
@@ -657,34 +695,18 @@ def generate_type_registry(classes):
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):
return "Object *"
if t == "int":

View File

@@ -3,46 +3,11 @@
#include <gdnative/array.h>
#include "Defs.hpp"
#include "String.hpp"
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 PoolByteArray;
class PoolIntArray;
@@ -133,19 +98,6 @@ public:
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();
};

View File

@@ -1,8 +1,6 @@
#ifndef BASIS_H
#define BASIS_H
#include <gdnative/basis.h>
#include "Defs.hpp"
#include "Vector3.hpp"
@@ -12,291 +10,12 @@ namespace godot {
class Quat;
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:
public:
union {
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];
}
Vector3 x, y, z;
};
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:
union {
ColumnVector3<0> x;
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 Vector3 &p_euler); // euler
Basis(const Vector3 &p_axis, real_t p_phi);
@@ -307,16 +26,8 @@ public:
Basis();
const Vector3 operator[](int axis) const {
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;
}
const Vector3 &operator[](int axis) const;
Vector3 &operator[](int axis);
void invert();
@@ -348,8 +59,6 @@ public:
Vector3 get_scale() const;
Basis slerp(Basis b, float t) const;
Vector3 get_euler_xyz() const;
void set_euler_xyz(const Vector3 &p_euler);
Vector3 get_euler_yxz() const;

View File

@@ -32,26 +32,8 @@ public:
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;
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_s() const;
@@ -60,12 +42,6 @@ public:
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) {
return components[idx];
}

View File

@@ -57,9 +57,45 @@ enum class Error {
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
#include <GodotGlobal.hpp>
#include <stdio.h>
typedef float real_t;
@@ -70,28 +106,11 @@ typedef float real_t;
#define _PLANE_EQ_DOT_EPSILON 0.999
#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
#ifndef WARN_PRINT
#define WARN_PRINT(msg) godot::Godot::print_warning(msg, __func__, __FILE__, __LINE__)
#define WARN_PRINT(msg) \
fprintf(stdout, "ERROR: %s\n", msg); \
fflush(stdout)
#endif
#ifndef WARN_PRINTS
@@ -99,104 +118,30 @@ typedef float real_t;
#endif
#ifndef ERR_PRINT
#define ERR_PRINT(msg) godot::Godot::print_error(msg, __func__, __FILE__, __LINE__)
#define ERR_PRINT(x) fprintf(stderr, "ERROR: %s\n", x)
#endif
#ifndef ERR_PRINTS
#define ERR_PRINTS(msg) ERR_PRINT((msg).utf8().get_data())
#endif
#ifndef FATAL_PRINT
#define FATAL_PRINT(msg) ERR_PRINT(godot::String("FATAL: ") + (msg))
#ifndef ERR_FAIL
#define ERR_FAIL() ERR_PRINT("Failed")
#endif
#ifndef ERR_MSG_INDEX
#define ERR_MSG_INDEX(index, size) (godot::String("Index ") + #index + "=" + godot::String::num_int64(index) + " out of size (" + #size + "=" + godot::String::num_int64(size) + ")")
#endif
#ifndef ERR_MSG_NULL
#define ERR_MSG_NULL(param) (godot::String("Parameter '") + #param + "' is null.")
#endif
#ifndef ERR_MSG_COND
#define ERR_MSG_COND(cond) (godot::String("Condition '") + #cond + "' is true.")
#endif
#ifndef ERR_FAIL_INDEX
#define ERR_FAIL_INDEX(index, size) \
do { \
if (unlikely((index) < 0 || (index) >= (size))) { \
ERR_PRINT(ERR_MSG_INDEX(index, size)); \
return; \
} \
} while (0)
#endif
#ifndef ERR_FAIL_INDEX_V
#define ERR_FAIL_INDEX_V(index, size, ret) \
do { \
if (unlikely((index) < 0 || (index) >= (size))) { \
ERR_PRINT(ERR_MSG_INDEX(index, size)); \
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)
#ifndef ERR_FAIL_V
#define ERR_FAIL_V(a) \
{ \
ERR_FAIL(); \
return a; \
}
#endif
#ifndef ERR_FAIL_COND
#define ERR_FAIL_COND(cond) \
#define ERR_FAIL_COND(a) \
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)); \
if (a) { \
ERR_PRINT(#a); \
return; \
} \
} while (0)
@@ -205,54 +150,30 @@ typedef float real_t;
#ifndef ERR_FAIL_COND_V
#define ERR_FAIL_COND_V(cond, ret) \
do { \
if (unlikely(cond)) { \
ERR_PRINT(ERR_MSG_COND(cond)); \
if (cond) { \
ERR_PRINT(#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() \
#ifndef ERR_FAIL_INDEX
#define ERR_FAIL_INDEX(a, b) \
do { \
ERR_PRINT("Method/Function Failed."); \
if (a < 0 || a >= b) { \
ERR_FAIL(); \
return; \
} \
} while (0)
#endif
#ifndef ERR_FAIL_V
#define ERR_FAIL_V(ret) \
#ifndef ERR_FAIL_INDEX_V
#define ERR_FAIL_INDEX_V(a, b, c) \
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; \
if (a < 0 || a >= b) { \
ERR_FAIL(); \
return c; \
} \
} while (0)
#endif

View File

@@ -45,8 +45,8 @@ public:
Name *instance = godot::as<Name>(script->new_()); \
return instance; \
} \
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_id() { return typeid(Name).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 Object *___get_from_variant(godot::Variant a) { return (godot::Object *)godot::as<Name>(godot::Object::___get_from_variant(a)); } \
\
@@ -326,13 +326,8 @@ void register_property(const char *name, P(T::*var), P default_value, godot_meth
godot_string *_hint_string = (godot_string *)&hint_string;
godot_property_attributes attr = {};
if (def_val.get_type() == Variant::NIL) {
attr.type = Variant::OBJECT;
} else {
attr.type = def_val.get_type();
attr.default_value = *(godot_variant *)&def_val;
}
attr.hint = hint;
attr.rset_type = rpc_mode;
attr.usage = usage;
@@ -361,19 +356,12 @@ 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 = "") {
Variant def_val = default_value;
godot_string *_hint_string = (godot_string *)&hint_string;
godot_property_attributes attr = {};
if (def_val.get_type() == Variant::NIL) {
attr.type = Variant::OBJECT;
} else {
attr.type = def_val.get_type();
attr.default_value = *(godot_variant *)&def_val;
}
attr.hint = hint;
attr.rset_type = rpc_mode;
attr.usage = usage;
attr.hint_string = *_hint_string;
_PropertySetFunc<T, P> *wrapped_set = (_PropertySetFunc<T, P> *)godot::api->godot_alloc(sizeof(_PropertySetFunc<T, P>));
wrapped_set->f = setter;

View File

@@ -8,17 +8,8 @@
namespace godot {
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_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;

View File

@@ -31,10 +31,6 @@ public:
bool is_empty() const;
NodePath get_as_property_path() const;
String get_concatenated_subnames() const;
operator String() const;
void operator=(const NodePath &other);

View File

@@ -20,8 +20,6 @@ public:
Quat normalized() const;
bool is_normalized() const;
Quat inverse() const;
void set_euler_xyz(const Vector3 &p_euler);
@@ -42,8 +40,6 @@ public:
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);
Quat operator*(const Quat &q) const;

View File

@@ -132,11 +132,6 @@ public:
signed char casecmp_to(String p_str) const;
signed char nocasecmp_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);

View File

@@ -58,13 +58,6 @@ public:
void operator*=(const Transform &p_transform);
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 inverse_xform(const Transform &t) const;

View File

@@ -226,7 +226,6 @@ public:
operator NodePath() const;
operator RID() const;
operator godot_object *() const;
template <typename T> operator T*() const { return static_cast<T*>(T::___get_from_variant(*this)); }
operator Dictionary() const;
operator Array() const;

View File

@@ -5,8 +5,6 @@
#include "Defs.hpp"
#include <cmath>
namespace godot {
class String;
@@ -22,75 +20,36 @@ struct Vector2 {
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) {
return p_idx ? y : x;
}
inline const real_t &operator[](int p_idx) const {
return p_idx ? y : x;
}
inline Vector2 operator+(const Vector2 &p_v) const {
return Vector2(x + p_v.x, y + p_v.y);
}
Vector2 operator+(const Vector2 &p_v) const;
inline void operator+=(const Vector2 &p_v) {
x += p_v.x;
y += p_v.y;
}
void operator+=(const Vector2 &p_v);
inline Vector2 operator-(const Vector2 &p_v) const {
return Vector2(x - p_v.x, y - p_v.y);
}
Vector2 operator-(const Vector2 &p_v) const;
inline void operator-=(const Vector2 &p_v) {
x -= p_v.x;
y -= p_v.y;
}
void operator-=(const Vector2 &p_v);
inline Vector2 operator*(const Vector2 &p_v1) const {
return Vector2(x * p_v1.x, y * p_v1.y);
}
Vector2 operator*(const Vector2 &p_v1) const;
inline Vector2 operator*(const real_t &rvalue) const {
return Vector2(x * rvalue, y * rvalue);
}
Vector2 operator*(const real_t &rvalue) const;
inline void operator*=(const real_t &rvalue) {
x *= rvalue;
y *= rvalue;
}
void operator*=(const real_t &rvalue);
inline void operator*=(const Vector2 &rvalue) {
*this = *this * rvalue;
}
inline void operator*=(const Vector2 &rvalue) { *this = *this * rvalue; }
inline Vector2 operator/(const Vector2 &p_v1) const {
return Vector2(x / p_v1.x, y / p_v1.y);
}
Vector2 operator/(const Vector2 &p_v1) const;
inline Vector2 operator/(const real_t &rvalue) const {
return Vector2(x / rvalue, y / rvalue);
}
Vector2 operator/(const real_t &rvalue) const;
inline void operator/=(const real_t &rvalue) {
x /= rvalue;
y /= rvalue;
}
void operator/=(const real_t &rvalue);
inline Vector2 operator-() const {
return Vector2(-x, -y);
}
Vector2 operator-() const;
bool operator==(const Vector2 &p_vec2) const;
@@ -99,56 +58,23 @@ 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 void normalize() {
real_t l = x * x + y * y;
if (l != 0) {
l = sqrt(l);
x /= l;
y /= l;
}
}
void normalize();
inline Vector2 normalized() const {
Vector2 v = *this;
v.normalize();
return v;
}
Vector2 normalized() const;
inline real_t length() const {
return sqrt(x * x + y * y);
}
real_t length() const;
real_t length_squared() const;
inline real_t length_squared() const {
return x * x + y * y;
}
real_t distance_to(const Vector2 &p_vector2) const;
real_t distance_squared_to(const Vector2 &p_vector2) const;
inline real_t 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 angle_to(const Vector2 &p_vector2) const;
real_t angle_to_point(const Vector2 &p_vector2) 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 dot(const Vector2 &p_other) const;
inline real_t angle_to(const Vector2 &p_vector2) 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);
}
real_t cross(const Vector2 &p_other) const;
Vector2 cross(real_t p_other) const;
Vector2 project(const Vector2 &p_vec) const;
@@ -156,71 +82,39 @@ struct Vector2 {
Vector2 clamped(real_t p_len) const;
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;
}
static Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t);
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;
inline Vector2 slide(const Vector2 &p_vec) const {
return p_vec - *this * this->dot(p_vec);
}
Vector2 slide(const Vector2 &p_vec) const;
inline Vector2 bounce(const Vector2 &p_normal) const {
return -reflect(p_normal);
}
Vector2 reflect(const Vector2 &p_vec) const;
inline Vector2 reflect(const Vector2 &p_vec) const {
return p_vec - *this * this->dot(p_vec) * 2.0;
}
real_t angle() const;
inline real_t angle() const {
return atan2(y, x);
}
void set_rotation(real_t p_radians);
inline void set_rotation(real_t p_radians) {
x = cosf(p_radians);
y = sinf(p_radians);
}
Vector2 abs() const;
Vector2 rotated(real_t p_by) const;
inline Vector2 abs() const {
return Vector2(fabs(x), fabs(y));
}
Vector2 tangent() 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 floor() const;
Vector2 snapped(const Vector2 &p_by) const;
inline real_t aspect() const { return width / height; }
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) {

View File

@@ -1,14 +1,10 @@
#ifndef VECTOR3_H
#define VECTOR3_H
#include <gdnative/vector3.h>
#include "Defs.hpp"
#include "String.hpp"
#include <cmath>
namespace godot {
class Basis;
@@ -28,192 +24,80 @@ struct Vector3 {
real_t z;
};
real_t coord[3]; // Not for direct access, use [] operator instead
real_t coord[3];
};
inline Vector3(real_t x, real_t y, real_t z) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3(real_t x, real_t y, real_t z);
inline Vector3() {
this->x = 0;
this->y = 0;
this->z = 0;
}
Vector3();
inline const real_t &operator[](int p_axis) const {
return coord[p_axis];
}
const real_t &operator[](int p_axis) const;
inline real_t &operator[](int p_axis) {
return coord[p_axis];
}
real_t &operator[](int p_axis);
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);
inline Vector3 operator+(const Vector3 &p_v) const {
Vector3 v = *this;
v += p_v;
return v;
}
Vector3 operator+(const Vector3 &p_v) const;
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);
inline Vector3 operator-(const Vector3 &p_v) const {
Vector3 v = *this;
v -= p_v;
return v;
}
Vector3 operator-(const Vector3 &p_v) const;
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);
inline Vector3 operator*(const Vector3 &p_v) const {
Vector3 v = *this;
v *= p_v;
return v;
}
Vector3 operator*(const Vector3 &p_v) const;
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);
inline Vector3 operator/(const Vector3 &p_v) const {
Vector3 v = *this;
v /= p_v;
return v;
}
Vector3 operator/(const Vector3 &p_v) const;
inline Vector3 &operator*=(real_t p_scalar) {
*this *= Vector3(p_scalar, p_scalar, p_scalar);
return *this;
}
Vector3 &operator*=(real_t p_scalar);
inline Vector3 operator*(real_t p_scalar) const {
Vector3 v = *this;
v *= p_scalar;
return v;
}
Vector3 operator*(real_t p_scalar) const;
inline Vector3 &operator/=(real_t p_scalar) {
*this /= Vector3(p_scalar, p_scalar, p_scalar);
return *this;
}
Vector3 &operator/=(real_t p_scalar);
inline Vector3 operator/(real_t p_scalar) const {
Vector3 v = *this;
v /= p_scalar;
return v;
}
Vector3 operator/(real_t p_scalar) const;
inline Vector3 operator-() const {
return Vector3(-x, -y, -z);
}
Vector3 operator-() 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;
inline Vector3 abs() const {
return Vector3(::fabs(x), ::fabs(y), ::fabs(z));
}
Vector3 abs() const;
inline Vector3 ceil() const {
return Vector3(::ceil(x), ::ceil(y), ::ceil(z));
}
Vector3 ceil() 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 cross(const Vector3 &b) 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 linear_interpolate(const Vector3 &p_b, real_t p_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 {
return -reflect(p_normal);
}
Vector3 bounce(const Vector3 &p_normal) const;
inline real_t length() const {
real_t x2 = x * x;
real_t y2 = y * y;
real_t z2 = z * z;
real_t length() const;
return ::sqrt(x2 + y2 + z2);
}
real_t length_squared() 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_squared_to(const Vector3 &b) const;
return x2 + y2 + z2;
}
real_t distance_to(const Vector3 &b) const;
inline real_t distance_squared_to(const Vector3 &b) const {
return (b - *this).length_squared();
}
real_t dot(const Vector3 &b) const;
inline real_t distance_to(const Vector3 &b) const {
return (b - *this).length();
}
real_t angle_to(const Vector3 &b) const;
inline real_t dot(const Vector3 &b) const {
return x * b.x + y * b.y + z * b.z;
}
Vector3 floor() const;
inline real_t angle_to(const Vector3 &b) const {
return std::atan2(cross(b).length(), dot(b));
}
Vector3 inverse() 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;
}
bool is_normalized() const;
Basis outer(const Vector3 &b) const;
@@ -221,46 +105,21 @@ struct Vector3 {
int min_axis() const;
inline void normalize() {
real_t l = length();
if (l == 0) {
x = y = z = 0;
} else {
x /= l;
y /= l;
z /= l;
}
}
void normalize();
inline Vector3 normalized() const {
Vector3 v = *this;
v.normalize();
return v;
}
Vector3 normalized() const;
inline Vector3 reflect(const Vector3 &by) const {
return by - *this * this->dot(by) * 2.f;
}
Vector3 reflect(const Vector3 &by) const;
inline Vector3 rotated(const Vector3 &axis, const real_t phi) const {
Vector3 v = *this;
v.rotate(axis, phi);
return v;
}
Vector3 rotated(const Vector3 &axis, const real_t phi) const;
void rotate(const Vector3 &p_axis, real_t p_phi);
inline Vector3 slide(const Vector3 &by) const {
return by - *this * this->dot(by);
}
Vector3 slide(const Vector3 &by) const;
void snap(real_t p_val);
inline Vector3 snapped(const float by) {
Vector3 v = *this;
v.snap(by);
return v;
}
Vector3 snapped(const float by);
operator String() const;
};

View File

@@ -1,40 +0,0 @@
#!/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

View File

@@ -158,35 +158,6 @@ void Array::sort_custom(Object *obj, const 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() {
godot::api->godot_array_destroy(&_godot_array);
}

View File

@@ -31,6 +31,15 @@ Basis::Basis() {
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) \
(elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1])
@@ -149,15 +158,6 @@ Vector3 Basis::get_scale() const {
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
// (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).

View File

@@ -67,86 +67,10 @@ uint32_t Color::to_ARGB32() const {
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 {
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 min = MIN(r, g);
@@ -243,74 +167,6 @@ 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() {
r = 1.0 - r;
g = 1.0 - g;

View File

@@ -24,19 +24,9 @@ namespace godot {
void *_RegisterState::nativescript_handle;
int _RegisterState::language_index;
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_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;
@@ -77,23 +67,11 @@ void Godot::print_error(const String &description, const String &function, const
}
void ___register_types();
void ___init_method_bindings();
void Godot::gdnative_init(godot_gdnative_init_options *options) {
godot::api = options->api_struct;
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
for (int i = 0; i < godot::api->num_extensions; i++) {
switch (godot::api->extensions[i]->type) {
@@ -110,39 +88,9 @@ void Godot::gdnative_init(godot_gdnative_init_options *options) {
extension = extension->next;
}
} 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;
}
}
// register these now
___register_types();
___init_method_bindings();
}
void Godot::gdnative_terminate(godot_gdnative_terminate_options *options) {
@@ -161,6 +109,8 @@ void Godot::nativescript_init(void *handle) {
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);
___register_types();
}
void Godot::nativescript_terminate(void *handle) {

View File

@@ -52,15 +52,6 @@ bool NodePath::is_empty() const {
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 {
godot_string str = godot::api->godot_node_path_as_string(&_node_path);

View File

@@ -89,10 +89,6 @@ Quat Quat::normalized() const {
return *this / length();
}
bool Quat::is_normalized() const {
return std::abs(length_squared() - 1.0) < 0.00001;
}
Quat Quat::inverse() const {
return Quat(-x, -y, -z, w);
}
@@ -175,21 +171,6 @@ void Quat::get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const {
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 {
return Quat(w * v.x + y * v.z - z * v.y,
w * v.y + z * v.x - x * v.z,
@@ -266,10 +247,10 @@ void Quat::operator-=(const Quat &q) {
}
void Quat::operator*=(const Quat &q) {
set(w * q.x + x * q.w + y * q.z - z * q.y,
w * q.y + y * q.w + z * q.x - x * q.z,
w * q.z + z * q.w + x * q.y - y * q.x,
w * q.w - x * q.x - y * q.y - z * q.z);
x *= q.x;
y *= q.y;
z *= q.z;
w *= q.w;
}
void Quat::operator*=(const real_t &s) {

View File

@@ -124,8 +124,8 @@ bool String::operator!=(const String &s) const {
}
String String::operator+(const String &s) const {
String new_string;
new_string._godot_string = godot::api->godot_string_operator_plus(&_godot_string, &s._godot_string);
String new_string = *this;
new_string._godot_string = godot::api->godot_string_operator_plus(&new_string._godot_string, &s._godot_string);
return new_string;
}
@@ -555,34 +555,4 @@ signed char String::naturalnocasecmp_to(String p_str) const {
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

View File

@@ -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 {
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);
basis[0].dot(p_vector) + origin.x,
basis[1].dot(p_vector) + origin.y,
basis[2].dot(p_vector) + origin.z);
}
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) {
for (int i = 0; i < 3; i++) {
origin[i] += basis.elements[i].dot(p_translation);
origin[i] += basis[i].dot(p_translation);
}
}

View File

@@ -205,9 +205,8 @@ Variant::operator double() const {
return godot::api->godot_variant_as_real(&_godot_variant);
}
Variant::operator String() const {
String ret;
*(godot_string *)&ret = godot::api->godot_variant_as_string(&_godot_variant);
return ret;
godot_string s = godot::api->godot_variant_as_string(&_godot_variant);
return *(String *)&s;
}
Variant::operator Vector2() const {
godot_vector2 s = godot::api->godot_variant_as_vector2(&_godot_variant);
@@ -251,9 +250,8 @@ Variant::operator Color() const {
return *(Color *)&s;
}
Variant::operator NodePath() const {
NodePath ret;
*(godot_node_path *)&ret = godot::api->godot_variant_as_node_path(&_godot_variant);
return ret;
godot_node_path s = godot::api->godot_variant_as_node_path(&_godot_variant);
return *(NodePath *)&s;
}
Variant::operator RID() const {
godot_rid s = godot::api->godot_variant_as_rid(&_godot_variant);
@@ -261,51 +259,42 @@ Variant::operator RID() const {
}
Variant::operator Dictionary() const {
Dictionary ret;
*(godot_dictionary *)&ret = godot::api->godot_variant_as_dictionary(&_godot_variant);
return ret;
godot_dictionary d = godot::api->godot_variant_as_dictionary(&_godot_variant);
return *(Dictionary *)&d;
}
Variant::operator Array() const {
Array ret;
*(godot_array *)&ret = godot::api->godot_variant_as_array(&_godot_variant);
return ret;
godot_array s = godot::api->godot_variant_as_array(&_godot_variant);
return *(Array *)&s;
}
Variant::operator PoolByteArray() const {
PoolByteArray ret;
*(godot_pool_byte_array *)&ret = godot::api->godot_variant_as_pool_byte_array(&_godot_variant);
return ret;
godot_pool_byte_array s = godot::api->godot_variant_as_pool_byte_array(&_godot_variant);
return *(PoolByteArray *)&s;
}
Variant::operator PoolIntArray() const {
PoolIntArray ret;
*(godot_pool_int_array *)&ret = godot::api->godot_variant_as_pool_int_array(&_godot_variant);
return ret;
godot_pool_int_array s = godot::api->godot_variant_as_pool_int_array(&_godot_variant);
return *(PoolIntArray *)&s;
}
Variant::operator PoolRealArray() const {
PoolRealArray ret;
*(godot_pool_real_array *)&ret = godot::api->godot_variant_as_pool_real_array(&_godot_variant);
return ret;
godot_pool_real_array s = godot::api->godot_variant_as_pool_real_array(&_godot_variant);
return *(PoolRealArray *)&s;
}
Variant::operator PoolStringArray() const {
PoolStringArray ret;
*(godot_pool_string_array *)&ret = godot::api->godot_variant_as_pool_string_array(&_godot_variant);
return ret;
godot_pool_string_array s = godot::api->godot_variant_as_pool_string_array(&_godot_variant);
return *(PoolStringArray *)&s;
}
Variant::operator PoolVector2Array() const {
PoolVector2Array ret;
*(godot_pool_vector2_array *)&ret = godot::api->godot_variant_as_pool_vector2_array(&_godot_variant);
return ret;
godot_pool_vector2_array s = godot::api->godot_variant_as_pool_vector2_array(&_godot_variant);
return *(PoolVector2Array *)&s;
}
Variant::operator PoolVector3Array() const {
PoolVector3Array ret;
*(godot_pool_vector3_array *)&ret = godot::api->godot_variant_as_pool_vector3_array(&_godot_variant);
return ret;
godot_pool_vector3_array s = godot::api->godot_variant_as_pool_vector3_array(&_godot_variant);
return *(PoolVector3Array *)&s;
}
Variant::operator PoolColorArray() const {
PoolColorArray ret;
*(godot_pool_color_array *)&ret = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
return ret;
godot_pool_color_array s = godot::api->godot_variant_as_pool_color_array(&_godot_variant);
return *(PoolColorArray *)&s;
}
Variant::operator godot_object *() const {
return godot::api->godot_variant_as_object(&_godot_variant);

View File

@@ -1,11 +1,61 @@
#include "Vector2.hpp"
#include <cmath>
#include <gdnative/vector2.h>
#include "String.hpp"
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 {
return x == p_vec2.x && y == p_vec2.y;
}
@@ -14,6 +64,56 @@ bool Vector2::operator!=(const Vector2 &p_vec2) const {
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 v1 = p_vec;
Vector2 v2 = *this;
@@ -34,6 +134,19 @@ Vector2 Vector2::clamped(real_t p_len) const {
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 p0 = p_pre_a;
Vector2 p1 = *this;
@@ -54,6 +167,51 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c
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 {
return String::num(x) + ", " + String::num(y);
}

View File

@@ -4,10 +4,118 @@
#include <stdlib.h>
#include <cmath>
#include "Basis.hpp"
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 {
if (x == p_v.x) {
if (y == p_v.y)
@@ -30,6 +138,30 @@ 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 p0 = pre_a;
Vector3 p1 = *this;
@@ -48,6 +180,54 @@ Vector3 Vector3::cubic_interpolate(const Vector3 &b, const Vector3 &pre_a, const
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 {
Vector3 row0(x * b.x, x * b.y, x * b.z);
Vector3 row1(y * b.x, y * b.y, y * b.z);
@@ -63,10 +243,41 @@ int Vector3::min_axis() const {
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) {
*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
#define _ugly_stepify(val, step) (step != 0 ? ::floor(val / step + 0.5) * step : val)
@@ -78,6 +289,12 @@ void Vector3::snap(real_t p_val) {
#undef _ugly_stepify
Vector3 Vector3::snapped(const float by) {
Vector3 v = *this;
v.snap(by);
return v;
}
Vector3::operator String() const {
return String::num(x) + ", " + String::num(y) + ", " + String::num(z);
}