Single Compilation Unit build.

Adds support for simple SCU build (DEV_ENABLED only).
This speeds up compilation by compiling multiple cpp files within a single translation unit.
This commit is contained in:
lawnjelly 2023-05-17 16:22:26 +01:00
parent 543750a1b3
commit b69c8b4791
29 changed files with 531 additions and 137 deletions

View file

@ -55,6 +55,7 @@ _helper_module("modules.modules_builders", "modules/modules_builders.py")
import methods
import glsl_builders
import gles3_builders
import scu_builders
from platform_methods import architectures, architecture_aliases
if ARGUMENTS.get("target", "editor") == "editor":
@ -223,6 +224,7 @@ opts.Add(
"",
)
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
opts.Add(EnumVariable("scu_build", "Use single compilation unit build", "none", ("none", "dev", "all")))
# Thirdparty libraries
opts.Add(BoolVariable("builtin_certs", "Use the built-in SSL certificates bundles", True))
@ -428,14 +430,20 @@ if env_base.debug_features:
# to give *users* extra debugging information for their game development.
env_base.Append(CPPDEFINES=["DEBUG_ENABLED"])
if env_base.dev_build:
# DEV_ENABLED enables *engine developer* code which should only be compiled for those
# working on the engine itself.
env_base.Append(CPPDEFINES=["DEV_ENABLED"])
env_base["use_scu"] = env_base["scu_build"] in ("dev", "all")
else:
# Disable assert() for production targets (only used in thirdparty code).
env_base.Append(CPPDEFINES=["NDEBUG"])
# SCU builds currently use a lot of compiler memory
# in release builds, so disallow outside of DEV builds unless "all" is set.
env_base["use_scu"] = env_base["scu_build"] == "all"
# SCons speed optimization controlled by the `fast_unsafe` option, which provide
# more than 10 s speed up for incremental rebuilds.
# Unsafe as they reduce the certainty of rebuilding all changed files, so it's
@ -550,6 +558,10 @@ if selected_platform in platform_list:
# LTO "auto" means we handle the preferred option in each platform detect.py.
env["lto"] = ARGUMENTS.get("lto", "auto")
# Run SCU file generation script if in a SCU build.
if env["use_scu"]:
methods.set_scu_folders(scu_builders.generate_scu_files(env["verbose"], env_base.dev_build == False))
# Must happen after the flags' definition, as configure is when most flags
# are actually handled to change compile options, etc.
detect.configure(env)

View file

@ -29,9 +29,8 @@ if env.editor_build:
reg_exporters_inc = '#include "register_exporters.h"\n\n'
reg_exporters = "void register_exporters() {\n"
for e in env.platform_exporters:
# Glob all .cpp files in export folder
files = Glob("#platform/" + e + "/export/" + "*.cpp")
env.add_source_files(env.editor_sources, files)
# Add all .cpp files in export folder
env.add_source_files(env.editor_sources, "../platform/" + e + "/export/" + "*.cpp")
reg_exporters += "\tregister_" + e + "_exporter();\n"
reg_exporters_inc += '#include "platform/' + e + '/export/export.h"\n'

View file

@ -36,7 +36,7 @@
#include "core/version.h"
// The metadata key used to store and retrieve the version text to copy to the clipboard.
static const String META_TEXT_TO_COPY = "text_to_copy";
const String EditorAbout::META_TEXT_TO_COPY = "text_to_copy";
void EditorAbout::_theme_changed() {
const Ref<Font> font = get_theme_font(SNAME("source"), SNAME("EditorFonts"));

View file

@ -51,6 +51,8 @@
class EditorAbout : public AcceptDialog {
GDCLASS(EditorAbout, AcceptDialog);
static const String META_TEXT_TO_COPY;
private:
void _license_tree_selected();
void _version_button_pressed();

View file

@ -46,14 +46,14 @@
#include "scene/property_utils.h"
#include "scene/resources/packed_scene.h"
static bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
bool EditorInspector::_property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style) {
if (p_property_path.findn(p_filter) != -1) {
return true;
}
const Vector<String> sections = p_property_path.split("/");
for (int i = 0; i < sections.size(); i++) {
if (p_filter.is_subsequence_ofn(EditorPropertyNameProcessor::get_singleton()->process_name(sections[i], p_style))) {
const Vector<String> prop_sections = p_property_path.split("/");
for (int i = 0; i < prop_sections.size(); i++) {
if (p_filter.is_subsequence_ofn(EditorPropertyNameProcessor::get_singleton()->process_name(prop_sections[i], p_style))) {
return true;
}
}

View file

@ -512,6 +512,7 @@ class EditorInspector : public ScrollContainer {
void _property_deleted(const String &p_path);
void _property_checked(const String &p_path, bool p_checked);
void _property_pinned(const String &p_path, bool p_pinned);
bool _property_path_matches(const String &p_property_path, const String &p_filter, EditorPropertyNameProcessor::Style p_style);
void _resource_selected(const String &p_path, Ref<Resource> p_resource);
void _property_selected(const String &p_path, int p_focusable);

View file

@ -6760,28 +6760,28 @@ EditorNode::EditorNode() {
switch (display_scale) {
case 0:
// Try applying a suitable display scale automatically.
editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
EditorScale::set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
break;
case 1:
editor_set_scale(0.75);
EditorScale::set_scale(0.75);
break;
case 2:
editor_set_scale(1.0);
EditorScale::set_scale(1.0);
break;
case 3:
editor_set_scale(1.25);
EditorScale::set_scale(1.25);
break;
case 4:
editor_set_scale(1.5);
EditorScale::set_scale(1.5);
break;
case 5:
editor_set_scale(1.75);
EditorScale::set_scale(1.75);
break;
case 6:
editor_set_scale(2.0);
EditorScale::set_scale(2.0);
break;
default:
editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
break;
}
}

View file

@ -34,8 +34,8 @@
#include "editor/editor_node.h"
#include "editor/editor_scale.h"
static Rect2i prev_rect = Rect2i();
static bool was_showed = false;
Rect2i EditorQuickOpen::prev_rect = Rect2i();
bool EditorQuickOpen::was_showed = false;
void EditorQuickOpen::popup_dialog(const String &p_base, bool p_enable_multi, bool p_dont_clear) {
base_type = p_base;

View file

@ -39,6 +39,9 @@
class EditorQuickOpen : public ConfirmationDialog {
GDCLASS(EditorQuickOpen, ConfirmationDialog);
static Rect2i prev_rect;
static bool was_showed;
LineEdit *search_box = nullptr;
Tree *search_options = nullptr;
String base_type;

View file

@ -30,14 +30,12 @@
#include "editor_scale.h"
#include "core/os/os.h"
float EditorScale::_scale = 1.0f;
static float scale = 1.0;
void editor_set_scale(float p_scale) {
scale = p_scale;
void EditorScale::set_scale(float p_scale) {
_scale = p_scale;
}
float editor_get_scale() {
return scale;
float EditorScale::get_scale() {
return _scale;
}

View file

@ -31,9 +31,14 @@
#ifndef EDITOR_SCALE_H
#define EDITOR_SCALE_H
void editor_set_scale(float p_scale);
float editor_get_scale();
class EditorScale {
static float _scale;
#define EDSCALE (editor_get_scale())
public:
static void set_scale(float p_scale);
static float get_scale();
};
#define EDSCALE (EditorScale::get_scale())
#endif // EDITOR_SCALE_H

View file

@ -481,7 +481,7 @@ void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
code_editor->convert_case(p_case);
}
static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource) {
ScriptEditorBase *TextEditor::create_editor(const Ref<Resource> &p_resource) {
if (Object::cast_to<TextFile>(*p_resource) || Object::cast_to<JSON>(*p_resource)) {
return memnew(TextEditor);
}

View file

@ -38,6 +38,8 @@
class TextEditor : public ScriptEditorBase {
GDCLASS(TextEditor, ScriptEditorBase);
static ScriptEditorBase *create_editor(const Ref<Resource> &p_resource);
private:
CodeTextEditor *code_editor = nullptr;

View file

@ -4982,7 +4982,7 @@ void VisualShaderEditor::_preview_size_changed() {
preview_vbox->set_custom_minimum_size(preview_window->get_size());
}
static ShaderLanguage::DataType _get_global_shader_uniform_type(const StringName &p_variable) {
static ShaderLanguage::DataType _visual_shader_editor_get_global_shader_uniform_type(const StringName &p_variable) {
RS::GlobalShaderParameterType gvt = RS::get_singleton()->global_shader_parameter_get_type(p_variable);
return (ShaderLanguage::DataType)RS::global_shader_uniform_type_get_shader_datatype(gvt);
}
@ -5001,7 +5001,7 @@ void VisualShaderEditor::_update_preview() {
info.functions = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(visual_shader->get_mode()));
info.render_modes = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(visual_shader->get_mode()));
info.shader_types = ShaderTypes::get_singleton()->get_types();
info.global_shader_uniform_type_func = _get_global_shader_uniform_type;
info.global_shader_uniform_type_func = _visual_shader_editor_get_global_shader_uniform_type;
ShaderLanguage sl;

View file

@ -2763,28 +2763,28 @@ ProjectManager::ProjectManager() {
switch (display_scale) {
case 0:
// Try applying a suitable display scale automatically.
editor_set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
EditorScale::set_scale(EditorSettings::get_singleton()->get_auto_display_scale());
break;
case 1:
editor_set_scale(0.75);
EditorScale::set_scale(0.75);
break;
case 2:
editor_set_scale(1.0);
EditorScale::set_scale(1.0);
break;
case 3:
editor_set_scale(1.25);
EditorScale::set_scale(1.25);
break;
case 4:
editor_set_scale(1.5);
EditorScale::set_scale(1.5);
break;
case 5:
editor_set_scale(1.75);
EditorScale::set_scale(1.75);
break;
case 6:
editor_set_scale(2.0);
EditorScale::set_scale(2.0);
break;
default:
editor_set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
EditorScale::set_scale(EDITOR_GET("interface/editor/custom_display_scale"));
break;
}
EditorFileDialog::get_icon_func = &ProjectManager::_file_dialog_get_icon;

View file

@ -6,9 +6,23 @@ import subprocess
from collections import OrderedDict
from collections.abc import Mapping
from typing import Iterator
from pathlib import Path
from os.path import normpath, basename
# Get the "Godot" folder name ahead of time
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
# Listing all the folders we have converted
# for SCU in scu_builders.py
_scu_folders = set()
def add_source_files(self, sources, files):
def set_scu_folders(scu_folders):
global _scu_folders
_scu_folders = scu_folders
def add_source_files_orig(self, sources, files, allow_gen=False):
# Convert string to list of absolute paths (including expanding wildcard)
if isinstance(files, (str, bytes)):
# Keep SCons project-absolute path as they are (no wildcard support)
@ -23,7 +37,7 @@ def add_source_files(self, sources, files):
skip_gen_cpp = "*" in files
dir_path = self.Dir(".").abspath
files = sorted(glob.glob(dir_path + "/" + files))
if skip_gen_cpp:
if skip_gen_cpp and not allow_gen:
files = [f for f in files if not f.endswith(".gen.cpp")]
# Add each path as compiled Object following environment (self) configuration
@ -35,6 +49,72 @@ def add_source_files(self, sources, files):
sources.append(obj)
# The section name is used for checking
# the hash table to see whether the folder
# is included in the SCU build.
# It will be something like "core/math".
def _find_scu_section_name(subdir):
section_path = os.path.abspath(subdir) + "/"
folders = []
folder = ""
for i in range(8):
folder = os.path.dirname(section_path)
folder = os.path.basename(folder)
if folder == base_folder_only:
break
folders += [folder]
section_path += "../"
section_path = os.path.abspath(section_path) + "/"
section_name = ""
for n in range(len(folders)):
# section_name += folders[len(folders) - n - 1] + " "
section_name += folders[len(folders) - n - 1]
if n != (len(folders) - 1):
section_name += "/"
return section_name
def add_source_files_scu(self, sources, files, allow_gen=False):
if self["use_scu"] and isinstance(files, str):
if "*." not in files:
return False
# If the files are in a subdirectory, we want to create the scu gen
# files inside this subdirectory.
subdir = os.path.dirname(files)
if subdir != "":
subdir += "/"
section_name = _find_scu_section_name(subdir)
# if the section name is in the hash table?
# i.e. is it part of the SCU build?
global _scu_folders
if section_name not in (_scu_folders):
return False
if self["verbose"]:
print("SCU building " + section_name)
# Add all the gen.cpp files in the SCU directory
add_source_files_orig(self, sources, subdir + "scu/scu_*.gen.cpp", True)
return True
return False
# Either builds the folder using the SCU system,
# or reverts to regular build.
def add_source_files(self, sources, files, allow_gen=False):
if not add_source_files_scu(self, sources, files, allow_gen):
# Wraps the original function when scu build is not active.
add_source_files_orig(self, sources, files, allow_gen)
return False
return True
def disable_warnings(self):
# 'self' is the environment
if self.msvc:

View file

@ -941,7 +941,7 @@ void AnimationTree::_clear_playing_caches() {
playing_caches.clear();
}
static void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
void AnimationTree::_call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred) {
// Separate function to use alloca() more efficiently
const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * p_params.size());
const Variant *args = p_params.ptr();

View file

@ -194,6 +194,8 @@ class AnimationNodeEndState : public AnimationRootNode {
class AnimationTree : public Node {
GDCLASS(AnimationTree, Node);
void _call_object(Object *p_object, const StringName &p_method, const Vector<Variant> &p_params, bool p_deferred);
public:
enum AnimationProcessCallback {
ANIMATION_PROCESS_PHYSICS,

View file

@ -34,12 +34,6 @@
#include "graph_edit.h"
struct _MinSizeCache {
int min_size;
bool will_stretch;
int final_size;
};
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
String str = p_name;

View file

@ -37,6 +37,12 @@
class GraphNode : public Container {
GDCLASS(GraphNode, Container);
struct _MinSizeCache {
int min_size;
bool will_stretch;
int final_size;
};
public:
enum Overlay {
OVERLAY_DISABLED,

View file

@ -795,8 +795,8 @@ void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, Local
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
}
static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
const uint32_t SurfaceTool::custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 };
const uint32_t SurfaceTool::custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT };
void SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, LocalVector<SurfaceTool::Vertex> &ret, uint32_t *r_format) {
ret.clear();

View file

@ -38,6 +38,9 @@
class SurfaceTool : public RefCounted {
GDCLASS(SurfaceTool, RefCounted);
static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT];
static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT];
public:
struct Vertex {
Vector3 vertex;

339
scu_builders.py Normal file
View file

@ -0,0 +1,339 @@
"""Functions used to generate scu build source files during build time
"""
import glob, os
import math
from pathlib import Path
from os.path import normpath, basename
base_folder_path = str(Path(__file__).parent) + "/"
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
_verbose = False
_is_release_build = False
_scu_folders = set()
def clear_out_existing_files(output_folder, extension):
output_folder = os.path.abspath(output_folder)
# print("clear_out_existing_files from folder: " + output_folder)
if not os.path.isdir(output_folder):
# folder does not exist or has not been created yet,
# no files to clearout. (this is not an error)
return
for file in glob.glob(output_folder + "/*." + extension):
# print("removed pre-existing file: " + file)
os.remove(file)
def folder_not_found(folder):
abs_folder = base_folder_path + folder + "/"
return not os.path.isdir(abs_folder)
def find_files_in_folder(folder, sub_folder, include_list, extension, sought_exceptions, found_exceptions):
abs_folder = base_folder_path + folder + "/" + sub_folder
if not os.path.isdir(abs_folder):
print("ERROR " + abs_folder + " not found.")
return include_list, found_exceptions
os.chdir(abs_folder)
sub_folder_slashed = ""
if sub_folder != "":
sub_folder_slashed = sub_folder + "/"
for file in glob.glob("*." + extension):
simple_name = Path(file).stem
if file.endswith(".gen.cpp"):
continue
li = '#include "../' + sub_folder_slashed + file + '"'
if not simple_name in sought_exceptions:
include_list.append(li)
else:
found_exceptions.append(li)
return include_list, found_exceptions
def write_output_file(file_count, include_list, start_line, end_line, output_folder, output_filename_prefix, extension):
output_folder = os.path.abspath(output_folder)
if not os.path.isdir(output_folder):
# create
os.mkdir(output_folder)
if not os.path.isdir(output_folder):
print("ERROR " + output_folder + " could not be created.")
return
print("CREATING folder " + output_folder)
file_text = ""
for l in range(start_line, end_line):
if l < len(include_list):
line = include_list[l]
li = line + "\n"
file_text += li
# print(file_text)
num_string = ""
if file_count > 0:
num_string = "_" + str(file_count)
short_filename = output_filename_prefix + num_string + ".gen." + extension
output_filename = output_folder + "/" + short_filename
if _verbose:
print("generating: " + short_filename)
output_path = Path(output_filename)
output_path.write_text(file_text, encoding="utf8")
def write_exception_output_file(file_count, exception_string, output_folder, output_filename_prefix, extension):
output_folder = os.path.abspath(output_folder)
if not os.path.isdir(output_folder):
print("ERROR " + output_folder + " does not exist.")
return
file_text = exception_string + "\n"
num_string = ""
if file_count > 0:
num_string = "_" + str(file_count)
short_filename = output_filename_prefix + "_exception" + num_string + ".gen." + extension
output_filename = output_folder + "/" + short_filename
if _verbose:
print("generating: " + short_filename)
# print("text: " + file_text)
# return
output_path = Path(output_filename)
output_path.write_text(file_text, encoding="utf8")
def find_section_name(sub_folder):
# Construct a useful name for the section from the path for debug logging
section_path = os.path.abspath(base_folder_path + sub_folder) + "/"
folders = []
folder = ""
for i in range(8):
folder = os.path.dirname(section_path)
folder = os.path.basename(folder)
if folder == base_folder_only:
break
folders.append(folder)
section_path += "../"
section_path = os.path.abspath(section_path) + "/"
section_name = ""
for n in range(len(folders)):
section_name += folders[len(folders) - n - 1]
if n != (len(folders) - 1):
section_name += "_"
return section_name
# "folders" is a list of folders to add all the files from to add to the SCU
# "section (like a module)". The name of the scu file will be derived from the first folder
# (thus e.g. scene/3d becomes scu_scene_3d.gen.cpp)
# "includes_per_scu" limits the number of includes in a single scu file.
# This allows the module to be built in several translation units instead of just 1.
# This will usually be slower to compile but will use less memory per compiler instance, which
# is most relevant in release builds.
# "sought_exceptions" are a list of files (without extension) that contain
# e.g. naming conflicts, and are therefore not suitable for the scu build.
# These will automatically be placed in their own separate scu file,
# which is slow like a normal build, but prevents the naming conflicts.
# Ideally in these situations, the source code should be changed to prevent naming conflicts.
# "extension" will usually be cpp, but can also be set to c (for e.g. third party libraries that use c)
def process_folder(folders, sought_exceptions=[], includes_per_scu=0, extension="cpp"):
if len(folders) == 0:
return
# Construct the filename prefix from the FIRST folder name
# e.g. "scene_3d"
out_filename = find_section_name(folders[0])
found_includes = []
found_exceptions = []
main_folder = folders[0]
abs_main_folder = base_folder_path + main_folder
# Keep a record of all folders that have been processed for SCU,
# this enables deciding what to do when we call "add_source_files()"
global _scu_folders
_scu_folders.add(main_folder)
# main folder (first)
found_includes, found_exceptions = find_files_in_folder(
main_folder, "", found_includes, extension, sought_exceptions, found_exceptions
)
# sub folders
for d in range(1, len(folders)):
found_includes, found_exceptions = find_files_in_folder(
main_folder, folders[d], found_includes, extension, sought_exceptions, found_exceptions
)
found_includes = sorted(found_includes)
# calculate how many lines to write in each file
total_lines = len(found_includes)
# adjust number of output files according to whether DEV or release
num_output_files = 1
if _is_release_build:
# always have a maximum in release
includes_per_scu = 8
num_output_files = max(math.ceil(total_lines / float(includes_per_scu)), 1)
else:
if includes_per_scu > 0:
num_output_files = max(math.ceil(total_lines / float(includes_per_scu)), 1)
lines_per_file = math.ceil(total_lines / float(num_output_files))
lines_per_file = max(lines_per_file, 1)
start_line = 0
file_number = 0
# These do not vary throughout the loop
output_folder = abs_main_folder + "/scu/"
output_filename_prefix = "scu_" + out_filename
# Clear out any existing files (usually we will be overwriting,
# but we want to remove any that are pre-existing that will not be
# overwritten, so as to not compile anything stale)
clear_out_existing_files(output_folder, extension)
for file_count in range(0, num_output_files):
end_line = start_line + lines_per_file
# special case to cover rounding error in final file
if file_count == (num_output_files - 1):
end_line = len(found_includes)
write_output_file(
file_count, found_includes, start_line, end_line, output_folder, output_filename_prefix, extension
)
start_line = end_line
# Write the exceptions each in their own scu gen file,
# so they can effectively compile in "old style / normal build".
for exception_count in range(len(found_exceptions)):
write_exception_output_file(
exception_count, found_exceptions[exception_count], output_folder, output_filename_prefix, extension
)
def generate_scu_files(verbose, is_release_build):
print("=============================")
print("Single Compilation Unit Build")
print("=============================")
print("Generating SCU build files")
global _verbose
_verbose = verbose
global _is_release_build
_is_release_build = is_release_build
curr_folder = os.path.abspath("./")
# check we are running from the correct folder
if folder_not_found("core") or folder_not_found("platform") or folder_not_found("scene"):
raise RuntimeError("scu_builders.py must be run from the godot folder.")
return
process_folder(["core"])
process_folder(["core/crypto"])
process_folder(["core/debugger"])
process_folder(["core/extension"])
process_folder(["core/input"])
process_folder(["core/io"])
process_folder(["core/math"])
process_folder(["core/object"])
process_folder(["core/os"])
process_folder(["core/string"])
process_folder(["core/variant"], ["variant_utility"])
process_folder(["drivers/unix"])
process_folder(["drivers/png"])
process_folder(["editor"], ["file_system_dock", "editor_resource_preview"], 32)
process_folder(["editor/debugger"])
process_folder(["editor/debugger/debug_adapter"])
process_folder(["editor/export"])
process_folder(["editor/gui"])
process_folder(["editor/import"])
process_folder(["editor/plugins"])
process_folder(["editor/plugins/gizmos"])
process_folder(["editor/plugins/tiles"])
process_folder(["platform/android/export"])
process_folder(["platform/ios/export"])
process_folder(["platform/linuxbsd/export"])
process_folder(["platform/macos/export"])
process_folder(["platform/uwp/export"])
process_folder(["platform/web/export"])
process_folder(["platform/windows/export"])
process_folder(["modules/gltf"])
process_folder(["modules/gltf/structures"])
process_folder(["modules/gltf/editor"])
process_folder(["modules/gltf/extensions"])
process_folder(["modules/gltf/extensions/physics"])
process_folder(["modules/navigation"])
process_folder(["modules/webrtc"])
process_folder(["modules/websocket"])
process_folder(["modules/gridmap"])
process_folder(["modules/multiplayer"])
process_folder(["modules/multiplayer/editor"])
process_folder(["modules/openxr"], ["register_types"])
process_folder(["modules/openxr/action_map"])
process_folder(["modules/openxr/editor"])
process_folder(["modules/csg"])
process_folder(["modules/gdscript"])
process_folder(["modules/gdscript/editor"])
process_folder(["modules/gdscript/language_server"])
process_folder(["scene/2d"])
process_folder(["scene/3d"])
process_folder(["scene/animation"])
process_folder(["scene/gui"])
process_folder(["scene/main"])
process_folder(["scene/resources"])
process_folder(["servers"])
process_folder(["servers/rendering"])
process_folder(["servers/rendering/storage"])
process_folder(["servers/rendering/renderer_rd"])
process_folder(["servers/rendering/renderer_rd/effects"])
process_folder(["servers/rendering/renderer_rd/environment"])
process_folder(["servers/rendering/renderer_rd/storage_rd"])
process_folder(["servers/physics_2d"])
process_folder(["servers/physics_3d"])
process_folder(["servers/physics_3d/joints"])
process_folder(["servers/audio"])
process_folder(["servers/audio/effects"])
# Finally change back the path to the calling folder
os.chdir(curr_folder)
return _scu_folders

View file

@ -39,6 +39,39 @@ protected:
bool dynamic_A = false;
bool dynamic_B = false;
void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
if (Math::abs(n.z) > Math_SQRT12) {
// choose p in y-z plane
real_t a = n[1] * n[1] + n[2] * n[2];
real_t k = 1.0 / Math::sqrt(a);
p = Vector3(0, -n[2] * k, n[1] * k);
// set q = n x p
q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
} else {
// choose p in x-y plane
real_t a = n.x * n.x + n.y * n.y;
real_t k = 1.0 / Math::sqrt(a);
p = Vector3(-n.y * k, n.x * k, 0);
// set q = n x p
q = Vector3(-n.z * p.y, n.z * p.x, a * k);
}
}
_FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
real_t coeff_1 = Math_PI / 4.0f;
real_t coeff_2 = 3.0f * coeff_1;
real_t abs_y = Math::abs(y);
real_t angle;
if (x >= 0.0f) {
real_t r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
} else {
real_t r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
return (y < 0.0f) ? -angle : angle;
}
public:
virtual bool setup(real_t p_step) override { return false; }
virtual bool pre_solve(real_t p_step) override { return true; }

View file

@ -51,39 +51,6 @@ Written by: Marcus Hennix
#include "godot_cone_twist_joint_3d.h"
static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
if (Math::abs(n.z) > Math_SQRT12) {
// choose p in y-z plane
real_t a = n[1] * n[1] + n[2] * n[2];
real_t k = 1.0 / Math::sqrt(a);
p = Vector3(0, -n[2] * k, n[1] * k);
// set q = n x p
q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
} else {
// choose p in x-y plane
real_t a = n.x * n.x + n.y * n.y;
real_t k = 1.0 / Math::sqrt(a);
p = Vector3(-n.y * k, n.x * k, 0);
// set q = n x p
q = Vector3(-n.z * p.y, n.z * p.x, a * k);
}
}
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
real_t coeff_1 = Math_PI / 4.0f;
real_t coeff_2 = 3.0f * coeff_1;
real_t abs_y = Math::abs(y);
real_t angle;
if (x >= 0.0f) {
real_t r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
} else {
real_t r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
return (y < 0.0f) ? -angle : angle;
}
GodotConeTwistJoint3D::GodotConeTwistJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &rbAFrame, const Transform3D &rbBFrame) :
GodotJoint3D(_arr, 2) {
A = rbA;

View file

@ -49,24 +49,6 @@ subject to the following restrictions:
#include "godot_hinge_joint_3d.h"
static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
if (Math::abs(n.z) > Math_SQRT12) {
// choose p in y-z plane
real_t a = n[1] * n[1] + n[2] * n[2];
real_t k = 1.0 / Math::sqrt(a);
p = Vector3(0, -n[2] * k, n[1] * k);
// set q = n x p
q = Vector3(a * k, -n[0] * p[2], n[0] * p[1]);
} else {
// choose p in x-y plane
real_t a = n.x * n.x + n.y * n.y;
real_t k = 1.0 / Math::sqrt(a);
p = Vector3(-n.y * k, n.x * k, 0);
// set q = n x p
q = Vector3(-n.z * p.y, n.z * p.x, a * k);
}
}
GodotHingeJoint3D::GodotHingeJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameA, const Transform3D &frameB) :
GodotJoint3D(_arr, 2) {
A = rbA;
@ -368,21 +350,6 @@ void HingeJointSW::updateRHS(real_t timeStep)
*/
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
real_t coeff_1 = Math_PI / 4.0f;
real_t coeff_2 = 3.0f * coeff_1;
real_t abs_y = Math::abs(y);
real_t angle;
if (x >= 0.0f) {
real_t r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
} else {
real_t r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
return (y < 0.0f) ? -angle : angle;
}
real_t GodotHingeJoint3D::get_hinge_angle() {
const Vector3 refAxis0 = A->get_transform().basis.xform(m_rbAFrame.basis.get_column(0));
const Vector3 refAxis1 = A->get_transform().basis.xform(m_rbAFrame.basis.get_column(1));

View file

@ -57,25 +57,6 @@ April 04, 2008
//-----------------------------------------------------------------------------
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
real_t coeff_1 = Math_PI / 4.0f;
real_t coeff_2 = 3.0f * coeff_1;
real_t abs_y = Math::abs(y);
real_t angle;
if (x >= 0.0f) {
real_t r = (x - abs_y) / (x + abs_y);
angle = coeff_1 - coeff_1 * r;
} else {
real_t r = (x + abs_y) / (abs_y - x);
angle = coeff_2 - coeff_1 * r;
}
return (y < 0.0f) ? -angle : angle;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
GodotSliderJoint3D::GodotSliderJoint3D(GodotBody3D *rbA, GodotBody3D *rbB, const Transform3D &frameInA, const Transform3D &frameInB) :
GodotJoint3D(_arr, 2),
m_frameInA(frameInA),

View file

@ -36,8 +36,6 @@
#include "rendering_server_globals.h"
#include "servers/rendering/storage/texture_storage.h"
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask) {
RENDER_TIMESTAMP("Cull CanvasItem Tree");

View file

@ -183,6 +183,8 @@ private:
void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t canvas_cull_mask);
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool allow_y_sort, uint32_t canvas_cull_mask);
static constexpr int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
RendererCanvasRender::Item **z_list;
RendererCanvasRender::Item **z_last_list;