PDA

View Full Version : Rotate like with the Rotate tool


kvb
04-25-2009, 09:17 PM
Warning: Long;)

Ok, so lets say I have an object that's rotated 90 degrees along it's B. Effectively, it's Y axis is pointing in the direction of the x axis now, so it's P rotation will effectively rotate it's H rotation, just like if you were simply using the rotate tool. The rotate tool honors the objects orientation, and I'd like a way to get coffee to do the same.

So, this is all related to my flight rig, helm_Control. I have the plane flying along it's z axis, and a control object that rotates the plane based on a 2d vector field: x affects the B rotation, and y affects P rotation. This is where the problem lies. I rotate my plane 90 degrees along it's B, when I then effect its P rotation, it simply rotates around the world Y axis. Altering pitch while banked should affect heading.

I've tried multiple techniques to affect the rotation. Finally landing on, what I thought, was the correct solution, which is quite similar to the position handling:


if (intLastFrame+1==intCurrentFrame) //check to see if the frame has changed
{ vecChildPos=objChild->GetPosition(); // In local coordinates
vecChildPos.z=Velocity; // add the distance/frame for the z axis
vecChildPos.y=VerticalLift; //add distance/frame for the y axis
vecChildPos.x=LateralShift; // add distance/frame for the x axis
vecGlobalPosition=GlobalMatrix->GetMulP(vecChildPos); // Convert to global position
objhelm_Control->SetPosition(vecGlobalPosition); // And set the new global position
outLastFrame = intCurrentFrame; //update LastFrame
}

The coffee propels the rig using a child object. I first get the child's local position (which will be 0 in relation to the parent), then making the z position equal to the "speed per frame", I essentially have a global coordinate that equates to forward momentum along the z. So I use GetMulP to convert that to global position and set that to the parent (the rig). So it's like the child throws out "ghost" positions that drag the rig around (wasn't my idea, all props to Nebu from the cafe).

I figured this same sort of thing would work for rotations too.

I added this code to the above conditional statement (above the position code):


var ParentRot=objhelm_Control->GetRotation();
var ChildRot=objChild->GetRotation();
ChildRot.z=RigRotB+Radians(Banking);
ChildRot.y=RigRotP+Radians(Elevator);
ParentRot=GlobalMatrix->GetMulV(ChildRot);
objhelm_Control->SetRotation(ParentRot);

It seems to be doing the trick... sort of. I get a heading change, even though I'm only making direct changes to the P and B rotations of the child, it seems to be properly transferring global coordinates to the parent. Problem is, they aren't additive, and I don't understand why. Just like its "sister code" that effects the position change, the child's new vector changes are never set, so once the coordinate changes are multiplied and set to the parent, the child still has the same global coordinates as the parent.

I even went so far as to input the child's local rotations into the coffee node (the RigRotB and RigRotP variables in the rotation code) just to make sure the Banking and Elevator values were being added to something.

So, next frame, if the controller is still adding values to the rotation, it should continue to add to the rotation of the rig, but it's not. It's almost like the controller is simply "range mapping" rotation values: for instance, if the controller's x and y positions are both 0, the whole rig has a global rotation of 0,0,0. This is undesirable:(

So, what's the solution. Am I just missing something that my newbie coder brain cells can't figure out? Or do I ignore the child object and the whole GetMulV() thing and formulate some equation that will add an H rotation change when P rotation is altered, based on the rigs B rotation.

I ponder that last one from observing the rotate object tool. It seems to do some sort of internal calculation of the objects overall orientation when rotating around a local axis. That would a helpful equation:)

Been at this for days:(

thanks in advance for any input,
kvb

kvb
04-26-2009, 03:49 AM
Ok, I'm making some progress in the understanding department:) Solution department is still vacant though.

After watching some tutorials at GuerillaCGProject, I understand euler rotations and gimble lock:) More relevant searches brought me to the knowledge that rotation orders aren't really possible in c4d because of it's "specialized" hpb system (or something along those lines).

So, it looks like what I need to do is create a nested setup that mimics rotation orders. Specifically a ZXY (BPH) rotation order. Now to figure out how to implement that in code and hierarchy.

back to work
kvb

kvb
04-26-2009, 10:35 PM
Ok, this is promising, if not a little wierd. This task seems to be the easiest frakkin' thing in the world to do with xpresso.

Pump your input into the Rotation of child, output child's global matrix into parent's local matrix. Done.

This is EXACTLY what the code is trying to do. And I don't mean, it gives the correct results... it does... but I mean almost step for step same thing. This is evident in the "momentum" code I posted above. You grab the child's local position, add to it, convert to global and plop it on the parent's local.

I know there's a difference between setting positions/rotations and setting matrices, and that's why I've explored those options in my code. Adding SetMl, replacing the SetPositions and SetRotations with SetMl, variations of getting the matrices first with code, feeding them into the node via xpresso, etc. Like I said, been at this for days;).

Best outcome has been that every bit of code inside the conditional statement that contains these functions, becomes broken:(

So, I'm going to use the xpresso option and wipe my hands of these evil rotations. Probably going to have to add another null to the rig, as this technique will actually change the driving object's rotation, unlike the momentum code, which never actually changes the driver's position. Don't want that child getting its orientation all screwed up:)

However, I am still VERY interested in how to get the correct rotation behavior with coffee. Both for learning purposes, and to create a good convenience function for it:)

So, come on you coffee gurus, spill the secret;)

thanks,
kvb

CGTalk Moderation
04-26-2009, 10:35 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.