Moderators: Sascha Willems, walaber
JOINTLIBRARY_API NewtonUserJoint *CreateCustomPlayerController (const dFloat* pins, const NewtonBody* player, dFloat maxStairStepFactor, dFloat cushion);
JOINTLIBRARY_API void CustomPlayerControllerSetVelocity (const NewtonUserJoint* playerController, dFloat forwardSpeed, dFloat sideSpeed, dFloat heading);
JOINTLIBRARY_API void CustomPlayerControllerGetVisualMaTrix (const NewtonUserJoint* playerController, dFloat* matrix);
JOINTLIBRARY_API dFloat CustomPlayerControllerGetMaxSlope (const NewtonUserJoint* playerController);
JOINTLIBRARY_API void CustomPlayerControllerSetMaxSlope (const NewtonUserJoint* playerController, dFloat maxSlopeAngleIndRadian);
JOINTLIBRARY_API const NewtonCollision* CustomPlayerControllerGetSensorShape (const NewtonUserJoint* playerController);
void CustomPlayerControllerSetVelocity (const NewtonUserJoint* playerController, dFloat forwardSpeed, dFloat sideSpeed, dFloat heading)
{
((PlayerController*)playerController)->SetVelocity (forwardSpeed, sideSpeed, heading);
}
void CustomPlayerController::SetVelocity (dFloat forwardSpeed, dFloat sideSpeed, dFloat heading)
{
m_heading = heading;
m_sideSpeed = sideSpeed;
m_forwardSpeed = forwardSpeed;
}
while(1)
{
car_camera_move();
if (key_w) { CustomPlayerControllerSetVelocity(CharJoint, 500, 1000, 0);}
wait(1);
}
void CustomPlayerControllerSetVelocity (const NewtonUserJoint* playerController, dFloat forwardSpeed, dFloat sideSpeed, dFloat heading)
{
((PlayerController*)playerController)->SetVelocity (forwardSpeed, sideSpeed, heading);
}
float forwspeed = 0;
float sidespeed = 0;
float headangle = 0;
while(1)
{
car_camera_move();
if (key_w) {forwspeed = 500;}
else {forwspeed = 0;}
if (key_s) {sidespeed = 200;}
else {sidespeed = 0;}
CustomPlayerControllerSetVelocity(CharJoint, forwspeed, sidespeed, headangle);
wait(1);
}
// Create a Body and attach a player controller joint
{
dFloat y0;
Entity* player;
NewtonBody* playerBody;
NewtonCollision* shape;
// find the a floor to place the player
y0 = FindFloor (world, 0.0f, 0.0f) + 1.0f;
// load the player mesh
player = sceneManager->CreateEntity();
player->LoadMesh ("gymnast.dat");
player->m_curPosition.m_y = y0;
player->m_prevPosition = player->m_curPosition;
// get the bounding Box of the player to get the collision shape dimensions
dVector minBox;
dVector maxBox;
player->GetBBox (minBox, maxBox);
// calculate player high and width
dFloat padding = 1.0f / 64.0f; // this si the default padding, for teh palye joint, we must subtract it from the shape
dFloat playerHigh = (maxBox.m_y - minBox.m_y) - padding;
dFloat playerRadius0 = (maxBox.m_z - minBox.m_z) * 0.5f;
dFloat playerRadius1 = (maxBox.m_x - minBox.m_x) * 0.5f;
dFloat playerRadius = (playerRadius0 > playerRadius1 ? playerRadius0 : playerRadius1) - padding;
// No we make and make a upright capsule for the collision mesh
dMatrix orientation;
orientation.m_front = dVector (0.0f, 1.0f, 0.0f, 0.0f); // this is the player up direction
orientation.m_up = dVector (1.0f, 0.0f, 0.0f, 0.0f); // this is the player front direction
orientation.m_right = orientation.m_front * orientation.m_up; // this is the player sideway direction
orientation.m_posit = dVector (0.0f, 0.0f, 0.0f, 1.0f);
// add a body with a box shape
//shape = CreateNewtonCapsule (world, player, playerHigh, playerRadius, m_wood, orientation);
shape = CreateNewtonCylinder (world, player, playerHigh, playerRadius, m_wood, orientation);
playerBody = CreateRigidBody (world, player, shape, 10.0f);
NewtonReleaseCollision (world, shape);
// make sure the player does not go to sleep
NewtonBodySetAutoSleep (playerBody, 0);
// now we will attach a player controller to the body
NewtonUserJoint* playerController;
// the player can take step up to 0.7 units;
dFloat maxStairStepFactor = 0.7f / playerHigh;
playerController = CreateCustomPlayerController (&orientation[0][0], playerBody, maxStairStepFactor, padding);
// set the Max Slope the player can climb to PLAYER_MAX_SLOPE degree
CustomPlayerControllerSetMaxSlope (playerController, PLAYER_MAX_SLOPE * 3.1416f / 180.0f);
// now we will append some application data for the application to control the player
PlayerController* userControl = (PlayerController*) malloc (sizeof (PlayerController));
userControl->m_isThirdView = 1;
userControl->m_point = dVector (0.0f, playerHigh, 0.0f,0.0f);
// set the user data for the application to control the player
CustomSetUserData (playerController, userControl);
// set the destruction call back so that the application can destroy local used data
CustomSetDestructorCallback (playerController, PlayerController::Destroy);
// set a call back to control the player
CustomSetSubmitContraintCallback (playerController, PlayerController::ApplyPlayerInput);
// we also need to set override the transform call back so the we can set the Camera
userControl->m_setTransformOriginal = NewtonBodyGetTransformCallback(playerBody);
NewtonBodySetTransformCallback (playerBody, PlayerController::SetTransform);
// we will need some ID to fin this joint in the transform Callback
CustomSetJointID (playerController, PLAYER_JOINT_ID);
}
Here is the data structure that control a player and keep all the player data
#define PLAYER_SPEED 10.0f
#define PLAYER_SIDE_SPEED 5.0f
#define PLAYER_JOINT_ID 0xEF38AB01
#define PLAYER_MAX_SLOPE 30.0f
struct PlayerController
{
// destructor to be call when the joint is destroyed
static void Destroy (const NewtonUserJoint* me)
{
PlayerController* path;
path = (PlayerController*) CustomGetUserData(me);
free (path);
}
// apply desire user control
static void ApplyPlayerInput (const NewtonUserJoint* me, dFloat timestep, int threadIndex)
{
dFloat velocity;
dFloat strafeVeloc;
dFloat headinAngle;
PlayerController* controller;
controller = (PlayerController*) CustomGetUserData(me);
velocity = 0;
if (IsKeyDown ('W')) {
velocity = PLAYER_SPEED;
} else if (IsKeyDown ('S')) {
velocity = -PLAYER_SPEED;
}
strafeVeloc = 0.0f;
if (IsKeyDown ('D')) {
strafeVeloc = PLAYER_SIDE_SPEED;
} else if (IsKeyDown ('A')) {
strafeVeloc = -PLAYER_SIDE_SPEED;
}
// now set the desired player velocity and heading
headinAngle = GetCameraYawAngle ();
// prevent player fro running faster when strafing and moving forward as the same time
dFloat mag2 = velocity * velocity + strafeVeloc * strafeVeloc;
if (mag2 > PLAYER_SPEED * PLAYER_SPEED) {
mag2 = PLAYER_SPEED * dSqrt (1.0f / mag2);
velocity *= mag2;
strafeVeloc *= mag2;
}
CustomPlayerControllerSetVelocity (me, velocity, strafeVeloc, headinAngle);
}
static void SetTransform (const NewtonBody* body, const dFloat* matrix, int threadId)
{
NewtonUserJoint* player;
PlayerController* controller;
// find the player joint;
player = NULL;
for (NewtonJoint* joint = NewtonBodyGetFirstJoint(body); joint; joint = NewtonBodyGetNextJoint(body, joint)) {
NewtonUserJoint* tmp;
tmp = (NewtonUserJoint*) NewtonJointGetUserData(joint);
if (CustomGetJointID (tmp) == PLAYER_JOINT_ID) {
player = tmp;
break;
}
}
// call the generic transform callback
controller = (PlayerController*) CustomGetUserData(player);
#if 1
// this will project the visual mesh to the ground
dMatrix visualMatrix;
CustomPlayerControllerGetVisualMaTrix (player, &visualMatrix[0][0]);
#else
// this will display the player at the collision shape position
const dMatrix& visualMatrix = *((dMatrix*) matrix);
#endif
controller->m_setTransformOriginal (body, &visualMatrix[0][0], threadId);
// now we will set the camera to follow the player
dVector eyePoint (visualMatrix.TransformVector(controller->m_point));
// check if the player wants third person view
static int prevCKeyDown = IsKeyDown ('C');
int isCkeyDwon = IsKeyDown ('C');
if (isCkeyDwon && !prevCKeyDown) {
controller->m_isThirdView = !controller->m_isThirdView;
}
prevCKeyDown = isCkeyDwon;
if (controller->m_isThirdView) {
dVector dir (GetCameraDir ());
eyePoint -= dir.Scale (8.0f);
}
SetCameraEyePoint (eyePoint);
// NewtonBodyGetMatrix (body, &matrix[0][0]);
// cameraEyepoint = matrix.m_posit;
// cameraEyepoint.m_y += 1.0f;
}
int m_isThirdView;
dVector m_point;
void (*m_setTransformOriginal) (const NewtonBody* body, const dFloat* matrix, int threadIndex);
};
void ApplyPlayerInput (const NewtonUserJoint* CharJoint, float timestep, int threadIndex)
{
// if (key_w) {forwspeed = 500;}
// else {forwspeed = 0;}
// if (key_s) {sidespeed = 200;}
// else {sidespeed = 0;}
CustomPlayerControllerSetVelocity(CharJoint, 100.0, 0.0, 0.0);
}
******
CharJoint = CreateCustomPlayerController (globalFrame, rigidBody, maxStairStepFactor, kinematicCushion);
CustomSetJointID(CharJoint, PLAYER_JOINT_ID);
CustomPlayerControllerSetMaxSlope(CharJoint, 0.6478);
// CustomSetUserData (CharJoint, CharJoint);
// CustomSetDestructorCallback(CharJoint, Destruction);
CustomSetSubmitContraintCallback(CharJoint, ApplyPlayerInput);
Error in 'map102.c' line 132: Can not convert 'LONG' to 'VOID'
< CustomSetSubmitContraintCallback(CharJoint, ApplyPlayerInput);
>
void ApplyPlayerInput (const NewtonUserJoint* CharJoint, float timestep, int threadIndex)
long ApplyPlayerInput (const NewtonUserJoint* CharJoint, float timestep, int threadIndex)
void PhysicsSetTransformCallback (const NewtonBody* body, const dFloat* matrix, int threadIndex)
{
// get the graphic entity form the rigid body
ENTITY *entity = (ENTITY*)NewtonBodyGetUserData(body);
// set the transformation matrix for this rigid body
ent_setmatrix_rb(entity, matrix);
}
void PhysicsSetOnforceCallback(NewtonBody* body)
{
float mass, ixx, iyy, izz;
NewtonBodyGetMassMatrix(body, &mass, &ixx, &iyy, &izz);
NewtonBodySetForce(body, vectorf(0, 0, -9.8 * mass));
}
***
typedef void (*NewtonUserJointSubmitConstraintCallback) (const NewtonUserJoint* me, dFloat timestep, int threadIndex);
// generic joint functions
***
JOINTLIBRARY_API void CustomSetSubmitContraintCallback (const NewtonUserJoint *joint, NewtonUserJointSubmitConstraintCallback callback);
typedef long NewtonUserJointSubmitConstraintCallback;
long ApplyPlayerInput (const NewtonUserJoint* CharJoint, float timestep, int threadIndex)
{
if (key_w) {forwspeed = 1000;}
else {forwspeed = 0;}
if (key_s) {sidespeed = 200;}
else {sidespeed = 0;}
CustomPlayerControllerSetVelocity(CharJoint, forwspeed, sidespeed, headangle);
}
***
CustomSetSubmitContraintCallback(CharJoint, ApplyPlayerInput);
Users browsing this forum: No registered users and 2 guests