Page MenuHome

Object with Copy Rotation Constraints translates when being parented
Closed, ResolvedPublicBUG


System Information
Operating system: Linux-5.8.16-200.fc32.x86_64-x86_64-with-fedora-32-Thirty_Two 64 Bits
Graphics card: GeForce RTX 2080 Ti/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 455.28

Blender Version
Broken: version: 2.92.0 Alpha, branch: master, commit date: 2020-10-24 21:44, hash: rB05129bc821fd
Worked: not sure if it ever did (2.79b also has this bug)
Short description of error
Parenting an object with a (copy rotation) constraint causes the object's *location* to jump, when using parent or parent keep transform

Exact steps for others to reproduce the error
Download the

The torus and cube should be selected with the cube active
Hit CTRL P and select Parent or Parent/Keep transform
Observe the jump

Since copy rotation does not affect the object location, I'd expect the location to remain stable.

Event Timeline

Germano Cavalcante (mano-wii) changed the task status from Needs Triage to Confirmed.Oct 28 2020, 4:22 PM
Germano Cavalcante (mano-wii) changed the subtype of this task from "Report" to "Bug".

In fact, it seems that something is wrong.
Perhaps the operator code does not assume that the object's matrix may be being altered by constraints.
A solution would be for the operator to recalculate the final matrix of the object without constraints.

This is possibly a limitation.

Turns out that this was caused by a cleanup gone bad . While I was investigating this issue I found the mistake in the cleanup, fixed it (rBad35fa1993a49f663f782af1c9c41640e94b7eb8), and then couldn't reproduce this issue any more :)

Sybren A. Stüvel (sybren) reopened this task as Confirmed.EditedNov 2 2020, 2:31 PM

It wasn't resolved by rBad35fa1993a49f663f782af1c9c41640e94b7eb8 -- that just introduced another problem that hid this one.

I think this issue is caused by the order in which geometric operations are applied. This is the normal order of evaluations:

  1. parent->obmat (the parent object's world matrix)
  2. ob->parentinv (the object's parent-inverse matrix)
  3. Object's loc/rot/scale
  4. Object's constraint evaluation

To compute ob->parentinv at the time of parenting, this is done. Here "zero" is meant to be "the no-op value", so it's (0, 0, 0) for translation & rotation, (1, 1, 1) for scale, and the unit matrix for matrices.

  1. Create a temp object that has zero transform and parent-inverse matrix.
  2. Compute its world matrix.
  3. Apply the original object's constraints to the temp object.
  4. Invert its world matrix. This will be used as parent-inverse matrix.

The problem here is that the constraints are computed, and then the effect is inverted and stored as parent-inverse matrix. In other words: constraints that are meant to be evaluated after the object's own local transform are now having their inverse effect applied before that. This means that the inverse of the Copy Rotation constraint is applied before the object's local translation, and thus that local translation is rotated as well.


Applying the constraints before computing the parent-inverse matrix has been in Blender since forever (rB12315f4d0e0a, that's literally the first commit).