Constrain rotation to object with skewed axis

On 05/06/2013 at 18:42, xxxxxxxx wrote:

User Information:
Cinema 4D Version:    
Language(s) :

Hi, I am throwing in the towel here, and need help!
I have object A, and object B. When Object A is rotated, B shall be rotated exactly the same way in global space (they should look like twins).
This functions ok:

Vector vA = objectA->GetRelRot();

However - and here is the challenge, this works fine, only when objecA and objectB have the same rotation axis. What I want is objectB to follow objectA (look the same on screen) when objectA and objectB have different axis orientations.
For my purpose, it is ok to do this in two passes, first a single pass to detect the differences in axis orientation, and then in subsequent executions use this difference to rotate correctly.

Using tags, this can be done with the Constraint tag plus rotation offset.
But in my C++ code I a) want to calculate some sort of an offset, and b) use this offset to rotate object B.

I have studied matrixes, multiplication of matrixes, MatrixToRotAxis, HPBToMatrix and a dozen other methods, but it seems I do not have the head for this, I cannot get it to work.

I came this far:

        Matrix objectA_Matrix = objectA->GetMg();
        Vector predefinedOffset = Vector(20, 30, 40);
        Matrix offsetMatrix = HPBToMatrix(predefinedOffset, ROTATIONORDER_HPB);
        Matrix result = objectA_Matrix * offsetMatrix; 
        Vector resultVector = MatrixToHPB(result, ROTATIONORDER_HPB);
        objectB->SetRelRot (resultVector);

When I know the predefinedOffset, I can get it to work. But I do not know how to calculate this offset based on the two objects initial positions, and am not even sure  this is the way to go.
Anyone knowing how to do this, will get first prize :)

On 06/06/2013 at 13:25, xxxxxxxx wrote:

I'm not sure If I understand what you want correctly.
But it sounds like you're trying to find out how much one object rotates. So you can then take that value and apply it to another object as a rotation offset.

This is how I would approach it:

In the prepass area use a global variable like this:

Vector prevRot = NULL;

In the execution part of the plugin. Do something like this:

    BaseObject *obj = doc->GetActiveObject();  
  Vector objRot = obj->GetAbsRot();  
  Vector diff = objRot.operator -= (prevRot);  
  GePrint("X: " +RealToString(diff.x) + "  " + "Y: " +RealToString(diff.y) + "  " + "Z: " +RealToString(diff.z) );

The result of this code is every time the obj is rotated. The amount it was rotated gets saved to the diff variable. Which can then be applied to other objects as an offset.


On 06/06/2013 at 23:40, xxxxxxxx wrote:

Originally posted by xxxxxxxx

I'm not sure If I understand what you want correctly.
But it sounds like you're trying to find out how much one object rotates. So you can then take that value and apply it to another object as a rotation offset.

No. How can you think  that? :) 
In my post, I submitted code that does exactly that.
But I admit I am poor at explaining what I am after.

The problem arises when 
a) The two objects have have different axis orientation
b) ObjectA is rotated in World space.

Then object B is not rotated in  World   _space  _but as a result of the difference between Object A's axis and its own axis. I probably need to make a video to explain what I mean..

Now, I have solved it to some extent. When adding a Null object as the child of object_A and have this Null's axis the same as object_B's axis, and doing this:

Vector vA = nullA->GetRelRot();

So my question boils down to: How to write code that will make the Null superfluous.

On 07/06/2013 at 00:18, xxxxxxxx wrote:

1. use c4ds frozen coords feature, it is basically a virtual null.


2. multiply your objects global matrix with the matrix you would have constructed
for your null and after that with your transformation  matrix.

On 07/06/2013 at 00:26, xxxxxxxx wrote:

Hi littledevil,
now we are talking!
I have, believe it or not, tried something similar. But could you please be so kind and elaborate on this a little more? It is about 2). Because I think 1) won't help me.
I almost understand what you write, and yes, you have understood my problem. But I cannot use your suggestion as it is, I need a little more details.

On 08/06/2013 at 07:41, xxxxxxxx wrote:

I have started a new thread on this topic.