   Switching Rotation Center Point
  Hi,I am working on some gameplay very similar to this: ">King of SwingIn particular the idea of moving hand over hand by rotating around one hand at a time.I have implemented the first part of this; i can rotate around each hand.  I do this by adding the concept a "center point" used to create my world matrix before rendering:Matrix world = Matrix.CreateTranslation(-mCenterPoint) *Matrix.CreateFromYawPitchRoll(mRotation.Y,mRotation.X,mRotation.Z) *Matrix.CreateTranslation(mCenterPoint) *Matrix.CreateScale(mScale) *Matrix.CreateTranslation(mPosition);That seems to work great.  This issue I am running into is what happens when the user switches hands (and there for switching to a new center point).  When that happens I must transform the object so that he continues his rotation in a seamless way.I did this by creating that same world matrix and grabbing the translation out of it, and using that as the new position for my player:Matrix world = Matrix.CreateTranslation(-mIceClimber.mCenterPoint) *Matrix.CreateFromYawPitchRoll(mIceClimber.pRotation.Y,mIceClimber.pRotation.X,mIceClimber.pRotation.Z) *Matrix.CreateTranslation(mIceClimber.mCenterPoint) *Matrix.CreateScale(mIceClimber.pScale) *Matrix.CreateTranslation(mIceClimber.pPosition);mIceClimber.pPosition = world.Translation;This puts the character in the correct position, but if I rotate him based on the new Center Point, it become obvious that he is not where he should be.I believe the issue is that I need to create a matrix based on what will be the new center point in some way.  I'm just not totally sure what I am trying to do...Anyone have so ideas?--------------------------Update:I have things almost working now.  I have updated the code that figures out the new position of the player when switching center points (the second chunk of code from above):Matrix world = Matrix.CreateTranslation(-mIceClimber.mCenterPoint) * Matrix.CreateFromYawPitchRoll( mIceClimber.pRotation.Y, mIceClimber.pRotation.X, mIceClimber.pRotation.Z) * Matrix.CreateTranslation(mIceClimber.mCenterPoint) * Matrix.CreateScale(mIceClimber.pScale) * Matrix.CreateTranslation(mIceClimber.pPosition);// Get the position of the player with all the transforms applied.Vector3 newPos = world.Translation;// Get the position of the current center point in world spaceVector3 centerInWorld = mIceClimber.pPosition + mIceClimber.mCenterPoint;// Get a vector from the current center point to the center of the model.Vector3 newHandDir = newPos - centerInWorld;// Offset the transformed world position, but the direction from the // old center point.  The idea is that we are find the position of // the new center point in world space.// Error: This assumes that the center points are the same distance from//   the center of the model, and that drawing a line between them//   would cut directly through the center of the model.Vector3 newHandPos = newPos + newHandDir;// Switch to the new center point.  For this game, that means just flipping // the X value.mIceClimber.mCenterPoint.X *= -1.0f;// Offset out new world position my the new center's position in local space.newHandPos -= mIceClimber.mCenterPoint;// Store the new position in world space.mIceClimber.pPosition = newHandPos;This works except for the fact that it assumes that the two center points are such that, if you drew a line from one to the other, they would cut directly through the center of the object.  Unfortunately that isn't the case...Any ideas on how to take this to the point where I can have arbitrary center points?Thanks![Edited by - matthughson on January 25, 2010 12:47:33 PM]
  I'm not sure whether I followed the OP correctly in all details, so I just write down how I would do it:It seems me that you're using row vector convention, so I'll use it in the following as well. However, it is unusual to first rotate and then scale, because it means to scale along the rotated axes. Are you sure you want to do so? Commonly the order would be scaling, then rotation, then translation. I will neglect scaling in the following for clarity.Let's define a local position vector hr for the right hand, i.e. the point around which rotation is done when hanging at the right hand. Similarly hl should be the same for the left hand. The matrices Hr and Hl, resp., should denote the corresponding translations.Let's assume that the global position p with its translation matrix P is the current point where the right hand grasps currently. ThenHr-1 * R * P =: Mdenotes the belonging transformation. Notice please that I don't use the translation back by Hr; this is because we want to position the right hand at p, and after Hr-1 the right hand is at the origin, so P is all we need for translation.After playing some animation by varying R we approach the time when the left hand grasps. We can compute the belonging point w.r.t. the global space asp' := hl * M   = hl * Hr-1 * R * Pusing the current M.Now we want to switch the transformation stuff to get the left hand working. That means we want to rebuild M from the current state so that no visible change occurs. In other word, we want findM' := Hl-1 * R' * P'so thatM' == MWell, in this equation all but R' and P' is already known. P' is easy, because we can build it directly from the p' point vector calculated above. Then, for R' , we just need to solveHl-1 * R' * P' = Hr-1 * R * Pso thatR' = Hl * Hr-1 * R * P * P'-1Gotcha, that's it! Continue with the new values, and switching hands is done. A left to right switch is done analogously. Does that help?   ;  Hi Haegarr,Thanks for taking the time to explain all that!  I think it all makes sense, but I'm at work right now, so I won't be able to try it out until later tonight.In regards to the Scale, I don't think I have any object with a non-one Scale, so I probably just haven't exposed the issue yet.Thanks!   