Another character controll question

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Another character controll question

Postby WarLocker » Tue Sep 01, 2009 11:16 am

I've created my character controller, but it seems wrong. Every frame I have to force rotate my character in X, Y and Z in order to face right direction (in Y) and not fall down(in X, Z). Seems that too much calculations are made: receive x,z rotation , if falling over then unrotate . The UpVector was doing well, but it updates too slow. So do I have to figure out some other way or stick with what I got?
WarLocker
 
Posts: 2
Joined: Tue Sep 01, 2009 11:04 am

Re: Another character controll question

Postby Julio Jerez » Tue Sep 01, 2009 11:31 am

you can use the player controller in SDK 2.08

It offers that basic funtionality already, althogju I need to add some more.
See the Wiki tutorial for 2.0x
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Another character controll question

Postby WarLocker » Mon Oct 19, 2009 5:31 am

Thanks, my physics body is kinda stable now. But I don't have control over it. When I output the state of Player it says: m_onFreeFall, although it slides along the ground just the way I want it. The SetVelocity function becomes useless when in air, can you give some advice or thoughts?
And the other thing - what values are best for maxStairStepFactor and kinematicCushion for a body which is 1.5 units high? Maybe I screwed up with them?
Thanks in adwance
WarLocker
 
Posts: 2
Joined: Tue Sep 01, 2009 11:04 am

Re: Another character controll question

Postby VeT » Sat Oct 24, 2009 6:02 pm

I want to continue this thread.

I'm using Newton 2.10 (the latest that i can get) and in Character controller i have accsses only to this functions
Code: Select all
   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);


Okay, i created body with CreateCustomPlayerController() (my capsule dont fall on its side), but how can i move Character?
I learned about CustomPlayerControllerSetVelocity(), it just calls:
Code: Select all
void CustomPlayerControllerSetVelocity (const NewtonUserJoint* playerController, dFloat forwardSpeed, dFloat sideSpeed, dFloat heading)
{
   ((PlayerController*)playerController)->SetVelocity (forwardSpeed, sideSpeed, heading);
}

and SetVelocity() just sets
Code: Select all
   void CustomPlayerController::SetVelocity (dFloat forwardSpeed, dFloat sideSpeed, dFloat heading)
{
   m_heading = heading;
   m_sideSpeed = sideSpeed;
   m_forwardSpeed = forwardSpeed;
}


Do i need to call SubmitConstraints(), or something else, as my character in lite-c dont react at all at
Code: Select all
   while(1)
   {
      car_camera_move();
      if (key_w) {   CustomPlayerControllerSetVelocity(CharJoint, 500, 1000, 0);}
      wait(1);
   }
1st prize: Lite-C and Newton 2.17 by Vasilenko Vitaliy
LiteC+Newton2 download: http://hosted.filefront.com/NeArGa
LiteC+Newton2 discussion: http://tinyurl.com/6l7y9v
VeT
 
Posts: 84
Joined: Thu Jul 31, 2008 11:31 am

Re: Another character controll question

Postby Julio Jerez » Sat Oct 24, 2009 6:46 pm

Code: Select all
void CustomPlayerControllerSetVelocity (const NewtonUserJoint* playerController, dFloat forwardSpeed, dFloat sideSpeed, dFloat heading)
{
   ((PlayerController*)playerController)->SetVelocity (forwardSpeed, sideSpeed, heading);
}


The the idea is to keep it as simple as possible, after you set it up all you need to do is set upi teh funtion callback and call that function and it will do the trick.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Another character controll question

Postby VeT » Sun Oct 25, 2009 4:10 am

I understand that, but Controller - dont understand that he may move :)

So, i just set another number to heading, sideSpeed and forwardSpeed... but where its called function, that applyes this speed to the Character?
1st prize: Lite-C and Newton 2.17 by Vasilenko Vitaliy
LiteC+Newton2 download: http://hosted.filefront.com/NeArGa
LiteC+Newton2 discussion: http://tinyurl.com/6l7y9v
VeT
 
Posts: 84
Joined: Thu Jul 31, 2008 11:31 am

Re: Another character controll question

Postby VeT » Sun Oct 25, 2009 5:30 am

Code: Select all
   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);
   }


This also dont work at all: controller even dont move.
1st prize: Lite-C and Newton 2.17 by Vasilenko Vitaliy
LiteC+Newton2 download: http://hosted.filefront.com/NeArGa
LiteC+Newton2 discussion: http://tinyurl.com/6l7y9v
VeT
 
Posts: 84
Joined: Thu Jul 31, 2008 11:31 am

Re: Another character controll question

Postby Julio Jerez » Sun Oct 25, 2009 8:36 am

Oh that's because you are calling the function yourself, Newton does not work that way you need to set the callbacks, here is an example how a player is set up
Code: Select all
   // 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);
   }

    These are the control callbacks
    // 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);

Code: Select all
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);

};



as you can set is is tha same funtion you have but you do no call teh joint library call it for you when you set as a funtion callback
static void ApplyPlayerInput (const NewtonUserJoint* me, dFloat timestep, int threadIndex)


this code is part of the Character controll toturial in the wiki, I have no written the text yet because I still nee to add few more funtionality to teh Player
but you can download teh series 200 tororial and see the demo
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Another character controll question

Postby VeT » Mon Oct 26, 2009 4:48 am

Ahh, really, i forgot about Newton tutorials code: i learned CharacterController.cpp from Newton demos.
I have some usexpected troubles, using

Code: Select all
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);

engine crashes with strange error
Error in 'map102.c' line 132: Can not convert 'LONG' to 'VOID'
< CustomSetSubmitContraintCallback(CharJoint, ApplyPlayerInput);
>


Do you have some ideas or recomendations with using callbacks? Any other callback works fine...
1st prize: Lite-C and Newton 2.17 by Vasilenko Vitaliy
LiteC+Newton2 download: http://hosted.filefront.com/NeArGa
LiteC+Newton2 discussion: http://tinyurl.com/6l7y9v
VeT
 
Posts: 84
Joined: Thu Jul 31, 2008 11:31 am

Re: Another character controll question

Postby Carli » Mon Oct 26, 2009 5:30 am

i think it's not a crash - it's a compiler error:
Code: Select all
void ApplyPlayerInput (const NewtonUserJoint* CharJoint, float timestep, int threadIndex)

just try
Code: Select all
long ApplyPlayerInput (const NewtonUserJoint* CharJoint, float timestep, int threadIndex)
Carli
 
Posts: 245
Joined: Fri Oct 02, 2009 5:28 am

Re: Another character controll question

Postby VeT » Wed Oct 28, 2009 4:32 am

Yep, that was my first idea... But the problem is still the same, thats why i'm asking about callbacks... in addition, as i saw, callback functions are always void:
Code: Select all
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));
}


Thats why i dont understand, why joint callback dont works.
1st prize: Lite-C and Newton 2.17 by Vasilenko Vitaliy
LiteC+Newton2 download: http://hosted.filefront.com/NeArGa
LiteC+Newton2 discussion: http://tinyurl.com/6l7y9v
VeT
 
Posts: 84
Joined: Thu Jul 31, 2008 11:31 am

Re: Another character controll question

Postby VeT » Wed Oct 28, 2009 10:04 am

I get some new info

JointLibrary.h, original
Code: Select all
***
   typedef void (*NewtonUserJointSubmitConstraintCallback) (const NewtonUserJoint* me, dFloat timestep, int threadIndex);

   // generic joint functions
***
   JOINTLIBRARY_API void CustomSetSubmitContraintCallback (const NewtonUserJoint *joint, NewtonUserJointSubmitConstraintCallback callback);

The same is in my wrapper's files.... and they crash.

BUT if i change my wrappers files
JointLibrary.h, wrapper
Code: Select all
   typedef long NewtonUserJointSubmitConstraintCallback;

then engine dont crash in
Code: Select all
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);


but, anyway, this dont move character at all :(
1st prize: Lite-C and Newton 2.17 by Vasilenko Vitaliy
LiteC+Newton2 download: http://hosted.filefront.com/NeArGa
LiteC+Newton2 discussion: http://tinyurl.com/6l7y9v
VeT
 
Posts: 84
Joined: Thu Jul 31, 2008 11:31 am

Re: Another character controll question

Postby Julio Jerez » Wed Oct 28, 2009 12:50 pm

Play the demo in teh wiki tutorial, and set it like it is there.
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest