@@ -52,6 +52,9 @@ class Node3D : public Node {
|
||||
GDCLASS(Node3D, Node);
|
||||
|
||||
public:
|
||||
// Edit mode for the rotation.
|
||||
// THIS MODE ONLY AFFECTS HOW DATA IS EDITED AND SAVED
|
||||
// IT DOES _NOT_ AFFECT THE TRANSFORM LOGIC (see comment in TransformDirty).
|
||||
enum RotationEditMode {
|
||||
ROTATION_EDIT_MODE_EULER,
|
||||
ROTATION_EDIT_MODE_QUATERNION,
|
||||
@@ -68,11 +71,27 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
// For the sake of ease of use, Node3D can operate with Transforms (Basis+Origin), Quaterinon/Scale and Euler Rotation/Scale.
|
||||
// Transform and Quaterinon are stored in data.local_transform Basis (so quaternion is not really stored, but converted back/forth from 3x3 matrix on demand).
|
||||
// Euler needs to be kept separate because converting to Basis and back may result in a different vector (which is troublesome for users
|
||||
// editing in the inspector, not only because of the numerical precision loss but because they expect these rotations to be consistent, or support
|
||||
// "redundant" rotations for animation interpolation, like going from 0 to 720 degrees).
|
||||
//
|
||||
// As such, the system works in a way where if the local transform is set (via transform/basis/quaternion), the EULER rotation and scale becomes dirty.
|
||||
// It will remain dirty until reading back is attempted (for performance reasons). Likewise, if the Euler rotation scale are set, the local transform
|
||||
// will become dirty (and again, will not become valid again until read).
|
||||
//
|
||||
// All this is transparent from outside the Node3D API, which allows everything to works by calling these functions in exchange.
|
||||
//
|
||||
// Additionally, setting either transform, quaternion, Euler rotation or scale makes the global transform dirty, which will be updated when read again.
|
||||
//
|
||||
// NOTE: Again, RotationEditMode is _independent_ of this mechanism, it is only meant to expose the right set of properties for editing (editor) and saving
|
||||
// (to scene, in order to keep the same values and avoid data loss on conversions). It has zero influence in the logic described above.
|
||||
enum TransformDirty {
|
||||
DIRTY_NONE = 0,
|
||||
DIRTY_VECTORS = 1,
|
||||
DIRTY_LOCAL = 2,
|
||||
DIRTY_GLOBAL = 4
|
||||
DIRTY_EULER_ROTATION_AND_SCALE = 1,
|
||||
DIRTY_LOCAL_TRANSFORM = 2,
|
||||
DIRTY_GLOBAL_TRANSFORM = 4
|
||||
};
|
||||
|
||||
mutable SelfList<Node> xform_change;
|
||||
@@ -80,8 +99,8 @@ private:
|
||||
struct Data {
|
||||
mutable Transform3D global_transform;
|
||||
mutable Transform3D local_transform;
|
||||
mutable Basis::EulerOrder rotation_order = Basis::EULER_ORDER_YXZ;
|
||||
mutable Vector3 rotation;
|
||||
mutable Basis::EulerOrder euler_rotation_order = Basis::EULER_ORDER_YXZ;
|
||||
mutable Vector3 euler_rotation;
|
||||
mutable Vector3 scale = Vector3(1, 1, 1);
|
||||
mutable RotationEditMode rotation_edit_mode = ROTATION_EDIT_MODE_EULER;
|
||||
|
||||
@@ -131,6 +150,7 @@ protected:
|
||||
_FORCE_INLINE_ void set_ignore_transform_notification(bool p_ignore) { data.ignore_notification = p_ignore; }
|
||||
|
||||
_FORCE_INLINE_ void _update_local_transform() const;
|
||||
_FORCE_INLINE_ void _update_rotation_and_scale() const;
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
Reference in New Issue
Block a user