Ok Matty, one more thing (for now -
).
The code below is a modified version of your babe.x sample:
// In this example we will look at getting your character walking around a level
// using a character controller, this is a special kind of kinematic dynamic actor.
// Because it is kinematic it is not affected by forces, it is designed to give you
// direct control over your characters. There are two types of controller, capsule
// and box, both have slightly different characteristics but basically do the same
// thing.
#include "DarkGDK.h"
#include "FulcrumPhy.h"
#define BABE_MOVE 1
#define WORLD_MAP 2
#define BABE_ATTACK 3
static int CURR_ANIM=1;
void controlCharacter(int objectID, float turnSpeed, float walkSpeed, float gravity);
void updateAnimation(int objectID, int firstFrame, int lastFrame);
void updateCamera(int objectID, float distance, float height, float smooth);
void ChangeAnimation( void );
FulcrumPhy myPhysics;
void DarkGDK ( void )
{
myPhysics.start(true);
myPhysics.setGravity( 0, -1.0f, 0 );
dbSyncOn ( );
dbSyncRate ( 60 );
dbRandomize ( dbTimer ( ) );
/* BABE_MOVE Setup */
dbLoadObject("Media//H-Babe-Move.x", BABE_MOVE);
// Here, I will show how to make both types of controllers, for each type there are
// two overloads for the respective 'make' functon, one tries to set up your character
// size and offset along the y-axis automatically while the other gives you a little
// more control. The box controller below uses the first way while the capsule controller
// uses the second.
// With the capsule controller we move the object so that its local(0, 0, 0)
// co-ordinate is in its centre and not at its feet, we do this using dbOffsetLimb(), passing
// in limb 0 as the limb parameter. The box controller does not need this in this particular
// example.
myPhysics.makeControllerCapsule(BABE_MOVE, 0.1, 45, dbObjectSizeX(1), dbObjectSizeY(1));
myPhysics.positionCharacterController(BABE_MOVE, 0, 5, 0);
dbOffsetLimb(BABE_MOVE,0,0,-dbObjectSizeY(BABE_MOVE)/2,0); //Not needed for box controller in this example.
/* WORLD_MAP Setup */
dbLoadObject("Media//TestLevel//TestMap.dbo", WORLD_MAP);
dbScaleObject(WORLD_MAP, 10, 10, 10);
myPhysics.makeTriangleMeshFromDBO(WORLD_MAP);
/* BABE_ATTACK Setup */
dbLoadObject("Media//H-Babe-Attack1.x", BABE_ATTACK);
dbOffsetLimb(BABE_ATTACK,0,0,-dbObjectSizeY(BABE_ATTACK)/2,0);
dbHideObject(BABE_ATTACK);
/* Add a few "Kick-Balls" */
for (int i=50; i>BABE_ATTACK; i--) {
dbMakeObjectSphere(i, 1, 12, 12);
dbColorObject(i, dbRGB(dbRND(255), dbRND(255), dbRND(255)));
dbPositionObject(i, dbRND(10), dbRND(10), dbRND(10));
myPhysics.makeSphere(i, true, (float) dbRND(9) + 1.0f);
}
myPhysics.simulate();
while ( LoopGDK ( ) )
{
myPhysics.getPhysicsResults();
if (dbSpaceKey() == 1)
{
ChangeAnimation();
myPhysics.simulate();
continue;
}
controlCharacter(CURR_ANIM, .50f, 0.1f, -0.3f);
updateAnimation(CURR_ANIM, 4, 26);
myPhysics.updateActors();
myPhysics.updateControllers();
updateCamera(CURR_ANIM, 4, 1, 10);
myPhysics.simulate();
dbSync ( );
}
myPhysics.stop();
return;
}
void ChangeAnimation( void )
{
float x=dbObjectPositionX(CURR_ANIM);
float y=dbObjectPositionY(CURR_ANIM);
float z=dbObjectPositionZ(CURR_ANIM);
float xx=dbObjectAngleX(CURR_ANIM);
float yy=dbObjectAngleY(CURR_ANIM);
float zz=dbObjectAngleZ(CURR_ANIM);
dbHideObject(CURR_ANIM);
CURR_ANIM = (CURR_ANIM == 1) ? 3 : 1;
dbPositionObject(CURR_ANIM, x, y, z);
dbRotateObject(CURR_ANIM, xx, yy, zz);
dbShowObject(CURR_ANIM);
myPhysics.swapObject( 1, CURR_ANIM );
}
void controlCharacter(int id, float turnSpeed, float walkSpeed, float gravity)
{
// if(dbLeftKey())
// dbRotateObject(id, 0, dbObjectAngleY(id) - turnSpeed, 0);
// if(dbRightKey())
// dbRotateObject(id, 0, dbObjectAngleY(id) + turnSpeed, 0);
// if(dbUpKey())
// walkSpeed = -walkSpeed;
// else if(dbDownKey())
// walkSpeed = walkSpeed;
//else
// walkSpeed = 0.0f;
// //myPhysics.moveCharacterController(id, walkSpeed, gravity);
// myPhysics.moveCharacterController(id, 1,0, 0);
float speed = 0;
/* Rotating is OK... */
if (dbLeftKey())
dbRotateObject(id, 0, dbObjectAngleY(id) - 2, 0);
if (dbRightKey())
dbRotateObject(id, 0, dbObjectAngleY(id) + 2, 0);
if (id == 1) {
// KEYS
if (dbUpKey())
speed = -0.2;
if (dbDownKey())
speed = 0.2;
// Move controller
// Controller is not controlled by physics so you need to add gravity yourself
//float gravity = -0.5;
float angleY = dbObjectAngleY(id);
float moveX = dbSin(angleY); // Calculate X component
float moveZ = dbCos(angleY); // Calculate Z component
myPhysics.moveCharacterController(1, moveX * speed, gravity, moveZ * speed);
}
}
void updateCamera(int id, float distance, float height, float smooth)
{
dbSetCameraToFollow(dbObjectPositionX(id), //PositionX
dbObjectPositionY(id), //PositionY
dbObjectPositionZ(id), //PositionZ
dbObjectAngleY(id) + 180, //Angle
distance, //Distance
height, //Height
smooth, //Smooth
0); //Collision
dbRotateCamera(0, dbObjectAngleY(id) + 180, 0);
}
void updateAnimation(int id, int firstFrame, int lastFrame)
{
if(dbUpKey())
dbSetObjectFrame(id, dbObjectFrame(id) + 1);
if(dbDownKey())
dbSetObjectFrame(id, dbObjectFrame(id) - 1);
if(dbObjectFrame(id) > lastFrame)
dbSetObjectFrame(id, firstFrame);
if(dbObjectFrame(id) < firstFrame)
dbSetObjectFrame(id, lastFrame);
}
Now the purpose of this "test" is multi-fold:
1) Change her animation at will (MOVE/ATTACK). This is working somewhat flawlessly (SPACE_BAR)
2) Make sure the physics still applies to the new animation. This does not appear to be working. I assume it has something to do with the shape/size of the controller - but not quite sure - I use the swapObject() method to tell the controller which object it's working with.
Anyway, the problem I seem to be having is this:
Once the balls settle down (stop moving), I can't get the collisions to make them move again. I assume I can use the ApplyForce() methods to start moving them again, but how do I know which object to apply the force to? That is, which ball is she kicking? Or, when walking, which ball has she bumped into?
I don't see any way of garnering such information from the myPhysics class instance... Or is this not the way to achieve those results?
JTK