#ifndef UTILS #define UTILS
typedef enum { MMNoOperation, MMPickAndTranslateObject, MMPickAndRotateObject, MMTranslateObject, MMRotateObject,
MOUSEMOVEOPERATIONFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
} MouseMoveOperation;
HandleLeftButtonDown() function to check the state of the shift key before deciding which operation the user selects. The skeleton RsMouseStatus structure supplies the shift and control status.
static RsEventStatus HandleLeftButtonDown(RsMouseStatus *mouseStatus) { /* Left mouse button down event handling... */ if (mouseStatus->shift) { MouseMoveAction = MMPickAndRotateObject; }
else
{
MouseMoveAction = MMPickAndTranslateObject;
}
return rsEVENTPROCESSED;
}
Idle() function to process the new MouseMoveAction states. The MMPickAndRotateObject, and MMRotateObject cases are very similar to the translate equivalents you wrote earlier. The RotateAtomic() function will be written shortly.
case MMTranslateObject : TranslateAtomic(); break; case MMPickAndRotateObject : PickedAtomic = RwCameraPickAtomicOnPixel(Camera, &MousePos);
if (PickedAtomic) { AtomicGetBBox(PickedAtomic, &PickBox); OldPos = MousePos; MouseMoveAction = MMRotateObject; } else { MouseMoveAction = MMNoOperation; } break;
case MMRotateObject : RotateAtomic(); break;
default: PickedAtomic = NULL; break; } Render();
RotateAtomic() and debug through the code. Confirm that the logic behaves as we would expect, and that you can enter all the states correctly.
Next add code to the update function to convert mouse deltas into rotation. These rotations are applied in object space, so we convert the camera vectors into the object space of the picked atomic. To do this we need to access the Local Transformation Matrix of the picked atomic. This is an object-to-world transformation. Inverting this matrix will convert from world space to the picked atomic's space. We can then use the left-right and up-down movements that the mouse makes in world space into rotations of the atomic.
RotateAtomic() function:
static void RotateAtomic(void) { RwFrame *f; RwMatrix *worldToLocal, *tmpMatrix; RwV3d up, right; RwReal dx, dy;
f = RwCameraGetFrame(Camera); right = *RwMatrixGetRight(RwFrameGetMatrix(f)); up = *RwMatrixGetUp(RwFrameGetMatrix(f));
f = RpAtomicGetFrame(PickedAtomic); worldToLocal = RwMatrixCreate(); tmpMatrix = RwFrameGetLTM(f); RwMatrixInvert(worldToLocal, tmpMatrix);
RwV3dTransformVector(&up, &up, worldToLocal); RwV3dNormalize(&up, &up); RwV3dTransformVector(&right, &right, worldToLocal); RwV3dNormalize(&right, &right);
RwMatrixDestroy(worldToLocal);
/* Apply the rotations */ RwFrameRotate(f, &up, -dx*0.5f, rwCOMBINEPRECONCAT); RwFrameRotate(f, &right, dy*0.5f, rwCOMBINEPRECONCAT); OldPos = MousePos; } /* ***************************************************************************** */ /* Idle */ static void Idle(void)

© 1993-2004 Criterion Software Limited. All rights reserved. Built Thu Feb 12 13:46:58 2004.
Send Feedback