Add docs for how object's stored transforms work #23

Open
Nathan Vegdahl wants to merge 4 commits from nathanvegdahl/blender-developer-docs:stored_object_transforms into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
Showing only changes of commit d321398dfb - Show all commits

View File

@ -136,36 +136,63 @@ be more or less complex. Steps in **bold** are rather mandatory.
## Stored Transforms ## Stored Transforms
Each object has a set of source-of-truth (i.e. not derived or cached) transforms stored directly in its DNA, in the `Object` struct in `DNA_object_types.h`. These specify the aspects of an object's transforms that are independent of other objects in the scene, and which do not result from constraints, etc. Each object has a set of source-of-truth (i.e. not derived or cached) transforms
stored directly in its DNA, in the `Object` struct in `DNA_object_types.h`.
These specify the aspects of an object's transforms that are independent of
other objects in the scene, and which do not result from constraints, etc.
### Loc/Rot/Scale ### Loc/Rot/Scale
The simplest of these are the `loc`, `rot`, and `scale` properties, which form the base transform of an object. These are the familiar properties that users use to set and animate an object's position in 3D space. The simplest of these are the `loc`, `rot`, and `scale` properties, which form
the base transform of an object. These are the familiar properties that users
use to set and animate an object's position in 3D space.
`rot` also has counterparts for quaternion and axis-angle rotations: `quat` for quaternions and `rotAxis` + `rotAngle` for axis-angle. These are used for the object's rotation when `rotmode` is set to the corresponding rotation mode. `rot` also has counterparts for quaternion and axis-angle rotations: `quat` for
quaternions and `rotAxis` + `rotAngle` for axis-angle. These are used for the
object's rotation when `rotmode` is set to the corresponding rotation mode.
### Delta Transforms ### Delta Transforms
After the base transform, there are the delta transforms, stored in the `dloc`, `drot`, and `dscale` properties. These can also be set by the user, and effectively define a "rest position" for the object. After the base transform, there are the delta transforms, stored in the `dloc`,
`drot`, and `dscale` properties. These can also be set by the user, and
effectively define a "rest position" for the object.
`loc`/`rot`/`scale` and `dloc`/`drot`/`dscale` are combined into a whole transform as follows: `loc`/`rot`/`scale` and `dloc`/`drot`/`dscale` are combined into a whole
transform as follows:
1. `loc` and `dloc` are simply added together as vectors. 1. `loc` and `dloc` are simply added together as vectors.
2. `rot` and `drot` are combined by first creating a 3x3 matrix for each, and then multiplying them together. The multiplication order is equivalent to first applying `rot`'s rotation to the object and then applying `drot`'s rotation. 2. `rot` and `drot` are combined by first creating a 3x3 matrix for each, and
then multiplying them together. The multiplication order is equivalent to
first applying `rot`'s rotation to the object and then applying `drot`'s
rotation.
3. `scale` and `dscale` are simply component-wise multiplied together. 3. `scale` and `dscale` are simply component-wise multiplied together.
4. Finally, the results of the previous steps are all combined together into a single transform matrix. 4. Finally, the results of the previous steps are all combined together into a
single transform matrix.
> NOTE: > NOTE: Quaternion and axis-angle rotation modes also have corresponding `d*`
> Quaternion and axis-angle rotation modes also have corresponding `d*` properties for delta transforms, for when the object is in those respective rotation modes. They are applied the same way as `drot`. > properties for delta transforms, for when the object is in those respective
> rotation modes. They are applied the same way as `drot`.
The relevant code for this is in `blenkernel/intern/object.cc` in the functions `BKE_object_scale_to_mat3`, `BKE_object_rot_to_mat3`, `BKE_object_to_mat3`, and `BKE_object_to_mat4`. The relevant code for this is in `blenkernel/intern/object.cc` in the functions
`BKE_object_scale_to_mat3`, `BKE_object_rot_to_mat3`, `BKE_object_to_mat3`, and
`BKE_object_to_mat4`.
### Parent-Inverse Matrix ### Parent-Inverse Matrix
Finally, there is one additional transform step that is internal to an object: the parent-inverse matrix. Finally, there is one additional transform step that is internal to an object:
the parent-inverse matrix.
The parent-inverse matrix is a 4x4 matrix stored in the property `parentinv`. Importantly, it is *not* the transform (inverse or otherwise) of the object's parent. Rather, it's an arbitrary 4x4 matrix that gets applied to an object's transforms if and only if it has a parent. The parent-inverse matrix is a 4x4 matrix stored in the property `parentinv`.
Importantly, it is *not* the transform (inverse or otherwise) of the object's
parent. Rather, it's an arbitrary 4x4 matrix that gets applied to an object's
transforms if and only if it has a parent.
Its intended purpose (and the source of its name) is to keep a child object where it is visually when a parent-child relationship is created, without changing the child's loc/rot/scale values. To accomplish this, the matrix is automatically set to the inverse of the parent's transform *at the time the parent-child relationship is created*. It is specifically *not* updated to continuously match the parent's inverse. Its intended purpose (and the source of its name) is to keep a child object
where it is visually when a parent-child relationship is created, without
changing the child's loc/rot/scale values. To accomplish this, the matrix is
automatically set to the inverse of the parent's transform *at the time the
parent-child relationship is created*. It is specifically *not* updated to
continuously match the parent's inverse.
The relevant code for this is in `blenkernel/intern/object.cc` in the function `BKE_object_apply_mat4_ex`. The relevant code for this is in `blenkernel/intern/object.cc` in the function
`BKE_object_apply_mat4_ex`.