Backported the improvements to Transform from Godot4.

This commit is contained in:
Relintai 2022-08-14 20:35:11 +02:00
parent e9bb723975
commit 5cd44e02d0
15 changed files with 275 additions and 134 deletions

View File

@ -33,17 +33,6 @@
#include "core/math/math_funcs.h"
#include "core/print_string.h"
void Transform::affine_invert() {
basis.invert();
origin = basis.xform(-origin);
}
Transform Transform::affine_inverse() const {
Transform ret = *this;
ret.affine_invert();
return ret;
}
void Transform::invert() {
basis.transpose();
origin = basis.xform(-origin);
@ -57,24 +46,41 @@ Transform Transform::inverse() const {
return ret;
}
void Transform::affine_invert() {
basis.invert();
origin = basis.xform(-origin);
}
Transform Transform::affine_inverse() const {
Transform ret = *this;
ret.affine_invert();
return ret;
}
Transform Transform::rotated(const Vector3 &p_axis, real_t p_angle) const {
// Equivalent to left multiplication
Basis p_basis(p_axis, p_angle);
return Transform(p_basis * basis, p_basis.xform(origin));
}
Transform Transform::rotated_local(const Vector3 &p_axis, real_t p_angle) const {
// Equivalent to right multiplication
Basis p_basis(p_axis, p_angle);
return Transform(basis * p_basis, origin);
}
void Transform::rotate(const Vector3 &p_axis, real_t p_phi) {
*this = rotated(p_axis, p_phi);
}
Transform Transform::rotated(const Vector3 &p_axis, real_t p_phi) const {
return Transform(Basis(p_axis, p_phi), Vector3()) * (*this);
void Transform::rotate_local(const Vector3 &p_axis, real_t p_phi) {
*this = rotated_local(p_axis, p_phi);
}
void Transform::rotate_basis(const Vector3 &p_axis, real_t p_phi) {
basis.rotate(p_axis, p_phi);
}
Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up) const {
Transform t = *this;
t.set_look_at(origin, p_target, p_up);
return t;
}
void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) {
#ifdef MATH_CHECKS
ERR_FAIL_COND(p_eye == p_target);
@ -108,22 +114,10 @@ void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const
origin = p_eye;
}
Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c) const {
/* not sure if very "efficient" but good enough? */
Vector3 src_scale = basis.get_scale();
Quaternion src_rot = basis.get_rotation_quaternion();
Vector3 src_loc = origin;
Vector3 dst_scale = p_transform.basis.get_scale();
Quaternion dst_rot = p_transform.basis.get_rotation_quaternion();
Vector3 dst_loc = p_transform.origin;
Transform interp;
interp.basis.set_quaternion_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.linear_interpolate(dst_scale, p_c));
interp.origin = src_loc.linear_interpolate(dst_loc, p_c);
return interp;
Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up) const {
Transform t = *this;
t.set_look_at(origin, p_target, p_up);
return t;
}
void Transform::scale(const Vector3 &p_scale) {
@ -132,28 +126,36 @@ void Transform::scale(const Vector3 &p_scale) {
}
Transform Transform::scaled(const Vector3 &p_scale) const {
Transform t = *this;
t.scale(p_scale);
return t;
// Equivalent to left multiplication
return Transform(basis.scaled(p_scale), origin * p_scale);
}
Transform Transform::scaled_local(const Vector3 &p_scale) const {
// Equivalent to right multiplication
return Transform(basis.scaled_local(p_scale), origin);
}
void Transform::scale_basis(const Vector3 &p_scale) {
basis.scale(p_scale);
}
void Transform::translate(real_t p_tx, real_t p_ty, real_t p_tz) {
translate(Vector3(p_tx, p_ty, p_tz));
void Transform::translate_local(real_t p_tx, real_t p_ty, real_t p_tz) {
translate_local(Vector3(p_tx, p_ty, p_tz));
}
void Transform::translate(const Vector3 &p_translation) {
void Transform::translate_local(const Vector3 &p_translation) {
for (int i = 0; i < 3; i++) {
origin[i] += basis[i].dot(p_translation);
}
}
Transform Transform::translated(const Vector3 &p_translation) const {
Transform t = *this;
t.translate(p_translation);
return t;
//Transform Transform::translated(const Vector3 &p_translation) const {
// // Equivalent to left multiplication
// return Transform(basis, origin + p_translation);
//}
Transform Transform::translated_local(const Vector3 &p_translation) const {
// Equivalent to right multiplication
return Transform(basis, origin + basis.xform(p_translation));
}
void Transform::orthonormalize() {
@ -166,6 +168,16 @@ Transform Transform::orthonormalized() const {
return _copy;
}
void Transform::orthogonalize() {
basis.orthogonalize();
}
Transform Transform::orthogonalized() const {
Transform _copy = *this;
_copy.orthogonalize();
return _copy;
}
bool Transform::is_equal_approx(const Transform &p_transform) const {
return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin);
}
@ -188,8 +200,40 @@ Transform Transform::operator*(const Transform &p_transform) const {
return t;
}
void Transform::operator*=(const real_t p_val) {
origin *= p_val;
basis *= p_val;
}
Transform Transform::operator*(const real_t p_val) const {
Transform ret(*this);
ret *= p_val;
return ret;
}
Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c) const {
/* not sure if very "efficient" but good enough? */
Vector3 src_scale = basis.get_scale();
Quaternion src_rot = basis.get_rotation_quaternion();
Vector3 src_loc = origin;
Vector3 dst_scale = p_transform.basis.get_scale();
Quaternion dst_rot = p_transform.basis.get_rotation_quaternion();
Vector3 dst_loc = p_transform.origin;
Transform interp;
interp.basis.set_quaternion_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.linear_interpolate(dst_scale, p_c));
interp.origin = src_loc.linear_interpolate(dst_loc, p_c);
return interp;
}
Transform::operator String() const {
return basis.operator String() + " - " + origin.operator String();
return "[X: " + basis.get_column(0).operator String() +
", Y: " + basis.get_column(1).operator String() +
", Z: " + basis.get_column(2).operator String() +
", O: " + origin.operator String() + "]";
}
Transform::Transform(const Basis &p_basis, const Vector3 &p_origin) :
@ -201,3 +245,10 @@ Transform::Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real
basis = Basis(xx, xy, xz, yx, yy, yz, zx, zy, zz);
origin = Vector3(ox, oy, oz);
}
Transform::Transform(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin) :
origin(p_origin) {
basis.set_column(0, p_x);
basis.set_column(1, p_y);
basis.set_column(2, p_z);
}

View File

@ -33,8 +33,8 @@
#include "core/math/aabb.h"
#include "core/math/basis.h"
#include "core/math/plane.h"
#include "core/pool_vector.h"
#include "core/math/vector3i.h"
#include "core/pool_vector.h"
class _NO_DISCARD_CLASS_ Transform {
public:
@ -48,8 +48,10 @@ public:
Transform affine_inverse() const;
Transform rotated(const Vector3 &p_axis, real_t p_phi) const;
Transform rotated_local(const Vector3 &p_axis, real_t p_phi) const;
void rotate(const Vector3 &p_axis, real_t p_phi);
void rotate_local(const Vector3 &p_axis, real_t p_phi);
void rotate_basis(const Vector3 &p_axis, real_t p_phi);
void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up);
@ -57,10 +59,14 @@ public:
void scale(const Vector3 &p_scale);
Transform scaled(const Vector3 &p_scale) const;
Transform scaled_local(const Vector3 &p_scale) const;
void scale_basis(const Vector3 &p_scale);
void translate(real_t p_tx, real_t p_ty, real_t p_tz);
void translate(const Vector3 &p_translation);
Transform translated(const Vector3 &p_translation) const;
void translate_local(real_t p_tx, real_t p_ty, real_t p_tz);
void translate_local(const Vector3 &p_translation);
//TODO Enable
//Transform translated(const Vector3 &p_translation) const;
Transform translated_local(const Vector3 &p_translation) const;
const Basis &get_basis() const { return basis; }
void set_basis(const Basis &p_basis) { basis = p_basis; }
@ -70,6 +76,8 @@ public:
void orthonormalize();
Transform orthonormalized() const;
void orthogonalize();
Transform orthogonalized() const;
bool is_equal_approx(const Transform &p_transform) const;
bool operator==(const Transform &p_transform) const;
@ -101,7 +109,10 @@ public:
void operator*=(const Transform &p_transform);
Transform operator*(const Transform &p_transform) const;
void operator*=(const real_t p_val);
Transform operator*(const real_t p_val) const;
Transform spherical_interpolate_with(const Transform &p_transform, real_t p_c) const;
Transform interpolate_with(const Transform &p_transform, real_t p_c) const;
_FORCE_INLINE_ Transform inverse_xform(const Transform &t) const {
@ -121,6 +132,7 @@ public:
Transform(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t ox, real_t oy, real_t oz);
Transform(const Basis &p_basis, const Vector3 &p_origin = Vector3());
Transform(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z, const Vector3 &p_origin);
Transform() {}
};

View File

@ -1297,7 +1297,7 @@ struct _VariantCall {
VCALL_PTR0R(Transform, affine_inverse);
VCALL_PTR2R(Transform, rotated);
VCALL_PTR1R(Transform, scaled);
VCALL_PTR1R(Transform, translated);
VCALL_PTR1R(Transform, translated_local);
VCALL_PTR0R(Transform, orthonormalized);
VCALL_PTR2R(Transform, looking_at);
VCALL_PTR2R(Transform, interpolate_with);
@ -2793,7 +2793,7 @@ void register_variant_methods() {
ADDFUNC0R(TRANSFORM, TRANSFORM, Transform, orthonormalized, varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, rotated, VECTOR3, "axis", REAL, "phi", varray());
ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, scaled, VECTOR3, "scale", varray());
ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, translated, VECTOR3, "offset", varray());
ADDFUNC1R(TRANSFORM, TRANSFORM, Transform, translated_local, VECTOR3, "offset", varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, looking_at, VECTOR3, "target", VECTOR3, "up", varray());
ADDFUNC2R(TRANSFORM, TRANSFORM, Transform, interpolate_with, TRANSFORM, "transform", REAL, "weight", varray());
ADDFUNC1R(TRANSFORM, BOOL, Transform, is_equal_approx, TRANSFORM, "transform", varray());

View File

@ -103,22 +103,63 @@
<argument index="0" name="axis" type="Vector3" />
<argument index="1" name="phi" type="float" />
<description>
Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]phi[/code] angle (in radians), using matrix multiplication. The [code]axis[/code] must be a normalized vector.
Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]angle[/code] (in radians).
The [code]axis[/code] must be a normalized vector.
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code].
This can be seen as transforming with respect to the global/parent frame.
</description>
</method>
<method name="rotated_local" qualifiers="const">
<return type="Transform" />
<argument index="0" name="axis" type="Vector3" />
<argument index="1" name="angle" type="float" />
<description>
Returns a copy of the transform rotated around the given [code]axis[/code] by the given [code]angle[/code] (in radians).
The [code]axis[/code] must be a normalized vector.
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding rotation transform [code]R[/code] from the right, i.e., [code]X * R[/code].
This can be seen as transforming with respect to the local frame.
</description>
</method>
<method name="scaled">
<return type="Transform" />
<argument index="0" name="scale" type="Vector3" />
<description>
Returns a copy of the transform with its basis and origin scaled by the given [code]scale[/code] factor, using matrix multiplication.
Returns a copy of the transform scaled by the given [code]scale[/code] factor.
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding scaling transform [code]S[/code] from the left, i.e., [code]S * X[/code].
This can be seen as transforming with respect to the global/parent frame.
</description>
</method>
<method name="translated">
<method name="scaled_local" qualifiers="const">
<return type="Transform" />
<argument index="0" name="scale" type="Vector3" />
<description>
Returns a copy of the transform scaled by the given [code]scale[/code] factor.
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding scaling transform [code]S[/code] from the right, i.e., [code]X * S[/code].
This can be seen as transforming with respect to the local frame.
</description>
</method>
<method name="translated" qualifiers="const">
<return type="Transform" />
<argument index="0" name="offset" type="Vector3" />
<description>
Returns a copy of the transform translated by the given [code]offset[/code], relative to the transform's basis vectors.
Unlike [method rotated] and [method scaled], this does not use matrix multiplication.
Returns a copy of the transform translated by the given [code]offset[/code].
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding translation transform [code]T[/code] from the left, i.e., [code]T * X[/code].
This can be seen as transforming with respect to the global/parent frame.
</description>
</method>
<method name="translated_local">
<return type="Transform" />
<argument index="0" name="offset" type="Vector3" />
<description>
Returns a copy of the transform translated by the given [code]offset[/code].
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding translation transform [code]T[/code] from the right, i.e., [code]X * T[/code].
This can be seen as transforming with respect to the local frame.
</description>
</method>
<method name="xform">

View File

@ -109,23 +109,60 @@
<return type="Transform2D" />
<argument index="0" name="phi" type="float" />
<description>
Returns a copy of the transform rotated by the given [code]phi[/code] angle (in radians), using matrix multiplication.
Returns a copy of the transform rotated by the given [code]angle[/code] (in radians).
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding rotation transform [code]R[/code] from the left, i.e., [code]R * X[/code].
This can be seen as transforming with respect to the global/parent frame.
</description>
</method>
<method name="rotated_local" qualifiers="const">
<return type="Transform2D" />
<argument index="0" name="angle" type="float" />
<description>
Returns a copy of the transform rotated by the given [code]angle[/code] (in radians).
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding rotation transform [code]R[/code] from the right, i.e., [code]X * R[/code].
This can be seen as transforming with respect to the local frame.
</description>
</method>
<method name="scaled">
<return type="Transform2D" />
<argument index="0" name="scale" type="Vector2" />
<description>
Returns a copy of the transform scaled by the given [code]scale[/code] factor, using matrix multiplication.
[b]Note:[/b] Negative X scales in 2D are not decomposable from the transformation matrix. Due to the way scale is represented with transformation matrices in Godot, negative scales on the X axis will be changed to negative scales on the Y axis and a rotation of 180 degrees when decomposed.
Returns a copy of the transform scaled by the given [code]scale[/code] factor.
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding scaling transform [code]S[/code] from the left, i.e., [code]S * X[/code].
This can be seen as transforming with respect to the global/parent frame.
</description>
</method>
<method name="translated">
<method name="scaled_local" qualifiers="const">
<return type="Transform2D" />
<argument index="0" name="scale" type="Vector2" />
<description>
Returns a copy of the transform scaled by the given [code]scale[/code] factor.
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding scaling transform [code]S[/code] from the right, i.e., [code]X * S[/code].
This can be seen as transforming with respect to the local frame.
</description>
</method>
<method name="translated" qualifiers="const">
<return type="Transform2D" />
<argument index="0" name="offset" type="Vector2" />
<description>
Returns a copy of the transform translated by the given [code]offset[/code], relative to the transform's basis vectors.
Unlike [method rotated] and [method scaled], this does not use matrix multiplication.
Returns a copy of the transform translated by the given [code]offset[/code].
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding translation transform [code]T[/code] from the left, i.e., [code]T * X[/code].
This can be seen as transforming with respect to the global/parent frame.
</description>
</method>
<method name="translated_local">
<return type="Transform2D" />
<argument index="0" name="offset" type="Vector2" />
<description>
Returns a copy of the transform translated by the given [code]offset[/code].
This method is an optimized version of multiplying the given transform [code]X[/code]
with a corresponding translation transform [code]T[/code] from the right, i.e., [code]X * T[/code].
This can be seen as transforming with respect to the local frame.
</description>
</method>
<method name="xform">

View File

@ -114,11 +114,11 @@ void RasterizerCanvasBaseGLES2::canvas_begin() {
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
csy = -1.0;
}
canvas_transform.translate(-(storage->frame.current_rt->width / 2.0f), -(storage->frame.current_rt->height / 2.0f), 0.0f);
canvas_transform.translate_local(-(storage->frame.current_rt->width / 2.0f), -(storage->frame.current_rt->height / 2.0f), 0.0f);
canvas_transform.scale(Vector3(2.0f / storage->frame.current_rt->width, csy * -2.0f / storage->frame.current_rt->height, 1.0f));
} else {
Vector2 ssize = OS::get_singleton()->get_window_size();
canvas_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
canvas_transform.translate_local(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
canvas_transform.scale(Vector3(2.0f / ssize.width, -2.0f / ssize.height, 1.0f));
}

View File

@ -402,14 +402,14 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) {
Transform SpatialEditorViewport::to_camera_transform(const Cursor &p_cursor) const {
Transform camera_transform;
camera_transform.translate(p_cursor.pos);
camera_transform.translate_local(p_cursor.pos);
camera_transform.basis.rotate(Vector3(1, 0, 0), -p_cursor.x_rot);
camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot);
if (orthogonal) {
camera_transform.translate(0, 0, (get_zfar() - get_znear()) / 2.0);
camera_transform.translate_local(0, 0, (get_zfar() - get_znear()) / 2.0);
} else {
camera_transform.translate(0, 0, p_cursor.distance);
camera_transform.translate_local(0, 0, p_cursor.distance);
}
return camera_transform;
@ -665,10 +665,10 @@ Vector3 SpatialEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) {
Vector2 screen_he = cm.get_viewport_half_extents();
Transform camera_transform;
camera_transform.translate(cursor.pos);
camera_transform.translate_local(cursor.pos);
camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot);
camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
camera_transform.translate(0, 0, cursor.distance);
camera_transform.translate_local(0, 0, cursor.distance);
return camera_transform.xform(Vector3(((p_vector3.x / get_size().width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (p_vector3.y / get_size().height)) * 2.0 - 1.0) * screen_he.y, -(get_znear() + p_vector3.z)));
}
@ -2449,7 +2449,7 @@ void SpatialEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const
Transform camera_transform;
camera_transform.translate(cursor.pos);
camera_transform.translate_local(cursor.pos);
camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot);
camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
const bool invert_x_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_x_axis");
@ -2459,7 +2459,7 @@ void SpatialEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const
(invert_y_axis ? -1 : 1) * p_relative.y * pan_speed,
0);
translation *= cursor.distance / DISTANCE_DEFAULT;
camera_transform.translate(translation);
camera_transform.translate_local(translation);
cursor.pos = camera_transform.origin;
}
@ -2870,14 +2870,14 @@ void SpatialEditorViewport::_notification(int p_what) {
const Vector3 offset(0.005, 0.005, 0.005);
Basis aabb_s;
aabb_s.scale(se->aabb.size + offset);
t.translate(se->aabb.position - offset / 2);
t.translate_local(se->aabb.position - offset / 2);
t.basis = t.basis * aabb_s;
}
{
const Vector3 offset(0.01, 0.01, 0.01);
Basis aabb_s;
aabb_s.scale(se->aabb.size + offset);
t_offset.translate(se->aabb.position - offset / 2);
t_offset.translate_local(se->aabb.position - offset / 2);
t_offset.basis = t_offset.basis * aabb_s;
}

View File

@ -3861,8 +3861,8 @@ Basis JointGizmosDrawer::look_body_toward_z(const Transform &p_joint_transform,
void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const Transform &p_offset, const Basis &p_base, real_t p_limit_lower, real_t p_limit_upper, Vector<Vector3> &r_points, bool p_inverse) {
if (p_limit_lower == p_limit_upper) {
r_points.push_back(p_offset.translated(Vector3()).origin);
r_points.push_back(p_offset.translated(p_base.xform(Vector3(0.5, 0, 0))).origin);
r_points.push_back(p_offset.translated_local(Vector3()).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(0.5, 0, 0))).origin);
} else {
if (p_limit_lower > p_limit_upper) {
@ -3904,20 +3904,20 @@ void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const
}
if (i == points - 1) {
r_points.push_back(p_offset.translated(to).origin);
r_points.push_back(p_offset.translated(Vector3()).origin);
r_points.push_back(p_offset.translated_local(to).origin);
r_points.push_back(p_offset.translated_local(Vector3()).origin);
}
if (i == 0) {
r_points.push_back(p_offset.translated(from).origin);
r_points.push_back(p_offset.translated(Vector3()).origin);
r_points.push_back(p_offset.translated_local(from).origin);
r_points.push_back(p_offset.translated_local(Vector3()).origin);
}
r_points.push_back(p_offset.translated(from).origin);
r_points.push_back(p_offset.translated(to).origin);
r_points.push_back(p_offset.translated_local(from).origin);
r_points.push_back(p_offset.translated_local(to).origin);
}
r_points.push_back(p_offset.translated(Vector3(0, p_radius * 1.5, 0)).origin);
r_points.push_back(p_offset.translated(Vector3()).origin);
r_points.push_back(p_offset.translated_local(Vector3(0, p_radius * 1.5, 0)).origin);
r_points.push_back(p_offset.translated_local(Vector3()).origin);
}
}
@ -3933,17 +3933,17 @@ void JointGizmosDrawer::draw_cone(const Transform &p_offset, const Basis &p_base
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w;
r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, a.x, a.y))).origin);
r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, b.x, b.y))).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, a.x, a.y))).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, b.x, b.y))).origin);
if (i % 90 == 0) {
r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, a.x, a.y))).origin);
r_points.push_back(p_offset.translated(p_base.xform(Vector3())).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(d, a.x, a.y))).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3())).origin);
}
}
r_points.push_back(p_offset.translated(p_base.xform(Vector3())).origin);
r_points.push_back(p_offset.translated(p_base.xform(Vector3(1, 0, 0))).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3())).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(1, 0, 0))).origin);
/// Twist
float ts = Math::rad2deg(p_twist);
@ -3957,8 +3957,8 @@ void JointGizmosDrawer::draw_cone(const Transform &p_offset, const Basis &p_base
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w * c;
Point2 b = Vector2(Math::sin(rb), Math::cos(rb)) * w * cn;
r_points.push_back(p_offset.translated(p_base.xform(Vector3(c, a.x, a.y))).origin);
r_points.push_back(p_offset.translated(p_base.xform(Vector3(cn, b.x, b.y))).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(c, a.x, a.y))).origin);
r_points.push_back(p_offset.translated_local(p_base.xform(Vector3(cn, b.x, b.y))).origin);
}
}
@ -4146,17 +4146,17 @@ void JointSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
void JointSpatialGizmoPlugin::CreatePinJointGizmo(const Transform &p_offset, Vector<Vector3> &r_cursor_points) {
float cs = 0.25;
r_cursor_points.push_back(p_offset.translated(Vector3(+cs, 0, 0)).origin);
r_cursor_points.push_back(p_offset.translated(Vector3(-cs, 0, 0)).origin);
r_cursor_points.push_back(p_offset.translated(Vector3(0, +cs, 0)).origin);
r_cursor_points.push_back(p_offset.translated(Vector3(0, -cs, 0)).origin);
r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, +cs)).origin);
r_cursor_points.push_back(p_offset.translated(Vector3(0, 0, -cs)).origin);
r_cursor_points.push_back(p_offset.translated_local(Vector3(+cs, 0, 0)).origin);
r_cursor_points.push_back(p_offset.translated_local(Vector3(-cs, 0, 0)).origin);
r_cursor_points.push_back(p_offset.translated_local(Vector3(0, +cs, 0)).origin);
r_cursor_points.push_back(p_offset.translated_local(Vector3(0, -cs, 0)).origin);
r_cursor_points.push_back(p_offset.translated_local(Vector3(0, 0, +cs)).origin);
r_cursor_points.push_back(p_offset.translated_local(Vector3(0, 0, -cs)).origin);
}
void JointSpatialGizmoPlugin::CreateHingeJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
r_common_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin);
r_common_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin);
r_common_points.push_back(p_offset.translated_local(Vector3(0, 0, 0.5)).origin);
r_common_points.push_back(p_offset.translated_local(Vector3(0, 0, -0.5)).origin);
if (!p_use_limit) {
p_limit_upper = -1;
@ -4189,34 +4189,34 @@ void JointSpatialGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset,
p_linear_limit_upper = -p_linear_limit_upper;
float cs = 0.25;
r_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin);
r_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin);
r_points.push_back(p_offset.translated_local(Vector3(0, 0, 0.5)).origin);
r_points.push_back(p_offset.translated_local(Vector3(0, 0, -0.5)).origin);
if (p_linear_limit_lower >= p_linear_limit_upper) {
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, 0, 0)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, 0, 0)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, 0, 0)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, 0, 0)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, -cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, -cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, cs, -cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, -cs, -cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, -cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, -cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, cs, -cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_upper, -cs, -cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, -cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, -cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, cs, -cs)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, -cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, -cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, -cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, cs, -cs)).origin);
r_points.push_back(p_offset.translated_local(Vector3(p_linear_limit_lower, -cs, -cs)).origin);
} else {
r_points.push_back(p_offset.translated(Vector3(+cs * 2, 0, 0)).origin);
r_points.push_back(p_offset.translated(Vector3(-cs * 2, 0, 0)).origin);
r_points.push_back(p_offset.translated_local(Vector3(+cs * 2, 0, 0)).origin);
r_points.push_back(p_offset.translated_local(Vector3(-cs * 2, 0, 0)).origin);
}
if (r_body_a_points) {
@ -4345,7 +4345,7 @@ void JointSpatialGizmoPlugin::CreateGeneric6DOFJointGizmo(
v[a1] = (x); \
v[a2] = (y); \
v[a3] = (z); \
r_points.push_back(p_offset.translated(v).origin); \
r_points.push_back(p_offset.translated_local(v).origin); \
}
if (enable_lin && lll >= lul) {

View File

@ -321,7 +321,7 @@ public:
Transform cameratr;
cameratr.rotate(Vector3(0, 1, 0), ofs_x);
cameratr.rotate(Vector3(1, 0, 0), -ofs_y);
cameratr.translate(Vector3(0, 2, 8));
cameratr.translate_local(Vector3(0, 2, 8));
VisualServer *vs = VisualServer::get_singleton();
vs->camera_set_transform(camera, cameratr);

View File

@ -144,7 +144,7 @@ public:
ii.instance = vs->instance_create2(test_cube, scenario);
ii.base.translate(Math::random(-20, 20), Math::random(-20, 20), Math::random(-20, 18));
ii.base.translate_local(Math::random(-20, 20), Math::random(-20, 20), Math::random(-20, 18));
ii.base.rotate(Vector3(0, 1, 0), Math::randf() * Math_PI);
ii.base.rotate(Vector3(1, 0, 0), Math::randf() * Math_PI);
vs->instance_set_transform(ii.instance, ii.base);

View File

@ -624,7 +624,7 @@ void PropInstanceMerger::_prop_preprocess(Transform transform, const Ref<PropDat
Transform et = e->get_transform() * Transform(Basis(), Vector3(0, 0, twd->get_collider_z_offset()));
Transform tt = transform * et;
//tt.origin += Vector3(hew, heh, 0);
tt.translate(hew, heh, 0);
tt.translate_local(hew, heh, 0);
_job->add_collision_shape(tws, tt, true);
}

View File

@ -141,7 +141,7 @@ void TiledWall::refresh() {
PhysicsServer::get_singleton()->shape_set_data(_physics_shape_rid, Vector3(_width / 2.0, _height / 2.0, 0.01));
Transform t = get_global_transform();
t.translate(Vector3(_width / 2.0, _height / 2.0, 0));
t.translate_local(Vector3(_width / 2.0, _height / 2.0, 0));
PhysicsServer::get_singleton()->body_set_state(_physics_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, t);
}
*/
@ -197,7 +197,7 @@ void TiledWall::generate_mesh() {
PhysicsServer::get_singleton()->shape_set_data(_physics_shape_rid, Vector3(_width / 2.0, _height / 2.0, 0.01));
Transform t = get_global_transform();
t.translate(Vector3(_width / 2.0, _height / 2.0, 0));
t.translate_local(Vector3(_width / 2.0, _height / 2.0, 0));
PhysicsServer::get_singleton()->body_set_state(_physics_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, t);
}
*/
@ -300,7 +300,7 @@ void TiledWall::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
Transform t = get_global_transform();
t.translate(Vector3(_width / 2.0, _height / 2.0, 0));
t.translate_local(Vector3(_width / 2.0, _height / 2.0, 0));
PhysicsServer::get_singleton()->body_set_state(_physics_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, t);
@ -318,7 +318,7 @@ void TiledWall::_notification(int p_what) {
case NOTIFICATION_TRANSFORM_CHANGED: {
if (_collision) {
Transform t = get_global_transform();
t.translate(Vector3(_width / 2.0, _height / 2.0, 0));
t.translate_local(Vector3(_width / 2.0, _height / 2.0, 0));
PhysicsServer::get_singleton()->body_set_state(_physics_body_rid, PhysicsServer::BODY_STATE_TRANSFORM, t);
}

View File

@ -214,7 +214,7 @@ void PathFollow::_update_transform(bool p_update_xyz_rot) {
}
}
t.translate(Vector3(h_offset, v_offset, 0));
t.translate_local(Vector3(h_offset, v_offset, 0));
} else {
t.origin = pos + Vector3(h_offset, v_offset, 0);
}

View File

@ -813,7 +813,7 @@ void Spatial::rotate_z(float p_angle) {
void Spatial::translate(const Vector3 &p_offset) {
Transform t = get_transform();
t.translate(p_offset);
t.translate_local(p_offset);
set_transform(t);
}
@ -821,7 +821,7 @@ void Spatial::translate_object_local(const Vector3 &p_offset) {
Transform t = get_transform();
Transform s;
s.translate(p_offset);
s.translate_local(p_offset);
set_transform(t * s);
}

View File

@ -140,7 +140,7 @@ Transform OccluderShapeSphere::center_node(const Transform &p_global_xform, cons
// new transform with no rotate or scale, centered
Transform new_local_xform = Transform();
new_local_xform.translate(center.x, center.y, center.z);
new_local_xform.translate_local(center.x, center.y, center.z);
Transform inv_xform = new_local_xform.affine_inverse();