home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Learn 3D Graphics Programming on the PC
/
Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso
/
rwdos
/
dosrobot.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-15
|
56KB
|
2,156 lines
/**********************************************************************
*
* File : dosrobot.c
*
* Abstract : A very simple, sample RenderWare application for
* Microsoft Windows 3.1. This application has very little
* functionality, but is simply intended as a demonstration
* of how to use the RenderWare API.
*
* This application had been written to be compatible with
* both the fixed and floating point versions of the
* RenderWare library, i.e., it uses the macros CREAL,
* INT2REAL, RAdd, RDiv, RSub etc. If your application is
* intended for the floating point version of the library
* only, these calls are not necessary.
*
* Please note that this application is intended for
* demonstration purposes only. No support will be
* provided for this code and it comes with no waranty.
*
* This application supports the following controls with the mouse button
* down:
*
* Control Key Depressed:
* Pan and zoom the camera.
* No Object Picked, No Virtual Keys Depressed:
* Pan and zoom the camera.
* No Object Picked, Shift Key Depressed:
* Pan the light.
* Object Picked, No Virtual Keys Depressed:
* Spin the clump or decal picked.
* Object Picked, Shift Key Depressed:
* Drag the clump or decal pciked.
* Object Picked, Shift and Control Key Depressed:
* Destroy the clump or decal picked.
*
* This file is a product of The Canon Research Centre Europe Ltd.
*
* This file is provided as is with no warranties of any kind and is
* provided without any obligiation on Canon Research Centre Europe Ltd.
* or Canon Inc. to assist in its use or modifiation.
*
* Canon Research Centre Europe Ltd. and Canon Inc. will not, under any
* circumstances, be liable for any lost revenue or other damages arising
* from the use of this file.
*
* Copyright (c) 1991, 1992, 1993. Canon Inc.
* All Rights Reserved.
*
**********************************************************************/
/**********************************************************************
*
* Header files.
*
**********************************************************************/
/****************************************************************************
Includes
*/
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <i86.h>
#include "rwlib.h"
#include "rwtypes.h"
#include "rwdos.h"
#include "doswrap.h"
/**********************************************************************
*
* Application constants.
*
**********************************************************************/
#define DELETE 8
#define BOOL int
/*
* MS Windows compatible defines
*/
#define MK_CONTROL 0x4
#define MK_SHIFT 0x2
/*
* Other defines
*/
#define DEFAULT_CAMERA_DISTANCE CREAL(-9.0)
#define M_PI CREAL(3.14159265358979323846)
/*--- Ansi Declarations */
/*
void LoadDemoMenu();
int CheckCommandLine(LPSTR Command);
static void HandleDrop(HWND Window, HDROP Drop, char *name);
*/
/**********************************************************************
*
* Type definitions.
*
**********************************************************************/
/*
* This enumerated type tells us what kind of action should be taken
* on mouse events.
*/
typedef enum
{
MMNoAction,
MMPanAndZoomCamera,
MMPanAndLiftCamera,
MMPanLight
}
MMMode;
typedef enum
{
APRest,
APAlert,
APLeftScan,
APRightScan,
APReach,
APGrab,
APPickUp,
APDiscard,
APOverBox,
APInBox,
APRelease
}
ArmPositionType;
/*
* This enumerated type tells us what kind of animated action should
* be taken on timer messages. It is used to allow us to spin clumps
* and decals for a momentum effect.
*/
typedef enum
{
ANoAction,
AAction
}
AMode;
/*
* The current camera mode.
*/
typedef enum
{
CMTrackMouse,
CMDroppedObject,
CMDiscardObject,
CMRobotHand
}
CameraModeType;
/*
* This structure holds the parameters necessary for the current
* parameteric motion of a joint.
*/
typedef struct
{
RwReal currentX;
RwReal lastX;
RwReal targetX;
RwReal currentY;
RwReal lastY;
RwReal targetY;
RwReal currentZ;
RwReal lastZ;
RwReal targetZ;
}
JointParams;
typedef struct _likedObjectNode
{
char name[64];
int like;
struct _likedObjectNode *next;
}
LikedObjectNode;
/**********************************************************************
*
* Application global variables.
*
**********************************************************************/
static RwScene *Scene = NULL;
static RwCamera *Camera = NULL;
/*#if 0
static RwCamera *ObjectCamera = NULL;
static RwCamera *HandCamera = NULL;
#endif */
static RwLight *Light = NULL;
static RwClump *DroppingObject = NULL;
static RwClump *DeformingObject = NULL;
static RwClump *DroppedObject = NULL;
static RwClump *DiscardObject = NULL;
static RwClump *Robot = NULL;
static RwClump *UpperArm = NULL;
static RwClump *ForeArm = NULL;
static RwClump *Hand = NULL;
static RwClump *FirstFinger = NULL;
static RwClump *SecondFinger = NULL;
static RwClump *FirstFingerTip = NULL;
static RwClump *SecondFingerTip = NULL;
static MMMode MouseMoveMode = MMNoAction;
static AMode AnimMode = ANoAction;
static int LastX;
static int LastY;
static RwReal CameraDistance = DEFAULT_CAMERA_DISTANCE;
static RwReal CamTilt = CREAL(0.0);
static RwReal JointParam;
static RwReal JointParamDelta;
static ArmPositionType ArmPosition = APRest;
static RwReal DropHeight = CREAL(10.0);
static RwReal DropAcceleration;
static RwReal DropX;
static RwReal DropY;
static RwReal DropZ;
static RwReal DropTime;
static RwReal DeformingStep;
static RwReal DiscardXSpin;
static RwReal DiscardYSpin;
static RwReal DiscardZSpin;
static RwV3d DiscardVector;
static int DiscardStep;
static int LikeDroppedObject = 0;
static LikedObjectNode *LikedObjects = NULL;
static CameraModeType CMMode = CMTrackMouse;
static BOOL RenderWareOpen = FALSE;
static char DropString[16] = "";
/*
* Dos globals
*/
static int nGScrWidth;
static int nGScrHeight;
static int nGTextColour;
static char sGClear[]=" ";
/**********************************************************************
*
* Functions.
*
**********************************************************************/
/****************************************************************************
DosPrintString
On entry : xcord
: ycord
: string
: colour
On exit :
*/
void DosPrintString(int nX,int nY,char *sString,int nCol)
{
RwPrintChar pcPrint;
pcPrint.x = nX;
pcPrint.y = nY;
pcPrint.color = nCol;
for (;(*sString);sString++) {
pcPrint.c = (*sString);
RwDeviceControl(rwPRINTCHAR,0,&pcPrint,sizeof(pcPrint));
pcPrint.x+=8;
};
}
/****************************************************************************
DosTimer
On entry :
On exit : Timer (in milliseconds)
*/
int DosTimer(void)
{
union REGS r;
int nTime;
r.h.ah=0;
int386(0x1a,&r,&r);
nTime = ((r.w.cx)<<16)|(r.w.dx);
return (nTime*55);
}
/****************************************************************************
DosGetKey
On entry :
On exit : Key pressed in ascii (or 0 if no key pressed)
*/
int DosGetKey(void)
{
union REGPACK rp;
memset(&rp,0,sizeof(rp));
rp.h.ah = 0x06;
rp.h.dl = 0xff;
intr(0x21,&rp);
if (!(rp.w.flags & 0x40 )) { /* Check Z flag */
/* Got key */
if (rp.h.al) {
return ((int)rp.h.al);
};
memset(&rp,0,sizeof(rp));
rp.h.ah = 0x06;
rp.h.dl = 0xff;
intr(0x21,&rp);
if (!(rp.w.flags & 0x40)) {
return ((int)rp.h.al);
};
return (rp.h.al|0x80);
};
return 0;
}
/****************************************************************************
DosShiftCtrl
On entry :
On exit : Bit Meaning
0 Right Shift
1 Left Shift
2 Ctrl
3 Alt
4 Scroll Lock
5 Num Lock
6 Caps Lock
7 Insert on
*/
int DosShiftCtrl(void)
{
union REGPACK rp;
memset(&rp,0,sizeof(rp));
rp.h.ah=0x02;
intr(0x16,&rp);
return ((int)rp.h.al);
}
/**********************************************************************/
void
BeginDiscard(RwClump *clump)
{
RwPushScratchMatrix();
RwGetClumpLTM(clump, RwScratchMatrix());
RwRemoveChildFromClump(clump);
RwTransformClump(clump, RwScratchMatrix(), rwREPLACE);
RwIdentityMatrix(RwScratchMatrix());
RwTransformClumpJoint(clump, RwScratchMatrix(), rwREPLACE);
DiscardObject = clump;
DiscardXSpin = RSub(RMul(RDiv(INT2REAL(rand()), INT2REAL(RAND_MAX)),
CREAL(30.0)), CREAL(15.0));
DiscardYSpin = RSub(RMul(RDiv(INT2REAL(rand()), INT2REAL(RAND_MAX)),
CREAL(30.0)), CREAL(15.0));
DiscardZSpin = RSub(RMul(RDiv(INT2REAL(rand()), INT2REAL(RAND_MAX)),
CREAL(30.0)), CREAL(15.0));
DiscardStep = 0;
DiscardVector.x = CREAL(0.0);
DiscardVector.y = CREAL(1.0);
DiscardVector.z = CREAL(0.0);
RwTransformVector(&DiscardVector, RwGetClumpLTM(Hand, RwScratchMatrix()));
RwNormalize(&DiscardVector);
DiscardVector.x = RDiv(DiscardVector.x, CREAL(3.0));
DiscardVector.y = RDiv(DiscardVector.y, CREAL(3.0));
DiscardVector.z = RDiv(DiscardVector.z, CREAL(3.0));
RwPopScratchMatrix();
}
/**********************************************************************/
void
DoDiscard()
{
if (DiscardObject)
{
RwPushScratchMatrix();
RwRotateMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(0.0), CREAL(0.0),
(DiscardXSpin), rwREPLACE);
RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0),
(DiscardYSpin), rwPOSTCONCAT);
RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(0.0), CREAL(1.0),
(DiscardZSpin), rwPOSTCONCAT);
RwTransformClump(DiscardObject, RwScratchMatrix(), rwPRECONCAT);
RwTranslateMatrix(RwScratchMatrix(), DiscardVector.x, DiscardVector.y,
DiscardVector.z, rwREPLACE);
RwTransformClump(DiscardObject, RwScratchMatrix(), rwPOSTCONCAT);
RwPopScratchMatrix();
DiscardStep++;
}
}
/**********************************************************************/
void
EndDiscard()
{
if (DiscardObject)
{
RwDestroyClump(DiscardObject);
DiscardObject = NULL;
DiscardStep = 0;
}
}
/**********************************************************************/
void
DoDrop()
{
RwReal height;
if (DroppingObject)
{
height = RAdd(RSub(DropHeight,
RDiv(RMul(RMul(DropTime,
DropTime),
DropAcceleration),
CREAL(2.0))),
DropY);
RwPushScratchMatrix();
RwTranslateMatrix(RwScratchMatrix(), DropX, height, DropZ, rwREPLACE);
RwTransformClump(DroppingObject, RwScratchMatrix(), rwREPLACE);
RwPopScratchMatrix();
DropTime = RAdd(DropTime, CREAL(0.1));
if (DropTime > CREAL(2.0))
{
DropTime = CREAL(0.0);
DeformingStep = CREAL(0.0);
DeformingObject = DroppingObject;
DroppingObject = NULL;
}
}
}
/**********************************************************************/
void
DoDeform()
{
RwReal scale;
RwV3d FUR;
RwV3d BLL;
if (DeformingObject)
{
scale = RMul(RSub(DeformingStep, CREAL(0.5)), CREAL(2.0));
scale = RDiv(RMul(scale, scale), CREAL(2.0));
scale = RAdd(scale, CREAL(0.5));
RwPushScratchMatrix();
RwScaleMatrix(RwScratchMatrix(), RAdd(RSub(CREAL(1.0), scale), CREAL(1.0)),
scale,
RAdd(RSub(CREAL(1.0), scale), CREAL(1.0)),
rwREPLACE);
RwTransformClump(DeformingObject, RwScratchMatrix(), rwREPLACE);
RwGetClumpBBox(DeformingObject, &FUR, &BLL);
RwTranslateMatrix(RwScratchMatrix(), DropX, BLL.y, DropZ, rwREPLACE);
RwTransformClump(DeformingObject, RwScratchMatrix(), rwPOSTCONCAT);
RwPopScratchMatrix();
DeformingStep = RAdd(DeformingStep, CREAL(0.1));
if (DeformingStep > CREAL(1.0))
{
DeformingStep = CREAL(0.0);
DroppedObject = DeformingObject;
DeformingObject = NULL;
}
}
}
/**********************************************************************/
/*
* Convert the given parameter (in range 0.0-1.0) to an output parameter
* in the range (0.0-1.0) where the curve is non-linear at the start and
* and to give an effect of acceleration, constant motion and decleration.
*/
RwReal
VelocityMapping(RwReal p)
{
int stage;
RwReal stagerange;
/*
* The processing has three distinct stages, so identify which of the
* stages we are in.
*/
stage = REAL2INT(RMul(p, CREAL(2.0)));
switch (stage)
{
case 0:
/* Acceleration. */
stagerange = RMul(CREAL(2.0), p);
return RMul(RDiv(CREAL(1.0), CREAL(2.0)), RMul(stagerange, stagerange));
default:
/* Deceleration. */
stagerange = RSub(CREAL(1.0), RMul(RSub(p, CREAL(0.5)), CREAL(2.0)));
stagerange = RSub(CREAL(1.0), RMul(stagerange, stagerange));
return RAdd(CREAL(0.5), RMul(CREAL(0.5), stagerange));
}
}
/**********************************************************************/
/*
* From the given clump, identify all the different bits of the robot
* arm and stash them away in global variables for later access.
*/
RwClump *
FindRobotArmBits(RwClump *clump)
{
if (!(Robot = RwFindTaggedClump(clump, 1)))
{
return NULL;
}
if (!(UpperArm = RwFindTaggedClump(Robot, 2)))
{
return NULL;
}
if (!(ForeArm = RwFindTaggedClump(UpperArm, 3)))
{
return NULL;
}
if (!(Hand = RwFindTaggedClump(ForeArm, 4)))
{
return NULL;
}
if (!(FirstFinger = RwFindTaggedClump(Hand, 5)))
{
return NULL;
}
if (!(FirstFingerTip = RwFindTaggedClump(FirstFinger, 7)))
{
return NULL;
}
if (!(SecondFinger = RwFindTaggedClump(Hand, 6)))
{
return NULL;
}
if (!(SecondFingerTip = RwFindTaggedClump(SecondFinger, 7)))
{
return NULL;
}
return Robot;
}
/**********************************************************************/
/*
* Initialize the joints of the robot arm for parametric motion.
*/
static int
InitJoints()
{
JointParams *params;
if (!(params = (JointParams *) malloc(sizeof(JointParams))))
{
return FALSE;
}
params->currentX = CREAL(0.0);
params->lastX = CREAL(0.0);
params->targetX = CREAL(0.0);
params->currentY = CREAL(0.0);
params->lastY = CREAL(0.0);
params->targetY = CREAL(0.0);
params->currentZ = CREAL(0.0);
params->lastZ = CREAL(0.0);
params->targetZ = CREAL(0.0);
RwSetClumpData(UpperArm, params);
if (!(params = (JointParams *) malloc(sizeof(JointParams))))
{
return FALSE;
}
params->currentX = CREAL(0.0);
params->lastX = CREAL(0.0);
params->targetX = CREAL(0.0);
params->currentY = CREAL(0.0);
params->lastY = CREAL(0.0);
params->targetY = CREAL(0.0);
params->currentZ = CREAL(0.0);
params->lastZ = CREAL(0.0);
params->targetZ = CREAL(0.0);
RwSetClumpData(ForeArm, params);
if (!(params = (JointParams *) malloc(sizeof(JointParams))))
{
return FALSE;
}
params->currentX = CREAL(0.0);
params->lastX = CREAL(0.0);
params->targetX = CREAL(0.0);
params->currentY = CREAL(0.0);
params->lastY = CREAL(0.0);
params->targetY = CREAL(0.0);
params->currentZ = CREAL(0.0);
params->lastZ = CREAL(0.0);
params->targetZ = CREAL(0.0);
RwSetClumpData(Hand, params);
if (!(params = (JointParams *) malloc(sizeof(JointParams))))
{
return FALSE;
}
params->currentX = CREAL(0.0);
params->lastX = CREAL(0.0);
params->targetX = CREAL(0.0);
params->currentY = CREAL(0.0);
params->lastY = CREAL(0.0);
params->targetY = CREAL(0.0);
params->currentZ = CREAL(0.0);
params->lastZ = CREAL(0.0);
params->targetZ = CREAL(0.0);
RwSetClumpData(FirstFinger, params);
if (!(params = (JointParams *) malloc(sizeof(JointParams))))
{
return FALSE;
}
params->currentX = CREAL(0.0);
params->lastX = CREAL(0.0);
params->targetX = CREAL(0.0);
params->currentY = CREAL(0.0);
params->lastY = CREAL(0.0);
params->targetY = CREAL(0.0);
params->currentZ = CREAL(0.0);
params->lastZ = CREAL(0.0);
params->targetZ = CREAL(0.0);
RwSetClumpData(FirstFingerTip, params);
if (!(params = (JointParams *) malloc(sizeof(JointParams))))
{
return FALSE;
}
params->currentX = CREAL(0.0);
params->lastX = CREAL(0.0);
params->targetX = CREAL(0.0);
params->currentY = CREAL(0.0);
params->lastY = CREAL(0.0);
params->targetY = CREAL(0.0);
params->currentZ = CREAL(0.0);
params->lastZ = CREAL(0.0);
params->targetZ = CREAL(0.0);
RwSetClumpData(SecondFinger, params);
if (!(params = (JointParams *) malloc(sizeof(JointParams))))
{
return FALSE;
}
params->currentX = CREAL(0.0);
params->lastX = CREAL(0.0);
params->targetX = CREAL(0.0);
params->currentY = CREAL(0.0);
params->lastY = CREAL(0.0);
params->targetY = CREAL(0.0);
params->currentZ = CREAL(0.0);
params->lastZ = CREAL(0.0);
params->targetZ = CREAL(0.0);
RwSetClumpData(SecondFingerTip, params);
return TRUE;
}
/**********************************************************************/
static void
SetClumpTargetAngleX(RwClump *clump, RwReal targetX)
{
JointParams *params;
params = (JointParams *) RwGetClumpData(clump);
params->lastX = params->currentX;
params->targetX = targetX;
}
/**********************************************************************/
static void
SetClumpTargetAngleY(RwClump *clump, RwReal targetY)
{
JointParams *params;
params = (JointParams *) RwGetClumpData(clump);
params->lastY = params->currentY;
params->targetY = targetY;
}
/**********************************************************************/
static void
SetClumpTargetAngleZ(RwClump *clump, RwReal targetZ)
{
JointParams *params;
params = (JointParams *) RwGetClumpData(clump);
params->lastZ = params->currentZ;
params->targetZ = targetZ;
}
/**********************************************************************/
static void
SetClumpTargetAngleXYZ(RwClump *clump, RwReal targetX, RwReal targetY,
RwReal targetZ)
{
JointParams *params;
params = (JointParams *) RwGetClumpData(clump);
params->lastX = params->currentX;
params->lastY = params->currentY;
params->lastZ = params->currentZ;
params->targetX = targetX;
params->targetY = targetY;
params->targetZ = targetZ;
}
/**********************************************************************/
static void
UpdateClumpTargetAngle(RwClump *clump)
{
JointParams *params;
params = (JointParams *) RwGetClumpData(clump);
params->lastX = params->currentX = params->targetX;
params->lastY = params->currentY = params->targetY;
params->lastZ = params->currentZ = params->targetZ;
}
/**********************************************************************/
static void
AnimateJoint(RwClump *Clump, RwReal p)
{
JointParams *params;
params = (JointParams *) RwGetClumpData(Clump);
params->currentX = RAdd(RMul(RSub(params->targetX, params->lastX),
VelocityMapping(p)), params->lastX);
params->currentY = RAdd(RMul(RSub(params->targetY, params->lastY),
VelocityMapping(p)), params->lastY);
params->currentZ = RAdd(RMul(RSub(params->targetZ, params->lastZ),
VelocityMapping(p)), params->lastZ);
RwRotateMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(0.0), CREAL(0.0),
params->currentX, rwREPLACE);
RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(1.0), CREAL(0.0),
params->currentY, rwPOSTCONCAT);
RwRotateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(0.0), CREAL(1.0),
params->currentZ, rwPOSTCONCAT);
RwTransformClumpJoint(Clump, RwScratchMatrix(), rwREPLACE);
}
/**********************************************************************/
static void
AnimateJoints(RwReal p)
{
RwPushScratchMatrix();
AnimateJoint(UpperArm, p);
AnimateJoint(ForeArm, p);
AnimateJoint(Hand, p);
AnimateJoint(FirstFinger, p);
AnimateJoint(FirstFingerTip, p);
AnimateJoint(SecondFinger, p);
AnimateJoint(SecondFingerTip, p);
RwPopScratchMatrix();
}
/**********************************************************************/
static void
ArmToRestPosition()
{
SetClumpTargetAngleX(UpperArm, CREAL(-60.0));
SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, CREAL(140.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(90.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-10.0), CREAL(0.0),
CREAL(0.0));
}
/**********************************************************************/
static void
ArmToAlertPosition()
{
SetClumpTargetAngleX(UpperArm, CREAL(-20.0));
SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, CREAL(40.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(80.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(20.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-20.0), CREAL(0.0),
CREAL(0.0));
}
/**********************************************************************/
static void
ArmToLeftScanPosition()
{
SetClumpTargetAngleX(UpperArm, CREAL(-20.0));
SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, CREAL(40.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(80.0), CREAL(45.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-15.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(25.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(15.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-25.0), CREAL(0.0),
CREAL(0.0));
}
/**********************************************************************/
static void
ArmToRightScanPosition()
{
SetClumpTargetAngleX(UpperArm, CREAL(-20.0));
SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, CREAL(40.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(80.0), CREAL(-45.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-15.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(25.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(15.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-25.0), CREAL(0.0),
CREAL(0.0));
}
/**********************************************************************/
static void
ArmRotatePosition()
{
SetClumpTargetAngleX(UpperArm, CREAL(-60.0));
SetClumpTargetAngleY(UpperArm, RAdd(RMul(RDiv(INT2REAL(rand()),
INT2REAL(RAND_MAX)),
CREAL(315.0)), CREAL(45.0)));
SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, CREAL(140.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(10.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-10.0), CREAL(0.0),
CREAL(0.0));
}
/**********************************************************************/
static void
ArmRotateUpPosition()
{
SetClumpTargetAngleX(UpperArm, CREAL(-20.0));
SetClumpTargetAngleY(UpperArm, RAdd(RMul(RDiv(INT2REAL(rand()),
INT2REAL(RAND_MAX)),
CREAL(315.0)), CREAL(45.0)));
SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, CREAL(40.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(80.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-15.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(25.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(15.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-25.0), CREAL(0.0),
CREAL(0.0));
}
/**********************************************************************/
static RwReal
XZToAngle(RwReal x, RwReal z)
{
RwReal Temp;
/* **** use table for atn() in real life **** */
Temp = RMul(RDiv(FL2REAL(atan(REAL2FL(RDiv(z, x)))), RMul(M_PI,
CREAL(2.0))),
CREAL(360));
if (x < CREAL(0.0))
{
return RAdd(Temp, CREAL(180.0));
}
else if (z < CREAL(0.0))
{
return RAdd(Temp, CREAL(360.0));
}
else
{
return Temp;
}
}
/**********************************************************************/
static void
ArmReachForPosition(RwReal x, RwReal y, RwReal z)
{
RwReal angle;
RwReal shoulderangle;
RwReal elbowangle;
RwReal wristangle;
RwReal hyp;
/* Stop warnings */
y=y;
angle = RSub(CREAL(450.0), XZToAngle(x, z));
if (angle < CREAL(0.0))
angle = RAdd(angle, CREAL(360.0));
if (angle >= CREAL(360.0))
angle = RSub(angle, CREAL(360.0));
hyp = RSqrt(RAdd(RMul(x, x), RMul(z, z)));
/* ***** use table for acos() ****** */
shoulderangle = RMul(CREAL(360.0),
RDiv(FL2REAL(acos REAL2FL(RDiv(RDiv(hyp, CREAL(2.0)),
CREAL(2.5)))),
RMul(M_PI, CREAL(2.0))));
elbowangle = RSub(CREAL(180.0), RMul(CREAL(2.0), RSub(CREAL(90.0),
shoulderangle)));
wristangle = RSub(CREAL(90.0), shoulderangle);
SetClumpTargetAngleXYZ(UpperArm, RSub(CREAL(90.0), shoulderangle), angle,
CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, elbowangle, CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, wristangle, CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-80.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(0.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(80.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(0.0), CREAL(0.0), CREAL(0.0));
}
/**********************************************************************/
static void
ArmGrab()
{
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-45.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(90.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(45.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-90.0), CREAL(0.0),
CREAL(0.0));
}
/**********************************************************************/
static void
ArmPickUp()
{
SetClumpTargetAngleX(UpperArm, CREAL(0.0));
SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, CREAL(90.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(90.0), CREAL(0.0), CREAL(0.0));
}
/**********************************************************************/
static void
ArmRelease()
{
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-55.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(45.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(55.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(-45.0), CREAL(0.0),
CREAL(0.0));
}
/**********************************************************************/
static void
ArmDiscard()
{
SetClumpTargetAngleX(UpperArm, CREAL(-55.0));
SetClumpTargetAngleZ(UpperArm, CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, CREAL(0.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(0.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFinger, CREAL(-90.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(FirstFingerTip, CREAL(0.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFinger, CREAL(90.0), CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(SecondFingerTip, CREAL(0.0), CREAL(0.0), CREAL(0.0));
}
/**********************************************************************/
static void
ArmOverBox()
{
RwReal angle;
RwReal shoulderangle;
RwReal hyp;
angle = RSub(CREAL(450.0), XZToAngle(CREAL(-2.0), CREAL(-2.0)));
if (angle < CREAL(0.0))
angle = RAdd(angle, CREAL(360.0));
if (angle >= CREAL(360.0))
angle = RSub(angle, CREAL(360.0));
hyp = RSub(RSqrt(CREAL(8.0)), CREAL(2.5));
shoulderangle = RMul(RDiv(FL2REAL(acos REAL2FL(RDiv(hyp, CREAL(2.5)))),
RMul(M_PI, CREAL(2.0))), CREAL(360));
SetClumpTargetAngleXYZ(UpperArm, RSub(CREAL(90.0), shoulderangle), angle,
CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, shoulderangle, CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, CREAL(90.0), CREAL(0.0), CREAL(0.0));
}
/**********************************************************************/
static void
ArmPutInBox()
{
RwReal angle;
RwReal shoulderangle;
RwReal elbowangle;
RwReal wristangle;
RwReal hyp;
angle = RSub(CREAL(450.0), XZToAngle(CREAL(-2.0), CREAL(-2.0)));
if (angle < CREAL(0.0))
angle = RAdd(angle, CREAL(360.0));
if (angle >= CREAL(360.0))
angle = RSub(angle, CREAL(360.0));
hyp = RSqrt(CREAL(8.0));
shoulderangle = RMul(RDiv(FL2REAL(acos REAL2FL(RDiv(RDiv(hyp, CREAL(2.0)),
CREAL(2.5)))),
RMul(M_PI, CREAL(2.0))), CREAL(360));
elbowangle = RSub(CREAL(180.0), RMul(CREAL(2.0), RSub(CREAL(90.0),
shoulderangle)));
wristangle = RSub(CREAL(90.0), shoulderangle);
SetClumpTargetAngleXYZ(UpperArm, RSub(CREAL(90.0), shoulderangle), angle,
CREAL(0.0));
SetClumpTargetAngleXYZ(ForeArm, elbowangle, CREAL(0.0), CREAL(0.0));
SetClumpTargetAngleXYZ(Hand, wristangle, CREAL(0.0), CREAL(0.0));
}
/**********************************************************************/
static void
UpdateArmPosition()
{
UpdateClumpTargetAngle(UpperArm);
UpdateClumpTargetAngle(ForeArm);
UpdateClumpTargetAngle(Hand);
UpdateClumpTargetAngle(FirstFinger);
UpdateClumpTargetAngle(FirstFingerTip);
UpdateClumpTargetAngle(SecondFinger);
UpdateClumpTargetAngle(SecondFingerTip);
}
/**********************************************************************/
/*
* This function initializes the 3D (i.e. RenderWare) components of the
* application. This function opens the RenderWare library, creates a camera,
* a scene, a light and loads an initial clump.
*/
static BOOL
Init3D(void)
{
RwClump *Clump;
char *title;
int fixed, debugging;
long nError;
RwReal naWhite[]={CREAL(1.0),CREAL(1.0),CREAL(1.0)};
if (!RwOpen("DOSMOUSE", &nError))
{
printf("Unable to access renderware!!\n");
switch (nError) {
case E_RW_DOS_MODE_UNAVAILABLE: {
printf("The installed VESA card is unable to switch to the resolution");
printf(" requested.\n");
printf("Either install a different video adapter or use a ");
printf("supported video mode.");
break;
};
case E_RW_DOS_NO_VESA_BIOS: {
printf("A VESA bios is unavailable on this machine.\n");
printf("Either use a VESA compatible Video Adapter or install a ");
printf("VESA bios emulation TSR.\n");
break;
};
case E_RW_DOS_INCOMPATIBLE_BIOS: {
printf("The VESA bios on this machine is not of high enough version ");
printf("to function\ncorrectly with RenderWare. Use a version 1.0 or");
printf(" higher VESA bios or TSR.\n");
break;
};
case E_RW_DOS_NO_MOUSE: {
printf("No Microsoft compatible mouse driver present.\n");
printf("Install a microsoft compatible mouse driver and try again.\n");
break;
};
default: {
printf("Unknown Error !!!!!!!!!!!!!!!\n");
break;
};
};
return FALSE;
}
/* Set up display parametere */
RwGetDeviceInfo(rwSCRHEIGHT,&nGScrHeight,sizeof(nGScrHeight));
RwGetDeviceInfo(rwSCRWIDTH,&nGScrWidth,sizeof(nGScrWidth));
nGTextColour = RwDeviceControl(rwSCRGETCOLOR,0,naWhite,sizeof(naWhite));
/* Set the path */
RwSetShapePath("SCRIPTS", rwPRECONCAT);
RwSetShapePath("TEXTURES", rwPRECONCAT);
/* Display status message */
RwGetSystemInfo(rwFIXEDPOINTLIB, &fixed,sizeof(fixed));
RwGetSystemInfo(rwDEBUGGINGLIB, &debugging,sizeof(debugging));
if ((fixed) && (debugging))
title = "Robot (Fixed & Debugging)";
else if (fixed)
title = "Robot (Fixed Point)";
else if (debugging)
title = "Robot (Debugging)";
else
title = "Robot (Floating Point)";
DosPrintString(0,nGScrHeight-16,title,nGTextColour);
/* Create camera */
Camera = RwCreateCamera(nGScrWidth,nGScrHeight-24, NULL);
if (!Camera)
{
/*
* As with RwOpen(), the most common cause for a failure to create
* a camera is insufficient memory so we will explicitly check for
* this condition and report it. Otherwise a general error is issued.
*/
if (RwGetError() == E_RW_NOMEM)
{
RwClose();
printf("Insufficient memory to create the RenderWare(tm) camera\n");
}
else
{
RwClose();
printf("Error creating the RenderWare(tm) camera\n");
}
exit(-1);
}
RwSetCameraViewport(Camera, 0, 0, nGScrWidth, nGScrHeight);
RwSetCameraBackColor(Camera, CREAL(0.3), CREAL(0.0), CREAL(0.0));
RwPanCamera(Camera, CREAL(45.0));
RwVCMoveCamera(Camera, CREAL(0.0), CREAL(3.0), CameraDistance);
/*
* Another change from previous versions of RenderWare is the amount of
* prespective generated by the default viewwindow size. When converting
* applications from previous versions of RenderWare the simple rule is
* to divide the viewwindow size by five to get the same prespective effect
* as given under previous versions.
*/
if (nGScrWidth >= nGScrHeight) {
RwSetCameraViewwindow(Camera,
CREAL(1.0),
RMul(CREAL(1.0),
RDiv(INT2REAL(nGScrHeight),
INT2REAL(nGScrWidth))));
} else {
RwSetCameraViewwindow(Camera,
RMul(CREAL(1.0),
RDiv(INT2REAL(nGScrWidth),
INT2REAL(nGScrHeight))),
CREAL(1.0));
};
/*
* Create a scene which will contain the clumps to be rendered and the
* light or lights illuminating those clumps . In this very simple
* application it would be perfectly acceptable to use the default scene
* (as returned by RwDefaultScene()) for rendering. However, it is good
* practice to always create a scene which will be used for your rendering
* and only use the default scene as a bag for currently unused clumps and
* lights.
*/
Scene = RwCreateScene();
if (!Scene)
{
RwDestroyCamera(Camera);
RwClose();
printf("Error creating the RenderWare(tm) scene\n");
exit(-1);
}
Light = RwCreateLight(rwDIRECTIONAL, CREAL(0.1), CREAL(-1.0), CREAL(-0.3),
CREAL(1.0));
if (!Light)
{
RwDestroyScene(Scene);
RwDestroyCamera(Camera);
RwClose();
printf("Error creating the RenderWare(tm) light\n");
exit(-1);
}
RwAddLightToScene(Scene, Light);
Clump = RwReadShape("roandfl.rwx");
if (!Clump)
{
RwDestroyScene(Scene);
if (RwGetError() == E_RW_NOMEM)
{
RwClose();
printf("Could not read script file roandfl.rwx\n");
}
else
{
RwClose();
printf("Could not read script file roandfl.rwx\n");
}
return FALSE;
}
RwAddClumpToScene(Scene, Clump);
if (!FindRobotArmBits(Clump))
{
RwDestroyScene(Scene);
RwClose();
printf("Internal error in structure of Robot\n");
return FALSE;
}
if (!InitJoints())
{
RwDestroyScene(Scene);
RwClose();
printf("Internal error initializing Robot Arm\n");
return FALSE;
}
AnimMode = AAction;
ArmPosition = APRest;
ArmToRestPosition();
JointParam = CREAL(0.0);
JointParamDelta = CREAL(0.03);
/* Display Menu */
DosPrintString(0,nGScrHeight-24,"Ball Eggs Torus Banana",nGTextColour);
RenderWareOpen = TRUE;
return TRUE;
}
/**********************************************************************/
/*
* This function shuts the 3D (i.e. RenderWare) components of the library
* down in a polite fashion.
*/
static void
TidyUp3D()
{
if (Scene)
RwDestroyScene(Scene);
if (Camera)
RwDestroyCamera(Camera);
RwClose();
}
/*************************************************************************/
static void
HandleRightButtonDown(int x, int y, int VKeys)
{
/* Stop warnings */
x=x;
y=y;
VKeys=VKeys;
}
static void
HandleRightButtonUp(void)
{
}
/**********************************************************************/
/*
* This functions handles the left mouse button going down. Its main
* job is to determine the kind of action to be taken when the mouse
* moves, such as spinning a clump, or panning the camera. This involves
* examining the virtual keys that were depressed when the mouse button
* went down and attempting to pick a clump or decal under the the
* mouse pointer position when the mouse went down.
*/
static void
HandleLeftButtonDown(int x, int y, int VKeys)
{
if ((y>nGScrHeight-24)&&(y<nGScrHeight-16)) {
switch(x>>6) {
case 0:
HandleDrop("ball.rwx");
break;
case 1:
HandleDrop("eggs.rwx");
break;
case 2:
HandleDrop("torus.rwx");
break;
case 3:
HandleDrop("banana.rwx");
break;
default:
break;
};
return;
};
if (VKeys & MK_SHIFT)
{
MouseMoveMode = MMPanAndLiftCamera;
RwDPointerRemove();
DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
DosPrintString(0,nGScrHeight-8,"Pan and Tilt Camera",nGTextColour);
}
else if (VKeys & MK_CONTROL)
{
MouseMoveMode = MMPanLight;
RwDPointerRemove();
DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
DosPrintString(0,nGScrHeight-8,"Rotate Light",nGTextColour);
}
else
{
MouseMoveMode = MMPanAndZoomCamera;
RwDPointerRemove();
DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
DosPrintString(0,nGScrHeight-8,"Pan and Zoom Camera",nGTextColour);
}
if (MouseMoveMode != MMNoAction)
{
LastX = x;
LastY = y;
}
}
/**********************************************************************/
/*
* Handle a movement of the mouse. If a previous left mouse button
* down event has set a mouse move mode then this function will take
* the necessary actions. For example, pan and zooming the camera,
* panning the light, dragging or spinning a clump etc.
*/
static void
HandleMouseMove(int x, int y)
{
switch (MouseMoveMode)
{
case MMNoAction:
break;
case MMPanAndZoomCamera:
RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), -CameraDistance);
RwTiltCamera(Camera, -CamTilt);
RwPanCamera(Camera, INT2REAL(LastX - x));
CameraDistance = RAdd(CameraDistance, RDiv(INT2REAL(LastY - y),
CREAL(10.0)));
RwTiltCamera(Camera, CamTilt);
RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CameraDistance);
break;
case MMPanAndLiftCamera:
RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), -CameraDistance);
RwTiltCamera(Camera, -CamTilt);
RwPanCamera(Camera, INT2REAL(LastX - x));
CamTilt += INT2REAL(LastY - y);
RwTiltCamera(Camera, CamTilt);
RwVCMoveCamera(Camera, CREAL(0.0), CREAL(0.0), CameraDistance);
break;
case MMPanLight:
RwPushScratchMatrix();
RwRotateMatrix(RwScratchMatrix(),
CREAL(0.0), CREAL(1.0), CREAL(0.0),
INT2REAL(x - LastX), rwREPLACE);
RwRotateMatrix(RwScratchMatrix(),
CREAL(1.0), CREAL(0.0), CREAL(0.0),
INT2REAL(y - LastY), rwPOSTCONCAT);
RwTransformLight(Light, RwScratchMatrix(),rwPOSTCONCAT);
RwPopScratchMatrix();
break;
}
LastX = x;
LastY = y;
}
/**********************************************************************/
/*
* Handle the left mouse button comming back up. The basic action is
* to turn of mouse move actions, and release mouse capture. Also,
* if the previous mouse move action was a spin then this function will
* turn on animation to continue the spin (and the objects "momentum").
*/
static void
HandleLeftButtonUp(void)
{
if (MouseMoveMode != MMNoAction)
{
RwDPointerRemove();
DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
MouseMoveMode = MMNoAction;
}
}
/**********************************************************************/
static void
HandleDrop(char *name)
{
char Path[_MAX_PATH];
RwV3d BLL, FUR;
RwReal Angle;
RwReal Radius;
LikedObjectNode *Node;
char buffer[256];
int i;
strcpy(Path, name); /* else use supplied filename */
if ((!DroppedObject) && (!DroppingObject))
{
if (DroppingObject = RwReadShape(Path))
{
for (i = strlen(Path); i && (Path[i-1] != '\\'); i--)
;
strcpy (DropString, &Path[i]);
RwDPointerRemove();
DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
for (Node = LikedObjects; Node; Node = Node ->next)
{
if (strcmp(Node ->name, Path) == 0)
break;
}
if (Node)
{
LikeDroppedObject = Node ->like;
}
else
{
if ((rand() & 0x0003)<2)
{
LikeDroppedObject = 0;
}
else
{
LikeDroppedObject = 1;
}
if (Node = (LikedObjectNode *) malloc(sizeof(LikedObjectNode)))
{
strcpy(Node ->name, Path);
Node ->like = LikeDroppedObject;
Node ->next = LikedObjects;
LikedObjects = Node;
}
}
Angle = RSub(RMul(CREAL(180.0), RDiv(INT2REAL(rand()),
INT2REAL(RAND_MAX))),
CREAL(90));
Radius = RAdd(RMul(CREAL(3), RDiv(INT2REAL(rand()),
INT2REAL(RAND_MAX))), CREAL(1));
DropX = RMul(Radius, FL2REAL(cos REAL2FL(RMul(RDiv(Angle,
CREAL(360)),
RMul(M_PI,
CREAL(2))))));
DropZ = RMul(Radius, FL2REAL(sin REAL2FL(RMul(RDiv(Angle,
CREAL(360)),
RMul(M_PI,
CREAL(2))))));
RwNormalizeClump(DroppingObject);
RwPushScratchMatrix();
RwGetClumpBBox(DroppingObject, &BLL, &FUR);
DropAcceleration = RDiv(DropHeight, CREAL(2.0));
DropY = -BLL.y;
DropTime = CREAL(0.0);
RwTranslateMatrix(RwScratchMatrix(), DropX, RAdd(DropHeight, DropY), DropZ,
rwREPLACE);
RwTransformClump(DroppingObject, RwScratchMatrix(), rwPOSTCONCAT);
RwPopScratchMatrix();
RwAddClumpToScene(Scene, DroppingObject);
}
else
{
if (RwGetError() == E_RW_NOMEM)
{
sprintf(buffer, "Insufficient memory for %s",
Path);
RwDPointerRemove();
DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
DosPrintString(0,nGScrHeight-8,buffer,nGTextColour);
}
else
{
sprintf(buffer, "Error reading %s", Path);
RwDPointerRemove();
DosPrintString(0,nGScrHeight-8,sGClear,nGTextColour);
DosPrintString(0,nGScrHeight-8,buffer,nGTextColour);
}
}
}
}
/**********************************************************************/
static void
HandleChar(int WParam)
{
RwCamera *Cam;
switch (WParam)
{
case '0':
CMMode = CMTrackMouse;
Cam = Camera;
break;
case '1':
if (DroppedObject)
{
CMMode = CMDroppedObject;
}
else if (DiscardObject)
{
CMMode = CMDiscardObject;
}
else
{
CMMode = CMTrackMouse;
Cam = Camera;
}
break;
case '2':
CMMode = CMRobotHand;
break;
default:
CMMode = CMTrackMouse;
Cam = Camera;
break;
}
RwInvalidateCameraViewport(Cam);
}
/**********************************************************************/
static void
HandleTimer(void)
{
RwV3d Origin;
RwV3d BLL, FUR;
RwCamera *Cam;
if (DiscardObject)
{
DoDiscard();
if (DiscardStep > 150)
{
if (CMMode == CMDiscardObject)
{
CMMode = CMTrackMouse;
RwInvalidateCameraViewport(Camera);
}
EndDiscard();
}
}
if (DroppingObject)
DoDrop();
if (DeformingObject)
DoDeform();
if (AnimMode != ANoAction)
{
AnimateJoints(JointParam);
JointParam = RAdd(JointParam, JointParamDelta);
if (JointParam > CREAL(1.0))
{
UpdateArmPosition();
switch (ArmPosition)
{
case APRest:
if (DroppedObject)
{
AnimMode = AAction;
ArmPosition = APReach;
ArmReachForPosition(DropX, CREAL(0.0), DropZ);
JointParam = CREAL(0.0);
JointParamDelta = CREAL(0.05);
}
else
{
AnimMode = ANoAction;
}
break;
case APAlert:
if (DroppedObject)
{
AnimMode = AAction;
ArmPosition = APReach;
ArmReachForPosition(DropX, CREAL(0.0), DropZ);
JointParam = CREAL(0.0);
JointParamDelta = CREAL(0.05);
}
else
{
AnimMode = AAction;
ArmPosition = APLeftScan;
JointParamDelta = CREAL(0.04);
ArmToLeftScanPosition();
}
break;
case APLeftScan:
if (DroppedObject)
{
AnimMode = AAction;
ArmPosition = APReach;
ArmReachForPosition(DropX, CREAL(0.0), DropZ);
JointParam = CREAL(0.0);
JointParamDelta = CREAL(0.05);
}
else if ((rand() & 0x03) != 0x03)
{
AnimMode = AAction;
JointParamDelta = CREAL(0.06);
ArmPosition = APRightScan;
ArmToRightScanPosition();
}
else if ((rand() & 0x03) != 0x03)
{
AnimMode = AAction;
JointParamDelta = CREAL(0.05);
ArmRotateUpPosition();
}
else
{
AnimMode = AAction;
/* JointParamDelta = CREAL(0.03); */
JointParamDelta = CREAL(0.07);
ArmPosition = APRest;
ArmToRestPosition();
}
break;
case APRightScan:
if (DroppedObject)
{
AnimMode = AAction;
ArmPosition = APReach;
ArmReachForPosition(DropX, CREAL(0.0), DropZ);
JointParam = CREAL(0.0);
JointParamDelta = CREAL(0.05);
}
else if ((rand() & 0x03) != 0x03)
{
AnimMode = AAction;
JointParamDelta = CREAL(0.06);
ArmPosition = APLeftScan;
ArmToLeftScanPosition();
}
else if ((rand() & 0x03) != 0x03)
{
AnimMode = AAction;
JointParamDelta = CREAL(0.05);
ArmRotateUpPosition();
}
else
{
AnimMode = AAction;
/* JointParamDelta = CREAL(0.03); */
JointParamDelta = CREAL(0.07);
ArmPosition = APRest;
ArmToRestPosition();
}
break;
case APReach:
AnimMode = AAction;
JointParamDelta = CREAL(0.05);
ArmPosition = APGrab;
ArmGrab();
break;
case APGrab:
RwPushScratchMatrix();
RwRotateMatrix(RwScratchMatrix(), CREAL(1.0), CREAL(0.0),
CREAL(0.0), CREAL(180.0), rwREPLACE);
RwTranslateMatrix(RwScratchMatrix(), CREAL(0.0), CREAL(0.7),
CREAL(0.0), rwPOSTCONCAT);
RwTransformClump(DroppedObject, RwScratchMatrix(), rwREPLACE);
RwPopScratchMatrix();
RwAddChildToClump(Hand, DroppedObject);
AnimMode = AAction;
JointParamDelta = CREAL(0.03);
ArmPosition = APPickUp;
ArmPickUp();
break;
case APPickUp:
if (LikeDroppedObject)
{
AnimMode = AAction;
ArmPosition = APOverBox;
JointParamDelta = CREAL(0.05);
ArmOverBox();
}
else
{
AnimMode = AAction;
JointParamDelta = CREAL(0.1);
ArmPosition = APDiscard;
ArmDiscard();
}
break;
case APDiscard:
AnimMode = AAction;
JointParamDelta = CREAL(0.03);
ArmPosition = APRest;
ArmToRestPosition();
if (DroppedObject)
{
BeginDiscard(DroppedObject);
DroppedObject = NULL;
/* strcpy(DropString, "");
ShowAppRightStatus(Window, Camera, DropString); */
if (CMMode == CMDroppedObject)
{
CMMode = CMDiscardObject;
}
}
break;
case APOverBox:
AnimMode = AAction;
ArmPosition = APInBox;
JointParamDelta = CREAL(0.05);
ArmPutInBox();
break;
case APInBox:
AnimMode = AAction;
ArmPosition = APRelease;
JointParamDelta = CREAL(0.08);
ArmRelease();
break;
case APRelease:
AnimMode = AAction;
JointParamDelta = CREAL(0.03);
ArmPosition = APRest;
ArmToRestPosition();
if (DroppedObject)
{
RwDestroyClump(DroppedObject);
DroppedObject = NULL;
/*
strcpy(DropString, "");
ShowAppRightStatus(Window, Camera, DropString);
*/
if (CMMode == CMDroppedObject)
{
CMMode = CMTrackMouse;
RwInvalidateCameraViewport(Camera);
}
}
break;
}
JointParam = CREAL(0.0);
}
}
else
{
if (DroppedObject)
{
AnimMode = AAction;
ArmPosition = APReach;
ArmReachForPosition(DropX, CREAL(0.0), DropZ);
JointParam = CREAL(0.0);
JointParamDelta = CREAL(0.05);
}
else if ((rand() & 0x3f) == 0x3f)
{
AnimMode = AAction;
ArmPosition = APAlert;
ArmToAlertPosition();
JointParam = CREAL(0.0);
/* JointParamDelta = CREAL(0.08); */
JointParamDelta = CREAL(0.10);
}
else if ((rand() & 0x1f) == 0x1f)
{
AnimMode = AAction;
ArmRotatePosition();
JointParam = CREAL(0.0);
/* JointParamDelta = CREAL(0.05); */
JointParamDelta = CREAL(0.10);
}
}
if ((CMMode == CMDroppedObject) && DroppedObject)
{
RwGetClumpOrigin(DroppedObject, &Origin);
RwSetCameraPosition(Cam, Origin.x, Origin.y, Origin.z);
Origin.x = CREAL(-1.0);
Origin.y = CREAL(0.0);
Origin.z = CREAL(0.0);
RwPushScratchMatrix();
RwGetClumpLTM(DroppedObject, RwScratchMatrix());
RwTransformVector(&Origin, RwScratchMatrix());
RwSetCameraLookAt(Cam, Origin.x, Origin.y, Origin.z);
RwPopScratchMatrix();
}
else if ((CMMode == CMDiscardObject) && DiscardObject)
{
RwGetClumpOrigin(DiscardObject, &Origin);
RwSetCameraPosition(Cam, Origin.x, Origin.y, Origin.z);
RwPushScratchMatrix();
RwGetClumpLTM(DiscardObject, RwScratchMatrix());
Origin.x = CREAL(0.0);
Origin.y = CREAL(0.0);
Origin.z = CREAL(1.0);
RwTransformVector(&Origin, RwScratchMatrix());
RwSetCameraLookAt(Cam, Origin.x, Origin.y, Origin.z);
Origin.x = CREAL(0.0);
Origin.y = CREAL(1.0);
Origin.z = CREAL(0.0);
RwTransformVector(&Origin, RwScratchMatrix());
RwSetCameraLookUp(Cam, Origin.x, Origin.y, Origin.z);
RwPopScratchMatrix();
}
else if (CMMode == CMRobotHand)
{
RwPushScratchMatrix();
RwGetClumpOrigin(FirstFingerTip, &Origin);
RwSetCameraPosition(Cam, Origin.x, Origin.y, Origin.z);
RwGetClumpLTM(FirstFingerTip, RwScratchMatrix());
Origin.x = CREAL(0.0);
Origin.y = CREAL(1.0);
Origin.z = CREAL(0.0);
RwTransformVector(&Origin, RwScratchMatrix());
RwSetCameraLookAt(Cam, Origin.x, Origin.y, Origin.z);
RwGetClumpBBox(FirstFingerTip, &BLL, &FUR);
RwVCMoveCamera(Cam, FUR.x, BLL.y, CREAL(0.0));
RwPopScratchMatrix();
}
else
{
Cam = Camera;
}
RwBeginCameraUpdate(Cam,NULL);
RwClearCameraViewport(Cam);
RwRenderScene(Scene);
RwEndCameraUpdate(Cam);
RwShowCameraImage(Cam,NULL);
}
/****************************************************************************
Main
*/
void main(int nArgc,char *saArgv[])
{
int nKey;
int nMouseX,nMouseY,nMouseBut,nOldMouseBut,nOldMouseX,nOldMouseY;
int nDX,nDY;
int nChange;
int nStatus;
int nCtrlShift;
RwReal naWhite[]={CREAL(1.0),CREAL(1.0),CREAL(1.0)};
RwReal naBlack[]={CREAL(0.0),CREAL(0.0),CREAL(0.0)};
int nWhite;
int nBlack;
/* Stop warnings */
nArgc = nArgc;
saArgv = saArgv;
if (!Init3D())
{
exit(-1);
};
/*
* Parse any command line parameters.
if (!ReadFromCommandLine(nArgc, saArgv))
{
TidyUp3D();
exit(-1);
};
*/
nWhite = RwDeviceControl(rwSCRGETCOLOR,0,naWhite,sizeof(naWhite));
nBlack = RwDeviceControl(rwSCRGETCOLOR,0,naBlack,sizeof(naBlack)),
RwDPointerDisplay(&nOldMouseX,&nOldMouseY,&nOldMouseBut);
/* Create pointer */
nKey = DosGetKey();
nStatus =0;
while (nKey!=27) { /* ESC quits */
RwDPointerDisplay(&nMouseX,&nMouseY,&nMouseBut);
nKey = DosGetKey();
nCtrlShift = DosShiftCtrl();
nDX =(nMouseX-nOldMouseX);
nDY =(nMouseY-nOldMouseY);
nChange = (nMouseBut&(2+8)) | ( (nOldMouseBut&(2+8)) >>1 );
switch (nChange) {
case 0+0:
case 2+1:
case 8+4:
case 8+2+4+1: {
/* No change */
break;
};
case 2:
case 8+2+4: {
/* Left Button Down */
HandleLeftButtonDown(nMouseX,nMouseY,nCtrlShift);
break;
};
case 8:
case 8+2+1: {
/* Right Button Down */
HandleRightButtonDown(nMouseX,nMouseY,nCtrlShift);
break;
};
case 8+1: {
/* Right down left Up */
HandleLeftButtonUp();
HandleRightButtonDown(nMouseX,nMouseY,nCtrlShift);
break;
};
case 2+4: {
/* Right up left Down */
HandleRightButtonUp();
HandleLeftButtonDown(nMouseX,nMouseY,nCtrlShift);
break;
};
case 8+2: {
/* Left down RIght Down */
HandleRightButtonDown(nMouseX,nMouseY,nCtrlShift);
HandleLeftButtonDown(nMouseX,nMouseY,nCtrlShift);
break;
};
case 1+4: {
/* Left up Right Up */
HandleRightButtonUp();
HandleLeftButtonUp();
break;
};
case 1:
case 8+4+1: {
/* Left up */
HandleLeftButtonUp();
break;
};
case 4:
case 2+4+1: {
/* Right up */
HandleRightButtonUp();
break;
};
};
if (nDX||nDY) {
/* Mouse Move */
if (!nStatus) HandleMouseMove(nMouseX,nMouseY);
};
if (nKey) {
HandleChar(nKey);
};
HandleTimer();
nOldMouseX = nMouseX;
nOldMouseY = nMouseY;
nOldMouseBut = nMouseBut;
};
/*
* Tidy up the 3D (RenderWare) components of the application.
*/
TidyUp3D();
exit(0);
}