VIDI Presenter 3D Animator Toolkit
#include "AnimatorModules.h"
#include <menus.h;>
#include <windows.h;>
#include <dialogs.h;>
#include <resources.h;>
#define k_FakeGA 3.864 /*1/100th earth's gravity (so we can see things in slow-motion)*/
#define k_SunGA 10825.521
#define k_MoonGA 65.980
#define k_MercuryGA 149.345 /*gravitational accelleration in in/sec^2*/
#define k_VenusGA 339.779
#define k_EarthGA 386.4 /*average earth gravity 32.2ft/sec^2 = 386.4in/sec^2*/
#define k_MarsGA 146.974
#define k_JupiterGA 904.761
#define k_SaturnGA 357.558
#define k_UranusGA 306.987
#define k_NeptuneGA 434.601
#define k_PlutoGA 169.89
/*My globals can go here*/
/*=============================================================*/
typedef struct ConfigData_Rec {
Point3D Va; /*Acceleration vector for our "gravity"*/
short PopUpSelection; /*current pop-up menu selection*/
} ConfigData_Rec;
typedef struct PopUpInfo_Rec {
MenuHandle PopUpMenu; /* Menu Handle for Pop Up */
short MenuID; /* Zero if NewMenu called, otherwise GetMenu was called */
short Selected; /* Currently selected item (1-n) */
short Font; /* Which font to use */
short FontSize; /* Font Size */
short Justified; /* 0=left, 1=right, 2=centered */
Point Position; /* Position of upper left, right or center of pop up rectangle */
Rect PopUpRect;
} PopUpInfo_Rec;
static long oldA4, newA4;
static PopUpInfo_Rec PopUpInfo;
/*=============================================================*/
/* make a pascal from from a floating point number */
static void Num2NiceStr(double theNum, uchar *theStr, GlobalProcs_Ptr gprocs)
{
uchar f;
short b, c, d;
double num;
if (theNum < 0)
num = -theNum;
else
num = theNum;
if ((num > 99999.99999) || ((num > 0) && (num < 0.00001))) {
f = 0; /* too many digits - make it a scientific notation float */
xNum2Str(&f;, theNum, theStr, gprocs);
return;
}
f = 0;
xNum2Str(&f;, theNum, theStr, gprocs);
c = theStr[0]; /* length of pascal string */
d = 0;
for (b = c; b > 0; b--)
if (theStr[b] == '.')
d = b;
if (d == 0)
return;
while (((theStr[c] == '0') || (theStr[c] == '.')) && (c >= d)) {
theStr[0]--; /* decrease length of string by 1 */
c--;
}
}
/* get config values from the handle, if no handle return default values */
static void GetConfigValues(Handle ConfigHndl, Point3D *Va, short *selection)
{
if (ConfigHndl != NULL) {
*Va = ((ConfigData_Rec *)(*ConfigHndl))->Va;
*selection = ((ConfigData_Rec *)(*ConfigHndl))->PopUpSelection;
return;
}
Va->x = 0.0;
Va->y = 0 - k_FakeGA;
Va->z = 0.0;
*selection = 1;
}
/* set up record with proper values */
static void LoadPopUp(PopUpInfo_Rec *PopUpInfo, short PopUpID, short selection,
short whichFont, short whichSize, short Justification,
short PosX, short PosY)
{
short Selected;
MenuInfo **PopUpMenu;
PopUpInfo->Selected = selection;
if (PopUpID < 0) {
PopUpInfo->PopUpMenu = NewMenu(-PopUpID, "\pPop up");
PopUpInfo->Selected = 0;
} else
PopUpInfo->PopUpMenu = GetMenu(PopUpID);
InsertMenu(PopUpInfo->PopUpMenu, -1);
PopUpInfo->MenuID = PopUpID;
PopUpInfo->Font = whichFont;
PopUpInfo->FontSize = whichSize;
PopUpInfo->Justified = Justification;
PopUpInfo->Position.h = PosX;
PopUpInfo->Position.v = PosY;
}
static void DisposePopUp(PopUpInfo_Rec *PopUpInfo)
{
if (PopUpInfo->MenuID < 0) {
DeleteMenu( -PopUpInfo->MenuID );
DisposeMenu(PopUpInfo->PopUpMenu);
} else {
DeleteMenu( PopUpInfo->MenuID );
ReleaseResource((Handle)PopUpInfo->PopUpMenu);
}
PopUpInfo->PopUpMenu = NULL;
}
/* the the dialog item to look like standard popup menu item */
static void DrawPopUp(PopUpInfo_Rec *PopUpInfo)
{
Str255 itemStr;
Point pt;
GetItem(PopUpInfo->PopUpMenu, PopUpInfo->Selected, itemStr);
pt = PopUpInfo->Position;
SetRect(&PopUpInfo-;>PopUpRect, pt.h, pt.v, pt.h + StringWidth(itemStr) + 25, pt.v + 19);
EraseRect(&PopUpInfo-;>PopUpRect);
FrameRect(&PopUpInfo-;>PopUpRect);
MoveTo(PopUpInfo->PopUpRect.left + 1, PopUpInfo->PopUpRect.bottom);
LineTo(PopUpInfo->PopUpRect.right, PopUpInfo->PopUpRect.bottom);
LineTo(PopUpInfo->PopUpRect.right, PopUpInfo->PopUpRect.top + 1);
MoveTo(PopUpInfo->PopUpRect.left + 14, PopUpInfo->PopUpRect.bottom - 5);
DrawString(itemStr);
}
/* When called from dialog update routine */
static pascal void DrawPopUpItem(WindowPeek theDialog, short theItem)
{
long oldA4;
oldA4 = SwapA4(theDialog->refCon);
DrawPopUp(&PopUpInfo;);
SetA4(oldA4);
}
static short AnimatorInterpolate( void )
{
return noErr;
}
static short AnimatorInit( void )
{
return noErr;
}
static short AnimatorDispose( void )
{
return noErr;
}
// Note: acceleration equations we use:
// Vy = Vyo + AyT, Y = Yo +(1/2)(Vyo+Vy)T, Y=Yo+VyoT+(1/2)AyT^2
static short AnimatorApply(ApplyParms_Ptr ParmsPtr, Handle *DataHndlPtr,
Handle ConfigHndl, GlobalProcs_Ptr gProcs)
{
short result, selection;
Point3D Va, Sa;
long deltaTime;
double TimeSlice;
Str255 s, f;
result = noErr;
/* Apply a time-slice or our acceleration vector to the current
velocity vector, Get Velocity Vector created by gravity that
will be applied to object for this time
*/
GetConfigValues(ConfigHndl, &Va;, &selection;);
deltaTime = ParmsPtr->ThisTime - ParmsPtr->LastTimePtr->Point1;
TimeSlice = (double)deltaTime / ParmsPtr->TimeScale;
xSetPoint3D(&Sa;, Va.x / 2 * TimeSlice * TimeSlice,
Va.y / 2 * TimeSlice * TimeSlice,
Va.z / 2 * TimeSlice * TimeSlice, gProcs);
if ( !ParmsPtr->ThisBaseInfoPtr->UseFlags.U1.UseLinearVelocity )
xOffsetPoint3D(&ParmsPtr-;>ThisBaseInfoPtr->LinearVelocity,
Va.x * TimeSlice, Va.y * TimeSlice, Va.z * TimeSlice, gProcs);
if ( !ParmsPtr->ThisBaseInfoPtr->UseFlags.U1.UsePoint1 )
xOffsetPoint3D(&ParmsPtr-;>ThisBaseInfoPtr->Point1, Sa.x, Sa.y, Sa.z, gProcs);
if ( !ParmsPtr->ThisBaseInfoPtr->UseFlags.U1.UsePoint2 )
xOffsetPoint3D(&ParmsPtr-;>ThisBaseInfoPtr->Point2, Sa.x, Sa.y, Sa.z, gProcs);
return result;
}
static OSErr AnimatorConfigOpen(ConfigOpenParms_Ptr ParmsPtr, Handle *DataHndl,
Handle *ConfigHndl, GlobalProcs_Ptr gProcs)
{
short result, itemType, selection;
Point3D Va;
Handle itemHndl;
Rect itemBox;
Str255 s;
GrafPort *theWindow;
result = noErr;
GetConfigValues(*ConfigHndl, &Va;, &selection;); /*Get Config Values*/
/*Allocate Config Handle if it hasn't been*/
if (*ConfigHndl == NULL) {
*ConfigHndl = NewHandle(sizeof(ConfigData_Rec));
((ConfigData_Rec *)(**ConfigHndl))->Va = Va;
((ConfigData_Rec *)(**ConfigHndl))->PopUpSelection = selection;
}
ParmsPtr->theWindow = GetNewDialog(11000, NULL, (GrafPort *)(-1));/*Create window*/
if (ParmsPtr->theWindow == NULL)
return result;
SetPort(ParmsPtr->theWindow);
SetWRefCon(ParmsPtr->theWindow, newA4);
/*Load default value*/
Num2NiceStr(0 - Va.y, s, gProcs);
GetDItem(ParmsPtr->theWindow, 4, &itemType;, &itemHndl;, &itemBox;);
SetIText(itemHndl, s);
SelIText(ParmsPtr->theWindow, 4, 0, 32000);
/*Load pop-up menu*/
GetDItem(ParmsPtr->theWindow, 5, &itemType;, &itemHndl;, &itemBox;);
LoadPopUp(&PopUpInfo;, 11000, selection, 0, 12, 0, itemBox.left,
itemBox.top);
SetDItem(ParmsPtr->theWindow, 5, itemType, (Handle) &DrawPopUpItem;, &itemBox;);
return result;
}
static OSErr AnimatorConfigEvent(ConfigEventParms_Ptr ParmsPtr, Handle *DataHndlPtr,
Handle *ConfigHndlPtr, GlobalProcs_Ptr gProcs)
{
short result, itemHit, itemType, selection;
Handle itemHndl;
Rect itemBox;
Str255 s;
double GA, theNum;
long menuResult;
DialogPtr theWindow;
result = noErr;
if (*ConfigHndlPtr == NULL)
return result;
if (!IsDialogEvent(&ParmsPtr-;>theEvent))
return result;
if (!DialogSelect(&ParmsPtr-;>theEvent, &theWindow;, &itemHit;))
return result;
if (itemHit == 1) {
ParmsPtr->ApplyFlags = 1;
return result;
}
if (itemHit == 4) {
GetDItem(ParmsPtr->theWindow, 4, &itemType;, &itemHndl;, &itemBox;);
GetIText(itemHndl, s);
xStr2Num(s, &theNum;, gProcs);
((ConfigData_Rec *)(**ConfigHndlPtr))->Va.y = 0 - theNum;
/*change menu selection to "custom" if it isn't already there*/
if (PopUpInfo.Selected == 1)
return result;
PopUpInfo.Selected = 1;
((ConfigData_Rec *)(**ConfigHndlPtr))->PopUpSelection = 1;
GetDItem(ParmsPtr->theWindow, 5, &itemType;, &itemHndl;, &itemBox;);
itemBox.top -= 3;
itemBox.right += 3;
itemBox.bottom += 3;
EraseRect(&itemBox;);
DrawPopUp(&PopUpInfo;);
return result;
}
if (itemHit != 5)
return result;
GetDItem(ParmsPtr->theWindow, 5, &itemType;, &itemHndl;, &itemBox;);
LocalToGlobal((Point *) &itemBox;);
menuResult = PopUpMenuSelect(PopUpInfo.PopUpMenu, itemBox.top,
itemBox.left, PopUpInfo.Selected);
if (menuResult == 0)
return result;
selection = menuResult & 0x0FFFF;
if (selection > 1)
{
switch (selection)
{
case 2: /*Sun*/
GA = k_SunGA;
break;
case 3:
GA = k_MoonGA;
break;
case 4:
GA = k_MercuryGA;
break;
case 5:
GA = k_VenusGA;
break;
case 6:
GA = k_EarthGA;
break;
case 7:
GA = k_MarsGA;
break;
case 8:
GA = k_JupiterGA;
break;
case 9:
GA = k_SaturnGA;
break;
case 10:
GA = k_NeptuneGA;
break;
case 11:
GA = k_UranusGA;
break;
case 12:
GA = k_PlutoGA;
break;
default:
GA = k_EarthGA;
break;
}/*case*/
((ConfigData_Rec *)(**ConfigHndlPtr))->Va.y = 0 - GA;
Num2NiceStr(GA, s, gProcs);
GetDItem(ParmsPtr->theWindow, 4, &itemType;, &itemHndl;, &itemBox;);
SetIText(itemHndl, s);
SelIText(ParmsPtr->theWindow, 4, 0, 32000);
}
PopUpInfo.Selected = selection;
((ConfigData_Rec *)(**ConfigHndlPtr))->PopUpSelection = selection;
GetDItem(ParmsPtr->theWindow, 5, &itemType;, &itemHndl;, &itemBox;);
itemBox.top -= 3;
itemBox.right += 3;
itemBox.bottom += 3;
EraseRect(&itemBox;);
DrawPopUp(&PopUpInfo;);
return result;
}
static OSErr AnimatorConfigClose(ConfigCloseParms_Ptr ParmsPtr, Handle *DataHndlPtr,
Handle *ConfigHndlPtr, GlobalProcs_Ptr gProcs)
{
short result;
result = noErr;
DisposePopUp(&PopUpInfo;);
DisposeDialog(ParmsPtr->theWindow);
return result;
}
pascal OSErr main(Ptr ParmsPtr, Handle *DataHndlPtr, Handle *ConfigHndlPtr,
GlobalProcs_Ptr gProcs, short Selector)
{
short Result;
oldA4 = InitA4();
newA4 = GetA4();
switch (Selector)
{
case k_AnimatorInit:
Result = AnimatorInit();
break;
case k_AnimatorDispose:
Result = AnimatorDispose();
break;
case k_AnimatorConfigOpen:
Result = AnimatorConfigOpen((ConfigOpenParms_Ptr) ParmsPtr, DataHndlPtr,
ConfigHndlPtr, gProcs);
break;
case k_AnimatorConfigEvent:
Result = AnimatorConfigEvent((ConfigEventParms_Ptr)ParmsPtr, DataHndlPtr,
ConfigHndlPtr, gProcs);
break;
case k_AnimatorConfigClose:
Result = AnimatorConfigClose((ConfigCloseParms_Ptr)ParmsPtr, DataHndlPtr,
ConfigHndlPtr, gProcs);
break;
case k_AnimatorInterpolate:
Result = AnimatorInterpolate();
break;
case k_AnimatorApply:
Result = AnimatorApply((ApplyParms_Ptr)ParmsPtr, DataHndlPtr, *ConfigHndlPtr, gProcs);
break;
default:
Result = Err_UnknownSelector;
break;
}
SetA4(oldA4);
return Result;
}
Last update 26FEB96 by Eric Popejoy.