Box2d FixedRotation Bug ?

BlitzMax Forums/Brucey's Modules/Box2d FixedRotation Bug ?

Armitage 1982(Posted 2008) [#1]
Hi Brucey

I'm having trouble with a special case.


When using FixedRotation with my main character collision points won't correctly work with ascending diagonals static shapes (descending diagonals, horizontal, vertical or other object shapes work correctly).

I've try bodyDef.SetisBulet(true), ensure a counter-clockwise from every points, Changing TSetting (hz or iterationCount) without success.

This only happen with b2PolygonDef (circle one work very well) and as you can see on the screenshot only happen when bodyDef.SetFixedRotation(True)

I know the down-left corner point never cross the diagonals ground.
This also happen with shapeDef.SetAsBox created bodies so it's probably not a vertices construction problem.

I wonder if you could take a look at SetFixedRotation (or ...) for eventual bugs.
So I can ask in the Box2d forum about this bug.

This may be my fault... But I can't see it either.


Armitage 1982(Posted 2008) [#2]
I successfully reproduce this bug in a testbed example :
SuperStrict

Framework BaH.Box2d
Import BRL.GLMax2D

Import "test.bmx"


Graphics 800,600, 0
SetBlend alphablend


Run(New ApplyForce.Create(), New TSettings)


Type ApplyForce Extends Test

	Field m_body:b2Body


	Method Create:ApplyForce()
	
		Init()
						
		m_world.SetGravity(New b2Vec2.Create(0.0, 0.0))

		Local bodyDef:b2BodyDef = New b2BodyDef
		Local specialWall:b2PolygonDef = New b2PolygonDef
		Local v:b2Vec2[] = New b2Vec2[4]
		
		' fail with negative (counter-clockwise)
		v[0] = Vec2(10.0, - 2.0)
		v[1] = Vec2(2.0, - 9.0)
		v[2] = Vec2(2.0, - 10.0)
		v[3] = Vec2(10.0, - 3.0)
		
		specialWall.SetVertices(v)
		bodyDef.SetPosition(New b2Vec2.Create(- 5.0, 0.0))
		m_world.CreateBody(bodyDef).CreateShape(specialWall)
		
		' fait with positive (counter-clockwise)
		v[3] = Vec2(10.0, 9.0)
		v[2] = Vec2(2.0, 2.0)
		v[1] = Vec2(2.0, 3.0)
		v[0] = Vec2(10.0, 10.0)

		specialWall.SetVertices(v)
		bodyDef.SetPosition(New b2Vec2.Create(- 5.0, 0.0))
		m_world.CreateBody(bodyDef).CreateShape(specialWall)
		
			
		Local bd:b2BodyDef = New b2BodyDef
		Local sd1:b2PolygonDef = New b2PolygonDef

		sd1.SetAsBox(1, 1)

'		event this won't do it
'		Local vertices:b2Vec2[] = New b2Vec2[4]
'		vertices[0] = Vec2(0.0, 0.0)
'		vertices[1] = Vec2(1.0, 0.0)
'		vertices[2] = Vec2(1.0, 2.0)
'		vertices[3] = Vec2(0.0, 2.0)
'		sd1.SetVertices(vertices)

		sd1.SetDensity(4.0)
		sd1.SetRestitution(0.25)
		sd1.SetFriction(0.01)

		bd = New b2BodyDef
		bd.SetFixedRotation(True)

		bd.SetPosition(New b2Vec2.Create(0.0, 0.0))
		m_body = m_world.CreateBody(bd)
		m_body.CreateShape(sd1)
		m_body.SetMassFromShapes()
		
		Return Self
	End Method
	
	Method Keyboard()
		Super.Keyboard()
		
		Local p:b2Vec2 = m_body.GetWorldPoint(New b2Vec2.Create(0.0, 0.0))
		If KeyDown(KEY_UP) Then
			m_body.ApplyForce(New b2Vec2.Create(0, 200), p)
		End If

		If KeyDown(KEY_LEFT)
			m_body.ApplyForce(New b2Vec2.Create(- 200, 0), p)
		End If

		If KeyDown(KEY_RIGHT)
			m_body.ApplyForce(New b2Vec2.Create(200, 0), p)
		End If

		If KeyDown(KEY_DOWN)
			m_body.ApplyForce(New b2Vec2.Create(0, - 200), p)
		End If

	End Method

End Type


And I try to reproduce this bug in the C++ TestBed of Box2d but everything work as intended !
ApplyForce.h file modified :
/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* This software is provided 'as-is', without any express or implied
* warranty.  In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

#ifndef APPLY_FORCE_H
#define APPLY_FORCE_H

class ApplyForce : public Test
{
public:
	ApplyForce()
	{
		m_world->SetGravity(b2Vec2(0.0f, 0.0f));

		{
			b2BodyDef bd;
			bd.position.Set(0.0f, 10.0f);
			b2Body* ground = m_world->CreateBody(&bd);

			b2PolygonDef sd;
			sd.vertexCount = 4;
			sd.vertices[0] = b2Vec2(10.0f, -2.0f);
			sd.vertices[1] = b2Vec2(2.0f, -9.0f);
			sd.vertices[2] = b2Vec2(2.0f, -10.0f);
			sd.vertices[3] = b2Vec2(10.0f, -3.0f);

			ground->CreateShape(&sd);

			sd.vertices[0] = b2Vec2(10.0f, 10.0f);
			sd.vertices[1] = b2Vec2(2.0f, 3.0f);
			sd.vertices[2] = b2Vec2(2.0f, 2.0f);
			sd.vertices[3] = b2Vec2(10.0f, 9.0f);
			bd.position.Set(0.0f, 10.0f);
			ground->CreateShape(&sd);

		}

		{
			b2PolygonDef sd1;
			sd1.SetAsBox(1.0f,1.0f);
//			sd1.vertexCount = 4;
//			sd1.vertices[0] = b2Vec2(0.0f, 0.0f);
//			sd1.vertices[1] = b2Vec2(1.0f, 0.0f);
//			sd1.vertices[2] = b2Vec2(1.0f, 2.0f);
//			sd1.vertices[3] = b2Vec2(0.0f, 2.0f);

			sd1.density = 2.0f;
			
			b2BodyDef bd;
			bd.angularDamping = 2.0f;
			bd.linearDamping = 0.1f;

			bd.fixedRotation = true;

			bd.position.Set(0.0f, 5.0f);
			bd.angle = b2_pi;
			m_body = m_world->CreateBody(&bd);
			m_body->CreateShape(&sd1);
			m_body->SetMassFromShapes();
		}
	}

	void Keyboard(unsigned char key)
	{
		switch (key)
		{
		case 'i':
			{
				b2Vec2 f = m_body->GetWorldVector(b2Vec2(0.0f, -400.0f));
				b2Vec2 p = m_body->GetWorldPoint(b2Vec2(0.0f, 0.0f));
				m_body->ApplyForce(f, p);
			}
			break;

		case 'k':
			{
				b2Vec2 f = m_body->GetWorldVector(b2Vec2(0.0f, 400.0f));
				b2Vec2 p = m_body->GetWorldPoint(b2Vec2(0.0f, 0.0f));
				m_body->ApplyForce(f, p);
			}
			break;

		case 'j':
			{
				b2Vec2 f = m_body->GetWorldVector(b2Vec2(400.0f, 0.0f));
				b2Vec2 p = m_body->GetWorldPoint(b2Vec2(0.0f, 0.0f));
				m_body->ApplyForce(f, p);
			}
			break;

		case 'l':
			{
				b2Vec2 f = m_body->GetWorldVector(b2Vec2(-400.0f, 0.0f));
				b2Vec2 p = m_body->GetWorldPoint(b2Vec2(0.0f, 0.0f));
				m_body->ApplyForce(f, p);
			}
			break;
		}
	}

	static Test* Create()
	{
		return new ApplyForce;
	}

	b2Body* m_body;
};

#endif


Erin tells me
-"There was a bug with polygon collision in a pre-2.0 version."
So maybe you need to update you SVN code ?


Brucey(Posted 2008) [#3]
It's very strange indeed!

Interestingly, even if you make a "box", and change its angle from horizontal, it doesn't seem to work properly.

The code is a very recent version from SVN... but I'll update it all anyway and see if it helps.
It's as if it simply doesn't "see" the angled edges...


Brucey(Posted 2008) [#4]
Well, this is strange...



Running the latest box2d... copy/pasted your c++, rebuilt, and... oops.

But you say it works when you try it?


Armitage 1982(Posted 2008) [#5]
Hum yeah it's working with my 2.0.1 version (yours is 2.0.2 as I can see).

This is very strange indeed !
I will try to reproduce this with 2.0.2 and see what's happen :)


Brucey(Posted 2008) [#6]
Maybe SVN code is broken...

I also built it with Codeblocks (MinGW).


I suppose I need to try the module running against the current "release" instead.


Armitage 1982(Posted 2008) [#7]
Well I will try to rebuild this example with 2.0.2 as soon as MS VS2008 express is downloaded (I was using MS VS2005).
If the problem occur with VC8 I will inform you.

I don't know if there is strong differences between 2.0.1 and 2.0.2
Maybe it's broken yeah...


Armitage 1982(Posted 2008) [#8]
Ok
This bug is present with Box2D 2.0.2 and not with 2.0.1.
I will create a topic in Box2D Forum to report that bug and see what we can do.


Armitage 1982(Posted 2008) [#9]
Syncing b2CollidePoly.cpp to rev 142 correct the bug.
This is the temporary solution find by Erin.


Brucey(Posted 2008) [#10]
That seems to work great. Thanks for your efforts :-)

I've committed the latest from the box2d SVN and rev 142 of that file.

:o)