Box2D Forums

It is currently Wed May 22, 2013 6:01 pm

All times are UTC - 8 hours [ DST ]




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Thu Aug 07, 2008 4:26 pm 
Offline

Joined: Thu Jul 17, 2008 11:24 am
Posts: 54
Hi,
i have a problem with rotation of a charcter controller in no-horizontale plane. an image will explain better than me ^^ :
Attachment:
File comment: problem
problem.JPG
problem.JPG [ 4.15 KiB | Viewed 2171 times ]

this is the code i use to limit rotation:
Code:
//limiting rotation of the body

//applying torque to adjuste the rotation
float timeStepLengthInSeconds = 1 / 60,
   timeStepsPerSecond = 60;
float maximumPossibleTorque = 20000;
float torqueAdjustment = 3.f;
float desiredAngle = 0;
float angleNow = body->GetAngle();
float changeExpected = body->GetAngularVelocity() * timeStepLengthInSeconds; //expected angle change in next timestep
float angleNextStep = angleNow + changeExpected;
float changeRequiredInNextStep = desiredAngle - angleNextStep;
float rotationalAcceleration = timeStepsPerSecond * changeRequiredInNextStep;
float torque = rotationalAcceleration * torqueAdjustment;
if ( torque > maximumPossibleTorque )
torque = maximumPossibleTorque;
body->ApplyTorque(torque);

//the rotation must in the range[-0.15, 0.15]
if(body->GetAngle() > 0.15f) body->SetXForm(body->GetPosition(), 0.15f); //0.15 arbirary
if(body->GetAngle() < -0.15f) body->SetXForm(body->GetPosition(), -0.15f);

thanks for your help, see you soon :)


Top
 Profile  
 
PostPosted: Thu Aug 07, 2008 5:44 pm 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1517
Location: Tokyo
It would be helpful if you could say what the current behaviour of this code is. One thing that jumps out at me is that:

float timeStepLengthInSeconds = 1 / 60;

will result in the value float timeStepLengthInSeconds becoming zero. Perhaps you mean:

float timeStepLengthInSeconds = 1 / 60.0f;
or
float timeStepLengthInSeconds = 1 / (float)60;

Try stepping through the code as it runs and check if everything makes sense.


Top
 Profile  
 
PostPosted: Thu Aug 07, 2008 9:56 pm 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1517
Location: Tokyo
I made a testbed entry to show how that code should work:
Attachment:
CharacterRotation.rar [206.82 KiB]
Downloaded 158 times

I've included the source and also build of the testbed so you can just run it if you like.

The initial values for the maximum torque and speed are set quite low, so the correction is weak. You can adjust these with the keyboard as mentioned in the top left of the screen. I've found that increasing them at about the same rate gives the most reasonable looking reaction.

You can get a feel for how the correction reacts by yanking the character around with the mouse, but I also put a couple of spinning things to whack the character to give a better idea of how it would react when hit, rather than pulled around.

If you swing the character block around very quickly you can get it into a state where the rotation corrections cause it to 'explode' and never reach a settled state. Not too sure what to do about that yet...
Attachment:
rotation.png
rotation.png [ 3.02 KiB | Viewed 2164 times ]


Last edited by irresistible force on Fri Aug 08, 2008 10:34 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Fri Aug 08, 2008 5:36 am 
Offline

Joined: Thu Jul 17, 2008 11:24 am
Posts: 54
irresistible force wrote:
It would be helpful if you could say what the current behaviour of this code is. One thing that jumps out at me is that:

float timeStepLengthInSeconds = 1 / 60;

will result in the value float timeStepLengthInSeconds becoming zero. Perhaps you mean:

float timeStepLengthInSeconds = 1 / 60.0f;
or
float timeStepLengthInSeconds = 1 / (float)60;

Try stepping through the code as it runs and check if everything makes sense.
i made this mistake only when pasete the code into the forum.
i wil try your testbed, ;)


Top
 Profile  
 
PostPosted: Fri Aug 08, 2008 6:02 am 
Offline

Joined: Thu Jul 17, 2008 11:24 am
Posts: 54
i have deleted that:
Code:
//the rotation must in the range[-0.15, 0.15]
if(body->GetAngle() > 0.15f) body->SetXForm(body->GetPosition(), 0.15f); //0.15 arbirary
if(body->GetAngle() < -0.15f) body->SetXForm(body->GetPosition(), -0.15f);

ad that's what i get now:
Attachment:
File comment: rotation problem
rotation.jpg
rotation.jpg [ 1.63 KiB | Viewed 2137 times ]


Top
 Profile  
 
PostPosted: Fri Aug 08, 2008 7:10 am 
Offline

Joined: Thu Jul 17, 2008 11:24 am
Posts: 54
in fact i wanna get something like that: http://adventuresoftinger.com/


Top
 Profile  
 
PostPosted: Fri Aug 08, 2008 12:26 pm 
Offline

Joined: Thu Jul 17, 2008 11:24 am
Posts: 54
wasn't i clear?


Top
 Profile  
 
PostPosted: Fri Aug 08, 2008 1:35 pm 
Offline

Joined: Mon Jan 07, 2008 10:51 am
Posts: 1911
Your code needs some tweaking. Firstly, you only limit maximun torque in one direction, you need to check for large negative values too.
Secondly, you don't fit changeRequiredInNextStep in the range [-pi,pi], so if your character does a somersault, then he will afterwards have a constant pull for him to undo the somersault, rather than stand up straight. Box2D does not normalize rotation within a fixed range for you.

But i'd keep on trying to tweak the parameters. I should imagine you can make someone stand on sloped surfaces decently with tecnique. I suspect Tinger does something more complex, and ad hoc, so I wouldn't aim to reproduce that.


Top
 Profile  
 
PostPosted: Fri Aug 08, 2008 2:33 pm 
Offline

Joined: Thu Jul 17, 2008 11:24 am
Posts: 54
i want just to precise, this code isn't from me, it's "irresistible force" 's code: viewtopic.php?f=3&t=1232


Top
 Profile  
 
PostPosted: Fri Aug 08, 2008 10:30 pm 
Offline

Joined: Tue Jun 24, 2008 8:25 pm
Posts: 1517
Location: Tokyo
Yes this is the method I am using to make my character stand up straight, I posted the pseudo code in another thread recently. Since maroxe could not quite get it working, I made an entry for the testbed so there could be no doubt about how it works, and the real code (not pseudo) could be studied.
I thought maroxe could use the testbed entry and plug in the values of his character to try it out.

Boris thankyou for the pointers. I should put my code up for proof-reading more often :D Fixing those has cured the 'explosion' problem I was talking about. Here is what the code should be:
Code:
      //correct rotation of character main body
      float desiredCharacterBodyAngle = m_desiredAngle * b2_pi / 180.0f;
      float angleNow = m_characterBody->GetXForm().R.GetAngle();
      float changeExpected = m_characterBody->GetAngularVelocity() / settings->hz;
      float angleNextStep = angleNow + changeExpected;
      float changeRequiredInNextStep = desiredCharacterBodyAngle - angleNextStep;
      while ( changeRequiredInNextStep > b2_pi )
         changeRequiredInNextStep -= 2 * b2_pi;
      while ( changeRequiredInNextStep < -b2_pi )
         changeRequiredInNextStep += 2 * b2_pi;
      float rotationalAcceleration = settings->hz * changeRequiredInNextStep;
      float torque = m_characterBody->GetMass() * rotationalAcceleration * m_correctionSpeed;
      if ( torque > m_correctionTorqueMax )
         torque = m_correctionTorqueMax;
      else if ( torque < -m_correctionTorqueMax )
         torque = -m_correctionTorqueMax;
      m_characterBody->ApplyTorque(torque);


I have updated the download above.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 8 hours [ DST ]


Who is online

Users browsing this forum: Bing [Bot], Exabot [Bot] and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group