diff options
Diffstat (limited to 'scene/3d')
41 files changed, 713 insertions, 612 deletions
diff --git a/scene/3d/SCsub b/scene/3d/SCsub index ce69e8aa19..40bdaee47d 100644 --- a/scene/3d/SCsub +++ b/scene/3d/SCsub @@ -4,6 +4,5 @@ Import("env") if env["disable_3d"]: env.add_source_files(env.scene_sources, "node_3d.cpp") - env.add_source_files(env.scene_sources, "skeleton_3d.cpp") else: env.add_source_files(env.scene_sources, "*.cpp") diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index ef648a126e..6208b1a1dc 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -273,7 +273,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> if (!mi && s) { Array bmeshes = p_at_node->call("get_bake_bmeshes"); if (bmeshes.size() && (bmeshes.size() & 1) == 0) { - Transform xf = get_global_transform().affine_inverse() * s->get_global_transform(); + Transform3D xf = get_global_transform().affine_inverse() * s->get_global_transform(); for (int i = 0; i < bmeshes.size(); i += 2) { Ref<Mesh> mesh = bmeshes[i]; if (!mesh.is_valid()) { @@ -282,7 +282,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> MeshesFound mf; - Transform mesh_xf = bmeshes[i + 1]; + Transform3D mesh_xf = bmeshes[i + 1]; mf.xform = xf * mesh_xf; mf.node_path = get_path_to(s); mf.subindex = i / 2; @@ -306,7 +306,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> LightmapProbe *probe = Object::cast_to<LightmapProbe>(p_at_node); if (probe) { - Transform xf = get_global_transform().affine_inverse() * probe->get_global_transform(); + Transform3D xf = get_global_transform().affine_inverse() * probe->get_global_transform(); probes.push_back(xf.origin); } @@ -887,7 +887,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d } for (int i = 0; i < lights_found.size(); i++) { Light3D *light = lights_found[i].light; - Transform xf = lights_found[i].xform; + Transform3D xf = lights_found[i].xform; if (Object::cast_to<DirectionalLight3D>(light)) { DirectionalLight3D *l = Object::cast_to<DirectionalLight3D>(light); diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h index e2d89ab2d0..690896f2e9 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/baked_lightmap.h @@ -152,12 +152,12 @@ private: Ref<BakedLightmapData> light_data; struct LightsFound { - Transform xform; + Transform3D xform; Light3D *light = nullptr; }; struct MeshesFound { - Transform xform; + Transform3D xform; NodePath node_path; int32_t subindex = 0; Ref<Mesh> mesh; diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 041da4f6ff..1c9418ae83 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -150,8 +150,8 @@ void Camera3D::_notification(int p_what) { } } -Transform Camera3D::get_camera_transform() const { - Transform tr = get_global_transform().orthonormalized(); +Transform3D Camera3D::get_camera_transform() const { + Transform3D tr = get_global_transform().orthonormalized(); tr.origin += tr.basis.get_axis(1) * v_offset; tr.origin += tr.basis.get_axis(0) * h_offset; return tr; @@ -318,7 +318,7 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const { }; bool Camera3D::is_position_behind(const Vector3 &p_pos) const { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); Vector3 eyedir = -t.basis.get_axis(2).normalized(); return eyedir.dot(p_pos - t.origin) < near; } @@ -337,7 +337,7 @@ Vector<Vector3> Camera3D::get_near_plane_points() const { } Vector3 endpoints[8]; - cm.get_endpoints(Transform(), endpoints); + cm.get_endpoints(Transform3D(), endpoints); Vector<Vector3> points; points.push_back(Vector3()); @@ -686,8 +686,8 @@ ClippedCamera3D::ClipProcessCallback ClippedCamera3D::get_process_callback() con return process_callback; } -Transform ClippedCamera3D::get_camera_transform() const { - Transform t = Camera3D::get_camera_transform(); +Transform3D ClippedCamera3D::get_camera_transform() const { + Transform3D t = Camera3D::get_camera_transform(); t.origin += -t.basis.get_axis(Vector3::AXIS_Z).normalized() * clip_offset; return t; } @@ -735,7 +735,7 @@ void ClippedCamera3D::_notification(int p_what) { } } - Transform xf = get_global_transform(); + Transform3D xf = get_global_transform(); xf.origin = ray_from; xf.orthonormalize(); diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index cea61e4db8..d9ebe78f1a 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -134,7 +134,7 @@ public: void set_near(float p_near); void set_frustum_offset(Vector2 p_offset); - virtual Transform get_camera_transform() const; + virtual Transform3D get_camera_transform() const; virtual Vector3 project_ray_normal(const Point2 &p_pos) const; virtual Vector3 project_ray_origin(const Point2 &p_pos) const; @@ -207,7 +207,7 @@ private: protected: void _notification(int p_what); static void _bind_methods(); - virtual Transform get_camera_transform() const override; + virtual Transform3D get_camera_transform() const override; public: void set_clip_to_areas(bool p_clip); diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index cba769a8f8..e0f93abf5f 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -406,7 +406,7 @@ Array CollisionObject3D::_get_shape_owners() { return ret; } -void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transform &p_transform) { +void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transform3D &p_transform) { ERR_FAIL_COND(!shapes.has(p_owner)); ShapeData &sd = shapes[p_owner]; @@ -421,9 +421,8 @@ void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transf _update_shape_data(p_owner); } - -Transform CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const { - ERR_FAIL_COND_V(!shapes.has(p_owner), Transform()); +Transform3D CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const { + ERR_FAIL_COND_V(!shapes.has(p_owner), Transform3D()); return shapes[p_owner].xform; } diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index 7ff3c5efde..50a9b4fcd0 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -46,7 +46,7 @@ class CollisionObject3D : public Node3D { struct ShapeData { Object *owner = nullptr; - Transform xform; + Transform3D xform; struct ShapeBase { RID debug_shape; Ref<Shape3D> shape; @@ -66,7 +66,7 @@ class CollisionObject3D : public Node3D { Set<uint32_t> debug_shapes_to_update; int debug_shapes_count = 0; - Transform debug_shape_old_transform; + Transform3D debug_shape_old_transform; void _update_pickable(); @@ -107,8 +107,8 @@ public: void get_shape_owners(List<uint32_t> *r_owners); Array _get_shape_owners(); - void shape_owner_set_transform(uint32_t p_owner, const Transform &p_transform); - Transform shape_owner_get_transform(uint32_t p_owner) const; + void shape_owner_set_transform(uint32_t p_owner, const Transform3D &p_transform); + Transform3D shape_owner_get_transform(uint32_t p_owner) const; Object *shape_owner_get_owner(uint32_t p_owner) const; void shape_owner_set_disabled(uint32_t p_owner, bool p_disabled); diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index ac715b22b2..8a4f8b639b 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -171,7 +171,7 @@ TypedArray<String> CollisionPolygon3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - warnings.push_back(TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.")); + warnings.push_back(TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, CharacterBody3D, etc. to give them a shape.")); } if (polygon.is_empty()) { diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 70d9cebb83..be3fde8013 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -124,7 +124,7 @@ TypedArray<String> CollisionShape3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - warnings.push_back(TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.")); + warnings.push_back(TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, CharacterBody3D, etc. to give them a shape.")); } if (!shape.is_valid()) { diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index aa29728c73..2301fef651 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -574,7 +574,7 @@ void CPUParticles3D::_particles_process(float p_delta) { } } - Transform emission_xform; + Transform3D emission_xform; Basis velocity_xform; if (!local_coords) { emission_xform = get_global_transform(); @@ -693,7 +693,7 @@ void CPUParticles3D::_particles_process(float p_delta) { p.custom[0] = Math::deg2rad(base_angle); //angle p.custom[1] = 0.0; //phase p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1) - p.transform = Transform(); + p.transform = Transform3D(); p.time = 0; p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness); p.base_color = Color(1, 1, 1, 1); @@ -1030,7 +1030,7 @@ void CPUParticles3D::_update_particle_data_buffer() { for (int i = 0; i < pc; i++) { int idx = order ? order[i] : i; - Transform t = r[idx].transform; + Transform3D t = r[idx].transform; if (!local_coords) { t = inv_emission_transform * t; @@ -1139,7 +1139,7 @@ void CPUParticles3D::_notification(int p_what) { float *ptr = w; for (int i = 0; i < pc; i++) { - Transform t = inv_emission_transform * r[i].transform; + Transform3D t = inv_emission_transform * r[i].transform; if (r[i].active) { ptr[0] = t.basis.elements[0][0]; diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index c073c93c47..b35e659757 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -83,7 +83,7 @@ private: bool emitting = false; struct Particle { - Transform transform; + Transform3D transform; Color color; float custom[4] = {}; Vector3 velocity; @@ -141,7 +141,7 @@ private: int fixed_fps = 0; bool fractional_delta = true; - Transform inv_emission_transform; + Transform3D inv_emission_transform; SafeFlag can_update; diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 6505fb1ee8..c31997ecaf 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -62,7 +62,7 @@ void GIProbeData::_set_data(const Dictionary &p_data) { octree_df = img->get_data(); } Vector<int> octree_levels = p_data["level_counts"]; - Transform to_cell_xform = p_data["to_cell_xform"]; + Transform3D to_cell_xform = p_data["to_cell_xform"]; allocate(to_cell_xform, bounds, octree_size, octree_cells, octree_data, octree_df, octree_levels); } @@ -90,7 +90,7 @@ Dictionary GIProbeData::_get_data() const { return d; } -void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { +void GIProbeData::allocate(const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) { RS::get_singleton()->gi_probe_allocate_data(probe, p_to_cell_xform, p_aabb, p_octree_size, p_octree_cells, p_data_cells, p_distance_field, p_level_counts); bounds = p_aabb; to_cell_xform = p_to_cell_xform; @@ -121,7 +121,7 @@ Vector<int> GIProbeData::get_level_counts() const { return RS::get_singleton()->gi_probe_get_level_counts(probe); } -Transform GIProbeData::get_to_cell_xform() const { +Transform3D GIProbeData::get_to_cell_xform() const { return to_cell_xform; } @@ -336,7 +336,7 @@ void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { if (mesh.is_valid()) { AABB aabb = mesh->get_aabb(); - Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform(); + Transform3D xf = get_global_transform().affine_inverse() * mi->get_global_transform(); if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) { PlotMesh pm; @@ -356,7 +356,7 @@ void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { if (s->is_visible_in_tree()) { Array meshes = p_at_node->call("get_meshes"); for (int i = 0; i < meshes.size(); i += 2) { - Transform mxf = meshes[i]; + Transform3D mxf = meshes[i]; Ref<Mesh> mesh = meshes[i + 1]; if (!mesh.is_valid()) { continue; @@ -364,7 +364,7 @@ void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) { AABB aabb = mesh->get_aabb(); - Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); + Transform3D xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) { PlotMesh pm; diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index dac7dd3e17..6d922e28f6 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -42,7 +42,7 @@ class GIProbeData : public Resource { void _set_data(const Dictionary &p_data); Dictionary _get_data() const; - Transform to_cell_xform; + Transform3D to_cell_xform; AABB bounds; Vector3 octree_size; @@ -62,14 +62,14 @@ protected: void _validate_property(PropertyInfo &property) const override; public: - void allocate(const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); + void allocate(const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3 &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts); AABB get_bounds() const; Vector3 get_octree_size() const; Vector<uint8_t> get_octree_cells() const; Vector<uint8_t> get_data_cells() const; Vector<uint8_t> get_distance_field() const; Vector<int> get_level_counts() const; - Transform get_to_cell_xform() const; + Transform3D get_to_cell_xform() const; void set_dynamic_range(float p_range); float get_dynamic_range() const; @@ -136,7 +136,7 @@ private: Ref<Material> override_material; Vector<Ref<Material>> instance_materials; Ref<Mesh> mesh; - Transform local_xform; + Transform3D local_xform; }; void _find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes); diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 83181064c3..d7f4bfeb4e 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -391,7 +391,7 @@ void GPUParticles3D::_validate_property(PropertyInfo &property) const { } } -void GPUParticles3D::emit_particle(const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { +void GPUParticles3D::emit_particle(const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) { RS::get_singleton()->particles_emit(particles, p_transform, p_velocity, p_color, p_custom, p_emit_flags); } @@ -458,7 +458,7 @@ void GPUParticles3D::_notification(int p_what) { } void GPUParticles3D::_skinning_changed() { - Vector<Transform> xforms; + Vector<Transform3D> xforms; if (skin.is_valid()) { xforms.resize(skin->get_bind_count()); for (int i = 0; i < skin->get_bind_count(); i++) { diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index 1b354b0d2a..7b21cf03f1 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -171,7 +171,7 @@ public: EMIT_FLAG_CUSTOM = RS::PARTICLES_EMIT_FLAG_CUSTOM }; - void emit_particle(const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags); + void emit_particle(const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags); AABB capture_aabb() const; GPUParticles3D(); diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 2d59461ff0..322bc60fce 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -131,7 +131,7 @@ void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, if (mesh.is_valid()) { AABB aabb = mesh->get_aabb(); - Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform(); + Transform3D xf = get_global_transform().affine_inverse() * mi->get_global_transform(); if (p_aabb.intersects(xf.xform(aabb))) { PlotMesh pm; @@ -147,7 +147,7 @@ void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, if (s->is_visible_in_tree()) { Array meshes = p_at_node->call("get_meshes"); for (int i = 0; i < meshes.size(); i += 2) { - Transform mxf = meshes[i]; + Transform3D mxf = meshes[i]; Ref<Mesh> mesh = meshes[i + 1]; if (!mesh.is_valid()) { continue; @@ -155,7 +155,7 @@ void GPUParticlesCollisionSDF::_find_meshes(const AABB &p_aabb, Node *p_at_node, AABB aabb = mesh->get_aabb(); - Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); + Transform3D xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); if (p_aabb.intersects(xf.xform(aabb))) { PlotMesh pm; @@ -598,14 +598,14 @@ void GPUParticlesCollisionHeightField::_notification(int p_what) { if (follow_camera_mode && get_viewport()) { Camera3D *cam = get_viewport()->get_camera(); if (cam) { - Transform xform = get_global_transform(); + Transform3D xform = get_global_transform(); Vector3 x_axis = xform.basis.get_axis(Vector3::AXIS_X).normalized(); Vector3 z_axis = xform.basis.get_axis(Vector3::AXIS_Z).normalized(); float x_len = xform.basis.get_scale().x; float z_len = xform.basis.get_scale().z; Vector3 cam_pos = cam->get_global_transform().origin; - Transform new_xform = xform; + Transform3D new_xform = xform; while (x_axis.dot(cam_pos - new_xform.origin) > x_len) { new_xform.origin += x_axis * x_len; diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index 81c33663f3..c55463378d 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -119,7 +119,7 @@ private: struct PlotMesh { Ref<Mesh> mesh; - Transform local_xform; + Transform3D local_xform; }; void _find_meshes(const AABB &p_aabb, Node *p_at_node, List<PlotMesh> &plot_meshes); diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp index 9842f152d7..636be083ab 100644 --- a/scene/3d/listener_3d.cpp +++ b/scene/3d/listener_3d.cpp @@ -105,7 +105,7 @@ void Listener3D::_notification(int p_what) { } } -Transform Listener3D::get_listener_transform() const { +Transform3D Listener3D::get_listener_transform() const { return get_global_transform().orthonormalized(); } diff --git a/scene/3d/listener_3d.h b/scene/3d/listener_3d.h index 85657a8e53..bcc66f167c 100644 --- a/scene/3d/listener_3d.h +++ b/scene/3d/listener_3d.h @@ -65,7 +65,7 @@ public: void clear_current(); bool is_current() const; - virtual Transform get_listener_transform() const; + virtual Transform3D get_listener_transform() const; void set_visible_layers(uint32_t p_layers); uint32_t get_visible_layers() const; diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index ba0f8cc870..e96e4df55c 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -223,7 +223,7 @@ void Node3D::_notification(int p_what) { } } -void Node3D::set_transform(const Transform &p_transform) { +void Node3D::set_transform(const Transform3D &p_transform) { data.local_transform = p_transform; data.dirty |= DIRTY_VECTORS; _propagate_transform_changed(this); @@ -232,8 +232,8 @@ void Node3D::set_transform(const Transform &p_transform) { } } -void Node3D::set_global_transform(const Transform &p_transform) { - Transform xform = +void Node3D::set_global_transform(const Transform3D &p_transform) { + Transform3D xform = (data.parent && !data.top_level_active) ? data.parent->get_global_transform().affine_inverse() * p_transform : p_transform; @@ -241,16 +241,15 @@ void Node3D::set_global_transform(const Transform &p_transform) { set_transform(xform); } -Transform Node3D::get_transform() const { +Transform3D Node3D::get_transform() const { if (data.dirty & DIRTY_LOCAL) { _update_local_transform(); } return data.local_transform; } - -Transform Node3D::get_global_transform() const { - ERR_FAIL_COND_V(!is_inside_tree(), Transform()); +Transform3D Node3D::get_global_transform() const { + ERR_FAIL_COND_V(!is_inside_tree(), Transform3D()); if (data.dirty & DIRTY_GLOBAL) { if (data.dirty & DIRTY_LOCAL) { @@ -274,11 +273,11 @@ Transform Node3D::get_global_transform() const { } #ifdef TOOLS_ENABLED -Transform Node3D::get_global_gizmo_transform() const { +Transform3D Node3D::get_global_gizmo_transform() const { return get_global_transform(); } -Transform Node3D::get_local_gizmo_transform() const { +Transform3D Node3D::get_local_gizmo_transform() const { return get_transform(); } #endif @@ -287,12 +286,11 @@ Node3D *Node3D::get_parent_spatial() const { return data.parent; } -Transform Node3D::get_relative_transform(const Node *p_parent) const { - if (p_parent == this) { - return Transform(); - } +Transform3D Node3D::get_relative_transform(const Node *p_parent) const { + if (p_parent == this) + return Transform3D(); - ERR_FAIL_COND_V(!data.parent, Transform()); + ERR_FAIL_COND_V(!data.parent, Transform3D()); if (p_parent == data.parent) { return get_transform(); @@ -301,8 +299,8 @@ Transform Node3D::get_relative_transform(const Node *p_parent) const { } } -void Node3D::set_translation(const Vector3 &p_translation) { - data.local_transform.origin = p_translation; +void Node3D::set_position(const Vector3 &p_position) { + data.local_transform.origin = p_position; _propagate_transform_changed(this); if (data.notify_local_transform) { notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); @@ -341,7 +339,7 @@ void Node3D::set_scale(const Vector3 &p_scale) { } } -Vector3 Node3D::get_translation() const { +Vector3 Node3D::get_position() const { return data.local_transform.origin; } @@ -557,87 +555,87 @@ bool Node3D::is_visible() const { } void Node3D::rotate_object_local(const Vector3 &p_axis, float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate_local(p_axis, p_angle); set_transform(t); } void Node3D::rotate(const Vector3 &p_axis, float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate(p_axis, p_angle); set_transform(t); } void Node3D::rotate_x(float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate(Vector3(1, 0, 0), p_angle); set_transform(t); } void Node3D::rotate_y(float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate(Vector3(0, 1, 0), p_angle); set_transform(t); } void Node3D::rotate_z(float p_angle) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.rotate(Vector3(0, 0, 1), p_angle); set_transform(t); } void Node3D::translate(const Vector3 &p_offset) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.translate(p_offset); set_transform(t); } void Node3D::translate_object_local(const Vector3 &p_offset) { - Transform t = get_transform(); + Transform3D t = get_transform(); - Transform s; + Transform3D s; s.translate(p_offset); set_transform(t * s); } void Node3D::scale(const Vector3 &p_ratio) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.scale(p_ratio); set_transform(t); } void Node3D::scale_object_local(const Vector3 &p_scale) { - Transform t = get_transform(); + Transform3D t = get_transform(); t.basis.scale_local(p_scale); set_transform(t); } void Node3D::global_rotate(const Vector3 &p_axis, float p_angle) { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); t.basis.rotate(p_axis, p_angle); set_global_transform(t); } void Node3D::global_scale(const Vector3 &p_scale) { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); t.basis.scale(p_scale); set_global_transform(t); } void Node3D::global_translate(const Vector3 &p_offset) { - Transform t = get_global_transform(); + Transform3D t = get_global_transform(); t.origin += p_offset; set_global_transform(t); } void Node3D::orthonormalize() { - Transform t = get_transform(); + Transform3D t = get_transform(); t.orthonormalize(); set_transform(t); } void Node3D::set_identity() { - set_transform(Transform()); + set_transform(Transform3D()); } void Node3D::look_at(const Vector3 &p_target, const Vector3 &p_up) { @@ -649,7 +647,7 @@ void Node3D::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target ERR_FAIL_COND_MSG(p_pos == p_target, "Node origin and target are in the same position, look_at() failed."); ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos) == Vector3(), "Up vector and direction between node origin and target are aligned, look_at() failed."); - Transform lookat; + Transform3D lookat; lookat.origin = p_pos; Vector3 original_scale(get_scale()); @@ -695,8 +693,8 @@ void Node3D::force_update_transform() { void Node3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_transform", "local"), &Node3D::set_transform); ClassDB::bind_method(D_METHOD("get_transform"), &Node3D::get_transform); - ClassDB::bind_method(D_METHOD("set_translation", "translation"), &Node3D::set_translation); - ClassDB::bind_method(D_METHOD("get_translation"), &Node3D::get_translation); + ClassDB::bind_method(D_METHOD("set_position", "position"), &Node3D::set_position); + ClassDB::bind_method(D_METHOD("get_position"), &Node3D::get_position); ClassDB::bind_method(D_METHOD("set_rotation", "euler"), &Node3D::set_rotation); ClassDB::bind_method(D_METHOD("get_rotation"), &Node3D::get_rotation); ClassDB::bind_method(D_METHOD("set_rotation_degrees", "euler_degrees"), &Node3D::set_rotation_degrees); @@ -758,16 +756,16 @@ void Node3D::_bind_methods() { BIND_CONSTANT(NOTIFICATION_EXIT_WORLD); BIND_CONSTANT(NOTIFICATION_VISIBILITY_CHANGED); - //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ; + //ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM3D,"transform/global",PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR ), "set_global_transform", "get_global_transform") ; ADD_GROUP("Transform", ""); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "translation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_translation", "get_translation"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "global_transform", PROPERTY_HINT_NONE, "", 0), "set_global_transform", "get_global_transform"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation", PROPERTY_HINT_NONE, "", 0), "set_rotation", "get_rotation"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_scale", "get_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "top_level"), "set_as_top_level", "is_set_as_top_level"); ADD_GROUP("Matrix", ""); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "transform", PROPERTY_HINT_NONE, ""), "set_transform", "get_transform"); ADD_GROUP("Visibility", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "Node3DGizmo", 0), "set_gizmo", "get_gizmo"); diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index a62c7b31a8..09a96bf8ca 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -62,8 +62,8 @@ class Node3D : public Node { mutable SelfList<Node> xform_change; struct Data { - mutable Transform global_transform; - mutable Transform local_transform; + mutable Transform3D global_transform; + mutable Transform3D local_transform; mutable Vector3 rotation; mutable Vector3 scale = Vector3(1, 1, 1); @@ -122,25 +122,25 @@ public: Ref<World3D> get_world_3d() const; - void set_translation(const Vector3 &p_translation); + void set_position(const Vector3 &p_position); void set_rotation(const Vector3 &p_euler_rad); void set_rotation_degrees(const Vector3 &p_euler_deg); void set_scale(const Vector3 &p_scale); - Vector3 get_translation() const; + Vector3 get_position() const; Vector3 get_rotation() const; Vector3 get_rotation_degrees() const; Vector3 get_scale() const; - void set_transform(const Transform &p_transform); - void set_global_transform(const Transform &p_transform); + void set_transform(const Transform3D &p_transform); + void set_global_transform(const Transform3D &p_transform); - Transform get_transform() const; - Transform get_global_transform() const; + Transform3D get_transform() const; + Transform3D get_global_transform() const; #ifdef TOOLS_ENABLED - virtual Transform get_global_gizmo_transform() const; - virtual Transform get_local_gizmo_transform() const; + virtual Transform3D get_global_gizmo_transform() const; + virtual Transform3D get_local_gizmo_transform() const; #endif void set_as_top_level(bool p_enabled); @@ -156,7 +156,7 @@ public: _FORCE_INLINE_ bool is_inside_world() const { return data.inside_world; } - Transform get_relative_transform(const Node *p_parent) const; + Transform3D get_relative_transform(const Node *p_parent) const; void rotate(const Vector3 &p_axis, float p_angle); void rotate_x(float p_angle); diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index d3a256db34..429e1d4b98 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -233,7 +233,7 @@ void OccluderInstance3D::_bake_node(Node *p_node, PackedVector3Array &r_vertices } if (valid) { - Transform global_to_local = get_global_transform().affine_inverse() * mi->get_global_transform(); + Transform3D global_to_local = get_global_transform().affine_inverse() * mi->get_global_transform(); for (int i = 0; i < mesh->get_surface_count(); i++) { if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 4ec4ee6207..de115b35e3 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -108,7 +108,7 @@ void PathFollow3D::_update_transform(bool p_update_xyz_rot) { } Vector3 pos = c->interpolate_baked(offset, cubic); - Transform t = get_transform(); + Transform3D t = get_transform(); // Vector3 pos_offset = Vector3(h_offset, v_offset, 0); not used in all cases // will be replaced by "Vector3(h_offset, v_offset, 0)" where it was formerly used diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index e895d18604..3496ed1a56 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -43,16 +43,35 @@ #include "editor/plugins/node_3d_editor_plugin.h" #endif -Vector3 PhysicsBody3D::get_linear_velocity() const { - return Vector3(); +void PhysicsBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only", "safe_margin"), &PhysicsBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false), DEFVAL(0.001)); + ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "collision", "safe_margin"), &PhysicsBody3D::test_move, DEFVAL(true), DEFVAL(true), DEFVAL(Variant()), DEFVAL(0.001)); + + ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicsBody3D::set_axis_lock); + ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicsBody3D::get_axis_lock); + + ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody3D::get_collision_exceptions); + ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody3D::add_collision_exception_with); + ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody3D::remove_collision_exception_with); + + ADD_GROUP("Axis Lock", "axis_lock_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); } -Vector3 PhysicsBody3D::get_angular_velocity() const { - return Vector3(); +PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : + CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode); } -real_t PhysicsBody3D::get_inverse_mass() const { - return 0; +PhysicsBody3D::~PhysicsBody3D() { + if (motion_cache.is_valid()) { + motion_cache->owner = nullptr; + } } TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() { @@ -83,11 +102,75 @@ void PhysicsBody3D::remove_collision_exception_with(Node *p_node) { PhysicsServer3D::get_singleton()->body_remove_collision_exception(get_rid(), collision_object->get_rid()); } -void PhysicsBody3D::_bind_methods() {} +Ref<KinematicCollision3D> PhysicsBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only, real_t p_margin) { + PhysicsServer3D::MotionResult result; + if (move_and_collide(p_motion, p_infinite_inertia, result, p_margin, p_exclude_raycast_shapes, p_test_only)) { + if (motion_cache.is_null()) { + motion_cache.instance(); + motion_cache->owner = this; + } -PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) : - CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(), false) { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), p_mode); + motion_cache->result = result; + + return motion_cache; + } + + return Ref<KinematicCollision3D>(); +} + +bool PhysicsBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes, bool p_test_only) { + Transform3D gt = get_global_transform(); + bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, p_margin, &r_result, p_exclude_raycast_shapes); + + for (int i = 0; i < 3; i++) { + if (locked_axis & (1 << i)) { + r_result.motion[i] = 0; + } + } + + if (!p_test_only) { + gt.origin += r_result.motion; + set_global_transform(gt); + } + + return colliding; +} + +bool PhysicsBody3D::test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, const Ref<KinematicCollision3D> &r_collision, real_t p_margin) { + ERR_FAIL_COND_V(!is_inside_tree(), false); + + PhysicsServer3D::MotionResult *r = nullptr; + if (r_collision.is_valid()) { + // Needs const_cast because method bindings don't support non-const Ref. + r = const_cast<PhysicsServer3D::MotionResult *>(&r_collision->result); + } + + return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, p_margin, r, p_exclude_raycast_shapes); +} + +void PhysicsBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { + if (p_lock) { + locked_axis |= p_axis; + } else { + locked_axis &= (~p_axis); + } + PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +} + +bool PhysicsBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { + return (locked_axis & p_axis); +} + +Vector3 PhysicsBody3D::get_linear_velocity() const { + return Vector3(); +} + +Vector3 PhysicsBody3D::get_angular_velocity() const { + return Vector3(); +} + +real_t PhysicsBody3D::get_inverse_mass() const { + return 0; } void StaticBody3D::set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override) { @@ -109,14 +192,44 @@ Ref<PhysicsMaterial> StaticBody3D::get_physics_material_override() const { return physics_material_override; } +void StaticBody3D::set_kinematic_motion_enabled(bool p_enabled) { + if (p_enabled == kinematic_motion) { + return; + } + + kinematic_motion = p_enabled; + + if (kinematic_motion) { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_KINEMATIC); + } else { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC); + } + + _update_kinematic_motion(); +} + +bool StaticBody3D::is_kinematic_motion_enabled() const { + return kinematic_motion; +} + void StaticBody3D::set_constant_linear_velocity(const Vector3 &p_vel) { constant_linear_velocity = p_vel; - PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + + if (kinematic_motion) { + _update_kinematic_motion(); + } else { + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity); + } } void StaticBody3D::set_constant_angular_velocity(const Vector3 &p_vel) { constant_angular_velocity = p_vel; - PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + + if (kinematic_motion) { + _update_kinematic_motion(); + } else { + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity); + } } Vector3 StaticBody3D::get_constant_linear_velocity() const { @@ -127,30 +240,81 @@ Vector3 StaticBody3D::get_constant_angular_velocity() const { return constant_angular_velocity; } +Vector3 StaticBody3D::get_linear_velocity() const { + return linear_velocity; +} + +Vector3 StaticBody3D::get_angular_velocity() const { + return angular_velocity; +} + +void StaticBody3D::_notification(int p_what) { + if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + + ERR_FAIL_COND(!kinematic_motion); + + real_t delta_time = get_physics_process_delta_time(); + + Transform3D new_transform = get_global_transform(); + new_transform.origin += constant_linear_velocity * delta_time; + + real_t ang_vel = constant_angular_velocity.length(); + if (!Math::is_zero_approx(ang_vel)) { + Vector3 ang_vel_axis = constant_angular_velocity / ang_vel; + Basis rot(ang_vel_axis, ang_vel * delta_time); + new_transform.basis = rot * new_transform.basis; + new_transform.orthonormalize(); + } + + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_TRANSFORM, new_transform); + + // Propagate transform change to node. + set_ignore_transform_notification(true); + set_global_transform(new_transform); + set_ignore_transform_notification(false); + _on_transform_changed(); + } +} + void StaticBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody3D::set_constant_linear_velocity); ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody3D::set_constant_angular_velocity); ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody3D::get_constant_linear_velocity); ClassDB::bind_method(D_METHOD("get_constant_angular_velocity"), &StaticBody3D::get_constant_angular_velocity); + ClassDB::bind_method(D_METHOD("set_kinematic_motion_enabled", "enabled"), &StaticBody3D::set_kinematic_motion_enabled); + ClassDB::bind_method(D_METHOD("is_kinematic_motion_enabled"), &StaticBody3D::is_kinematic_motion_enabled); + ClassDB::bind_method(D_METHOD("set_physics_material_override", "physics_material_override"), &StaticBody3D::set_physics_material_override); ClassDB::bind_method(D_METHOD("get_physics_material_override"), &StaticBody3D::get_physics_material_override); - ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody3D::get_collision_exceptions); - ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody3D::add_collision_exception_with); - ClassDB::bind_method(D_METHOD("remove_collision_exception_with", "body"), &PhysicsBody3D::remove_collision_exception_with); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_linear_velocity"), "set_constant_linear_velocity", "get_constant_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "constant_angular_velocity"), "set_constant_angular_velocity", "get_constant_angular_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "kinematic_motion"), "set_kinematic_motion_enabled", "is_kinematic_motion_enabled"); +} + +void StaticBody3D::_direct_state_changed(Object *p_state) { +#ifdef DEBUG_ENABLED + PhysicsDirectBodyState3D *state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); + ERR_FAIL_NULL_MSG(state, "Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument"); +#else + PhysicsDirectBodyState3D *state = (PhysicsDirectBodyState3D *)p_state; //trust it +#endif + + linear_velocity = state->get_linear_velocity(); + angular_velocity = state->get_angular_velocity(); } StaticBody3D::StaticBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { } -StaticBody3D::~StaticBody3D() {} - void StaticBody3D::_reload_physics_characteristics() { if (physics_material_override.is_null()) { PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_BOUNCE, 0); @@ -161,6 +325,27 @@ void StaticBody3D::_reload_physics_characteristics() { } } +void StaticBody3D::_update_kinematic_motion() { +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + + if (kinematic_motion) { + PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &StaticBody3D::_direct_state_changed)); + + if (!constant_angular_velocity.is_equal_approx(Vector3()) || !constant_linear_velocity.is_equal_approx(Vector3())) { + set_physics_process_internal(true); + return; + } + } else { + PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), Callable()); + } + + set_physics_process_internal(false); +} + void RigidBody3D::_body_enter_tree(ObjectID p_id) { Object *obj = ObjectDB::get_instance(p_id); Node *node = Object::cast_to<Node>(obj); @@ -398,15 +583,15 @@ void RigidBody3D::_notification(int p_what) { void RigidBody3D::set_mode(Mode p_mode) { mode = p_mode; switch (p_mode) { - case MODE_RIGID: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_RIGID); + case MODE_DYNAMIC: { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC); } break; case MODE_STATIC: { PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC); } break; - case MODE_CHARACTER: { - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_CHARACTER); + case MODE_DYNAMIC_LOCKED: { + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC_LOCKED); } break; case MODE_KINEMATIC: { @@ -627,14 +812,6 @@ bool RigidBody3D::is_contact_monitor_enabled() const { return contact_monitor != nullptr; } -void RigidBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); -} - -bool RigidBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); -} - Array RigidBody3D::get_colliding_bodies() const { ERR_FAIL_COND_V(!contact_monitor, Array()); @@ -654,12 +831,12 @@ Array RigidBody3D::get_colliding_bodies() const { } TypedArray<String> RigidBody3D::get_configuration_warnings() const { - Transform t = get_transform(); + Transform3D t = get_transform(); TypedArray<String> warnings = Node::get_configuration_warnings(); - if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { - warnings.push_back(TTR("Size changes to RigidBody3D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + if ((get_mode() == MODE_DYNAMIC || get_mode() == MODE_DYNAMIC_LOCKED) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { + warnings.push_back(TTR("Size changes to RigidBody3D (in dynamic modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; @@ -720,14 +897,11 @@ void RigidBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &RigidBody3D::set_can_sleep); ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &RigidBody3D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &RigidBody3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &RigidBody3D::get_axis_lock); - ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody3D::get_colliding_bodies); BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState3D"))); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Rigid,Static,Character,Kinematic"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Dynamic,Static,DynamicLocked,Kinematic"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material_override", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material_override", "get_physics_material_override"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-128,128,0.01"), "set_gravity_scale", "get_gravity_scale"); @@ -737,13 +911,6 @@ void RigidBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "contact_monitor"), "set_contact_monitor", "is_contact_monitor_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sleeping"), "set_sleeping", "is_sleeping"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); - ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); ADD_GROUP("Linear", "linear_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); @@ -757,14 +924,14 @@ void RigidBody3D::_bind_methods() { ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("sleeping_state_changed")); - BIND_ENUM_CONSTANT(MODE_RIGID); + BIND_ENUM_CONSTANT(MODE_DYNAMIC); BIND_ENUM_CONSTANT(MODE_STATIC); - BIND_ENUM_CONSTANT(MODE_CHARACTER); + BIND_ENUM_CONSTANT(MODE_DYNAMIC_LOCKED); BIND_ENUM_CONSTANT(MODE_KINEMATIC); } RigidBody3D::RigidBody3D() : - PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) { + PhysicsBody3D(PhysicsServer3D::BODY_MODE_DYNAMIC) { PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &RigidBody3D::_direct_state_changed)); } @@ -784,147 +951,92 @@ void RigidBody3D::_reload_physics_characteristics() { } } -////////////////////////////////////////////////////// -////////////////////////// - -Ref<KinematicCollision3D> KinematicBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) { - Collision col; - if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) { - if (motion_cache.is_null()) { - motion_cache.instance(); - motion_cache->owner = this; - } - - motion_cache->collision = col; - - return motion_cache; - } - - return Ref<KinematicCollision3D>(); -} - -Vector3 KinematicBody3D::get_linear_velocity() const { - return linear_velocity; -} - -Vector3 KinematicBody3D::get_angular_velocity() const { - return angular_velocity; -} - -bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) { - Transform gt = get_global_transform(); - PhysicsServer3D::MotionResult result; - bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes); - - if (colliding) { - r_collision.collider_metadata = result.collider_metadata; - r_collision.collider_shape = result.collider_shape; - r_collision.collider_vel = result.collider_velocity; - r_collision.collision = result.collision_point; - r_collision.normal = result.collision_normal; - r_collision.collider = result.collider_id; - r_collision.collider_rid = result.collider; - r_collision.travel = result.motion; - r_collision.remainder = result.remainder; - r_collision.local_shape = result.collision_local_shape; - } - - for (int i = 0; i < 3; i++) { - if (locked_axis & (1 << i)) { - result.motion[i] = 0; - } - } - - if (!p_test_only) { - gt.origin += result.motion; - set_global_transform(gt); - } - - return colliding; -} +/////////////////////////////////////// //so, if you pass 45 as limit, avoid numerical precision errors when angle is 45. #define FLOOR_ANGLE_THRESHOLD 0.01 -Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { - Vector3 body_velocity = p_linear_velocity; - Vector3 body_velocity_normal = body_velocity.normalized(); - Vector3 up_direction = p_up_direction.normalized(); +void CharacterBody3D::move_and_slide() { + Vector3 body_velocity_normal = linear_velocity.normalized(); + + bool was_on_floor = on_floor; for (int i = 0; i < 3; i++) { if (locked_axis & (1 << i)) { - body_velocity[i] = 0; + linear_velocity[i] = 0.0; } } // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky - Vector3 motion = (floor_velocity + body_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); + Vector3 motion = (floor_velocity + linear_velocity) * (Engine::get_singleton()->is_in_physics_frame() ? get_physics_process_delta_time() : get_process_delta_time()); on_floor = false; on_floor_body = RID(); on_ceiling = false; on_wall = false; - colliders.clear(); + motion_results.clear(); floor_normal = Vector3(); floor_velocity = Vector3(); - while (p_max_slides) { - Collision collision; + int slide_count = max_slides; + while (slide_count) { + PhysicsServer3D::MotionResult result; bool found_collision = false; for (int i = 0; i < 2; ++i) { bool collided; if (i == 0) { //collide - collided = move_and_collide(motion, p_infinite_inertia, collision); + collided = move_and_collide(motion, infinite_inertia, result, margin); if (!collided) { motion = Vector3(); //clear because no collision happened and motion completed } } else { //separate raycasts (if any) - collided = separate_raycast_shapes(p_infinite_inertia, collision); + collided = separate_raycast_shapes(result); if (collided) { - collision.remainder = motion; //keep - collision.travel = Vector3(); + result.remainder = motion; //keep + result.motion = Vector3(); } } if (collided) { found_collision = true; - colliders.push_back(collision); - motion = collision.remainder; + motion_results.push_back(result); + motion = result.remainder; if (up_direction == Vector3()) { //all is a wall on_wall = true; } else { - if (Math::acos(collision.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //floor on_floor = true; - floor_normal = collision.normal; - on_floor_body = collision.collider_rid; - floor_velocity = collision.collider_vel; - - if (p_stop_on_slope) { - if ((body_velocity_normal + up_direction).length() < 0.01 && collision.travel.length() < 1) { - Transform gt = get_global_transform(); - gt.origin -= collision.travel.slide(up_direction); + floor_normal = result.collision_normal; + on_floor_body = result.collider; + floor_velocity = result.collider_velocity; + + if (stop_on_slope) { + if ((body_velocity_normal + up_direction).length() < 0.01 && result.motion.length() < 1) { + Transform3D gt = get_global_transform(); + gt.origin -= result.motion.slide(up_direction); set_global_transform(gt); - return Vector3(); + linear_velocity = Vector3(); + return; } } - } else if (Math::acos(collision.normal.dot(-up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling + } else if (Math::acos(result.collision_normal.dot(-up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { //ceiling on_ceiling = true; } else { on_wall = true; } } - motion = motion.slide(collision.normal); - body_velocity = body_velocity.slide(collision.normal); + motion = motion.slide(result.collision_normal); + linear_velocity = linear_velocity.slide(result.collision_normal); for (int j = 0; j < 3; j++) { if (locked_axis & (1 << j)) { - body_velocity[j] = 0; + linear_velocity[j] = 0.0; } } } @@ -934,83 +1046,47 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const break; } - --p_max_slides; + --slide_count; } - return body_velocity; -} - -Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, real_t p_floor_max_angle, bool p_infinite_inertia) { - Vector3 up_direction = p_up_direction.normalized(); - bool was_on_floor = on_floor; - - Vector3 ret = move_and_slide(p_linear_velocity, up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia); - if (!was_on_floor || p_snap == Vector3()) { - return ret; + if (!was_on_floor || snap == Vector3()) { + return; } - Collision col; - Transform gt = get_global_transform(); - - if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) { + // Apply snap. + Transform3D gt = get_global_transform(); + PhysicsServer3D::MotionResult result; + if (move_and_collide(snap, infinite_inertia, result, margin, false, true)) { bool apply = true; if (up_direction != Vector3()) { - if (Math::acos(col.normal.dot(up_direction)) <= p_floor_max_angle + FLOOR_ANGLE_THRESHOLD) { + if (Math::acos(result.collision_normal.dot(up_direction)) <= floor_max_angle + FLOOR_ANGLE_THRESHOLD) { on_floor = true; - floor_normal = col.normal; - on_floor_body = col.collider_rid; - floor_velocity = col.collider_vel; - if (p_stop_on_slope) { + floor_normal = result.collision_normal; + on_floor_body = result.collider; + floor_velocity = result.collider_velocity; + if (stop_on_slope) { // move and collide may stray the object a bit because of pre un-stucking, // so only ensure that motion happens on floor direction in this case. - col.travel = col.travel.project(up_direction); + result.motion = result.motion.project(up_direction); } } else { apply = false; //snapped with floor direction, but did not snap to a floor, do not snap. } } if (apply) { - gt.origin += col.travel; + gt.origin += result.motion; set_global_transform(gt); } } - - return ret; -} - -bool KinematicBody3D::is_on_floor() const { - return on_floor; } -bool KinematicBody3D::is_on_wall() const { - return on_wall; -} - -bool KinematicBody3D::is_on_ceiling() const { - return on_ceiling; -} - -Vector3 KinematicBody3D::get_floor_normal() const { - return floor_normal; -} - -Vector3 KinematicBody3D::get_floor_velocity() const { - return floor_velocity; -} - -bool KinematicBody3D::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) { - ERR_FAIL_COND_V(!is_inside_tree(), false); - - return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia); -} - -bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) { +bool CharacterBody3D::separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result) { PhysicsServer3D::SeparationResult sep_res[8]; //max 8 rays - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); Vector3 recover; - int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, p_infinite_inertia, recover, sep_res, 8, margin); + int hits = PhysicsServer3D::get_singleton()->body_test_ray_separation(get_rid(), gt, infinite_inertia, recover, sep_res, 8, margin); int deepest = -1; real_t deepest_depth; for (int i = 0; i < hits; i++) { @@ -1024,15 +1100,15 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision set_global_transform(gt); if (deepest != -1) { - r_collision.collider = sep_res[deepest].collider_id; - r_collision.collider_metadata = sep_res[deepest].collider_metadata; - r_collision.collider_shape = sep_res[deepest].collider_shape; - r_collision.collider_vel = sep_res[deepest].collider_velocity; - r_collision.collision = sep_res[deepest].collision_point; - r_collision.normal = sep_res[deepest].collision_normal; - r_collision.local_shape = sep_res[deepest].collision_local_shape; - r_collision.travel = recover; - r_collision.remainder = Vector3(); + r_result.collider_id = sep_res[deepest].collider_id; + r_result.collider_metadata = sep_res[deepest].collider_metadata; + r_result.collider_shape = sep_res[deepest].collider_shape; + r_result.collider_velocity = sep_res[deepest].collider_velocity; + r_result.collision_point = sep_res[deepest].collision_point; + r_result.collision_normal = sep_res[deepest].collision_normal; + r_result.collision_local_shape = sep_res[deepest].collision_local_shape; + r_result.motion = recover; + r_result.remainder = Vector3(); return true; } else { @@ -1040,39 +1116,53 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision } } -void KinematicBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - if (p_lock) { - locked_axis |= p_axis; - } else { - locked_axis &= (~p_axis); - } - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); +void CharacterBody3D::set_safe_margin(real_t p_margin) { + margin = p_margin; } -bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); +real_t CharacterBody3D::get_safe_margin() const { + return margin; } -void KinematicBody3D::set_safe_margin(real_t p_margin) { - margin = p_margin; - PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin); +Vector3 CharacterBody3D::get_linear_velocity() const { + return linear_velocity; } -real_t KinematicBody3D::get_safe_margin() const { - return margin; +void CharacterBody3D::set_linear_velocity(const Vector3 &p_velocity) { + linear_velocity = p_velocity; +} + +bool CharacterBody3D::is_on_floor() const { + return on_floor; +} + +bool CharacterBody3D::is_on_wall() const { + return on_wall; } -int KinematicBody3D::get_slide_count() const { - return colliders.size(); +bool CharacterBody3D::is_on_ceiling() const { + return on_ceiling; +} + +Vector3 CharacterBody3D::get_floor_normal() const { + return floor_normal; +} + +Vector3 CharacterBody3D::get_floor_velocity() const { + return floor_velocity; } -KinematicBody3D::Collision KinematicBody3D::get_slide_collision(int p_bounce) const { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision()); - return colliders[p_bounce]; +int CharacterBody3D::get_slide_count() const { + return motion_results.size(); } -Ref<KinematicCollision3D> KinematicBody3D::_get_slide_collision(int p_bounce) { - ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision3D>()); +PhysicsServer3D::MotionResult CharacterBody3D::get_slide_collision(int p_bounce) const { + ERR_FAIL_INDEX_V(p_bounce, motion_results.size(), PhysicsServer3D::MotionResult()); + return motion_results[p_bounce]; +} + +Ref<KinematicCollision3D> CharacterBody3D::_get_slide_collision(int p_bounce) { + ERR_FAIL_INDEX_V(p_bounce, motion_results.size(), Ref<KinematicCollision3D>()); if (p_bounce >= slide_colliders.size()) { slide_colliders.resize(p_bounce + 1); } @@ -1082,75 +1172,115 @@ Ref<KinematicCollision3D> KinematicBody3D::_get_slide_collision(int p_bounce) { slide_colliders.write[p_bounce]->owner = this; } - slide_colliders.write[p_bounce]->collision = colliders[p_bounce]; + slide_colliders.write[p_bounce]->result = motion_results[p_bounce]; return slide_colliders[p_bounce]; } -void KinematicBody3D::_notification(int p_what) { +bool CharacterBody3D::is_stop_on_slope_enabled() const { + return stop_on_slope; +} + +void CharacterBody3D::set_stop_on_slope_enabled(bool p_enabled) { + stop_on_slope = p_enabled; +} + +bool CharacterBody3D::is_infinite_inertia_enabled() const { + return infinite_inertia; +} +void CharacterBody3D::set_infinite_inertia_enabled(bool p_enabled) { + infinite_inertia = p_enabled; +} + +int CharacterBody3D::get_max_slides() const { + return max_slides; +} + +void CharacterBody3D::set_max_slides(int p_max_slides) { + ERR_FAIL_COND(p_max_slides > 0); + max_slides = p_max_slides; +} + +real_t CharacterBody3D::get_floor_max_angle() const { + return floor_max_angle; +} + +void CharacterBody3D::set_floor_max_angle(real_t p_floor_max_angle) { + floor_max_angle = p_floor_max_angle; +} + +const Vector3 &CharacterBody3D::get_snap() const { + return snap; +} + +void CharacterBody3D::set_snap(const Vector3 &p_snap) { + snap = p_snap; +} + +const Vector3 &CharacterBody3D::get_up_direction() const { + return up_direction; +} + +void CharacterBody3D::set_up_direction(const Vector3 &p_up_direction) { + up_direction = p_up_direction.normalized(); +} + +void CharacterBody3D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { // Reset move_and_slide() data. on_floor = false; on_floor_body = RID(); on_ceiling = false; on_wall = false; - colliders.clear(); + motion_results.clear(); floor_velocity = Vector3(); } } -void KinematicBody3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); - ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody3D::move_and_slide_with_snap, DEFVAL(Vector3(0, 0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((real_t)45.0)), DEFVAL(true)); - - ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody3D::test_move, DEFVAL(true)); - - ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody3D::is_on_floor); - ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody3D::is_on_ceiling); - ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody3D::is_on_wall); - ClassDB::bind_method(D_METHOD("get_floor_normal"), &KinematicBody3D::get_floor_normal); - ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody3D::get_floor_velocity); +void CharacterBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody3D::move_and_slide); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &KinematicBody3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &KinematicBody3D::get_axis_lock); + ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &CharacterBody3D::set_linear_velocity); + ClassDB::bind_method(D_METHOD("get_linear_velocity"), &CharacterBody3D::get_linear_velocity); - ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody3D::set_safe_margin); - ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody3D::get_safe_margin); + ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody3D::set_safe_margin); + ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody3D::get_safe_margin); + ClassDB::bind_method(D_METHOD("is_stop_on_slope_enabled"), &CharacterBody3D::is_stop_on_slope_enabled); + ClassDB::bind_method(D_METHOD("set_stop_on_slope_enabled", "enabled"), &CharacterBody3D::set_stop_on_slope_enabled); + ClassDB::bind_method(D_METHOD("is_infinite_inertia_enabled"), &CharacterBody3D::is_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("set_infinite_inertia_enabled", "enabled"), &CharacterBody3D::set_infinite_inertia_enabled); + ClassDB::bind_method(D_METHOD("get_max_slides"), &CharacterBody3D::get_max_slides); + ClassDB::bind_method(D_METHOD("set_max_slides", "max_slides"), &CharacterBody3D::set_max_slides); + ClassDB::bind_method(D_METHOD("get_floor_max_angle"), &CharacterBody3D::get_floor_max_angle); + ClassDB::bind_method(D_METHOD("set_floor_max_angle", "floor_max_angle"), &CharacterBody3D::set_floor_max_angle); + ClassDB::bind_method(D_METHOD("get_snap"), &CharacterBody3D::get_snap); + ClassDB::bind_method(D_METHOD("set_snap", "snap"), &CharacterBody3D::set_snap); + ClassDB::bind_method(D_METHOD("get_up_direction"), &CharacterBody3D::get_up_direction); + ClassDB::bind_method(D_METHOD("set_up_direction", "up_direction"), &CharacterBody3D::set_up_direction); - ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody3D::get_slide_count); - ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody3D::_get_slide_collision); + ClassDB::bind_method(D_METHOD("is_on_floor"), &CharacterBody3D::is_on_floor); + ClassDB::bind_method(D_METHOD("is_on_ceiling"), &CharacterBody3D::is_on_ceiling); + ClassDB::bind_method(D_METHOD("is_on_wall"), &CharacterBody3D::is_on_wall); + ClassDB::bind_method(D_METHOD("get_floor_normal"), &CharacterBody3D::get_floor_normal); + ClassDB::bind_method(D_METHOD("get_floor_velocity"), &CharacterBody3D::get_floor_velocity); - ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); + ClassDB::bind_method(D_METHOD("get_slide_count"), &CharacterBody3D::get_slide_count); + ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &CharacterBody3D::_get_slide_collision); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stop_on_slope"), "set_stop_on_slope_enabled", "is_stop_on_slope_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "infinite_inertia"), "set_infinite_inertia_enabled", "is_infinite_inertia_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides"), "set_max_slides", "get_max_slides"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle"), "set_floor_max_angle", "get_floor_max_angle"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap"), "set_snap", "get_snap"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } -void KinematicBody3D::_direct_state_changed(Object *p_state) { -#ifdef DEBUG_ENABLED - PhysicsDirectBodyState3D *state = Object::cast_to<PhysicsDirectBodyState3D>(p_state); - ERR_FAIL_NULL_MSG(state, "Method '_direct_state_changed' must receive a valid PhysicsDirectBodyState3D object as argument"); -#else - PhysicsDirectBodyState3D *state = (PhysicsDirectBodyState3D *)p_state; //trust it -#endif - - linear_velocity = state->get_linear_velocity(); - angular_velocity = state->get_angular_velocity(); -} - -KinematicBody3D::KinematicBody3D() : +CharacterBody3D::CharacterBody3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) { - set_safe_margin(0.001); - PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &KinematicBody3D::_direct_state_changed)); } -KinematicBody3D::~KinematicBody3D() { - if (motion_cache.is_valid()) { - motion_cache->owner = nullptr; - } - +CharacterBody3D::~CharacterBody3D() { for (int i = 0; i < slide_colliders.size(); i++) { if (slide_colliders[i].is_valid()) { slide_colliders.write[i]->owner = nullptr; @@ -1161,39 +1291,39 @@ KinematicBody3D::~KinematicBody3D() { /////////////////////////////////////// Vector3 KinematicCollision3D::get_position() const { - return collision.collision; + return result.collision_point; } Vector3 KinematicCollision3D::get_normal() const { - return collision.normal; + return result.collision_normal; } Vector3 KinematicCollision3D::get_travel() const { - return collision.travel; + return result.motion; } Vector3 KinematicCollision3D::get_remainder() const { - return collision.remainder; + return result.remainder; } Object *KinematicCollision3D::get_local_shape() const { if (!owner) { return nullptr; } - uint32_t ownerid = owner->shape_find_owner(collision.local_shape); + uint32_t ownerid = owner->shape_find_owner(result.collision_local_shape); return owner->shape_owner_get_owner(ownerid); } Object *KinematicCollision3D::get_collider() const { - if (collision.collider.is_valid()) { - return ObjectDB::get_instance(collision.collider); + if (result.collider_id.is_valid()) { + return ObjectDB::get_instance(result.collider_id); } return nullptr; } ObjectID KinematicCollision3D::get_collider_id() const { - return collision.collider; + return result.collider_id; } Object *KinematicCollision3D::get_collider_shape() const { @@ -1201,7 +1331,7 @@ Object *KinematicCollision3D::get_collider_shape() const { if (collider) { CollisionObject3D *obj2d = Object::cast_to<CollisionObject3D>(collider); if (obj2d) { - uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape); + uint32_t ownerid = obj2d->shape_find_owner(result.collider_shape); return obj2d->shape_owner_get_owner(ownerid); } } @@ -1210,11 +1340,11 @@ Object *KinematicCollision3D::get_collider_shape() const { } int KinematicCollision3D::get_collider_shape_index() const { - return collision.collider_shape; + return result.collider_shape; } Vector3 KinematicCollision3D::get_collider_velocity() const { - return collision.collider_vel; + return result.collider_velocity; } Variant KinematicCollision3D::get_collider_metadata() const { @@ -1247,12 +1377,6 @@ void KinematicCollision3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata"); } -KinematicCollision3D::KinematicCollision3D() { - collision.collider_shape = 0; - collision.local_shape = 0; - owner = nullptr; -} - /////////////////////////////////////// bool PhysicalBone3D::JointData::_set(const StringName &p_name, const Variant &p_value, RID j) { @@ -1989,7 +2113,7 @@ void PhysicalBone3D::_direct_state_changed(Object *p_state) { state = (PhysicsDirectBodyState3D *)p_state; //trust it #endif - Transform global_transform(state->get_transform()); + Transform3D global_transform(state->get_transform()); set_ignore_transform_notification(true); set_global_transform(global_transform); @@ -2048,16 +2172,13 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); - ClassDB::bind_method(D_METHOD("set_axis_lock", "axis", "lock"), &PhysicalBone3D::set_axis_lock); - ClassDB::bind_method(D_METHOD("get_axis_lock", "axis"), &PhysicalBone3D::get_axis_lock); - ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "joint_offset"), "set_joint_offset", "get_joint_offset"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "joint_offset"), "set_joint_offset", "get_joint_offset"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation_degrees", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_joint_rotation_degrees", "get_joint_rotation_degrees"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "joint_rotation", PROPERTY_HINT_NONE, "", 0), "set_joint_rotation", "get_joint_rotation"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "body_offset"), "set_body_offset", "get_body_offset"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "body_offset"), "set_body_offset", "get_body_offset"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_EXP_RANGE, "0.01,65535,0.01"), "set_mass", "get_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); @@ -2067,14 +2188,6 @@ void PhysicalBone3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); - ADD_GROUP("Axis Lock", "axis_lock_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_linear_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_X); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_angular_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_ANGULAR_Z); - BIND_ENUM_CONSTANT(JOINT_TYPE_NONE); BIND_ENUM_CONSTANT(JOINT_TYPE_PIN); BIND_ENUM_CONSTANT(JOINT_TYPE_CONE); @@ -2124,8 +2237,8 @@ void PhysicalBone3D::_reload_joint() { return; } - Transform joint_transf = get_global_transform() * joint_offset; - Transform local_a = body_a->get_global_transform().affine_inverse() * joint_transf; + Transform3D joint_transf = get_global_transform() * joint_offset; + Transform3D local_a = body_a->get_global_transform().affine_inverse() * joint_transf; local_a.orthonormalize(); switch (get_joint_type()) { @@ -2218,11 +2331,11 @@ void PhysicalBone3D::_set_gizmo_move_joint(bool p_move_joint) { } #ifdef TOOLS_ENABLED -Transform PhysicalBone3D::get_global_gizmo_transform() const { +Transform3D PhysicalBone3D::get_global_gizmo_transform() const { return gizmo_move_joint ? get_global_transform() * joint_offset : get_global_transform(); } -Transform PhysicalBone3D::get_local_gizmo_transform() const { +Transform3D PhysicalBone3D::get_local_gizmo_transform() const { return gizmo_move_joint ? get_transform() * joint_offset : get_transform(); } #endif @@ -2278,13 +2391,13 @@ PhysicalBone3D::JointType PhysicalBone3D::get_joint_type() const { return joint_data ? joint_data->get_joint_type() : JOINT_TYPE_NONE; } -void PhysicalBone3D::set_joint_offset(const Transform &p_offset) { +void PhysicalBone3D::set_joint_offset(const Transform3D &p_offset) { joint_offset = p_offset; _update_joint_offset(); } -const Transform &PhysicalBone3D::get_joint_offset() const { +const Transform3D &PhysicalBone3D::get_joint_offset() const { return joint_offset; } @@ -2306,11 +2419,11 @@ Vector3 PhysicalBone3D::get_joint_rotation_degrees() const { return get_joint_rotation() * (180.0 / Math_PI); } -const Transform &PhysicalBone3D::get_body_offset() const { +const Transform3D &PhysicalBone3D::get_body_offset() const { return body_offset; } -void PhysicalBone3D::set_body_offset(const Transform &p_offset) { +void PhysicalBone3D::set_body_offset(const Transform3D &p_offset) { body_offset = p_offset; body_offset_inverse = body_offset.affine_inverse(); @@ -2416,14 +2529,6 @@ bool PhysicalBone3D::is_able_to_sleep() const { return can_sleep; } -void PhysicalBone3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) { - PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock); -} - -bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const { - return PhysicsServer3D::get_singleton()->body_is_axis_locked(get_rid(), p_axis); -} - PhysicalBone3D::PhysicalBone3D() : PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) { joint = PhysicsServer3D::get_singleton()->joint_create(); @@ -2463,7 +2568,7 @@ void PhysicalBone3D::update_bone_id() { void PhysicalBone3D::update_offset() { #ifdef TOOLS_ENABLED if (parent_skeleton) { - Transform bone_transform(parent_skeleton->get_global_transform()); + Transform3D bone_transform(parent_skeleton->get_global_transform()); if (-1 != bone_id) { bone_transform *= parent_skeleton->get_bone_global_pose(bone_id); } @@ -2483,7 +2588,7 @@ void PhysicalBone3D::_start_physics_simulation() { return; } reset_to_rest_position(); - PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_RIGID); + PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_DYNAMIC); PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), get_collision_layer()); PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), get_collision_mask()); PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), callable_mp(this, &PhysicalBone3D::_direct_state_changed)); @@ -2506,7 +2611,7 @@ void PhysicalBone3D::_stop_physics_simulation() { } if (_internal_simulate_physics) { PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), Callable()); - parent_skeleton->set_bone_global_pose_override(bone_id, Transform(), 0.0, false); + parent_skeleton->set_bone_global_pose_override(bone_id, Transform3D(), 0.0, false); set_as_top_level(false); _internal_simulate_physics = false; } diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 818ff97730..d5e474c5d5 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -37,6 +37,8 @@ #include "servers/physics_server_3d.h" #include "skeleton_3d.h" +class KinematicCollision3D; + class PhysicsBody3D : public CollisionObject3D { GDCLASS(PhysicsBody3D, CollisionObject3D); @@ -44,7 +46,19 @@ protected: static void _bind_methods(); PhysicsBody3D(PhysicsServer3D::BodyMode p_mode); + Ref<KinematicCollision3D> motion_cache; + + uint16_t locked_axis = 0; + + Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false, real_t p_margin = 0.001); + public: + bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult &r_result, real_t p_margin, bool p_exclude_raycast_shapes = true, bool p_test_only = false); + bool test_move(const Transform3D &p_from, const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, const Ref<KinematicCollision3D> &r_collision = Ref<KinematicCollision3D>(), real_t p_margin = 0.001); + + void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); + bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; + virtual Vector3 get_linear_velocity() const; virtual Vector3 get_angular_velocity() const; virtual real_t get_inverse_mass() const; @@ -53,7 +67,7 @@ public: void add_collision_exception_with(Node *p_node); //must be physicsbody void remove_collision_exception_with(Node *p_node); - PhysicsBody3D(); + virtual ~PhysicsBody3D(); }; class StaticBody3D : public PhysicsBody3D { @@ -62,11 +76,19 @@ class StaticBody3D : public PhysicsBody3D { Vector3 constant_linear_velocity; Vector3 constant_angular_velocity; + Vector3 linear_velocity; + Vector3 angular_velocity; + Ref<PhysicsMaterial> physics_material_override; + bool kinematic_motion = false; + protected: + void _notification(int p_what); static void _bind_methods(); + void _direct_state_changed(Object *p_state); + public: void set_physics_material_override(const Ref<PhysicsMaterial> &p_physics_material_override); Ref<PhysicsMaterial> get_physics_material_override() const; @@ -77,11 +99,18 @@ public: Vector3 get_constant_linear_velocity() const; Vector3 get_constant_angular_velocity() const; + virtual Vector3 get_linear_velocity() const override; + virtual Vector3 get_angular_velocity() const override; + StaticBody3D(); - ~StaticBody3D(); private: void _reload_physics_characteristics(); + + void _update_kinematic_motion(); + + void set_kinematic_motion_enabled(bool p_enabled); + bool is_kinematic_motion_enabled() const; }; class RigidBody3D : public PhysicsBody3D { @@ -89,16 +118,16 @@ class RigidBody3D : public PhysicsBody3D { public: enum Mode { - MODE_RIGID, + MODE_DYNAMIC, MODE_STATIC, - MODE_CHARACTER, + MODE_DYNAMIC_LOCKED, MODE_KINEMATIC, }; protected: bool can_sleep = true; PhysicsDirectBodyState3D *state = nullptr; - Mode mode = MODE_RIGID; + Mode mode = MODE_DYNAMIC; real_t mass = 1.0; Ref<PhysicsMaterial> physics_material_override; @@ -212,9 +241,6 @@ public: void set_use_continuous_collision_detection(bool p_enable); bool is_using_continuous_collision_detection() const; - void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); - bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; - Array get_colliding_bodies() const; void add_central_force(const Vector3 &p_force); @@ -238,30 +264,20 @@ VARIANT_ENUM_CAST(RigidBody3D::Mode); class KinematicCollision3D; -class KinematicBody3D : public PhysicsBody3D { - GDCLASS(KinematicBody3D, PhysicsBody3D); - -public: - struct Collision { - Vector3 collision; - Vector3 normal; - Vector3 collider_vel; - ObjectID collider; - RID collider_rid; - int collider_shape = 0; - Variant collider_metadata; - Vector3 remainder; - Vector3 travel; - int local_shape = 0; - }; +class CharacterBody3D : public PhysicsBody3D { + GDCLASS(CharacterBody3D, PhysicsBody3D); private: - Vector3 linear_velocity; - Vector3 angular_velocity; + real_t margin = 0.001; - uint16_t locked_axis = 0; + bool stop_on_slope = false; + bool infinite_inertia = true; + int max_slides = 4; + real_t floor_max_angle = Math::deg2rad((real_t)45.0); + Vector3 snap; + Vector3 up_direction = Vector3(0.0, 1.0, 0.0); - real_t margin; + Vector3 linear_velocity; Vector3 floor_normal; Vector3 floor_velocity; @@ -269,38 +285,44 @@ private: bool on_floor = false; bool on_ceiling = false; bool on_wall = false; - Vector<Collision> colliders; + Vector<PhysicsServer3D::MotionResult> motion_results; Vector<Ref<KinematicCollision3D>> slide_colliders; - Ref<KinematicCollision3D> motion_cache; - - _FORCE_INLINE_ bool _ignores_mode(PhysicsServer3D::BodyMode) const; - Ref<KinematicCollision3D> _move(const Vector3 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false); Ref<KinematicCollision3D> _get_slide_collision(int p_bounce); -protected: - void _notification(int p_what); - static void _bind_methods(); + bool separate_raycast_shapes(PhysicsServer3D::MotionResult &r_result); - virtual void _direct_state_changed(Object *p_state); + void set_safe_margin(real_t p_margin); + real_t get_safe_margin() const; -public: - virtual Vector3 get_linear_velocity() const override; - virtual Vector3 get_angular_velocity() const override; + bool is_stop_on_slope_enabled() const; + void set_stop_on_slope_enabled(bool p_enabled); - bool move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false); - bool test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia); + bool is_infinite_inertia_enabled() const; + void set_infinite_inertia_enabled(bool p_enabled); - bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision); + int get_max_slides() const; + void set_max_slides(int p_max_slides); - void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); - bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; + real_t get_floor_max_angle() const; + void set_floor_max_angle(real_t p_floor_max_angle); - void set_safe_margin(real_t p_margin); - real_t get_safe_margin() const; + const Vector3 &get_snap() const; + void set_snap(const Vector3 &p_snap); + + const Vector3 &get_up_direction() const; + void set_up_direction(const Vector3 &p_up_direction); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + void move_and_slide(); + + virtual Vector3 get_linear_velocity() const override; + void set_linear_velocity(const Vector3 &p_velocity); - Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); - Vector3 move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction = Vector3(0, 0, 0), bool p_stop_on_slope = false, int p_max_slides = 4, real_t p_floor_max_angle = Math::deg2rad((real_t)45.0), bool p_infinite_inertia = true); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; @@ -308,18 +330,19 @@ public: Vector3 get_floor_velocity() const; int get_slide_count() const; - Collision get_slide_collision(int p_bounce) const; + PhysicsServer3D::MotionResult get_slide_collision(int p_bounce) const; - KinematicBody3D(); - ~KinematicBody3D(); + CharacterBody3D(); + ~CharacterBody3D(); }; class KinematicCollision3D : public Reference { GDCLASS(KinematicCollision3D, Reference); - KinematicBody3D *owner; - friend class KinematicBody3D; - KinematicBody3D::Collision collision; + PhysicsBody3D *owner = nullptr; + friend class PhysicsBody3D; + friend class CharacterBody3D; + PhysicsServer3D::MotionResult result; protected: static void _bind_methods(); @@ -336,8 +359,6 @@ public: int get_collider_shape_index() const; Vector3 get_collider_velocity() const; Variant get_collider_metadata() const; - - KinematicCollision3D(); }; class PhysicalBone3D : public PhysicsBody3D { @@ -467,12 +488,12 @@ private: #endif JointData *joint_data = nullptr; - Transform joint_offset; + Transform3D joint_offset; RID joint; Skeleton3D *parent_skeleton = nullptr; - Transform body_offset; - Transform body_offset_inverse; + Transform3D body_offset; + Transform3D body_offset_inverse; bool simulate_physics = false; bool _internal_simulate_physics = false; int bone_id = -1; @@ -508,8 +529,8 @@ public: public: #ifdef TOOLS_ENABLED - virtual Transform get_global_gizmo_transform() const override; - virtual Transform get_local_gizmo_transform() const override; + virtual Transform3D get_global_gizmo_transform() const override; + virtual Transform3D get_local_gizmo_transform() const override; #endif const JointData *get_joint_data() const; @@ -520,8 +541,8 @@ public: void set_joint_type(JointType p_joint_type); JointType get_joint_type() const; - void set_joint_offset(const Transform &p_offset); - const Transform &get_joint_offset() const; + void set_joint_offset(const Transform3D &p_offset); + const Transform3D &get_joint_offset() const; void set_joint_rotation(const Vector3 &p_euler_rad); Vector3 get_joint_rotation() const; @@ -529,8 +550,8 @@ public: void set_joint_rotation_degrees(const Vector3 &p_euler_deg); Vector3 get_joint_rotation_degrees() const; - void set_body_offset(const Transform &p_offset); - const Transform &get_body_offset() const; + void set_body_offset(const Transform3D &p_offset); + const Transform3D &get_body_offset() const; void set_simulate_physics(bool p_simulate); bool get_simulate_physics(); @@ -560,9 +581,6 @@ public: void set_can_sleep(bool p_active); bool is_able_to_sleep() const; - void set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock); - bool get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const; - void apply_central_impulse(const Vector3 &p_impulse); void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()); diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 3d58d1c10e..01f10c171f 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -372,15 +372,15 @@ bool HingeJoint3D::get_flag(Flag p_flag) const { } void HingeJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { - Transform gt = get_global_transform(); - Transform ainv = body_a->get_global_transform().affine_inverse(); + Transform3D gt = get_global_transform(); + Transform3D ainv = body_a->get_global_transform().affine_inverse(); - Transform local_a = ainv * gt; + Transform3D local_a = ainv * gt; local_a.orthonormalize(); - Transform local_b = gt; + Transform3D local_b = gt; if (body_b) { - Transform binv = body_b->get_global_transform().affine_inverse(); + Transform3D binv = body_b->get_global_transform().affine_inverse(); local_b = binv * gt; } @@ -506,15 +506,15 @@ real_t SliderJoint3D::get_param(Param p_param) const { } void SliderJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { - Transform gt = get_global_transform(); - Transform ainv = body_a->get_global_transform().affine_inverse(); + Transform3D gt = get_global_transform(); + Transform3D ainv = body_a->get_global_transform().affine_inverse(); - Transform local_a = ainv * gt; + Transform3D local_a = ainv * gt; local_a.orthonormalize(); - Transform local_b = gt; + Transform3D local_b = gt; if (body_b) { - Transform binv = body_b->get_global_transform().affine_inverse(); + Transform3D binv = body_b->get_global_transform().affine_inverse(); local_b = binv * gt; } @@ -611,18 +611,18 @@ real_t ConeTwistJoint3D::get_param(Param p_param) const { } void ConeTwistJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); //Vector3 cone_twistpos = gt.origin; //Vector3 cone_twistdir = gt.basis.get_axis(2); - Transform ainv = body_a->get_global_transform().affine_inverse(); + Transform3D ainv = body_a->get_global_transform().affine_inverse(); - Transform local_a = ainv * gt; + Transform3D local_a = ainv * gt; local_a.orthonormalize(); - Transform local_b = gt; + Transform3D local_b = gt; if (body_b) { - Transform binv = body_b->get_global_transform().affine_inverse(); + Transform3D binv = body_b->get_global_transform().affine_inverse(); local_b = binv * gt; } @@ -936,18 +936,18 @@ bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const { } void Generic6DOFJoint3D::_configure_joint(RID p_joint, PhysicsBody3D *body_a, PhysicsBody3D *body_b) { - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); //Vector3 cone_twistpos = gt.origin; //Vector3 cone_twistdir = gt.basis.get_axis(2); - Transform ainv = body_a->get_global_transform().affine_inverse(); + Transform3D ainv = body_a->get_global_transform().affine_inverse(); - Transform local_a = ainv * gt; + Transform3D local_a = ainv * gt; local_a.orthonormalize(); - Transform local_b = gt; + Transform3D local_b = gt; if (body_b) { - Transform binv = body_b->get_global_transform().affine_inverse(); + Transform3D binv = body_b->get_global_transform().affine_inverse(); local_b = binv * gt; } diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index 475f8c07fd..db841101e5 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -205,7 +205,7 @@ void RayCast3D::_update_raycast_state() { PhysicsDirectSpaceState3D *dss = PhysicsServer3D::get_singleton()->space_get_direct_state(w3d->get_space()); ERR_FAIL_COND(!dss); - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); Vector3 to = target_position; if (to == Vector3()) { diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp index 29a407905b..a7b3a6f1ec 100644 --- a/scene/3d/remote_transform_3d.cpp +++ b/scene/3d/remote_transform_3d.cpp @@ -65,7 +65,7 @@ void RemoteTransform3D::_update_remote() { if (update_remote_position && update_remote_rotation && update_remote_scale) { n->set_global_transform(get_global_transform()); } else { - Transform our_trans = get_global_transform(); + Transform3D our_trans = get_global_transform(); if (update_remote_rotation) { n->set_rotation(our_trans.basis.get_rotation()); @@ -76,7 +76,7 @@ void RemoteTransform3D::_update_remote() { } if (update_remote_position) { - Transform n_trans = n->get_global_transform(); + Transform3D n_trans = n->get_global_transform(); n_trans.set_origin(our_trans.get_origin()); n->set_global_transform(n_trans); @@ -87,7 +87,7 @@ void RemoteTransform3D::_update_remote() { if (update_remote_position && update_remote_rotation && update_remote_scale) { n->set_transform(get_transform()); } else { - Transform our_trans = get_transform(); + Transform3D our_trans = get_transform(); if (update_remote_rotation) { n->set_rotation(our_trans.basis.get_rotation()); @@ -98,7 +98,7 @@ void RemoteTransform3D::_update_remote() { } if (update_remote_position) { - Transform n_trans = n->get_transform(); + Transform3D n_trans = n->get_transform(); n_trans.set_origin(our_trans.get_origin()); n->set_transform(n_trans); diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 82927df5f1..f9d613a4bb 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -135,9 +135,9 @@ void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const { String prep = "bones/" + itos(i) + "/"; p_list->push_back(PropertyInfo(Variant::STRING, prep + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "rest", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prep + "rest", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); p_list->push_back(PropertyInfo(Variant::BOOL, prep + "enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); - p_list->push_back(PropertyInfo(Variant::TRANSFORM, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + p_list->push_back(PropertyInfo(Variant::TRANSFORM3D, prep + "pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); } } @@ -211,7 +211,7 @@ void Skeleton3D::_notification(int p_what) { if (b.disable_rest) { if (b.enabled) { - Transform pose = b.pose; + Transform3D pose = b.pose; if (b.custom_pose_enable) { pose = b.custom_pose * pose; } @@ -227,14 +227,14 @@ void Skeleton3D::_notification(int p_what) { b.pose_global = bonesptr[b.parent].pose_global; b.pose_global_no_override = bonesptr[b.parent].pose_global; } else { - b.pose_global = Transform(); - b.pose_global_no_override = Transform(); + b.pose_global = Transform3D(); + b.pose_global_no_override = Transform3D(); } } } else { if (b.enabled) { - Transform pose = b.pose; + Transform3D pose = b.pose; if (b.custom_pose_enable) { pose = b.custom_pose * pose; } @@ -337,7 +337,6 @@ void Skeleton3D::_notification(int p_what) { } break; -#ifndef _3D_DISABLED case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { // This is active only if the skeleton animates the physical bones // and the state of the bone is not active. @@ -356,7 +355,6 @@ void Skeleton3D::_notification(int p_what) { set_physics_process_internal(true); } } break; -#endif } } @@ -368,7 +366,7 @@ void Skeleton3D::clear_bones_global_pose_override() { _make_dirty(); } -void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent) { +void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, float p_amount, bool p_persistent) { ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].global_pose_override_amount = p_amount; bones.write[p_bone].global_pose_override = p_pose; @@ -376,16 +374,16 @@ void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform &p_po _make_dirty(); } -Transform Skeleton3D::get_bone_global_pose(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_global_pose(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); if (dirty) { const_cast<Skeleton3D *>(this)->notification(NOTIFICATION_UPDATE_SKELETON); } return bones[p_bone].pose_global; } -Transform Skeleton3D::get_bone_global_pose_no_override(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_global_pose_no_override(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); if (dirty) { const_cast<Skeleton3D *>(this)->notification(NOTIFICATION_UPDATE_SKELETON); } @@ -496,15 +494,14 @@ int Skeleton3D::get_bone_parent(int p_bone) const { return bones[p_bone].parent; } -void Skeleton3D::set_bone_rest(int p_bone, const Transform &p_rest) { +void Skeleton3D::set_bone_rest(int p_bone, const Transform3D &p_rest) { ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].rest = p_rest; _make_dirty(); } - -Transform Skeleton3D::get_bone_rest(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_rest(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); return bones[p_bone].rest; } @@ -563,7 +560,7 @@ void Skeleton3D::clear_bones() { // posing api -void Skeleton3D::set_bone_pose(int p_bone, const Transform &p_pose) { +void Skeleton3D::set_bone_pose(int p_bone, const Transform3D &p_pose) { ERR_FAIL_INDEX(p_bone, bones.size()); bones.write[p_bone].pose = p_pose; @@ -571,24 +568,23 @@ void Skeleton3D::set_bone_pose(int p_bone, const Transform &p_pose) { _make_dirty(); } } - -Transform Skeleton3D::get_bone_pose(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_pose(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); return bones[p_bone].pose; } -void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose) { +void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform3D &p_custom_pose) { ERR_FAIL_INDEX(p_bone, bones.size()); //ERR_FAIL_COND( !is_inside_scene() ); - bones.write[p_bone].custom_pose_enable = (p_custom_pose != Transform()); + bones.write[p_bone].custom_pose_enable = (p_custom_pose != Transform3D()); bones.write[p_bone].custom_pose = p_custom_pose; _make_dirty(); } -Transform Skeleton3D::get_bone_custom_pose(int p_bone) const { - ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform()); +Transform3D Skeleton3D::get_bone_custom_pose(int p_bone) const { + ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform3D()); return bones[p_bone].custom_pose; } @@ -623,8 +619,6 @@ void Skeleton3D::localize_rests() { } } -#ifndef _3D_DISABLED - void Skeleton3D::set_animate_physical_bones(bool p_animate) { animate_physical_bones = p_animate; @@ -785,8 +779,6 @@ void Skeleton3D::physical_bones_remove_collision_exception(RID p_exception) { _physical_bones_add_remove_collision_exception(false, this, p_exception); } -#endif // _3D_DISABLED - void Skeleton3D::_skin_changed() { _make_dirty(); } @@ -852,11 +844,11 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) { } // helper functions -Transform Skeleton3D::bone_transform_to_world_transform(Transform p_bone_transform) { +Transform3D Skeleton3D::bone_transform_to_world_transform(Transform3D p_bone_transform) { return get_global_transform() * p_bone_transform; } -Transform Skeleton3D::world_transform_to_bone_transform(Transform p_world_transform) { +Transform3D Skeleton3D::world_transform_to_bone_transform(Transform3D p_world_transform) { return get_global_transform().affine_inverse() * p_world_transform; } @@ -900,8 +892,6 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("bone_transform_to_world_transform", "bone_transform"), &Skeleton3D::bone_transform_to_world_transform); ClassDB::bind_method(D_METHOD("world_transform_to_bone_transform", "world_transform"), &Skeleton3D::world_transform_to_bone_transform); -#ifndef _3D_DISABLED - ClassDB::bind_method(D_METHOD("set_animate_physical_bones"), &Skeleton3D::set_animate_physical_bones); ClassDB::bind_method(D_METHOD("get_animate_physical_bones"), &Skeleton3D::get_animate_physical_bones); @@ -911,7 +901,6 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("physical_bones_remove_collision_exception", "exception"), &Skeleton3D::physical_bones_remove_collision_exception); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "animate_physical_bones"), "set_animate_physical_bones", "get_animate_physical_bones"); -#endif // _3D_DISABLED #ifdef TOOLS_ENABLED ADD_SIGNAL(MethodInfo("pose_updated")); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 299a4b6a02..9be7dce5d2 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -35,12 +35,9 @@ #include "scene/3d/node_3d.h" #include "scene/resources/skin.h" -#ifndef _3D_DISABLED typedef int BoneId; class PhysicalBone3D; -#endif // _3D_DISABLED - class Skeleton3D; class SkinReference : public Reference { @@ -79,23 +76,21 @@ private: int sort_index = 0; //used for re-sorting process order bool disable_rest = false; - Transform rest; + Transform3D rest; - Transform pose; - Transform pose_global; - Transform pose_global_no_override; + Transform3D pose; + Transform3D pose_global; + Transform3D pose_global_no_override; bool custom_pose_enable = false; - Transform custom_pose; + Transform3D custom_pose; float global_pose_override_amount = 0.0; bool global_pose_override_reset = false; - Transform global_pose_override; + Transform3D global_pose_override; -#ifndef _3D_DISABLED PhysicalBone3D *physical_bone = nullptr; PhysicalBone3D *cache_parent_physical_bone = nullptr; -#endif // _3D_DISABLED List<ObjectID> nodes_bound; }; @@ -146,13 +141,13 @@ public: int get_bone_count() const; - void set_bone_rest(int p_bone, const Transform &p_rest); - Transform get_bone_rest(int p_bone) const; - Transform get_bone_global_pose(int p_bone) const; - Transform get_bone_global_pose_no_override(int p_bone) const; + void set_bone_rest(int p_bone, const Transform3D &p_rest); + Transform3D get_bone_rest(int p_bone) const; + Transform3D get_bone_global_pose(int p_bone) const; + Transform3D get_bone_global_pose_no_override(int p_bone) const; void clear_bones_global_pose_override(); - void set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent = false); + void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, float p_amount, bool p_persistent = false); void set_bone_enabled(int p_bone, bool p_enabled); bool is_bone_enabled(int p_bone) const; @@ -165,11 +160,11 @@ public: // posing api - void set_bone_pose(int p_bone, const Transform &p_pose); - Transform get_bone_pose(int p_bone) const; + void set_bone_pose(int p_bone, const Transform3D &p_pose); + Transform3D get_bone_pose(int p_bone) const; - void set_bone_custom_pose(int p_bone, const Transform &p_custom_pose); - Transform get_bone_custom_pose(int p_bone) const; + void set_bone_custom_pose(int p_bone, const Transform3D &p_custom_pose); + Transform3D get_bone_custom_pose(int p_bone) const; void localize_rests(); // used for loaders and tools int get_process_order(int p_idx); @@ -178,10 +173,9 @@ public: Ref<SkinReference> register_skin(const Ref<Skin> &p_skin); // Helper functions - Transform bone_transform_to_world_transform(Transform p_transform); - Transform world_transform_to_bone_transform(Transform p_transform); + Transform3D bone_transform_to_world_transform(Transform3D p_transform); + Transform3D world_transform_to_bone_transform(Transform3D p_transform); -#ifndef _3D_DISABLED // Physical bone API void set_animate_physical_bones(bool p_animate); @@ -203,7 +197,6 @@ public: void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones); void physical_bones_add_collision_exception(RID p_exception); void physical_bones_remove_collision_exception(RID p_exception); -#endif // _3D_DISABLED public: Skeleton3D(); diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index 294e313300..1005d51e63 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -212,7 +212,7 @@ void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_ } } -FabrikInverseKinematic::Task *FabrikInverseKinematic::create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform) { +FabrikInverseKinematic::Task *FabrikInverseKinematic::create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform3D &goal_transform) { FabrikInverseKinematic::EndEffector ee; ee.tip_bone = tip_bone; @@ -236,17 +236,17 @@ void FabrikInverseKinematic::free_task(Task *p_task) { } } -void FabrikInverseKinematic::set_goal(Task *p_task, const Transform &p_goal) { +void FabrikInverseKinematic::set_goal(Task *p_task, const Transform3D &p_goal) { p_task->goal_global_transform = p_goal; } -void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta) { +void FabrikInverseKinematic::make_goal(Task *p_task, const Transform3D &p_inverse_transf, real_t blending_delta) { if (blending_delta >= 0.99f) { // Update the end_effector (local transform) without blending p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform; } else { // End effector in local transform - const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose_no_override(p_task->end_effectors[0].tip_bone)); + const Transform3D end_effector_pose(p_task->skeleton->get_bone_global_pose_no_override(p_task->end_effectors[0].tip_bone)); // Update the end_effector (local transform) by blending with current pose p_task->end_effectors.write[0].goal_transform = end_effector_pose.interpolate_with(p_inverse_transf * p_task->goal_global_transform, blending_delta); @@ -273,7 +273,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove // Update the initial root transform so its synced with any animation changes _update_chain(p_task->skeleton, &p_task->chain.chain_root); - p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, false); + p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform3D(), 0.0, false); Vector3 origin_pos = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone).origin; make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta); @@ -287,7 +287,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove // Assign new bone position. ChainItem *ci(&p_task->chain.chain_root); while (ci) { - Transform new_bone_pose(ci->initial_transform); + Transform3D new_bone_pose(ci->initial_transform); new_bone_pose.origin = ci->current_pos; if (!ci->children.is_empty()) { @@ -397,7 +397,7 @@ void SkeletonIK3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "root_bone"), "set_root_bone", "get_root_bone"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "tip_bone"), "set_tip_bone", "get_tip_bone"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "interpolation", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_interpolation", "get_interpolation"); - ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "target"), "set_target_transform", "get_target_transform"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "target"), "set_target_transform", "get_target_transform"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_tip_basis"), "set_override_tip_basis", "is_override_tip_basis"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_magnet"), "set_use_magnet", "is_using_magnet"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "magnet"), "set_magnet_position", "get_magnet_position"); @@ -461,12 +461,12 @@ real_t SkeletonIK3D::get_interpolation() const { return interpolation; } -void SkeletonIK3D::set_target_transform(const Transform &p_target) { +void SkeletonIK3D::set_target_transform(const Transform3D &p_target) { target = p_target; reload_goal(); } -const Transform &SkeletonIK3D::get_target_transform() const { +const Transform3D &SkeletonIK3D::get_target_transform() const { return target; } @@ -537,7 +537,7 @@ void SkeletonIK3D::stop() { } } -Transform SkeletonIK3D::_get_target_transform() { +Transform3D SkeletonIK3D::_get_target_transform() { if (!target_node_override && !target_node_path_override.is_empty()) { target_node_override = Object::cast_to<Node3D>(get_node(target_node_path_override)); } diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 9b5ae240f6..81dfe675c3 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -37,13 +37,13 @@ * @author AndreaCatania */ -#include "core/math/transform.h" +#include "core/math/transform_3d.h" #include "scene/3d/skeleton_3d.h" class FabrikInverseKinematic { struct EndEffector { BoneId tip_bone; - Transform goal_transform; + Transform3D goal_transform; }; struct ChainItem { @@ -55,7 +55,7 @@ class FabrikInverseKinematic { real_t length = 0.0; /// Positions relative to root bone - Transform initial_transform; + Transform3D initial_transform; Vector3 current_pos; // Direction from this bone to child Vector3 current_ori; @@ -97,7 +97,7 @@ public: BoneId root_bone = -1; Vector<EndEffector> end_effectors; - Transform goal_global_transform; + Transform3D goal_global_transform; Task() {} }; @@ -112,11 +112,11 @@ private: static void solve_simple_forwards(Chain &r_chain, bool p_solve_magnet, Vector3 p_origin_pos); public: - static Task *create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform); + static Task *create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform3D &goal_transform); static void free_task(Task *p_task); // The goal of chain should be always in local space - static void set_goal(Task *p_task, const Transform &p_goal); - static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta); + static void set_goal(Task *p_task, const Transform3D &p_goal); + static void make_goal(Task *p_task, const Transform3D &p_inverse_transf, real_t blending_delta); static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position); static void _update_chain(const Skeleton3D *p_skeleton, ChainItem *p_chain_item); @@ -128,7 +128,7 @@ class SkeletonIK3D : public Node { StringName root_bone; StringName tip_bone; real_t interpolation = 1.0; - Transform target; + Transform3D target; NodePath target_node_path_override; bool override_tip_basis = true; bool use_magnet = false; @@ -161,8 +161,8 @@ public: void set_interpolation(real_t p_interpolation); real_t get_interpolation() const; - void set_target_transform(const Transform &p_target); - const Transform &get_target_transform() const; + void set_target_transform(const Transform3D &p_target); + const Transform3D &get_target_transform() const; void set_target_node(const NodePath &p_node); NodePath get_target_node(); @@ -190,7 +190,7 @@ public: void stop(); private: - Transform _get_target_transform(); + Transform3D _get_target_transform(); void reload_chain(); void reload_goal(); void _solve_chain(); diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index dc4deb0570..df5474d03e 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -283,7 +283,7 @@ void SoftBody3D::_notification(int p_what) { set_notify_transform(false); // Required to be top level with Transform at center of world in order to modify RenderingServer only to support custom Transform set_as_top_level(true); - set_transform(Transform()); + set_transform(Transform3D()); set_notify_transform(true); } break; @@ -373,7 +373,7 @@ TypedArray<String> SoftBody3D::get_configuration_warnings() const { warnings.push_back(TTR("This body will be ignored until you set a mesh.")); } - Transform t = get_transform(); + Transform3D t = get_transform(); if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { warnings.push_back(TTR("Size changes to SoftBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } @@ -408,7 +408,7 @@ void SoftBody3D::_draw_soft_mesh() { /// Necessary in order to render the mesh correctly (Soft body nodes are in global space) simulation_started = true; call_deferred("set_as_top_level", true); - call_deferred("set_transform", Transform()); + call_deferred("set_transform", Transform3D()); } _update_physics_server(); diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 9518b47696..1911e14d54 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -153,7 +153,7 @@ void SpringArm3D::process_spring() { } current_spring_length = spring_length * motion_delta; - Transform childs_transform; + Transform3D childs_transform; childs_transform.origin = get_global_transform().origin + cast_direction * (spring_length * motion_delta); for (int i = get_child_count() - 1; 0 <= i; --i) { diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index 9493f686c4..0d88769b70 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -346,7 +346,7 @@ VehicleWheel3D::VehicleWheel3D() { void VehicleBody3D::_update_wheel_transform(VehicleWheel3D &wheel, PhysicsDirectBodyState3D *s) { wheel.m_raycastInfo.m_isInContact = false; - Transform chassisTrans = s->get_transform(); + Transform3D chassisTrans = s->get_transform(); /* if (interpolatedTransform && (getRigidBody()->getMotionState())) { getRigidBody()->getMotionState()->getWorldTransform(chassisTrans); @@ -784,7 +784,7 @@ void VehicleBody3D::_update_friction(PhysicsDirectBodyState3D *s) { Vector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel]; #if defined ROLLING_INFLUENCE_FIX // fix. It only worked if car's up was along Y - VT. - Vector3 vChassisWorldUp = s->get_transform().basis.transposed()[1]; //getRigidBody()->getCenterOfMassTransform().getBasis().getColumn(m_indexUpAxis); + Vector3 vChassisWorldUp = s->get_transform().basis.transposed()[1]; //getRigidBody()->getCenterOfMassTransform3D().getBasis().getColumn(m_indexUpAxis); rel_pos -= vChassisWorldUp * (vChassisWorldUp.dot(rel_pos) * (1.f - wheelInfo.m_rollInfluence)); #else rel_pos[1] *= wheelInfo.m_rollInfluence; //? @@ -841,7 +841,7 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) { Vector3 vel = state->get_linear_velocity() + (state->get_angular_velocity()).cross(relpos); // * mPos); if (wheel.m_raycastInfo.m_isInContact) { - const Transform &chassisWorldTransform = state->get_transform(); + const Transform3D &chassisWorldTransform = state->get_transform(); Vector3 fwd( chassisWorldTransform.basis[0][Vector3::AXIS_Z], diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h index 646071a363..2c10205ea3 100644 --- a/scene/3d/vehicle_body_3d.h +++ b/scene/3d/vehicle_body_3d.h @@ -40,8 +40,8 @@ class VehicleWheel3D : public Node3D { friend class VehicleBody3D; - Transform m_worldTransform; - Transform local_xform; + Transform3D m_worldTransform; + Transform3D local_xform; bool engine_traction = false; bool steers = false; diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp index 471838b9d1..b230cb2fd7 100644 --- a/scene/3d/visibility_notifier_3d.cpp +++ b/scene/3d/visibility_notifier_3d.cpp @@ -138,7 +138,7 @@ void VisibilityEnabler3D::_find_nodes(Node *p_node) { { RigidBody3D *rb = Object::cast_to<RigidBody3D>(p_node); - if (rb && ((rb->get_mode() == RigidBody3D::MODE_CHARACTER || rb->get_mode() == RigidBody3D::MODE_RIGID))) { + if (rb && ((rb->get_mode() == RigidBody3D::MODE_DYNAMIC || rb->get_mode() == RigidBody3D::MODE_DYNAMIC_LOCKED))) { add = true; meta = rb->get_mode(); } diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index d81b09b86c..6971c1ce2a 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -61,7 +61,7 @@ void VisualInstance3D::_notification(int p_what) { } break; case NOTIFICATION_TRANSFORM_CHANGED: { - Transform gt = get_global_transform(); + Transform3D gt = get_global_transform(); RenderingServer::get_singleton()->instance_set_transform(instance, gt); } break; case NOTIFICATION_EXIT_WORLD: { diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 1b9ce0201f..18ef5acbe3 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -378,7 +378,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material return mc; } -void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material) { +void Voxelizer::plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material) { for (int i = 0; i < p_mesh->get_surface_count(); i++) { if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) { continue; //only triangles @@ -647,11 +647,11 @@ void Voxelizer::begin_bake(int p_subdiv, const AABB &p_bounds) { po2_bounds.size[i] = po2_bounds.size[longest_axis]; } - Transform to_bounds; + Transform3D to_bounds; to_bounds.basis.scale(Vector3(po2_bounds.size[longest_axis], po2_bounds.size[longest_axis], po2_bounds.size[longest_axis])); to_bounds.origin = po2_bounds.position; - Transform to_grid; + Transform3D to_grid; to_grid.basis.scale(Vector3(axis_cell_size[longest_axis], axis_cell_size[longest_axis], axis_cell_size[longest_axis])); to_cell_space = to_grid * to_bounds.affine_inverse(); @@ -891,7 +891,7 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const { void Voxelizer::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx) { if (p_level == cell_subdiv - 1) { Vector3 center = p_aabb.position + p_aabb.size * 0.5; - Transform xform; + Transform3D xform; xform.origin = center; xform.basis.scale(p_aabb.size * 0.5); p_multimesh->set_instance_transform(idx, xform); @@ -1002,7 +1002,7 @@ Ref<MultiMesh> Voxelizer::create_debug_multimesh() { return mm; } -Transform Voxelizer::get_to_cell_space_xform() const { +Transform3D Voxelizer::get_to_cell_space_xform() const { return to_cell_space; } diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h index 87f949e7db..d0da5a5624 100644 --- a/scene/3d/voxelizer.h +++ b/scene/3d/voxelizer.h @@ -93,7 +93,7 @@ private: AABB po2_bounds; int axis_cell_size[3] = {}; - Transform to_cell_space; + Transform3D to_cell_space; int color_scan_cell_width = 4; int bake_texture_size = 128; @@ -114,7 +114,7 @@ private: public: void begin_bake(int p_subdiv, const AABB &p_bounds); - void plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material); + void plot_mesh(const Transform3D &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material); void end_bake(); int get_gi_probe_octree_depth() const; @@ -127,7 +127,7 @@ public: Ref<MultiMesh> create_debug_multimesh(); - Transform get_to_cell_space_xform() const; + Transform3D get_to_cell_space_xform() const; Voxelizer(); }; diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index b5037f9be7..09662f3e7a 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -397,7 +397,7 @@ void XRAnchor3D::_notification(int p_what) { is_active = false; } else { is_active = true; - Transform transform; + Transform3D transform; // we'll need our world_scale real_t world_scale = xr_server->get_world_scale(); @@ -493,7 +493,7 @@ TypedArray<String> XRAnchor3D::get_configuration_warnings() const { }; Plane XRAnchor3D::get_plane() const { - Vector3 location = get_translation(); + Vector3 location = get_position(); Basis orientation = get_transform().basis; Plane plane(location, orientation.get_axis(1).normalized()); @@ -571,7 +571,7 @@ void XROrigin3D::_notification(int p_what) { Ref<XRInterface> xr_interface = xr_server->get_primary_interface(); if (xr_interface.is_valid() && tracked_camera != nullptr) { // get our positioning transform for our headset - Transform t = xr_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform()); + Transform3D t = xr_interface->get_transform_for_eye(XRInterface::EYE_MONO, Transform3D()); // now apply this to our camera tracked_camera->set_transform(t); |