mirror of
https://github.com/Relintai/pandemonium_engine_minimal.git
synced 2024-12-21 16:56:50 +01:00
Removed RenderingServerScene.
This commit is contained in:
parent
8d5eb28de5
commit
bbb446c509
@ -67,7 +67,6 @@
|
||||
#include "servers/navigation_server.h"
|
||||
#include "servers/physics_2d_server.h"
|
||||
#include "servers/register_server_types.h"
|
||||
#include "servers/rendering_server_callbacks.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "editor/doc/doc_data.h"
|
||||
@ -111,7 +110,6 @@ static MessageQueue *message_queue = nullptr;
|
||||
// Initialized in setup2()
|
||||
static AudioServer *audio_server = nullptr;
|
||||
static Physics2DServer *physics_2d_server = nullptr;
|
||||
static RenderingServerCallbacks *rendering_server_callbacks = nullptr;
|
||||
static NavigationMeshGeneratorManager *navigation_mesh_generator_manager = nullptr;
|
||||
static NavigationMeshGenerator *navigation_mesh_generator = nullptr;
|
||||
static NavigationServer *navigation_server = nullptr;
|
||||
@ -1573,9 +1571,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
|
||||
script_debugger->profiling_start();
|
||||
}
|
||||
|
||||
rendering_server_callbacks = memnew(RenderingServerCallbacks);
|
||||
RenderingServer::get_singleton()->callbacks_register(rendering_server_callbacks);
|
||||
|
||||
_start_success = true;
|
||||
|
||||
ClassDB::set_current_api(ClassDB::API_NONE); //no more api is registered at this point
|
||||
@ -2308,7 +2303,7 @@ bool Main::iteration() {
|
||||
if (OS::get_singleton()->get_main_loop()->idle(step * time_scale)) {
|
||||
exit = true;
|
||||
}
|
||||
rendering_server_callbacks->flush();
|
||||
|
||||
message_queue->flush();
|
||||
|
||||
NavigationMeshGenerator::get_singleton()->process();
|
||||
@ -2538,10 +2533,6 @@ void Main::cleanup(bool p_force) {
|
||||
message_queue->flush();
|
||||
memdelete(message_queue);
|
||||
|
||||
if (rendering_server_callbacks) {
|
||||
memdelete(rendering_server_callbacks);
|
||||
}
|
||||
|
||||
unregister_core_driver_types();
|
||||
unregister_core_types();
|
||||
|
||||
|
@ -255,7 +255,6 @@ void Viewport::_notification(int p_what) {
|
||||
world_2d->_remove_world(this);
|
||||
}
|
||||
|
||||
RenderingServer::get_singleton()->viewport_set_scenario(viewport, RID());
|
||||
// SpatialSoundServer::get_singleton()->listener_set_space(internal_listener, RID());
|
||||
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
|
||||
if (contact_2d_debug.is_valid()) {
|
||||
@ -604,7 +603,6 @@ void Viewport::_on_before_world_override_changed() {
|
||||
World *w = get_override_world_or_this();
|
||||
|
||||
if (w) {
|
||||
RenderingServer::get_singleton()->viewport_set_scenario(viewport, RID());
|
||||
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
|
||||
w->find_world_2d()->_remove_world(this);
|
||||
}
|
||||
|
@ -37,4 +37,3 @@ Rasterizer *RenderingServerGlobals::rasterizer = nullptr;
|
||||
|
||||
RenderingServerCanvas *RenderingServerGlobals::canvas = nullptr;
|
||||
RenderingServerViewport *RenderingServerGlobals::viewport = nullptr;
|
||||
RenderingServerScene *RenderingServerGlobals::scene = nullptr;
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
class RenderingServerCanvas;
|
||||
class RenderingServerViewport;
|
||||
class RenderingServerScene;
|
||||
|
||||
class RenderingServerGlobals {
|
||||
public:
|
||||
@ -45,7 +44,6 @@ public:
|
||||
|
||||
static RenderingServerCanvas *canvas;
|
||||
static RenderingServerViewport *viewport;
|
||||
static RenderingServerScene *scene;
|
||||
};
|
||||
|
||||
#define RSG RenderingServerGlobals
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "core/os/os.h"
|
||||
#include "rendering_server_canvas.h"
|
||||
#include "rendering_server_globals.h"
|
||||
#include "rendering_server_scene.h"
|
||||
|
||||
// careful, these may run in different threads than the visual server
|
||||
|
||||
@ -79,9 +78,6 @@ void RenderingServerRaster::free(RID p_rid) {
|
||||
if (RSG::viewport->free(p_rid)) {
|
||||
return;
|
||||
}
|
||||
if (RSG::scene->free(p_rid)) {
|
||||
return;
|
||||
}
|
||||
if (RSG::scene_render->free(p_rid)) {
|
||||
return;
|
||||
}
|
||||
@ -110,8 +106,6 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) {
|
||||
|
||||
RSG::rasterizer->begin_frame(frame_step);
|
||||
|
||||
RSG::scene->update_dirty_instances(); //update scene stuff
|
||||
|
||||
RSG::viewport->draw_viewports();
|
||||
_draw_margins();
|
||||
RSG::rasterizer->end_frame(p_swap_buffers);
|
||||
@ -136,17 +130,14 @@ void RenderingServerRaster::sync() {
|
||||
}
|
||||
|
||||
void RenderingServerRaster::set_physics_interpolation_enabled(bool p_enabled) {
|
||||
RSG::scene->set_physics_interpolation_enabled(p_enabled);
|
||||
RSG::canvas->set_physics_interpolation_enabled(p_enabled);
|
||||
}
|
||||
|
||||
void RenderingServerRaster::tick() {
|
||||
RSG::scene->tick();
|
||||
RSG::canvas->tick();
|
||||
}
|
||||
|
||||
void RenderingServerRaster::pre_draw(bool p_will_draw) {
|
||||
RSG::scene->pre_draw(p_will_draw);
|
||||
}
|
||||
|
||||
bool RenderingServerRaster::has_changed(ChangedPriority p_priority) const {
|
||||
@ -230,7 +221,6 @@ bool RenderingServerRaster::is_low_end() const {
|
||||
RenderingServerRaster::RenderingServerRaster() {
|
||||
RSG::canvas = memnew(RenderingServerCanvas);
|
||||
RSG::viewport = memnew(RenderingServerViewport);
|
||||
RSG::scene = memnew(RenderingServerScene);
|
||||
RSG::rasterizer = Rasterizer::create();
|
||||
RSG::storage = RSG::rasterizer->get_storage();
|
||||
RSG::canvas_render = RSG::rasterizer->get_canvas();
|
||||
@ -246,5 +236,4 @@ RenderingServerRaster::~RenderingServerRaster() {
|
||||
memdelete(RSG::canvas);
|
||||
memdelete(RSG::viewport);
|
||||
memdelete(RSG::rasterizer);
|
||||
memdelete(RSG::scene);
|
||||
}
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "core/math/octree.h"
|
||||
#include "rendering_server_canvas.h"
|
||||
#include "rendering_server_globals.h"
|
||||
#include "rendering_server_scene.h"
|
||||
#include "rendering_server_viewport.h"
|
||||
#include "servers/rendering/rasterizer.h"
|
||||
#include "servers/rendering_server.h"
|
||||
@ -282,23 +281,6 @@ public:
|
||||
BIND2(multimesh_set_visible_instances, RID, int)
|
||||
BIND1RC(int, multimesh_get_visible_instances, RID)
|
||||
|
||||
#undef BINDBASE
|
||||
//from now on, calls forwarded to this singleton
|
||||
#define BINDBASE RSG::scene
|
||||
|
||||
/* CAMERA API */
|
||||
|
||||
BIND0R(RID, camera_create)
|
||||
BIND4(camera_set_perspective, RID, float, float, float)
|
||||
BIND4(camera_set_orthogonal, RID, float, float, float)
|
||||
BIND5(camera_set_frustum, RID, float, Vector2, float, float)
|
||||
BIND2(camera_set_transform, RID, const Transform &)
|
||||
BIND2(camera_set_interpolated, RID, bool)
|
||||
BIND1(camera_reset_physics_interpolation, RID)
|
||||
BIND2(camera_set_cull_mask, RID, uint32_t)
|
||||
BIND2(camera_set_environment, RID, RID)
|
||||
BIND2(camera_set_use_vertical_aspect, RID, bool)
|
||||
|
||||
#undef BINDBASE
|
||||
//from now on, calls forwarded to this singleton
|
||||
#define BINDBASE RSG::viewport
|
||||
@ -323,14 +305,11 @@ public:
|
||||
|
||||
BIND1RC(RID, viewport_get_texture, RID)
|
||||
|
||||
BIND2(viewport_set_hide_scenario, RID, bool)
|
||||
BIND2(viewport_set_hide_canvas, RID, bool)
|
||||
BIND2(viewport_set_disable_environment, RID, bool)
|
||||
BIND2(viewport_set_disable_3d, RID, bool)
|
||||
BIND2(viewport_set_keep_3d_linear, RID, bool)
|
||||
|
||||
BIND2(viewport_attach_camera, RID, RID)
|
||||
BIND2(viewport_set_scenario, RID, RID)
|
||||
BIND2(viewport_attach_canvas, RID, RID)
|
||||
|
||||
BIND2(viewport_remove_canvas, RID, RID)
|
||||
@ -350,20 +329,6 @@ public:
|
||||
BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
|
||||
BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw)
|
||||
|
||||
/* ENVIRONMENT API */
|
||||
|
||||
#undef BINDBASE
|
||||
#define BINDBASE RSG::scene
|
||||
|
||||
/* SCENARIO API */
|
||||
|
||||
BIND0R(RID, scenario_create)
|
||||
|
||||
BIND2(scenario_set_debug, RID, ScenarioDebugMode)
|
||||
|
||||
// Callbacks
|
||||
BIND1(callbacks_register, RenderingServerCallbacks *)
|
||||
|
||||
#undef BINDBASE
|
||||
//from now on, calls forwarded to this singleton
|
||||
#define BINDBASE RSG::canvas
|
||||
|
@ -1,929 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* rendering_server_scene.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "rendering_server_scene.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/math/transform_interpolator.h"
|
||||
#include "core/os/os.h"
|
||||
#include "rendering_server_globals.h"
|
||||
#include "rendering_server_raster.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
/* CAMERA API */
|
||||
|
||||
Transform RenderingServerScene::Camera::get_transform_interpolated() const {
|
||||
if (!interpolated) {
|
||||
return transform;
|
||||
}
|
||||
|
||||
Transform final;
|
||||
TransformInterpolator::interpolate_transform_via_method(transform_prev, transform, final, Engine::get_singleton()->get_physics_interpolation_fraction(), interpolation_method);
|
||||
return final;
|
||||
}
|
||||
|
||||
RID RenderingServerScene::camera_create() {
|
||||
Camera *camera = memnew(Camera);
|
||||
return camera_owner.make_rid(camera);
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
camera->type = Camera::PERSPECTIVE;
|
||||
camera->fov = p_fovy_degrees;
|
||||
camera->znear = p_z_near;
|
||||
camera->zfar = p_z_far;
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
camera->type = Camera::ORTHOGONAL;
|
||||
camera->size = p_size;
|
||||
camera->znear = p_z_near;
|
||||
camera->zfar = p_z_far;
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
camera->type = Camera::FRUSTUM;
|
||||
camera->size = p_size;
|
||||
camera->offset = p_offset;
|
||||
camera->znear = p_z_near;
|
||||
camera->zfar = p_z_far;
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_reset_physics_interpolation(RID p_camera) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
|
||||
if (_interpolation_data.interpolation_enabled && camera->interpolated) {
|
||||
_interpolation_data.camera_teleport_list.push_back(p_camera);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_set_interpolated(RID p_camera, bool p_interpolated) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
camera->interpolated = p_interpolated;
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_set_transform(RID p_camera, const Transform &p_transform) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
|
||||
camera->transform = p_transform.orthonormalized();
|
||||
|
||||
if (_interpolation_data.interpolation_enabled && camera->interpolated) {
|
||||
if (!camera->on_interpolate_transform_list) {
|
||||
_interpolation_data.camera_transform_update_list_curr->push_back(p_camera);
|
||||
camera->on_interpolate_transform_list = true;
|
||||
}
|
||||
|
||||
// decide on the interpolation method .. slerp if possible
|
||||
camera->interpolation_method = TransformInterpolator::find_method(camera->transform_prev.basis, camera->transform.basis);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
|
||||
camera->visible_layers = p_layers;
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_set_environment(RID p_camera, RID p_env) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
camera->env = p_env;
|
||||
}
|
||||
|
||||
void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) {
|
||||
Camera *camera = camera_owner.get(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
camera->vaspect = p_enable;
|
||||
}
|
||||
|
||||
/* SPATIAL PARTITIONING */
|
||||
|
||||
RenderingServerScene::SpatialPartitioningScene_BVH::SpatialPartitioningScene_BVH() {
|
||||
_bvh.params_set_thread_safe(GLOBAL_GET("rendering/threads/thread_safe_bvh"));
|
||||
_bvh.params_set_pairing_expansion(GLOBAL_GET("rendering/quality/spatial_partitioning/bvh_collision_margin"));
|
||||
|
||||
_dummy_cull_object = memnew(Instance);
|
||||
}
|
||||
|
||||
RenderingServerScene::SpatialPartitioningScene_BVH::~SpatialPartitioningScene_BVH() {
|
||||
if (_dummy_cull_object) {
|
||||
memdelete(_dummy_cull_object);
|
||||
_dummy_cull_object = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
RenderingServerScene::SpatialPartitionID RenderingServerScene::SpatialPartitioningScene_BVH::create(Instance *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
||||
#if defined(DEBUG_ENABLED) && defined(TOOLS_ENABLED)
|
||||
// we are relying on this instance to be valid in order to pass
|
||||
// the visible flag to the bvh.
|
||||
DEV_ASSERT(p_userdata);
|
||||
#endif
|
||||
|
||||
// cache the pairable mask and pairable type on the instance as it is needed for user callbacks from the BVH, and this is
|
||||
// too complex to calculate each callback...
|
||||
p_userdata->bvh_pairable_mask = p_pairable_mask;
|
||||
p_userdata->bvh_pairable_type = p_pairable_type;
|
||||
|
||||
uint32_t tree_collision_mask = 0;
|
||||
uint32_t tree_id = find_tree_id_and_collision_mask(p_pairable, tree_collision_mask);
|
||||
|
||||
return _bvh.create(p_userdata, p_userdata->visible, tree_id, tree_collision_mask, p_aabb, p_subindex) + 1;
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::erase(SpatialPartitionID p_handle) {
|
||||
_bvh.erase(p_handle - 1);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::move(SpatialPartitionID p_handle, const AABB &p_aabb) {
|
||||
_bvh.move(p_handle - 1, p_aabb);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::activate(SpatialPartitionID p_handle, const AABB &p_aabb) {
|
||||
// be very careful here, we are deferring the collision check, expecting a set_pairable to be called
|
||||
// immediately after.
|
||||
// see the notes in the BVH function.
|
||||
_bvh.activate(p_handle - 1, p_aabb, true);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::deactivate(SpatialPartitionID p_handle) {
|
||||
_bvh.deactivate(p_handle - 1);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::force_collision_check(SpatialPartitionID p_handle) {
|
||||
_bvh.force_collision_check(p_handle - 1);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::update() {
|
||||
_bvh.update();
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::update_collisions() {
|
||||
_bvh.update_collisions();
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::set_pairable(Instance *p_instance, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
||||
SpatialPartitionID handle = p_instance->spatial_partition_id;
|
||||
|
||||
p_instance->bvh_pairable_mask = p_pairable_mask;
|
||||
p_instance->bvh_pairable_type = p_pairable_type;
|
||||
|
||||
uint32_t tree_collision_mask = 0;
|
||||
uint32_t tree_id = find_tree_id_and_collision_mask(p_pairable, tree_collision_mask);
|
||||
|
||||
_bvh.set_tree(handle - 1, tree_id, tree_collision_mask);
|
||||
}
|
||||
|
||||
int RenderingServerScene::SpatialPartitioningScene_BVH::cull_convex(const Vector<Plane> &p_convex, Instance **p_result_array, int p_result_max, uint32_t p_mask) {
|
||||
_dummy_cull_object->bvh_pairable_mask = p_mask;
|
||||
_dummy_cull_object->bvh_pairable_type = 0;
|
||||
return _bvh.cull_convex(p_convex, p_result_array, p_result_max, _dummy_cull_object);
|
||||
}
|
||||
|
||||
int RenderingServerScene::SpatialPartitioningScene_BVH::cull_aabb(const AABB &p_aabb, Instance **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
|
||||
_dummy_cull_object->bvh_pairable_mask = p_mask;
|
||||
_dummy_cull_object->bvh_pairable_type = 0;
|
||||
return _bvh.cull_aabb(p_aabb, p_result_array, p_result_max, _dummy_cull_object, 0xFFFFFFFF, p_subindex_array);
|
||||
}
|
||||
|
||||
int RenderingServerScene::SpatialPartitioningScene_BVH::cull_segment(const Vector3 &p_from, const Vector3 &p_to, Instance **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
|
||||
_dummy_cull_object->bvh_pairable_mask = p_mask;
|
||||
_dummy_cull_object->bvh_pairable_type = 0;
|
||||
return _bvh.cull_segment(p_from, p_to, p_result_array, p_result_max, _dummy_cull_object, 0xFFFFFFFF, p_subindex_array);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::set_pair_callback(PairCallback p_callback, void *p_userdata) {
|
||||
_bvh.set_pair_callback(p_callback, p_userdata);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_BVH::set_unpair_callback(UnpairCallback p_callback, void *p_userdata) {
|
||||
_bvh.set_unpair_callback(p_callback, p_userdata);
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
|
||||
RenderingServerScene::SpatialPartitionID RenderingServerScene::SpatialPartitioningScene_Octree::create(Instance *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
||||
return _octree.create(p_userdata, p_aabb, p_subindex, p_pairable, p_pairable_type, p_pairable_mask);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_Octree::erase(SpatialPartitionID p_handle) {
|
||||
_octree.erase(p_handle);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_Octree::move(SpatialPartitionID p_handle, const AABB &p_aabb) {
|
||||
_octree.move(p_handle, p_aabb);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_Octree::set_pairable(Instance *p_instance, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
|
||||
SpatialPartitionID handle = p_instance->spatial_partition_id;
|
||||
_octree.set_pairable(handle, p_pairable, p_pairable_type, p_pairable_mask);
|
||||
}
|
||||
|
||||
int RenderingServerScene::SpatialPartitioningScene_Octree::cull_convex(const Vector<Plane> &p_convex, Instance **p_result_array, int p_result_max, uint32_t p_mask) {
|
||||
return _octree.cull_convex(p_convex, p_result_array, p_result_max, p_mask);
|
||||
}
|
||||
|
||||
int RenderingServerScene::SpatialPartitioningScene_Octree::cull_aabb(const AABB &p_aabb, Instance **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
|
||||
return _octree.cull_aabb(p_aabb, p_result_array, p_result_max, p_subindex_array, p_mask);
|
||||
}
|
||||
|
||||
int RenderingServerScene::SpatialPartitioningScene_Octree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, Instance **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
|
||||
return _octree.cull_segment(p_from, p_to, p_result_array, p_result_max, p_subindex_array, p_mask);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_Octree::set_pair_callback(PairCallback p_callback, void *p_userdata) {
|
||||
_octree.set_pair_callback(p_callback, p_userdata);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_Octree::set_unpair_callback(UnpairCallback p_callback, void *p_userdata) {
|
||||
_octree.set_unpair_callback(p_callback, p_userdata);
|
||||
}
|
||||
|
||||
void RenderingServerScene::SpatialPartitioningScene_Octree::set_balance(float p_balance) {
|
||||
_octree.set_balance(p_balance);
|
||||
}
|
||||
|
||||
/* SCENARIO API */
|
||||
|
||||
RenderingServerScene::Scenario::Scenario() {
|
||||
debug = RS::SCENARIO_DEBUG_DISABLED;
|
||||
|
||||
bool use_bvh_or_octree = GLOBAL_GET("rendering/quality/spatial_partitioning/use_bvh");
|
||||
|
||||
if (use_bvh_or_octree) {
|
||||
sps = memnew(SpatialPartitioningScene_BVH);
|
||||
} else {
|
||||
sps = memnew(SpatialPartitioningScene_Octree);
|
||||
}
|
||||
}
|
||||
|
||||
void *RenderingServerScene::_instance_pair(void *p_self, SpatialPartitionID, Instance *p_A, int, SpatialPartitionID, Instance *p_B, int) {
|
||||
//RenderingServerScene *self = (RenderingServerScene*)p_self;
|
||||
Instance *A = p_A;
|
||||
Instance *B = p_B;
|
||||
|
||||
//instance indices are designed so greater always contains lesser
|
||||
if (A->base_type > B->base_type) {
|
||||
SWAP(A, B); //lesser always first
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void RenderingServerScene::_instance_unpair(void *p_self, SpatialPartitionID, Instance *p_A, int, SpatialPartitionID, Instance *p_B, int, void *udata) {
|
||||
//RenderingServerScene *self = (RenderingServerScene*)p_self;
|
||||
Instance *A = p_A;
|
||||
Instance *B = p_B;
|
||||
|
||||
//instance indices are designed so greater always contains lesser
|
||||
if (A->base_type > B->base_type) {
|
||||
SWAP(A, B); //lesser always first
|
||||
}
|
||||
}
|
||||
|
||||
RID RenderingServerScene::scenario_create() {
|
||||
Scenario *scenario = memnew(Scenario);
|
||||
ERR_FAIL_COND_V(!scenario, RID());
|
||||
RID scenario_rid = scenario_owner.make_rid(scenario);
|
||||
scenario->self = scenario_rid;
|
||||
|
||||
scenario->sps->set_balance(GLOBAL_GET("rendering/quality/spatial_partitioning/render_tree_balance"));
|
||||
scenario->sps->set_pair_callback(_instance_pair, this);
|
||||
scenario->sps->set_unpair_callback(_instance_unpair, this);
|
||||
|
||||
return scenario_rid;
|
||||
}
|
||||
|
||||
void RenderingServerScene::set_physics_interpolation_enabled(bool p_enabled) {
|
||||
_interpolation_data.interpolation_enabled = p_enabled;
|
||||
}
|
||||
|
||||
void RenderingServerScene::tick() {
|
||||
if (_interpolation_data.interpolation_enabled) {
|
||||
update_interpolation_tick(true);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingServerScene::pre_draw(bool p_will_draw) {
|
||||
// even when running and not drawing scenes, we still need to clear intermediate per frame
|
||||
// interpolation data .. hence the p_will_draw flag (so we can reduce the processing if the frame
|
||||
// will not be drawn)
|
||||
if (_interpolation_data.interpolation_enabled) {
|
||||
update_interpolation_frame(p_will_draw);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingServerScene::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) {
|
||||
Scenario *scenario = scenario_owner.get(p_scenario);
|
||||
ERR_FAIL_COND(!scenario);
|
||||
scenario->debug = p_debug_mode;
|
||||
}
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
void RenderingServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_materials) {
|
||||
if (p_update_aabb) {
|
||||
p_instance->update_aabb = true;
|
||||
}
|
||||
if (p_update_materials) {
|
||||
p_instance->update_materials = true;
|
||||
}
|
||||
|
||||
if (p_instance->update_item.in_list()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_instance_update_list.add(&p_instance->update_item);
|
||||
}
|
||||
|
||||
void RenderingServerScene::InterpolationData::notify_free_camera(RID p_rid, Camera &r_camera) {
|
||||
r_camera.on_interpolate_transform_list = false;
|
||||
|
||||
if (!interpolation_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the camera was on any of the lists, remove
|
||||
camera_transform_update_list_curr->erase_multiple_unordered(p_rid);
|
||||
camera_transform_update_list_prev->erase_multiple_unordered(p_rid);
|
||||
camera_teleport_list.erase_multiple_unordered(p_rid);
|
||||
}
|
||||
|
||||
void RenderingServerScene::InterpolationData::notify_free_instance(RID p_rid, Instance &r_instance) {
|
||||
r_instance.on_interpolate_list = false;
|
||||
r_instance.on_interpolate_transform_list = false;
|
||||
|
||||
if (!interpolation_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if the instance was on any of the lists, remove
|
||||
instance_interpolate_update_list.erase_multiple_unordered(p_rid);
|
||||
instance_transform_update_list_curr->erase_multiple_unordered(p_rid);
|
||||
instance_transform_update_list_prev->erase_multiple_unordered(p_rid);
|
||||
instance_teleport_list.erase_multiple_unordered(p_rid);
|
||||
}
|
||||
|
||||
void RenderingServerScene::update_interpolation_tick(bool p_process) {
|
||||
// update interpolation in storage
|
||||
RSG::storage->update_interpolation_tick(p_process);
|
||||
|
||||
// detect any that were on the previous transform list that are no longer active,
|
||||
// we should remove them from the interpolate list
|
||||
|
||||
for (unsigned int n = 0; n < _interpolation_data.instance_transform_update_list_prev->size(); n++) {
|
||||
const RID &rid = (*_interpolation_data.instance_transform_update_list_prev)[n];
|
||||
Instance *instance = instance_owner.getornull(rid);
|
||||
|
||||
bool active = true;
|
||||
|
||||
// no longer active? (either the instance deleted or no longer being transformed)
|
||||
if (instance && !instance->on_interpolate_transform_list) {
|
||||
active = false;
|
||||
instance->on_interpolate_list = false;
|
||||
|
||||
// make sure the most recent transform is set
|
||||
instance->transform = instance->transform_curr;
|
||||
|
||||
// and that both prev and current are the same, just in case of any interpolations
|
||||
instance->transform_prev = instance->transform_curr;
|
||||
|
||||
// make sure are updated one more time to ensure the AABBs are correct
|
||||
_instance_queue_update(instance, true);
|
||||
}
|
||||
|
||||
if (!instance) {
|
||||
active = false;
|
||||
}
|
||||
|
||||
if (!active) {
|
||||
_interpolation_data.instance_interpolate_update_list.erase(rid);
|
||||
}
|
||||
}
|
||||
|
||||
// and now for any in the transform list (being actively interpolated), keep the previous transform
|
||||
// value up to date ready for the next tick
|
||||
if (p_process) {
|
||||
for (unsigned int n = 0; n < _interpolation_data.instance_transform_update_list_curr->size(); n++) {
|
||||
const RID &rid = (*_interpolation_data.instance_transform_update_list_curr)[n];
|
||||
Instance *instance = instance_owner.getornull(rid);
|
||||
if (instance) {
|
||||
instance->transform_prev = instance->transform_curr;
|
||||
instance->transform_checksum_prev = instance->transform_checksum_curr;
|
||||
instance->on_interpolate_transform_list = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we maintain a mirror list for the transform updates, so we can detect when an instance
|
||||
// is no longer being transformed, and remove it from the interpolate list
|
||||
SWAP(_interpolation_data.instance_transform_update_list_curr, _interpolation_data.instance_transform_update_list_prev);
|
||||
|
||||
// prepare for the next iteration
|
||||
_interpolation_data.instance_transform_update_list_curr->clear();
|
||||
|
||||
// CAMERAS
|
||||
// detect any that were on the previous transform list that are no longer active,
|
||||
for (unsigned int n = 0; n < _interpolation_data.camera_transform_update_list_prev->size(); n++) {
|
||||
const RID &rid = (*_interpolation_data.camera_transform_update_list_prev)[n];
|
||||
Camera *camera = camera_owner.getornull(rid);
|
||||
|
||||
// no longer active? (either the instance deleted or no longer being transformed)
|
||||
if (camera && !camera->on_interpolate_transform_list) {
|
||||
camera->transform = camera->transform_prev;
|
||||
}
|
||||
}
|
||||
|
||||
// cameras , swap any current with previous
|
||||
for (unsigned int n = 0; n < _interpolation_data.camera_transform_update_list_curr->size(); n++) {
|
||||
const RID &rid = (*_interpolation_data.camera_transform_update_list_curr)[n];
|
||||
Camera *camera = camera_owner.getornull(rid);
|
||||
if (camera) {
|
||||
camera->transform_prev = camera->transform;
|
||||
camera->on_interpolate_transform_list = false;
|
||||
}
|
||||
}
|
||||
|
||||
// we maintain a mirror list for the transform updates, so we can detect when an instance
|
||||
// is no longer being transformed, and remove it from the interpolate list
|
||||
SWAP(_interpolation_data.camera_transform_update_list_curr, _interpolation_data.camera_transform_update_list_prev);
|
||||
|
||||
// prepare for the next iteration
|
||||
_interpolation_data.camera_transform_update_list_curr->clear();
|
||||
}
|
||||
|
||||
void RenderingServerScene::update_interpolation_frame(bool p_process) {
|
||||
// update interpolation in storage
|
||||
RSG::storage->update_interpolation_frame(p_process);
|
||||
|
||||
// teleported instances
|
||||
for (unsigned int n = 0; n < _interpolation_data.instance_teleport_list.size(); n++) {
|
||||
const RID &rid = _interpolation_data.instance_teleport_list[n];
|
||||
Instance *instance = instance_owner.getornull(rid);
|
||||
if (instance) {
|
||||
instance->transform_prev = instance->transform_curr;
|
||||
instance->transform_checksum_prev = instance->transform_checksum_curr;
|
||||
}
|
||||
}
|
||||
|
||||
_interpolation_data.instance_teleport_list.clear();
|
||||
|
||||
// camera teleports
|
||||
for (unsigned int n = 0; n < _interpolation_data.camera_teleport_list.size(); n++) {
|
||||
const RID &rid = _interpolation_data.camera_teleport_list[n];
|
||||
Camera *camera = camera_owner.getornull(rid);
|
||||
if (camera) {
|
||||
camera->transform_prev = camera->transform;
|
||||
}
|
||||
}
|
||||
|
||||
_interpolation_data.camera_teleport_list.clear();
|
||||
|
||||
if (p_process) {
|
||||
real_t f = Engine::get_singleton()->get_physics_interpolation_fraction();
|
||||
|
||||
for (unsigned int i = 0; i < _interpolation_data.instance_interpolate_update_list.size(); i++) {
|
||||
const RID &rid = _interpolation_data.instance_interpolate_update_list[i];
|
||||
Instance *instance = instance_owner.getornull(rid);
|
||||
if (instance) {
|
||||
TransformInterpolator::interpolate_transform_via_method(instance->transform_prev, instance->transform_curr, instance->transform, f, instance->interpolation_method);
|
||||
|
||||
// make sure AABBs are constantly up to date through the interpolation
|
||||
_instance_queue_update(instance, true);
|
||||
}
|
||||
} // for n
|
||||
}
|
||||
}
|
||||
|
||||
// Rooms
|
||||
void RenderingServerScene::callbacks_register(RenderingServerCallbacks *p_callbacks) {
|
||||
_rendering_server_callbacks = p_callbacks;
|
||||
}
|
||||
|
||||
|
||||
void RenderingServerScene::_update_instance(Instance *p_instance) {
|
||||
p_instance->version++;
|
||||
|
||||
// when not using interpolation the transform is used straight
|
||||
const Transform *instance_xform = &p_instance->transform;
|
||||
|
||||
// Can possibly use the most up to date current transform here when using physics interpolation ..
|
||||
// uncomment the next line for this..
|
||||
// if (p_instance->is_currently_interpolated()) {
|
||||
// instance_xform = &p_instance->transform_curr;
|
||||
// }
|
||||
// However it does seem that using the interpolated transform (transform) works for keeping AABBs
|
||||
// up to date to avoid culling errors.
|
||||
|
||||
if (p_instance->aabb.has_no_surface()) {
|
||||
return;
|
||||
}
|
||||
|
||||
p_instance->mirror = instance_xform->basis.determinant() < 0.0;
|
||||
|
||||
AABB new_aabb;
|
||||
|
||||
new_aabb = instance_xform->xform(p_instance->aabb);
|
||||
|
||||
p_instance->transformed_aabb = new_aabb;
|
||||
|
||||
if (!p_instance->scenario) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_instance->spatial_partition_id == 0) {
|
||||
uint32_t base_type = 1 << p_instance->base_type;
|
||||
uint32_t pairable_mask = 0;
|
||||
bool pairable = false;
|
||||
|
||||
// not inside octree
|
||||
p_instance->spatial_partition_id = p_instance->scenario->sps->create(p_instance, new_aabb, 0, pairable, base_type, pairable_mask);
|
||||
|
||||
} else {
|
||||
/*
|
||||
if (new_aabb==p_instance->data.transformed_aabb)
|
||||
return;
|
||||
*/
|
||||
|
||||
p_instance->scenario->sps->move(p_instance->spatial_partition_id, new_aabb);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RenderingServerScene::_update_instance_aabb(Instance *p_instance) {
|
||||
AABB new_aabb;
|
||||
|
||||
ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_NONE && !p_instance->base.is_valid());
|
||||
|
||||
switch (p_instance->base_type) {
|
||||
case RenderingServer::INSTANCE_NONE: {
|
||||
// do nothing
|
||||
} break;
|
||||
case RenderingServer::INSTANCE_MESH: {
|
||||
if (p_instance->custom_aabb) {
|
||||
new_aabb = *p_instance->custom_aabb;
|
||||
} else {
|
||||
new_aabb = RSG::storage->mesh_get_aabb(p_instance->base);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case RenderingServer::INSTANCE_MULTIMESH: {
|
||||
if (p_instance->custom_aabb) {
|
||||
new_aabb = *p_instance->custom_aabb;
|
||||
} else {
|
||||
new_aabb = RSG::storage->multimesh_get_aabb(p_instance->base);
|
||||
}
|
||||
|
||||
} break;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
||||
// <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs
|
||||
if (p_instance->extra_margin) {
|
||||
new_aabb.grow_by(p_instance->extra_margin);
|
||||
}
|
||||
|
||||
p_instance->aabb = new_aabb;
|
||||
}
|
||||
|
||||
void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
|
||||
if (p_instance->update_aabb) {
|
||||
_update_instance_aabb(p_instance);
|
||||
}
|
||||
|
||||
if (p_instance->update_materials) {
|
||||
if (p_instance->base_type == RS::INSTANCE_MESH) {
|
||||
//remove materials no longer used and un-own them
|
||||
|
||||
int new_mat_count = RSG::storage->mesh_get_surface_count(p_instance->base);
|
||||
for (int i = p_instance->materials.size() - 1; i >= new_mat_count; i--) {
|
||||
if (p_instance->materials[i].is_valid()) {
|
||||
RSG::storage->material_remove_instance_owner(p_instance->materials[i], p_instance);
|
||||
}
|
||||
}
|
||||
p_instance->materials.resize(new_mat_count);
|
||||
|
||||
int new_blend_shape_count = RSG::storage->mesh_get_blend_shape_count(p_instance->base);
|
||||
if (new_blend_shape_count != p_instance->blend_values.size()) {
|
||||
p_instance->blend_values.resize(new_blend_shape_count);
|
||||
for (int i = 0; i < new_blend_shape_count; i++) {
|
||||
p_instance->blend_values.write().ptr()[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
|
||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
|
||||
|
||||
bool is_animated = false;
|
||||
|
||||
if (p_instance->material_override.is_valid()) {
|
||||
is_animated = RSG::storage->material_is_animated(p_instance->material_override);
|
||||
} else {
|
||||
if (p_instance->base_type == RS::INSTANCE_MESH) {
|
||||
RID mesh = p_instance->base;
|
||||
|
||||
if (mesh.is_valid()) {
|
||||
for (int i = 0; i < p_instance->materials.size(); i++) {
|
||||
RID mat = p_instance->materials[i].is_valid() ? p_instance->materials[i] : RSG::storage->mesh_surface_get_material(mesh, i);
|
||||
|
||||
if (mat.is_valid()) {
|
||||
if (RSG::storage->material_is_animated(mat)) {
|
||||
is_animated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (p_instance->base_type == RS::INSTANCE_MULTIMESH) {
|
||||
RID mesh = RSG::storage->multimesh_get_mesh(p_instance->base);
|
||||
if (mesh.is_valid()) {
|
||||
int sc = RSG::storage->mesh_get_surface_count(mesh);
|
||||
for (int i = 0; i < sc; i++) {
|
||||
RID mat = RSG::storage->mesh_surface_get_material(mesh, i);
|
||||
|
||||
if (mat.is_valid()) {
|
||||
if (RSG::storage->material_is_animated(mat)) {
|
||||
is_animated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_instance->material_overlay.is_valid()) {
|
||||
is_animated = is_animated || RSG::storage->material_is_animated(p_instance->material_overlay);
|
||||
}
|
||||
|
||||
geom->material_is_animated = is_animated;
|
||||
}
|
||||
}
|
||||
|
||||
_instance_update_list.remove(&p_instance->update_item);
|
||||
|
||||
_update_instance(p_instance);
|
||||
|
||||
p_instance->update_aabb = false;
|
||||
p_instance->update_materials = false;
|
||||
}
|
||||
|
||||
void RenderingServerScene::render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size) {
|
||||
// render to mono camera
|
||||
#ifndef _3D_DISABLED
|
||||
|
||||
Camera *camera = camera_owner.getornull(p_camera);
|
||||
ERR_FAIL_COND(!camera);
|
||||
|
||||
/* STEP 1 - SETUP CAMERA */
|
||||
Projection camera_matrix;
|
||||
bool ortho = false;
|
||||
|
||||
switch (camera->type) {
|
||||
case Camera::ORTHOGONAL: {
|
||||
camera_matrix.set_orthogonal(
|
||||
camera->size,
|
||||
p_viewport_size.width / (float)p_viewport_size.height,
|
||||
camera->znear,
|
||||
camera->zfar,
|
||||
camera->vaspect);
|
||||
ortho = true;
|
||||
} break;
|
||||
case Camera::PERSPECTIVE: {
|
||||
camera_matrix.set_perspective(
|
||||
camera->fov,
|
||||
p_viewport_size.width / (float)p_viewport_size.height,
|
||||
camera->znear,
|
||||
camera->zfar,
|
||||
camera->vaspect);
|
||||
ortho = false;
|
||||
|
||||
} break;
|
||||
case Camera::FRUSTUM: {
|
||||
camera_matrix.set_frustum(
|
||||
camera->size,
|
||||
p_viewport_size.width / (float)p_viewport_size.height,
|
||||
camera->offset,
|
||||
camera->znear,
|
||||
camera->zfar,
|
||||
camera->vaspect);
|
||||
ortho = false;
|
||||
} break;
|
||||
}
|
||||
|
||||
Transform camera_transform = _interpolation_data.interpolation_enabled ? camera->get_transform_interpolated() : camera->transform;
|
||||
|
||||
_prepare_scene(camera_transform, camera_matrix, ortho, camera->env, camera->visible_layers, p_scenario, camera->previous_room_id_hint);
|
||||
_render_scene(camera_transform, camera_matrix, 0, ortho, camera->env, p_scenario);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, int32_t &r_previous_room_id_hint) {
|
||||
// Note, in stereo rendering:
|
||||
// - p_cam_transform will be a transform in the middle of our two eyes
|
||||
// - p_cam_projection is a wider frustrum that encompasses both eyes
|
||||
|
||||
render_pass++;
|
||||
uint32_t camera_layer_mask = p_visible_layers;
|
||||
|
||||
RSG::scene_render->set_scene_pass(render_pass);
|
||||
|
||||
//rasterizer->set_camera(camera->transform, camera_matrix,ortho);
|
||||
|
||||
Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform);
|
||||
|
||||
Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2).normalized());
|
||||
float z_far = p_cam_projection.get_z_far();
|
||||
|
||||
/* STEP 2 - CULL */
|
||||
instance_cull_count = 0;
|
||||
|
||||
//light_samplers_culled=0;
|
||||
|
||||
/*
|
||||
print_line("OT: "+rtos( (OS::get_singleton()->get_ticks_usec()-t)/1000.0));
|
||||
print_line("OTO: "+itos(p_scenario->octree.get_octant_count()));
|
||||
print_line("OTE: "+itos(p_scenario->octree.get_elem_count()));
|
||||
print_line("OTP: "+itos(p_scenario->octree.get_pair_count()));
|
||||
*/
|
||||
|
||||
/* STEP 3 - PROCESS PORTALS, VALIDATE ROOMS */
|
||||
//removed, will replace with culling
|
||||
|
||||
/* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */
|
||||
|
||||
for (int i = 0; i < instance_cull_count; i++) {
|
||||
Instance *ins = instance_cull_result[i];
|
||||
|
||||
bool keep = false;
|
||||
|
||||
if ((camera_layer_mask & ins->layer_mask) == 0) {
|
||||
//failure
|
||||
} else if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible) {
|
||||
keep = true;
|
||||
|
||||
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
|
||||
|
||||
if (ins->redraw_if_visible) {
|
||||
RenderingServerRaster::redraw_request(false);
|
||||
}
|
||||
|
||||
if (geom->lighting_dirty) {
|
||||
//only called when lights AABB enter/exit this geometry
|
||||
ins->light_instances.resize(geom->lighting.size());
|
||||
geom->lighting_dirty = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!keep) {
|
||||
// remove, no reason to keep
|
||||
instance_cull_count--;
|
||||
SWAP(instance_cull_result[i], instance_cull_result[instance_cull_count]);
|
||||
i--;
|
||||
ins->last_render_pass = 0; // make invalid
|
||||
} else {
|
||||
ins->last_render_pass = render_pass;
|
||||
}
|
||||
}
|
||||
|
||||
/* STEP 5 - PROCESS LIGHTS */
|
||||
|
||||
// Calculate instance->depth from the camera, after shadow calculation has stopped overwriting instance->depth
|
||||
for (int i = 0; i < instance_cull_count; i++) {
|
||||
Instance *ins = instance_cull_result[i];
|
||||
|
||||
if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible) {
|
||||
Vector3 center = ins->transform.origin;
|
||||
if (ins->use_aabb_center) {
|
||||
center = ins->transformed_aabb.position + (ins->transformed_aabb.size * 0.5);
|
||||
}
|
||||
if (p_cam_orthogonal) {
|
||||
ins->depth = near_plane.distance_to(center) - ins->sorting_offset;
|
||||
} else {
|
||||
ins->depth = p_cam_transform.origin.distance_to(center) - ins->sorting_offset;
|
||||
}
|
||||
ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingServerScene::_render_scene(const Transform p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario) {
|
||||
/* PROCESS GEOMETRY AND DRAW SCENE */
|
||||
|
||||
RSG::scene_render->render_scene(p_cam_transform, p_cam_projection, p_eye, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count);
|
||||
}
|
||||
|
||||
void RenderingServerScene::render_empty_scene(RID p_scenario) {
|
||||
#ifndef _3D_DISABLED
|
||||
RSG::scene_render->render_scene(Transform(), Projection(), 0, true, nullptr, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void RenderingServerScene::update_dirty_instances() {
|
||||
RSG::storage->update_dirty_resources();
|
||||
|
||||
// this is just to get access to scenario so we can update the spatial partitioning scheme
|
||||
Scenario *scenario = nullptr;
|
||||
if (_instance_update_list.first()) {
|
||||
scenario = _instance_update_list.first()->self()->scenario;
|
||||
}
|
||||
|
||||
while (_instance_update_list.first()) {
|
||||
_update_dirty_instance(_instance_update_list.first()->self());
|
||||
}
|
||||
|
||||
if (scenario) {
|
||||
scenario->sps->update();
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderingServerScene::free(RID p_rid) {
|
||||
if (camera_owner.owns(p_rid)) {
|
||||
Camera *camera = camera_owner.get(p_rid);
|
||||
|
||||
_interpolation_data.notify_free_camera(p_rid, *camera);
|
||||
|
||||
camera_owner.free(p_rid);
|
||||
memdelete(camera);
|
||||
} else if (scenario_owner.owns(p_rid)) {
|
||||
Scenario *scenario = scenario_owner.get(p_rid);
|
||||
|
||||
|
||||
scenario_owner.free(p_rid);
|
||||
memdelete(scenario);
|
||||
|
||||
} else if (instance_owner.owns(p_rid)) {
|
||||
// delete the instance
|
||||
|
||||
update_dirty_instances();
|
||||
|
||||
Instance *instance = instance_owner.get(p_rid);
|
||||
|
||||
_interpolation_data.notify_free_instance(p_rid, *instance);
|
||||
|
||||
update_dirty_instances(); //in case something changed this
|
||||
|
||||
instance_owner.free(p_rid);
|
||||
memdelete(instance);
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RenderingServerScene *RenderingServerScene::singleton = nullptr;
|
||||
|
||||
RenderingServerScene::RenderingServerScene() {
|
||||
render_pass = 1;
|
||||
singleton = this;
|
||||
_use_bvh = GLOBAL_DEF("rendering/quality/spatial_partitioning/use_bvh", true);
|
||||
GLOBAL_DEF("rendering/quality/spatial_partitioning/bvh_collision_margin", 0.1);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/spatial_partitioning/bvh_collision_margin", PropertyInfo(Variant::REAL, "rendering/quality/spatial_partitioning/bvh_collision_margin", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"));
|
||||
|
||||
_rendering_server_callbacks = nullptr;
|
||||
}
|
||||
|
||||
RenderingServerScene::~RenderingServerScene() {
|
||||
}
|
@ -1,455 +0,0 @@
|
||||
#ifndef RENDERINGSERVERSCENE_H
|
||||
#define RENDERINGSERVERSCENE_H
|
||||
/*************************************************************************/
|
||||
/* rendering_server_scene.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "servers/rendering/rasterizer.h"
|
||||
|
||||
#include "core/containers/self_list.h"
|
||||
#include "core/math/bvh.h"
|
||||
#include "core/math/geometry.h"
|
||||
#include "core/math/octree.h"
|
||||
#include "core/os/safe_refcount.h"
|
||||
#include "core/os/semaphore.h"
|
||||
#include "core/os/thread.h"
|
||||
|
||||
class RenderingServerScene {
|
||||
public:
|
||||
enum {
|
||||
|
||||
MAX_INSTANCE_CULL = 65536,
|
||||
MAX_LIGHTS_CULLED = 4096,
|
||||
MAX_REFLECTION_PROBES_CULLED = 4096,
|
||||
};
|
||||
|
||||
uint64_t render_pass;
|
||||
static RenderingServerScene *singleton;
|
||||
|
||||
/* EVENT QUEUING */
|
||||
|
||||
void tick();
|
||||
void pre_draw(bool p_will_draw);
|
||||
|
||||
/* CAMERA API */
|
||||
|
||||
struct Scenario;
|
||||
|
||||
struct Camera : public RID_Data {
|
||||
enum Type {
|
||||
PERSPECTIVE,
|
||||
ORTHOGONAL,
|
||||
FRUSTUM
|
||||
};
|
||||
Type type;
|
||||
float fov;
|
||||
float znear, zfar;
|
||||
float size;
|
||||
Vector2 offset;
|
||||
uint32_t visible_layers;
|
||||
RID env;
|
||||
|
||||
// transform_prev is only used when using fixed timestep interpolation
|
||||
Transform transform;
|
||||
Transform transform_prev;
|
||||
|
||||
bool interpolated : 1;
|
||||
bool on_interpolate_transform_list : 1;
|
||||
|
||||
bool vaspect : 1;
|
||||
TransformInterpolator::Method interpolation_method : 3;
|
||||
|
||||
int32_t previous_room_id_hint;
|
||||
|
||||
Transform get_transform_interpolated() const;
|
||||
|
||||
Camera() {
|
||||
visible_layers = 0xFFFFFFFF;
|
||||
fov = 70;
|
||||
type = PERSPECTIVE;
|
||||
znear = 0.05;
|
||||
zfar = 100;
|
||||
size = 1.0;
|
||||
offset = Vector2();
|
||||
vaspect = false;
|
||||
previous_room_id_hint = -1;
|
||||
interpolated = true;
|
||||
on_interpolate_transform_list = false;
|
||||
interpolation_method = TransformInterpolator::INTERP_LERP;
|
||||
}
|
||||
};
|
||||
|
||||
mutable RID_Owner<Camera> camera_owner;
|
||||
|
||||
virtual RID camera_create();
|
||||
virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far);
|
||||
virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
|
||||
virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far);
|
||||
virtual void camera_set_transform(RID p_camera, const Transform &p_transform);
|
||||
virtual void camera_set_interpolated(RID p_camera, bool p_interpolated);
|
||||
virtual void camera_reset_physics_interpolation(RID p_camera);
|
||||
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers);
|
||||
virtual void camera_set_environment(RID p_camera, RID p_env);
|
||||
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable);
|
||||
|
||||
/* SCENARIO API */
|
||||
|
||||
struct Instance;
|
||||
|
||||
// common interface for all spatial partitioning schemes
|
||||
// this is a bit excessive boilerplatewise but can be removed if we decide to stick with one method
|
||||
|
||||
// note this is actually the BVH id +1, so that visual server can test against zero
|
||||
// for validity to maintain compatibility with octree (where 0 indicates invalid)
|
||||
typedef uint32_t SpatialPartitionID;
|
||||
|
||||
class SpatialPartitioningScene {
|
||||
public:
|
||||
virtual SpatialPartitionID create(Instance *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t pairable_mask) = 0;
|
||||
virtual void erase(SpatialPartitionID p_handle) = 0;
|
||||
virtual void move(SpatialPartitionID p_handle, const AABB &p_aabb) = 0;
|
||||
virtual void activate(SpatialPartitionID p_handle, const AABB &p_aabb) {}
|
||||
virtual void deactivate(SpatialPartitionID p_handle) {}
|
||||
virtual void force_collision_check(SpatialPartitionID p_handle) {}
|
||||
virtual void update() {}
|
||||
virtual void update_collisions() {}
|
||||
virtual void set_pairable(Instance *p_instance, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) = 0;
|
||||
virtual int cull_convex(const Vector<Plane> &p_convex, Instance **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF) = 0;
|
||||
virtual int cull_aabb(const AABB &p_aabb, Instance **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF) = 0;
|
||||
virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, Instance **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF) = 0;
|
||||
|
||||
typedef void *(*PairCallback)(void *, uint32_t, Instance *, int, uint32_t, Instance *, int);
|
||||
typedef void (*UnpairCallback)(void *, uint32_t, Instance *, int, uint32_t, Instance *, int, void *);
|
||||
|
||||
virtual void set_pair_callback(PairCallback p_callback, void *p_userdata) = 0;
|
||||
virtual void set_unpair_callback(UnpairCallback p_callback, void *p_userdata) = 0;
|
||||
|
||||
// bvh specific
|
||||
virtual void params_set_node_expansion(real_t p_value) {}
|
||||
virtual void params_set_pairing_expansion(real_t p_value) {}
|
||||
|
||||
// octree specific
|
||||
virtual void set_balance(float p_balance) {}
|
||||
|
||||
virtual ~SpatialPartitioningScene() {}
|
||||
};
|
||||
|
||||
class SpatialPartitioningScene_Octree : public SpatialPartitioningScene {
|
||||
Octree_CL<Instance, true> _octree;
|
||||
|
||||
public:
|
||||
SpatialPartitionID create(Instance *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t pairable_mask);
|
||||
void erase(SpatialPartitionID p_handle);
|
||||
void move(SpatialPartitionID p_handle, const AABB &p_aabb);
|
||||
void set_pairable(Instance *p_instance, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask);
|
||||
int cull_convex(const Vector<Plane> &p_convex, Instance **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF);
|
||||
int cull_aabb(const AABB &p_aabb, Instance **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
|
||||
int cull_segment(const Vector3 &p_from, const Vector3 &p_to, Instance **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
|
||||
void set_pair_callback(PairCallback p_callback, void *p_userdata);
|
||||
void set_unpair_callback(UnpairCallback p_callback, void *p_userdata);
|
||||
void set_balance(float p_balance);
|
||||
};
|
||||
|
||||
class SpatialPartitioningScene_BVH : public SpatialPartitioningScene {
|
||||
template <class T>
|
||||
class UserPairTestFunction {
|
||||
public:
|
||||
static bool user_pair_check(const T *p_a, const T *p_b) {
|
||||
// return false if no collision, decided by masks etc
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class UserCullTestFunction {
|
||||
// write this logic once for use in all routines
|
||||
// double check this as a possible source of bugs in future.
|
||||
static bool _cull_pairing_mask_test_hit(uint32_t p_maskA, uint32_t p_typeA, uint32_t p_maskB, uint32_t p_typeB) {
|
||||
// double check this as a possible source of bugs in future.
|
||||
bool A_match_B = p_maskA & p_typeB;
|
||||
|
||||
if (!A_match_B) {
|
||||
bool B_match_A = p_maskB & p_typeA;
|
||||
if (!B_match_A) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
static bool user_cull_check(const T *p_a, const T *p_b) {
|
||||
DEV_ASSERT(p_a);
|
||||
DEV_ASSERT(p_b);
|
||||
|
||||
uint32_t a_mask = p_a->bvh_pairable_mask;
|
||||
uint32_t a_type = p_a->bvh_pairable_type;
|
||||
uint32_t b_mask = p_b->bvh_pairable_mask;
|
||||
uint32_t b_type = p_b->bvh_pairable_type;
|
||||
|
||||
if (!_cull_pairing_mask_test_hit(a_mask, a_type, b_mask, b_type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
// Note that SpatialPartitionIDs are +1 based when stored in visual server, to enable 0 to indicate invalid ID.
|
||||
BVH_Manager<Instance, 2, true, 256, UserPairTestFunction<Instance>, UserCullTestFunction<Instance>> _bvh;
|
||||
Instance *_dummy_cull_object;
|
||||
|
||||
uint32_t find_tree_id_and_collision_mask(bool p_pairable, uint32_t &r_tree_collision_mask) const {
|
||||
// "pairable" (lights etc) can pair with geometry (non pairable) or other pairables.
|
||||
// Geometry never pairs with other geometry, so we can eliminate geometry - geometry collision checks.
|
||||
|
||||
// Additionally, when lights are made invisible their p_pairable_mask is set to zero to stop their collisions.
|
||||
// We could potentially choose `tree_collision_mask` based on whether p_pairable_mask is zero,
|
||||
// in order to catch invisible lights, but in practice these instances will already have been deactivated within
|
||||
// the BVH so this step is unnecessary. So we can keep the simpler logic of geometry collides with pairable,
|
||||
// pairable collides with everything.
|
||||
r_tree_collision_mask = !p_pairable ? 2 : 3;
|
||||
|
||||
// Returns tree_id.
|
||||
return p_pairable ? 1 : 0;
|
||||
}
|
||||
|
||||
public:
|
||||
SpatialPartitioningScene_BVH();
|
||||
~SpatialPartitioningScene_BVH();
|
||||
SpatialPartitionID create(Instance *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask);
|
||||
void erase(SpatialPartitionID p_handle);
|
||||
void move(SpatialPartitionID p_handle, const AABB &p_aabb);
|
||||
void activate(SpatialPartitionID p_handle, const AABB &p_aabb);
|
||||
void deactivate(SpatialPartitionID p_handle);
|
||||
void force_collision_check(SpatialPartitionID p_handle);
|
||||
void update();
|
||||
void update_collisions();
|
||||
void set_pairable(Instance *p_instance, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask);
|
||||
int cull_convex(const Vector<Plane> &p_convex, Instance **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF);
|
||||
int cull_aabb(const AABB &p_aabb, Instance **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
|
||||
int cull_segment(const Vector3 &p_from, const Vector3 &p_to, Instance **p_result_array, int p_result_max, int *p_subindex_array = nullptr, uint32_t p_mask = 0xFFFFFFFF);
|
||||
void set_pair_callback(PairCallback p_callback, void *p_userdata);
|
||||
void set_unpair_callback(UnpairCallback p_callback, void *p_userdata);
|
||||
|
||||
void params_set_node_expansion(real_t p_value) { _bvh.params_set_node_expansion(p_value); }
|
||||
void params_set_pairing_expansion(real_t p_value) { _bvh.params_set_pairing_expansion(p_value); }
|
||||
};
|
||||
|
||||
struct Scenario : RID_Data {
|
||||
RS::ScenarioDebugMode debug;
|
||||
RID self;
|
||||
|
||||
SpatialPartitioningScene *sps;
|
||||
|
||||
SelfList<Instance>::List instances;
|
||||
|
||||
Scenario();
|
||||
~Scenario() { memdelete(sps); }
|
||||
};
|
||||
|
||||
mutable RID_Owner<Scenario> scenario_owner;
|
||||
|
||||
static void *_instance_pair(void *p_self, SpatialPartitionID, Instance *p_A, int, SpatialPartitionID, Instance *p_B, int);
|
||||
static void _instance_unpair(void *p_self, SpatialPartitionID, Instance *p_A, int, SpatialPartitionID, Instance *p_B, int, void *);
|
||||
|
||||
virtual RID scenario_create();
|
||||
|
||||
virtual void scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode);
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
struct InstanceBaseData {
|
||||
virtual ~InstanceBaseData() {}
|
||||
};
|
||||
|
||||
struct Instance : RasterizerScene::InstanceBase {
|
||||
RID self;
|
||||
//scenario stuff
|
||||
SpatialPartitionID spatial_partition_id;
|
||||
|
||||
Scenario *scenario;
|
||||
SelfList<Instance> scenario_item;
|
||||
|
||||
//aabb stuff
|
||||
bool update_aabb;
|
||||
bool update_materials;
|
||||
|
||||
SelfList<Instance> update_item;
|
||||
|
||||
AABB aabb;
|
||||
AABB transformed_aabb;
|
||||
AABB *custom_aabb; // <Zylann> would using aabb directly with a bool be better?
|
||||
float sorting_offset;
|
||||
bool use_aabb_center;
|
||||
float extra_margin;
|
||||
uint32_t object_id;
|
||||
|
||||
float lod_begin;
|
||||
float lod_end;
|
||||
float lod_begin_hysteresis;
|
||||
float lod_end_hysteresis;
|
||||
RID lod_instance;
|
||||
|
||||
// These are used for the user cull testing function
|
||||
// in the BVH, this is precached rather than recalculated each time.
|
||||
uint32_t bvh_pairable_mask;
|
||||
uint32_t bvh_pairable_type;
|
||||
|
||||
uint64_t last_render_pass;
|
||||
uint64_t last_frame_pass;
|
||||
|
||||
uint64_t version; // changes to this, and changes to base increase version
|
||||
|
||||
InstanceBaseData *base_data;
|
||||
|
||||
virtual void base_removed() {
|
||||
}
|
||||
|
||||
virtual void base_changed(bool p_aabb, bool p_materials) {
|
||||
singleton->_instance_queue_update(this, p_aabb, p_materials);
|
||||
}
|
||||
|
||||
Instance() :
|
||||
scenario_item(this),
|
||||
update_item(this) {
|
||||
spatial_partition_id = 0;
|
||||
scenario = nullptr;
|
||||
|
||||
update_aabb = false;
|
||||
update_materials = false;
|
||||
|
||||
extra_margin = 0;
|
||||
|
||||
object_id = 0;
|
||||
visible = true;
|
||||
|
||||
lod_begin = 0;
|
||||
lod_end = 0;
|
||||
lod_begin_hysteresis = 0;
|
||||
lod_end_hysteresis = 0;
|
||||
|
||||
bvh_pairable_mask = 0;
|
||||
bvh_pairable_type = 0;
|
||||
|
||||
last_render_pass = 0;
|
||||
last_frame_pass = 0;
|
||||
version = 1;
|
||||
base_data = nullptr;
|
||||
|
||||
custom_aabb = nullptr;
|
||||
sorting_offset = 0.0f;
|
||||
use_aabb_center = true;
|
||||
}
|
||||
|
||||
~Instance() {
|
||||
if (base_data) {
|
||||
memdelete(base_data);
|
||||
}
|
||||
if (custom_aabb) {
|
||||
memdelete(custom_aabb);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SelfList<Instance>::List _instance_update_list;
|
||||
|
||||
// fixed timestep interpolation
|
||||
virtual void set_physics_interpolation_enabled(bool p_enabled);
|
||||
|
||||
struct InterpolationData {
|
||||
void notify_free_camera(RID p_rid, Camera &r_camera);
|
||||
void notify_free_instance(RID p_rid, Instance &r_instance);
|
||||
LocalVector<RID> instance_interpolate_update_list;
|
||||
LocalVector<RID> instance_transform_update_lists[2];
|
||||
LocalVector<RID> *instance_transform_update_list_curr = &instance_transform_update_lists[0];
|
||||
LocalVector<RID> *instance_transform_update_list_prev = &instance_transform_update_lists[1];
|
||||
LocalVector<RID> instance_teleport_list;
|
||||
|
||||
LocalVector<RID> camera_transform_update_lists[2];
|
||||
LocalVector<RID> *camera_transform_update_list_curr = &camera_transform_update_lists[0];
|
||||
LocalVector<RID> *camera_transform_update_list_prev = &camera_transform_update_lists[1];
|
||||
LocalVector<RID> camera_teleport_list;
|
||||
|
||||
bool interpolation_enabled = false;
|
||||
} _interpolation_data;
|
||||
|
||||
void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_materials = false);
|
||||
|
||||
struct InstanceGeometryData : public InstanceBaseData {
|
||||
List<Instance *> lighting;
|
||||
bool lighting_dirty;
|
||||
bool material_is_animated;
|
||||
|
||||
InstanceGeometryData() {
|
||||
lighting_dirty = true;
|
||||
material_is_animated = true;
|
||||
}
|
||||
};
|
||||
|
||||
int instance_cull_count;
|
||||
Instance *instance_cull_result[MAX_INSTANCE_CULL];
|
||||
|
||||
RID_Owner<Instance> instance_owner;
|
||||
|
||||
public:
|
||||
virtual void callbacks_register(RenderingServerCallbacks *p_callbacks);
|
||||
RenderingServerCallbacks *get_callbacks() const {
|
||||
return _rendering_server_callbacks;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void _update_instance(Instance *p_instance);
|
||||
_FORCE_INLINE_ void _update_instance_aabb(Instance *p_instance);
|
||||
_FORCE_INLINE_ void _update_dirty_instance(Instance *p_instance);
|
||||
|
||||
void _prepare_scene(const Transform p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, uint32_t p_visible_layers, RID p_scenario, int32_t &r_previous_room_id_hint);
|
||||
void _render_scene(const Transform p_cam_transform, const Projection &p_cam_projection, const int p_eye, bool p_cam_orthogonal, RID p_force_environment, RID p_scenario);
|
||||
void render_empty_scene(RID p_scenario);
|
||||
|
||||
void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size);
|
||||
void update_dirty_instances();
|
||||
|
||||
// interpolation
|
||||
void update_interpolation_tick(bool p_process = true);
|
||||
void update_interpolation_frame(bool p_process = true);
|
||||
|
||||
bool free(RID p_rid);
|
||||
|
||||
private:
|
||||
bool _use_bvh;
|
||||
RenderingServerCallbacks *_rendering_server_callbacks;
|
||||
|
||||
public:
|
||||
RenderingServerScene();
|
||||
virtual ~RenderingServerScene();
|
||||
};
|
||||
|
||||
#endif // RENDERINGSERVERSCENE_H
|
@ -31,9 +31,9 @@
|
||||
#include "rendering_server_viewport.h"
|
||||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/config/engine.h"
|
||||
#include "rendering_server_canvas.h"
|
||||
#include "rendering_server_globals.h"
|
||||
#include "rendering_server_scene.h"
|
||||
|
||||
static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_viewport, RenderingServerCanvas::Canvas *p_canvas, RenderingServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
|
||||
Transform2D xf = p_viewport->global_transform;
|
||||
@ -64,18 +64,9 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi
|
||||
return xf;
|
||||
}
|
||||
|
||||
void RenderingServerViewport::_draw_3d(Viewport *p_viewport) {
|
||||
RSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size);
|
||||
}
|
||||
|
||||
void RenderingServerViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
/* Camera should always be BEFORE any other 3D */
|
||||
|
||||
bool scenario_draw_canvas_bg = false; //draw canvas, or some layer of it, as BG for 3D instead of in front
|
||||
int scenario_canvas_max_layer = 0;
|
||||
|
||||
bool can_draw_3d = !p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && RSG::scene->camera_owner.owns(p_viewport->camera);
|
||||
|
||||
if (p_viewport->clear_mode != RS::VIEWPORT_CLEAR_NEVER) {
|
||||
RSG::rasterizer->clear_render_target(p_viewport->transparent_bg ? Color(0, 0, 0, 0) : clear_color);
|
||||
if (p_viewport->clear_mode == RS::VIEWPORT_CLEAR_ONLY_NEXT_FRAME) {
|
||||
@ -83,10 +74,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!scenario_draw_canvas_bg && can_draw_3d) {
|
||||
_draw_3d(p_viewport);
|
||||
}
|
||||
|
||||
if (!p_viewport->hide_canvas) {
|
||||
RBMap<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map;
|
||||
|
||||
@ -94,21 +81,10 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
Rect2 shadow_rect;
|
||||
|
||||
for (RBMap<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
|
||||
RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas);
|
||||
|
||||
canvas_map[Viewport::CanvasKey(E->key(), E->get().layer, E->get().sublayer)] = &E->get();
|
||||
}
|
||||
|
||||
RSG::rasterizer->restore_render_target(!scenario_draw_canvas_bg && can_draw_3d);
|
||||
|
||||
if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) {
|
||||
if (!can_draw_3d) {
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario);
|
||||
} else {
|
||||
_draw_3d(p_viewport);
|
||||
}
|
||||
scenario_draw_canvas_bg = false;
|
||||
}
|
||||
RSG::rasterizer->restore_render_target(false);
|
||||
|
||||
for (RBMap<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) {
|
||||
RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get()->canvas);
|
||||
@ -118,27 +94,7 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport) {
|
||||
int canvas_layer_id = E->get()->layer;
|
||||
|
||||
RSG::canvas->render_canvas(canvas, xform, clip_rect, canvas_layer_id);
|
||||
|
||||
if (scenario_draw_canvas_bg && E->key().get_layer() >= scenario_canvas_max_layer) {
|
||||
if (!can_draw_3d) {
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario);
|
||||
} else {
|
||||
_draw_3d(p_viewport);
|
||||
}
|
||||
|
||||
scenario_draw_canvas_bg = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (scenario_draw_canvas_bg) {
|
||||
if (!can_draw_3d) {
|
||||
RSG::scene->render_empty_scene(p_viewport->scenario);
|
||||
} else {
|
||||
_draw_3d(p_viewport);
|
||||
}
|
||||
}
|
||||
|
||||
//RSG::canvas_render->canvas_debug_viewport_shadows(lights_with_shadow);
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,18 +317,6 @@ void RenderingServerViewport::viewport_set_keep_3d_linear(RID p_viewport, bool p
|
||||
RSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR, p_keep_3d_linear);
|
||||
}
|
||||
|
||||
void RenderingServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->camera = p_camera;
|
||||
}
|
||||
void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) {
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->scenario = p_scenario;
|
||||
}
|
||||
void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) {
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
@ -532,7 +476,6 @@ bool RenderingServerViewport::free(RID p_rid) {
|
||||
viewport_remove_canvas(p_rid, viewport->canvas_map.front()->key());
|
||||
}
|
||||
|
||||
viewport_set_scenario(p_rid, RID());
|
||||
active_viewports.erase(viewport);
|
||||
|
||||
viewport_owner.free(p_rid);
|
||||
|
@ -138,7 +138,6 @@ public:
|
||||
|
||||
private:
|
||||
Color clear_color;
|
||||
void _draw_3d(Viewport *p_viewport);
|
||||
void _draw_viewport(Viewport *p_viewport);
|
||||
|
||||
public:
|
||||
@ -165,8 +164,6 @@ public:
|
||||
void viewport_set_disable_3d(RID p_viewport, bool p_disable);
|
||||
void viewport_set_keep_3d_linear(RID p_viewport, bool p_keep_3d_linear);
|
||||
|
||||
void viewport_attach_camera(RID p_viewport, RID p_camera);
|
||||
void viewport_set_scenario(RID p_viewport, RID p_scenario);
|
||||
void viewport_attach_canvas(RID p_viewport, RID p_canvas);
|
||||
void viewport_remove_canvas(RID p_viewport, RID p_canvas);
|
||||
void viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset);
|
||||
|
@ -145,9 +145,7 @@ void RenderingServerWrapMT::finish() {
|
||||
material_free_cached_ids();
|
||||
mesh_free_cached_ids();
|
||||
multimesh_free_cached_ids();
|
||||
camera_free_cached_ids();
|
||||
viewport_free_cached_ids();
|
||||
scenario_free_cached_ids();
|
||||
canvas_free_cached_ids();
|
||||
canvas_item_free_cached_ids();
|
||||
}
|
||||
|
@ -209,19 +209,6 @@ public:
|
||||
FUNC2(multimesh_set_visible_instances, RID, int)
|
||||
FUNC1RC(int, multimesh_get_visible_instances, RID)
|
||||
|
||||
/* CAMERA API */
|
||||
|
||||
FUNCRID(camera)
|
||||
FUNC4(camera_set_perspective, RID, float, float, float)
|
||||
FUNC4(camera_set_orthogonal, RID, float, float, float)
|
||||
FUNC5(camera_set_frustum, RID, float, Vector2, float, float)
|
||||
FUNC2(camera_set_transform, RID, const Transform &)
|
||||
FUNC2(camera_set_interpolated, RID, bool)
|
||||
FUNC1(camera_reset_physics_interpolation, RID)
|
||||
FUNC2(camera_set_cull_mask, RID, uint32_t)
|
||||
FUNC2(camera_set_environment, RID, RID)
|
||||
FUNC2(camera_set_use_vertical_aspect, RID, bool)
|
||||
|
||||
/* VIEWPORT TARGET API */
|
||||
|
||||
FUNCRID(viewport)
|
||||
@ -242,14 +229,11 @@ public:
|
||||
|
||||
FUNC1RC(RID, viewport_get_texture, RID)
|
||||
|
||||
FUNC2(viewport_set_hide_scenario, RID, bool)
|
||||
FUNC2(viewport_set_hide_canvas, RID, bool)
|
||||
FUNC2(viewport_set_disable_environment, RID, bool)
|
||||
FUNC2(viewport_set_disable_3d, RID, bool)
|
||||
FUNC2(viewport_set_keep_3d_linear, RID, bool)
|
||||
|
||||
FUNC2(viewport_attach_camera, RID, RID)
|
||||
FUNC2(viewport_set_scenario, RID, RID)
|
||||
FUNC2(viewport_attach_canvas, RID, RID)
|
||||
|
||||
FUNC2(viewport_remove_canvas, RID, RID)
|
||||
@ -273,15 +257,6 @@ public:
|
||||
|
||||
FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
|
||||
|
||||
/* SCENARIO API */
|
||||
|
||||
FUNCRID(scenario)
|
||||
|
||||
FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
|
||||
|
||||
// Callbacks
|
||||
FUNC1(callbacks_register, RenderingServerCallbacks *)
|
||||
|
||||
/* CANVAS (2D) */
|
||||
|
||||
FUNCRID(canvas)
|
||||
|
@ -1889,17 +1889,6 @@ void RenderingServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("multimesh_set_physics_interpolation_quality", "multimesh", "quality"), &RenderingServer::multimesh_set_physics_interpolation_quality);
|
||||
ClassDB::bind_method(D_METHOD("multimesh_instance_reset_physics_interpolation", "multimesh", "index"), &RenderingServer::multimesh_instance_reset_physics_interpolation);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("camera_create"), &RenderingServer::camera_create);
|
||||
ClassDB::bind_method(D_METHOD("camera_set_perspective", "camera", "fovy_degrees", "z_near", "z_far"), &RenderingServer::camera_set_perspective);
|
||||
ClassDB::bind_method(D_METHOD("camera_set_orthogonal", "camera", "size", "z_near", "z_far"), &RenderingServer::camera_set_orthogonal);
|
||||
ClassDB::bind_method(D_METHOD("camera_set_frustum", "camera", "size", "offset", "z_near", "z_far"), &RenderingServer::camera_set_frustum);
|
||||
ClassDB::bind_method(D_METHOD("camera_set_transform", "camera", "transform"), &RenderingServer::camera_set_transform);
|
||||
ClassDB::bind_method(D_METHOD("camera_set_interpolated", "camera", "interpolated"), &RenderingServer::camera_set_interpolated);
|
||||
ClassDB::bind_method(D_METHOD("camera_reset_physics_interpolation", "camera"), &RenderingServer::camera_reset_physics_interpolation);
|
||||
ClassDB::bind_method(D_METHOD("camera_set_cull_mask", "camera", "layers"), &RenderingServer::camera_set_cull_mask);
|
||||
ClassDB::bind_method(D_METHOD("camera_set_environment", "camera", "env"), &RenderingServer::camera_set_environment);
|
||||
ClassDB::bind_method(D_METHOD("camera_set_use_vertical_aspect", "camera", "enable"), &RenderingServer::camera_set_use_vertical_aspect);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("viewport_create"), &RenderingServer::viewport_create);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_size", "viewport", "width", "height"), &RenderingServer::viewport_set_size);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_active", "viewport", "active"), &RenderingServer::viewport_set_active);
|
||||
@ -1911,12 +1900,9 @@ void RenderingServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_vflip", "viewport", "enabled"), &RenderingServer::viewport_set_vflip);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_clear_mode", "viewport", "clear_mode"), &RenderingServer::viewport_set_clear_mode);
|
||||
ClassDB::bind_method(D_METHOD("viewport_get_texture", "viewport"), &RenderingServer::viewport_get_texture);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_hide_scenario", "viewport", "hidden"), &RenderingServer::viewport_set_hide_scenario);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_hide_canvas", "viewport", "hidden"), &RenderingServer::viewport_set_hide_canvas);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_disable_environment", "viewport", "disabled"), &RenderingServer::viewport_set_disable_environment);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_disable_3d", "viewport", "disabled"), &RenderingServer::viewport_set_disable_3d);
|
||||
ClassDB::bind_method(D_METHOD("viewport_attach_camera", "viewport", "camera"), &RenderingServer::viewport_attach_camera);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_scenario", "viewport", "scenario"), &RenderingServer::viewport_set_scenario);
|
||||
ClassDB::bind_method(D_METHOD("viewport_attach_canvas", "viewport", "canvas"), &RenderingServer::viewport_attach_canvas);
|
||||
ClassDB::bind_method(D_METHOD("viewport_remove_canvas", "viewport", "canvas"), &RenderingServer::viewport_remove_canvas);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_canvas_transform", "viewport", "canvas", "offset"), &RenderingServer::viewport_set_canvas_transform);
|
||||
@ -1933,9 +1919,6 @@ void RenderingServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("viewport_get_render_info", "viewport", "info"), &RenderingServer::viewport_get_render_info);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_debug_draw", "viewport", "draw"), &RenderingServer::viewport_set_debug_draw);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("scenario_create"), &RenderingServer::scenario_create);
|
||||
ClassDB::bind_method(D_METHOD("scenario_set_debug", "scenario", "debug_mode"), &RenderingServer::scenario_set_debug);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("canvas_create"), &RenderingServer::canvas_create);
|
||||
ClassDB::bind_method(D_METHOD("canvas_set_item_mirroring", "canvas", "item", "mirroring"), &RenderingServer::canvas_set_item_mirroring);
|
||||
ClassDB::bind_method(D_METHOD("canvas_set_modulate", "canvas", "color"), &RenderingServer::canvas_set_modulate);
|
||||
@ -2129,11 +2112,6 @@ void RenderingServer::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_OVERDRAW);
|
||||
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_WIREFRAME);
|
||||
|
||||
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_DISABLED);
|
||||
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_WIREFRAME);
|
||||
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_OVERDRAW);
|
||||
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_SHADELESS);
|
||||
|
||||
BIND_ENUM_CONSTANT(INSTANCE_NONE);
|
||||
BIND_ENUM_CONSTANT(INSTANCE_MESH);
|
||||
BIND_ENUM_CONSTANT(INSTANCE_MULTIMESH);
|
||||
@ -2188,10 +2166,6 @@ void RenderingServer::_canvas_item_add_style_box(RID p_item, const Rect2 &p_rect
|
||||
//canvas_item_add_style_box(p_item,p_rect,p_source,p_texture,Vector2(p_margins[0],p_margins[1]),Vector2(p_margins[2],p_margins[3]),true,p_modulate);
|
||||
}
|
||||
|
||||
void RenderingServer::_camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) {
|
||||
camera_set_orthogonal(p_camera, p_size, p_z_near, p_z_far);
|
||||
}
|
||||
|
||||
void RenderingServer::mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry::MeshData &p_mesh_data) {
|
||||
PoolVector<Vector3> vertices;
|
||||
PoolVector<Vector3> normals;
|
||||
|
@ -51,7 +51,6 @@ class RenderingServer : public Object {
|
||||
bool force_shader_fallbacks = false;
|
||||
#endif
|
||||
|
||||
void _camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far);
|
||||
void _canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate = Color(1, 1, 1));
|
||||
Array _get_array_from_surface(uint32_t p_format, PoolVector<uint8_t> p_vertex_data, int p_vertex_len, PoolVector<uint8_t> p_index_data, int p_index_len) const;
|
||||
|
||||
@ -387,28 +386,6 @@ public:
|
||||
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
|
||||
virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
|
||||
|
||||
/* CAMERA API */
|
||||
|
||||
virtual RID camera_create() = 0;
|
||||
virtual void camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) = 0;
|
||||
virtual void camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) = 0;
|
||||
virtual void camera_set_frustum(RID p_camera, float p_size, Vector2 p_offset, float p_z_near, float p_z_far) = 0;
|
||||
virtual void camera_set_transform(RID p_camera, const Transform &p_transform) = 0;
|
||||
virtual void camera_set_interpolated(RID p_camera, bool p_interpolated) = 0;
|
||||
virtual void camera_reset_physics_interpolation(RID p_camera) = 0;
|
||||
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0;
|
||||
virtual void camera_set_environment(RID p_camera, RID p_env) = 0;
|
||||
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0;
|
||||
|
||||
/*
|
||||
enum ParticlesCollisionMode {
|
||||
PARTICLES_COLLISION_NONE,
|
||||
PARTICLES_COLLISION_TEXTURE,
|
||||
PARTICLES_COLLISION_CUBEMAP,
|
||||
};
|
||||
|
||||
virtual void particles_set_collision(RID p_particles,ParticlesCollisionMode p_mode,const Transform&, p_xform,const RID p_depth_tex,const RID p_normal_tex)=0;
|
||||
*/
|
||||
/* VIEWPORT TARGET API */
|
||||
|
||||
virtual RID viewport_create() = 0;
|
||||
@ -442,14 +419,11 @@ public:
|
||||
|
||||
virtual RID viewport_get_texture(RID p_viewport) const = 0;
|
||||
|
||||
virtual void viewport_set_hide_scenario(RID p_viewport, bool p_hide) = 0;
|
||||
virtual void viewport_set_hide_canvas(RID p_viewport, bool p_hide) = 0;
|
||||
virtual void viewport_set_disable_environment(RID p_viewport, bool p_disable) = 0;
|
||||
virtual void viewport_set_disable_3d(RID p_viewport, bool p_disable) = 0;
|
||||
virtual void viewport_set_keep_3d_linear(RID p_viewport, bool p_disable) = 0;
|
||||
|
||||
virtual void viewport_attach_camera(RID p_viewport, RID p_camera) = 0;
|
||||
virtual void viewport_set_scenario(RID p_viewport, RID p_scenario) = 0;
|
||||
virtual void viewport_attach_canvas(RID p_viewport, RID p_canvas) = 0;
|
||||
virtual void viewport_remove_canvas(RID p_viewport, RID p_canvas) = 0;
|
||||
virtual void viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) = 0;
|
||||
@ -512,20 +486,6 @@ public:
|
||||
|
||||
virtual void set_physics_interpolation_enabled(bool p_enabled) = 0;
|
||||
|
||||
/* SCENARIO API */
|
||||
|
||||
virtual RID scenario_create() = 0;
|
||||
|
||||
enum ScenarioDebugMode {
|
||||
SCENARIO_DEBUG_DISABLED,
|
||||
SCENARIO_DEBUG_WIREFRAME,
|
||||
SCENARIO_DEBUG_OVERDRAW,
|
||||
SCENARIO_DEBUG_SHADELESS,
|
||||
|
||||
};
|
||||
|
||||
virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0;
|
||||
|
||||
/* INSTANCING API */
|
||||
|
||||
enum InstanceType {
|
||||
@ -538,9 +498,6 @@ public:
|
||||
INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH)
|
||||
};
|
||||
|
||||
// callbacks are used to send messages back from the visual server to scene tree in thread friendly manner
|
||||
virtual void callbacks_register(RenderingServerCallbacks *p_callbacks) = 0;
|
||||
|
||||
enum InstanceFlags {
|
||||
INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE,
|
||||
INSTANCE_FLAG_MAX
|
||||
@ -732,7 +689,6 @@ VARIANT_ENUM_CAST(RenderingServer::ViewportMSAA);
|
||||
VARIANT_ENUM_CAST(RenderingServer::ViewportUsage);
|
||||
VARIANT_ENUM_CAST(RenderingServer::ViewportRenderInfo);
|
||||
VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw);
|
||||
VARIANT_ENUM_CAST(RenderingServer::ScenarioDebugMode);
|
||||
VARIANT_ENUM_CAST(RenderingServer::InstanceType);
|
||||
VARIANT_ENUM_CAST(RenderingServer::NinePatchAxisMode);
|
||||
VARIANT_ENUM_CAST(RenderingServer::RenderInfo);
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*************************************************************************/
|
||||
/* rendering_server_callbacks.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "rendering_server_callbacks.h"
|
||||
|
||||
#include "core/object/object.h"
|
||||
|
||||
void RenderingServerCallbacks::lock() {
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
void RenderingServerCallbacks::unlock() {
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
void RenderingServerCallbacks::flush() {
|
||||
// should be ok without a lock ..
|
||||
// is the most common case and should be quicker
|
||||
if (!messages.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
lock();
|
||||
for (int n = 0; n < messages.size(); n++) {
|
||||
const Message &mess = messages[n];
|
||||
|
||||
Object *obj = ObjectDB::get_instance(mess.object_id);
|
||||
if (!obj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
obj->notification_callback(mess.type);
|
||||
}
|
||||
|
||||
messages.clear();
|
||||
|
||||
unlock();
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
#ifndef RENDERING_SERVER_CALLBACKS_H
|
||||
#define RENDERING_SERVER_CALLBACKS_H
|
||||
/*************************************************************************/
|
||||
/* rendering_server_callbacks.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "core/containers/local_vector.h"
|
||||
#include "core/object/object_id.h"
|
||||
#include "core/os/mutex.h"
|
||||
|
||||
class RenderingServerCallbacks {
|
||||
public:
|
||||
enum CallbackType {
|
||||
CALLBACK_NOTIFICATION_ENTER_GAMEPLAY,
|
||||
CALLBACK_NOTIFICATION_EXIT_GAMEPLAY,
|
||||
CALLBACK_SIGNAL_ENTER_GAMEPLAY,
|
||||
CALLBACK_SIGNAL_EXIT_GAMEPLAY,
|
||||
};
|
||||
|
||||
struct Message {
|
||||
CallbackType type;
|
||||
ObjectID object_id;
|
||||
};
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
void flush();
|
||||
|
||||
void push_message(const Message &p_message) { messages.push_back(p_message); }
|
||||
int32_t get_num_messages() const { return messages.size(); }
|
||||
const Message &get_message(int p_index) const { return messages[p_index]; }
|
||||
void clear() { messages.clear(); }
|
||||
|
||||
private:
|
||||
LocalVector<Message, int32_t> messages;
|
||||
Mutex mutex;
|
||||
};
|
||||
|
||||
#endif // RENDERING_SERVER_CALLBACKS_H
|
Loading…
Reference in New Issue
Block a user