You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-17 14:11:06 +00:00
Merge pull request #105437 from Ansraer/teleport_spatial_nodes
Allow moving meshes without motion vectors
This commit is contained in:
@@ -2046,6 +2046,13 @@
|
|||||||
Sets whether an instance is drawn or not. Equivalent to [member Node3D.visible].
|
Sets whether an instance is drawn or not. Equivalent to [member Node3D.visible].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="instance_teleport">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="instance" type="RID" />
|
||||||
|
<description>
|
||||||
|
Resets motion vectors and other interpolated values. Use this [i]after[/i] teleporting a mesh from one position to another to avoid ghosting artifacts.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="instances_cull_aabb" qualifiers="const">
|
<method name="instances_cull_aabb" qualifiers="const">
|
||||||
<return type="PackedInt64Array" />
|
<return type="PackedInt64Array" />
|
||||||
<param index="0" name="aabb" type="AABB" />
|
<param index="0" name="aabb" type="AABB" />
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ void VisualInstance3D::_notification(int p_what) {
|
|||||||
if (!_is_using_identity_transform()) {
|
if (!_is_using_identity_transform()) {
|
||||||
RenderingServer::get_singleton()->instance_set_transform(instance, get_global_transform());
|
RenderingServer::get_singleton()->instance_set_transform(instance, get_global_transform());
|
||||||
}
|
}
|
||||||
|
RenderingServer::get_singleton()->instance_teleport(instance);
|
||||||
|
|
||||||
RenderingServer::get_singleton()->instance_reset_physics_interpolation(instance);
|
RenderingServer::get_singleton()->instance_reset_physics_interpolation(instance);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public:
|
|||||||
virtual void set_surface_materials(const Vector<RID> &p_materials) override {}
|
virtual void set_surface_materials(const Vector<RID> &p_materials) override {}
|
||||||
virtual void set_mesh_instance(RID p_mesh_instance) override {}
|
virtual void set_mesh_instance(RID p_mesh_instance) override {}
|
||||||
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override {}
|
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override {}
|
||||||
|
virtual void reset_motion_vectors() override {}
|
||||||
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) override {}
|
virtual void set_pivot_data(float p_sorting_offset, bool p_use_aabb_center) override {}
|
||||||
virtual void set_lod_bias(float p_lod_bias) override {}
|
virtual void set_lod_bias(float p_lod_bias) override {}
|
||||||
virtual void set_layer_mask(uint32_t p_layer_mask) override {}
|
virtual void set_layer_mask(uint32_t p_layer_mask) override {}
|
||||||
|
|||||||
@@ -134,6 +134,9 @@ void RenderGeometryInstanceBase::set_cast_double_sided_shadows(bool p_enable) {
|
|||||||
_mark_dirty();
|
_mark_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderGeometryInstanceBase::reset_motion_vectors() {
|
||||||
|
}
|
||||||
|
|
||||||
Transform3D RenderGeometryInstanceBase::get_transform() {
|
Transform3D RenderGeometryInstanceBase::get_transform() {
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ public:
|
|||||||
virtual void set_instance_shader_uniforms_offset(int32_t p_offset) = 0;
|
virtual void set_instance_shader_uniforms_offset(int32_t p_offset) = 0;
|
||||||
virtual void set_cast_double_sided_shadows(bool p_enable) = 0;
|
virtual void set_cast_double_sided_shadows(bool p_enable) = 0;
|
||||||
|
|
||||||
|
virtual void reset_motion_vectors() = 0;
|
||||||
|
|
||||||
virtual Transform3D get_transform() = 0;
|
virtual Transform3D get_transform() = 0;
|
||||||
virtual AABB get_aabb() = 0;
|
virtual AABB get_aabb() = 0;
|
||||||
|
|
||||||
@@ -145,6 +147,8 @@ public:
|
|||||||
virtual void set_instance_shader_uniforms_offset(int32_t p_offset) override;
|
virtual void set_instance_shader_uniforms_offset(int32_t p_offset) override;
|
||||||
virtual void set_cast_double_sided_shadows(bool p_enable) override;
|
virtual void set_cast_double_sided_shadows(bool p_enable) override;
|
||||||
|
|
||||||
|
virtual void reset_motion_vectors() override;
|
||||||
|
|
||||||
virtual Transform3D get_transform() override;
|
virtual Transform3D get_transform() override;
|
||||||
virtual AABB get_aabb() override;
|
virtual AABB get_aabb() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1015,7 +1015,7 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI || p_pass_mode == PASS_MODE_COLOR) {
|
if (p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || p_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI || p_pass_mode == PASS_MODE_COLOR) {
|
||||||
bool transform_changed = inst->prev_transform_change_frame == frame;
|
bool transform_changed = inst->transform_status == GeometryInstanceForwardClustered::TransformStatus::MOVED;
|
||||||
bool has_mesh_instance = inst->mesh_instance.is_valid();
|
bool has_mesh_instance = inst->mesh_instance.is_valid();
|
||||||
bool uses_particles = inst->base_flags & INSTANCE_DATA_FLAG_PARTICLES;
|
bool uses_particles = inst->base_flags & INSTANCE_DATA_FLAG_PARTICLES;
|
||||||
bool is_multimesh_with_motion = !uses_particles && (inst->base_flags & INSTANCE_DATA_FLAG_MULTIMESH) && mesh_storage->_multimesh_uses_motion_vectors_offsets(inst->data->base);
|
bool is_multimesh_with_motion = !uses_particles && (inst->base_flags & INSTANCE_DATA_FLAG_MULTIMESH) && mesh_storage->_multimesh_uses_motion_vectors_offsets(inst->data->base);
|
||||||
@@ -1044,9 +1044,9 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
|
|||||||
lod_distance = surface_distance.length();
|
lod_distance = surface_distance.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(inst->prev_transform_dirty && frame > inst->prev_transform_change_frame + 1 && inst->prev_transform_change_frame)) {
|
if (unlikely(inst->transform_status != GeometryInstanceForwardClustered::TransformStatus::NONE && frame > inst->prev_transform_change_frame + 1 && inst->prev_transform_change_frame)) {
|
||||||
inst->prev_transform = inst->transform;
|
inst->prev_transform = inst->transform;
|
||||||
inst->prev_transform_dirty = false;
|
inst->transform_status = GeometryInstanceForwardClustered::TransformStatus::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (surf) {
|
while (surf) {
|
||||||
@@ -4694,12 +4694,19 @@ void RenderForwardClustered::GeometryInstanceForwardClustered::set_transform(con
|
|||||||
if (frame != prev_transform_change_frame) {
|
if (frame != prev_transform_change_frame) {
|
||||||
prev_transform = transform;
|
prev_transform = transform;
|
||||||
prev_transform_change_frame = frame;
|
prev_transform_change_frame = frame;
|
||||||
prev_transform_dirty = true;
|
transform_status = TransformStatus::MOVED;
|
||||||
|
} else if (unlikely(transform_status == TransformStatus::TELEPORTED)) {
|
||||||
|
prev_transform = transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderGeometryInstanceBase::set_transform(p_transform, p_aabb, p_transformed_aabb);
|
RenderGeometryInstanceBase::set_transform(p_transform, p_aabb, p_transformed_aabb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderForwardClustered::GeometryInstanceForwardClustered::reset_motion_vectors() {
|
||||||
|
prev_transform = transform;
|
||||||
|
transform_status = TransformStatus::TELEPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderForwardClustered::GeometryInstanceForwardClustered::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
|
void RenderForwardClustered::GeometryInstanceForwardClustered::set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
|
||||||
lightmap_instance = p_lightmap_instance;
|
lightmap_instance = p_lightmap_instance;
|
||||||
lightmap_uv_scale = p_lightmap_uv_scale;
|
lightmap_uv_scale = p_lightmap_uv_scale;
|
||||||
|
|||||||
@@ -544,7 +544,11 @@ private:
|
|||||||
|
|
||||||
//used during setup
|
//used during setup
|
||||||
uint64_t prev_transform_change_frame = 0xFFFFFFFF;
|
uint64_t prev_transform_change_frame = 0xFFFFFFFF;
|
||||||
bool prev_transform_dirty = true;
|
enum TransformStatus {
|
||||||
|
NONE,
|
||||||
|
MOVED,
|
||||||
|
TELEPORTED,
|
||||||
|
} transform_status = TransformStatus::MOVED;
|
||||||
Transform3D prev_transform;
|
Transform3D prev_transform;
|
||||||
RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE];
|
RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE];
|
||||||
GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
|
GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
|
||||||
@@ -556,6 +560,7 @@ private:
|
|||||||
virtual void _mark_dirty() override;
|
virtual void _mark_dirty() override;
|
||||||
|
|
||||||
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
|
virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
|
||||||
|
virtual void reset_motion_vectors() override;
|
||||||
virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
|
virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
|
||||||
virtual void set_lightmap_capture(const Color *p_sh9) override;
|
virtual void set_lightmap_capture(const Color *p_sh9) override;
|
||||||
|
|
||||||
|
|||||||
@@ -1044,6 +1044,8 @@ void RendererSceneCull::instance_reset_physics_interpolation(RID p_instance) {
|
|||||||
Instance *instance = instance_owner.get_or_null(p_instance);
|
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||||
ERR_FAIL_NULL(instance);
|
ERR_FAIL_NULL(instance);
|
||||||
|
|
||||||
|
instance->teleported = true;
|
||||||
|
|
||||||
if (_interpolation_data.interpolation_enabled && instance->interpolated) {
|
if (_interpolation_data.interpolation_enabled && instance->interpolated) {
|
||||||
instance->transform_prev = instance->transform_curr;
|
instance->transform_prev = instance->transform_curr;
|
||||||
instance->transform_checksum_prev = instance->transform_checksum_curr;
|
instance->transform_checksum_prev = instance->transform_checksum_curr;
|
||||||
@@ -1156,8 +1158,10 @@ void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
|
void RendererSceneCull::instance_teleport(RID p_instance) {
|
||||||
return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES;
|
Instance *instance = instance_owner.get_or_null(p_instance);
|
||||||
|
ERR_FAIL_NULL(instance);
|
||||||
|
instance->teleported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
|
void RendererSceneCull::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
|
||||||
@@ -1790,7 +1794,11 @@ void RendererSceneCull::_update_instance(Instance *p_instance) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ERR_FAIL_NULL(geom->geometry_instance);
|
ERR_FAIL_NULL(geom->geometry_instance);
|
||||||
|
|
||||||
geom->geometry_instance->set_transform(*instance_xform, p_instance->aabb, p_instance->transformed_aabb);
|
geom->geometry_instance->set_transform(*instance_xform, p_instance->aabb, p_instance->transformed_aabb);
|
||||||
|
if (p_instance->teleported) {
|
||||||
|
geom->geometry_instance->reset_motion_vectors();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// note: we had to remove is equal approx check here, it meant that det == 0.000004 won't work, which is the case for some of our scenes.
|
// note: we had to remove is equal approx check here, it meant that det == 0.000004 won't work, which is the case for some of our scenes.
|
||||||
@@ -4204,6 +4212,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) const {
|
|||||||
|
|
||||||
_update_instance(p_instance);
|
_update_instance(p_instance);
|
||||||
|
|
||||||
|
p_instance->teleported = false;
|
||||||
p_instance->update_aabb = false;
|
p_instance->update_aabb = false;
|
||||||
p_instance->update_dependencies = false;
|
p_instance->update_dependencies = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -412,6 +412,7 @@ public:
|
|||||||
// This will either be the interpolated transform (when using fixed timestep interpolation)
|
// This will either be the interpolated transform (when using fixed timestep interpolation)
|
||||||
// or the ONLY transform (when not using FTI).
|
// or the ONLY transform (when not using FTI).
|
||||||
Transform3D transform;
|
Transform3D transform;
|
||||||
|
bool teleported = false;
|
||||||
|
|
||||||
// For interpolation we store the current transform (this physics tick)
|
// For interpolation we store the current transform (this physics tick)
|
||||||
// and the transform in the previous tick.
|
// and the transform in the previous tick.
|
||||||
@@ -1054,6 +1055,8 @@ public:
|
|||||||
virtual void instance_set_visible(RID p_instance, bool p_visible);
|
virtual void instance_set_visible(RID p_instance, bool p_visible);
|
||||||
virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency);
|
virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency);
|
||||||
|
|
||||||
|
virtual void instance_teleport(RID p_instance);
|
||||||
|
|
||||||
virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb);
|
virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb);
|
||||||
|
|
||||||
virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton);
|
virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton);
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ public:
|
|||||||
virtual void instance_set_visible(RID p_instance, bool p_visible) = 0;
|
virtual void instance_set_visible(RID p_instance, bool p_visible) = 0;
|
||||||
virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency) = 0;
|
virtual void instance_geometry_set_transparency(RID p_instance, float p_transparency) = 0;
|
||||||
|
|
||||||
|
virtual void instance_teleport(RID p_instance) = 0;
|
||||||
|
|
||||||
virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb) = 0;
|
virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb) = 0;
|
||||||
|
|
||||||
virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0;
|
virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0;
|
||||||
|
|||||||
@@ -889,6 +889,8 @@ public:
|
|||||||
FUNC3(instance_set_surface_override_material, RID, int, RID)
|
FUNC3(instance_set_surface_override_material, RID, int, RID)
|
||||||
FUNC2(instance_set_visible, RID, bool)
|
FUNC2(instance_set_visible, RID, bool)
|
||||||
|
|
||||||
|
FUNC1(instance_teleport, RID)
|
||||||
|
|
||||||
FUNC2(instance_set_custom_aabb, RID, AABB)
|
FUNC2(instance_set_custom_aabb, RID, AABB)
|
||||||
|
|
||||||
FUNC2(instance_attach_skeleton, RID, RID)
|
FUNC2(instance_attach_skeleton, RID, RID)
|
||||||
|
|||||||
@@ -3172,6 +3172,8 @@ void RenderingServer::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("instance_set_visible", "instance", "visible"), &RenderingServer::instance_set_visible);
|
ClassDB::bind_method(D_METHOD("instance_set_visible", "instance", "visible"), &RenderingServer::instance_set_visible);
|
||||||
ClassDB::bind_method(D_METHOD("instance_geometry_set_transparency", "instance", "transparency"), &RenderingServer::instance_geometry_set_transparency);
|
ClassDB::bind_method(D_METHOD("instance_geometry_set_transparency", "instance", "transparency"), &RenderingServer::instance_geometry_set_transparency);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("instance_teleport", "instance"), &RenderingServer::instance_teleport);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("instance_set_custom_aabb", "instance", "aabb"), &RenderingServer::instance_set_custom_aabb);
|
ClassDB::bind_method(D_METHOD("instance_set_custom_aabb", "instance", "aabb"), &RenderingServer::instance_set_custom_aabb);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("instance_attach_skeleton", "instance", "skeleton"), &RenderingServer::instance_attach_skeleton);
|
ClassDB::bind_method(D_METHOD("instance_attach_skeleton", "instance", "skeleton"), &RenderingServer::instance_attach_skeleton);
|
||||||
|
|||||||
@@ -1449,6 +1449,8 @@ public:
|
|||||||
virtual void instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material) = 0;
|
virtual void instance_set_surface_override_material(RID p_instance, int p_surface, RID p_material) = 0;
|
||||||
virtual void instance_set_visible(RID p_instance, bool p_visible) = 0;
|
virtual void instance_set_visible(RID p_instance, bool p_visible) = 0;
|
||||||
|
|
||||||
|
virtual void instance_teleport(RID p_instance) = 0;
|
||||||
|
|
||||||
virtual void instance_set_custom_aabb(RID p_instance, AABB aabb) = 0;
|
virtual void instance_set_custom_aabb(RID p_instance, AABB aabb) = 0;
|
||||||
|
|
||||||
virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0;
|
virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user