/***** Ball.c *****/ /* This file contains code required to implement a trackball user * interface for manipulating a 3D scene. This code was taken from * Graphics Gems 4, editted by Andrew Glassner */ #include "Ball.h" #include "BallMath.h" #include #define TRUE 1 #define FALSE 0 HMatrix mId = { {1, 0, 0, 0} , {0, 1, 0, 0} , {0, 0, 1, 0} , {0, 0, 0, 1} }; float otherAxis[][4] = { {-0.48, 0.80, 0.36, 1} }; /* Establish reasonable initial values for controller. */ void Ball_Init(BallData * ball) { int i; ball->center = qOne; ball->radius = 1.0; ball->vDown = ball->vNow = qOne; ball->qDown = ball->qNow = qOne; for (i = 15; i >= 0; i--) ((float *)ball->mNow)[i] = ((float *)ball->mDown)[i] = ((float *)mId)[i]; ball->dragging = 0; } /* Set the center and size of the controller. */ void Ball_Place(BallData * ball, HVect center, double radius) { ball->center = center; ball->radius = radius; } /* Incorporate new mouse position. */ void Ball_Mouse(BallData * ball, HVect vNow) { ball->vNow = vNow; } /* Using vDown, vNow, dragging, and axisSet, compute rotation etc. */ void Ball_Update(BallData * ball) { Quat qout, qout2; ball->vFrom = MouseOnSphere(ball->vDown, ball->center, ball->radius); ball->vTo = MouseOnSphere(ball->vNow, ball->center, ball->radius); if (ball->dragging) { ball->qDrag = Qt_FromBallPoints(ball->vFrom, ball->vTo); ball->qNow = Qt_Mul(ball->qDrag, ball->qDown); } Qt_ToBallPoints(ball->qDown, &ball->vrFrom, &ball->vrTo); Qt_ToMatrix(Qt_Conj(ball->qNow), ball->mNow); /* Gives transpose for GL. */ qout2 = Matrix_to_Qt(ball->mNow); qout = Qt_Conj(qout2); } void Ball_SetMatrix(BallData * ball, HMatrix mat) { int i, j; Quat qt; Ball_Init(ball); qt = Matrix_to_Qt(mat); ball->qNow = Qt_Conj(qt); ball->qDown = ball->qNow; for (i = 0; i < QuatLen; i++) for (j = 0; j < QuatLen; j++) ball->mNow[i][j] = mat[i][j]; } /* Return rotation matrix defined by controller use. */ void Ball_Value(BallData * ball, HMatrix mNow) { int i; for (i = 15; i >= 0; i--) ((float *)mNow)[i] = ((float *)ball->mNow)[i]; } /* Begin drag sequence. */ void Ball_BeginDrag(BallData * ball) { ball->dragging = 1; ball->vDown = ball->vNow; } /* Stop drag sequence. */ void Ball_EndDrag(BallData * ball) { int i; ball->dragging = 0; ball->qDown = ball->qNow; for (i = 15; i >= 0; i--) ((float *)ball->mDown)[i] = ((float *)ball->mNow)[i]; }