//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

#include "giofx.h"

#ifdef USE_BOX2D

#define DEFAULT_GRAVITY	 9.81 

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

class MyContactListener : public b2ContactListener
{
public:

	void BeginContact(b2Contact* contact)
	{
		b2Fixture* bFixA = contact->GetFixtureA();
		b2Fixture* bFixB = contact->GetFixtureB();
		ContactResponder(NULL,bFixA->GetBody(),bFixB->GetBody());
        
	}
};

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
b2Vec2 cScene::PhysicScreenToWorld(float xx, float yy,bool useCamPos)
{
	float32 u = xx / float32(resolutionX);
	float32 v = yy / float32(resolutionY);

    cVertex t_extents = GetExtents();
    b2Vec2 extents(t_extents.x,t_extents.y);
    
	float viewZoom = 1.0f;
	extents *= viewZoom;
	b2Vec2 viewCenter(0.0f, 0.0f);
	
	b2Vec2 lower = viewCenter - extents;
	b2Vec2 upper = viewCenter + extents;
    
	b2Vec2 p;
	p.x = (1.0f - u) * lower.x + u * upper.x;
	p.y = (1.0f - v) * lower.y + v * upper.y;

    if (useCamPos)
        p.y -= this->position.y;
    
	return p;
}
/*
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::PhysicAddSpringForce(b2Body* bA , b2Body* bB , float k , float friction , float desiredDist)
      {
         //var pA:b2Vec2 = new b2Vec2();
         //var pB:b2Vec2 = new b2Vec2();
         //var diff:b2Vec2 = new b2Vec2();

         
         b2Vec2 pA      = bA->GetPosition();
         b2Vec2 pB      = bB->GetPosition();
         b2Vec2 diff    = b2Vec2(pB.x-pA.x , pB.y-pA.y);

         b2Vec2 vA = bA->m_linearVelocity;
         b2Vec2 vB = bB->m_linearVelocity;

         var vdiff:b2Vec2 = new b2Vec2(vB.x-vA.x , vB.y-vA.y);
         
         var dx:Number = diff.Normalize(); //normalizes diff and puts length into dx
         var vrel:Number = vdiff.x*diff.x + vdiff.y*diff.y;
         var forceMag:Number = -k*(dx-desiredDist) - friction*vrel;
         
         //diff.mulLocal(forceMag); // diff *= forceMag
         diff.x *= forceMag;
         diff.y *= forceMag;
         
         bB.ApplyForce(diff , bA.GetPosition());
         
         var diff2:b2Vec2 = new b2Vec2(diff.x *=-1 , diff.y *=-1);
         
         bA.ApplyForce(diff2 , bB.GetPosition());
         //bA.applyForce(diff.mulLocal(-1.0) , bB.GetPosition());
         
         bA.WakeUp();
         bB.WakeUp();
      }
*/
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cScene::PhysicStart(float gravityX,float gravityY,float stepSimulation)
{
	b2Vec2 gravity(gravityX, gravityY); 
	world = new b2World(gravity);

    float block_len  = 5.0;
    float block_dim  = 0.50;
	timeStep = stepSimulation; 
	velocityIterations = 6;
	positionIterations = 6;	

    cVertex extents = GetExtents();

    float boundX = extents.x + (block_dim);
    float boundY = extents.y + (block_dim);

#ifdef FULLRES_DEVICE

    #ifdef FULLRES_DEVICE_DEPRECATED

        boundX = extents.x * 2.0;
        boundY = extents.y * 2.0;
    
        if (extents.x == 1.5f)                  //ipad
            boundX = extents.x * 2.0 - 0.30;
        else if (extents.x == 1.7f)             //iphone3/4
            boundX = extents.x * 2.0 - 0.50;
        else if (extents.x == 2.0f)             //iphone5/6/+
            boundX = extents.x * 2.0 - 0.80;
    
    #endif
    
#endif


    //bottom
	{
		b2BodyDef groundBodyDef;
		groundBodyDef.position.Set(0.0f, -boundY);
		m_boundBody[0] = world->CreateBody(&groundBodyDef);
		b2PolygonShape groundBox;
		groundBox.SetAsBox(block_len, block_dim);
		b2FixtureDef fixtureDef;
		fixtureDef.shape = &groundBox;
		m_boundBody[0]->CreateFixture(&fixtureDef);
	}
	
    //top
	{
		b2BodyDef groundBodyDef;
		groundBodyDef.position.Set(0.0f, +boundY);
		m_boundBody[1] = world->CreateBody(&groundBodyDef);
		b2PolygonShape groundBox;
		groundBox.SetAsBox(block_len, block_dim);
		b2FixtureDef fixtureDef;
		fixtureDef.shape = &groundBox;
		m_boundBody[1]->CreateFixture(&fixtureDef);
	}

    //left
	{
		b2BodyDef groundBodyDef;
		groundBodyDef.position.Set(-boundX, 0);
		m_boundBody[2] = world->CreateBody(&groundBodyDef);
		b2PolygonShape groundBox;
		groundBox.SetAsBox(block_dim, block_len);
		b2FixtureDef fixtureDef;
		fixtureDef.shape = &groundBox;
		m_boundBody[2]->CreateFixture(&fixtureDef);
	}
    
	//right
	{
		b2BodyDef groundBodyDef;
		groundBodyDef.position.Set(+boundX, 0);
		m_boundBody[3] = world->CreateBody(&groundBodyDef);
		b2PolygonShape groundBox;
		groundBox.SetAsBox(block_dim, block_len);
		b2FixtureDef fixtureDef;
		fixtureDef.shape = &groundBox;
		m_boundBody[3]->CreateFixture(&fixtureDef);
	}

    //per mousejoint - sempre attivo
	{
		b2BodyDef gBodyDef;
		gBodyDef.position.Set(0.0f,-(boundY * 10));
		m_mouseBody = world->CreateBody(&gBodyDef);
		b2PolygonShape gBox;
		gBox.SetAsBox(0.01,0.01);
		b2FixtureDef fixtureDef;
		fixtureDef.shape = &gBox;
		m_mouseBody->CreateFixture(&fixtureDef);
	}

    world->Step(timeStep, velocityIterations, positionIterations);
    world->SetContactListener(new MyContactListener);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
b2Vec2 cScene::PhysicGetPos(b2Body* tBody)
{
    b2Vec2 tRet(0,0);

    if (tBody)
        tRet = tBody->GetPosition();
    
    return tRet;
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::PhysicMovePlane(int tPlane,float tPosX, float tPosY)
{
    if (m_boundBody[tPlane])
    {
        b2Vec2 position;
        position.Set(tPosX,tPosY);
        m_boundBody[tPlane]->SetActive(false);
        m_boundBody[tPlane]->SetTransform(position, 0);
        m_boundBody[tPlane]->SetActive(true);
    }
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::PhysicEnablePlane(int tPlane,bool tEnabled)
{
	if (m_boundBody[tPlane])
		m_boundBody[tPlane]->SetActive(tEnabled);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::PhysicIdle()
{
	if (world)
	{
		world->Step(timeStep, velocityIterations, positionIterations);
		world->ClearForces();
	}
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::PhysicStop()
{	
	if (world)
		delete (world);
	
	world			= NULL;
	m_mouseJoint	= NULL;
	m_mouseForce	= 100000.0f;
	m_boundBody[0]	= NULL;
	m_boundBody[1]	= NULL;
	m_boundBody[2]	= NULL;
	m_boundBody[3]	= NULL;
	m_mouseBody		= NULL;
}
//---------------------------------------------------------------------------------
// PRISMATIC
//---------------------------------------------------------------------------------
void cScene::PhysicAddPrismaticJoint(cObj* obj1,cObj* obj2,float anchorX, float anchorY,float axysX, float axysY, float tLower, float tUpper)
{

	b2PrismaticJointDef jointDef;
    
	b2Vec2 worldAxis(1.0f, 0.0f);
    jointDef.Initialize(obj1->body, obj2->body , b2Vec2(anchorX,anchorY), b2Vec2(axysX,axysY));
	jointDef.lowerTranslation = tLower;
	jointDef.upperTranslation = tUpper;
	jointDef.enableLimit = (tLower != tUpper);
	jointDef.motorSpeed = 0.0f;
    jointDef.maxMotorForce = 1.0;
	jointDef.enableMotor = false;
	
	for (int i=0;i<MAX_JOINT;i++)
	{
		if (obj1->prismatic_joint[i] == NULL)
		{	
			obj1->prismatic_joint[i] = (b2PrismaticJoint*)world->CreateJoint(&jointDef);
			return;
		}
	}
}

//---------------------------------------------------------------------------------
// LINE usato per esempio per le sospensioni di un'auto
//---------------------------------------------------------------------------------

void cScene::PhysicAddLineJoint(cObj* obj1,cObj* obj2,float x1, float y1,float x2, float y2,float axis1_x,float axis1_y,float tLow,float tUp)
{

	b2WheelJointDef line_joint;
	
	line_joint.type = e_wheelJoint;
	line_joint.localAnchorA.SetZero();
	line_joint.localAnchorB.SetZero();
	line_joint.localAxisA.Set(1.0f, 0.0f);
	line_joint.enableMotor = false;
	line_joint.maxMotorTorque = 0.0f;
	line_joint.motorSpeed = 0.0f;
    
	line_joint.Initialize(obj1->body, obj2->body, b2Vec2(0,0),b2Vec2(axis1_x,axis1_y));
    if (axis1_x && !axis1_y)
        line_joint.localAxisA.Set(1.0f, 0.0f);	
    else if (axis1_y && !axis1_x)
        line_joint.localAxisA.Set(0.0f, 1.0f);	
    else
        line_joint.localAxisA.Set(axis1_x, axis1_y);	
    
	if ((x1 != x2 || y1 != y2) && (x2!=0 || y2!=0))
	{
		line_joint.localAnchorA = b2Vec2(x1,y1);
		line_joint.localAnchorB = b2Vec2(x2,y2);
	}
	line_joint.collideConnected = false;
	line_joint.enableMotor = false;

	for (int i=0;i<MAX_JOINT;i++)
	{
		if (obj1->line_joint[i] == NULL)
		{	
			obj1->line_joint[i] = (b2WheelJoint*)world->CreateJoint(&line_joint);
			return;
		}
	}
}
//---------------------------------------------------------------------------------
// REVOLUTE
//---------------------------------------------------------------------------------
void cScene::PhysicAddRevoluteJoint(cObj* obj1,cObj* obj2,float x1, float y1,float x2, float y2, float downAngle, float upAngle)
{
	b2RevoluteJointDef revolute_joint;
		
	revolute_joint.Initialize(obj1->body, obj2->body, b2Vec2(x1,y1));
	revolute_joint.lowerAngle = D2R(downAngle); 
	revolute_joint.upperAngle = D2R(upAngle);	
	revolute_joint.referenceAngle = 0.0f;
	if ((x1 != x2 || y1 != y2) && (x2!=0 || y2!=0))
	{
		revolute_joint.localAnchorA = b2Vec2(x1,y1);
		revolute_joint.localAnchorB = b2Vec2(x2,y2);
	}
	revolute_joint.collideConnected = false;
	revolute_joint.enableLimit = (bool)(upAngle != downAngle);
	revolute_joint.maxMotorTorque = 1.0f;
	revolute_joint.motorSpeed = 1.0f;
	revolute_joint.enableMotor = false;

	for (int i=0;i<MAX_JOINT;i++)
		if (obj1->revolute_joint[i] == NULL)
		{	
			obj1->revolute_joint[i] = (b2RevoluteJoint*)world->CreateJoint(&revolute_joint);
			return;
		}
}
//---------------------------------------------------------------------------------
// PULLEY connette 2 oggetti e due punti fissi //e_pulleyJoint
//---------------------------------------------------------------------------------
/*

    var anchor1:b2Vec2 = box1.GetWorldCenter();
var anchor2:b2Vec2 = box2.GetWorldCenter();
 
var groundAnchor1:b2Vec2 = new b2Vec2(anchor1.x, anchor1.y - (300 / PIXELS_TO_METRE)); 
var groundAnchor2:b2Vec2 = new b2Vec2(anchor2.x, anchor2.y - (300 / PIXELS_TO_METRE));
 
var ratio:Number = 1.0;
 
var pulleyJointDef:b2PulleyJointDef = new b2PulleyJointDef();
pulleyJointDef.Initialize(box1, box2, groundAnchor1, groundAnchor2, anchor1, anchor2, ratio);
pulleyJointDef.maxLengthA = 600 / PIXELS_TO_METRE;
pulleyJointDef.maxLengthB = 600 / PIXELS_TO_METRE;
 
_world.CreateJoint(pulleyJointDef);

*/

//---------------------------------------------------------------------------------
// FRICTION definisce una frizione alto-basso //e_frictionJoint
//---------------------------------------------------------------------------------
/*





*/
//---------------------------------------------------------------------------------
// WELD attacca 2 oggetti (senza distanza etc) usato per corpi "rompibili"
//---------------------------------------------------------------------------------
void cScene::PhysicAddWeldJoint(cObj* obj1,cObj* obj2,float wCenterX,float wCenterY)
{
 
	b2WeldJointDef weldJointDef;
    weldJointDef.Initialize(obj1->body, obj2->body, b2Vec2(wCenterX,wCenterY));

	for (int i=0;i<MAX_JOINT;i++)
	{
		if (obj1->weld_joint[i] == NULL)
		{
			obj1->weld_joint[i] = (b2WeldJoint*)world->CreateJoint(&weldJointDef);
			return;
		}
	}
	
}

//---------------------------------------------------------------------------------
// GEAR : connette 2 giunti PRISMATIC o REVOLUTION
//---------------------------------------------------------------------------------
void cScene::PhysicAddGearJoint(cObj* obj1,b2Joint* tJoint1,b2Joint* tJoint2,float tRatio)
{
	b2GearJointDef gearJoint;

	gearJoint.joint1 = tJoint1;
	gearJoint.joint2 = tJoint2;
	gearJoint.ratio = tRatio;

	for (int i=0;i<MAX_JOINT;i++)
	{
		if (obj1->gear_joint[i] == NULL)
		{
			obj1->gear_joint[i] = (b2GearJoint*)world->CreateJoint(&gearJoint);
			return;
		}
	}
	
}
//---------------------------------------------------------------------------------
// ROPE : basicamente il giunto di distanza ma senza distanza (=0)
//---------------------------------------------------------------------------------
void cScene::PhysicAddRopeJoint(cObj* obj1,cObj* obj2,float x1, float y1,float x2, float y2)
{
	b2RopeJointDef rope_joint;
    
    //rope_joint.Initialize(obj1->body, obj2->body, b2Vec2(x1,y1),b2Vec2(x2,y2));
    rope_joint.type = e_ropeJoint;
    rope_joint.localAnchorA = b2Vec2(x1,y1);
    rope_joint.localAnchorB = b2Vec2(x2,y2);
    rope_joint.maxLength = 0.0f;

	//for (int i=0;i<MAX_JOINT;i++)
	{
		if (obj1->rope_joint == NULL)
		{	
			obj1->rope_joint = (b2RopeJoint*)world->CreateJoint(&rope_joint);
			return;
		}
	}
}
//---------------------------------------------------------------------------------
// DISTANCE : connette 2 oggetti con distanza definita
//---------------------------------------------------------------------------------
void cScene::PhysicAddDistanceJoint(cObj* obj1,cObj* obj2,float x1, float y1,float x2, float y2,float length,float damping,float frequency)
{
	b2DistanceJointDef distanceJoint;
    
    distanceJoint.Initialize(obj1->body, obj2->body, b2Vec2(x1,y1),b2Vec2(x2,y2));
	if ((x1 != x2 || y1 != y2) && (x2!=0 || y2!=0))
	{
		distanceJoint.localAnchorA = b2Vec2(x1,y1);
		distanceJoint.localAnchorB = b2Vec2(x2,y2);
	}
	distanceJoint.collideConnected = false;
	distanceJoint.length = length;
	distanceJoint.frequencyHz = frequency;
	distanceJoint.dampingRatio = damping;

	for (int i=0;i<MAX_JOINT;i++)
	{
		if (obj1->distance_joint[i] == NULL)
		{
			obj1->distance_joint[i] = (b2DistanceJoint*)world->CreateJoint(&distanceJoint);
			return;
		}
	}
	
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicSetMotor(bool tEnabled,float speed,float torque)
{
    if (!revolute_joint[0])
        return;

    revolute_joint[0]->EnableMotor(tEnabled);
    revolute_joint[0]->SetMotorSpeed(speed);
    revolute_joint[0]->SetMaxMotorTorque(torque);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicSetPos(float x,float y,float angle)
{
    if (body)
    {
        b2Vec2 position;
        position.Set(x,y);
        rotation.x = angle;
        body->SetTransform(position, angle);
    }
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicSetUserID(int tValue)
{
    long tID = tValue;
    body->SetUserData((void*)tID);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
int cObj::PhysicGetUserID(void)
{
    long tID = (long)(void*)body->GetUserData();
    //body->GetNext();
    //body->GetContactList();
    return (int)tID;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicGetPos()
{
	if (p_static || !parent->world)
		return;
	
	b2Vec2  pos = body->GetPosition();
	if (!body->IsFixedRotation())
    {
        float32 rot = body->GetAngle();
        SetAngle(rotation.x,rotation.y,R2D(rot));
	}
    
    SetPosition( pos.x, pos.y, position.z);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicDestroy()
{

	for (int i=0;i<MAX_JOINT;i++)
	{
        //viene effettuato dalla successiva distruzione del body
        /*
        if (distance_joint[i])  parent->world->DestroyJoint(distance_joint[i]);
        if (revolute_joint[i])  parent->world->DestroyJoint(revolute_joint[i]);
        if (prismatic_joint[i]) parent->world->DestroyJoint(prismatic_joint[i]);
        if (line_joint[i])      parent->world->DestroyJoint(line_joint[i]);
        if (rope_joint)         parent->world->DestroyJoint(rope_joint);
        if (gear_joint[i])      parent->world->DestroyJoint(gear_joint[i]);
        if (weld_joint[i])      parent->world->DestroyJoint(weld_joint[i]);
        */
        
		revolute_joint[i]   = NULL;
		distance_joint[i]	= NULL;  
        prismatic_joint[i]	= NULL;  
        line_joint[i]       = NULL;
        rope_joint          = NULL;
        gear_joint[i]       = NULL;
        weld_joint[i]       = NULL;
	}
    
    if (body)
    {
        body->SetActive(false);
        parent->world->DestroyBody(body);
    }
    
	body = NULL;
}
//-------------------------------------------------------------------------
// mass = 
//  0 static: zero mass, zero velocity, may be manually moved
// -1 kinematic: zero mass, non-zero velocity set by user, moved by solver
// +1 dynamic: positive mass, non-zero velocity determined by forces, moved by solver
//-------------------------------------------------------------------------
void cObj::PhysicAdd(float dimx,float dimy,float mass,float density,float friction,int groupIndex,short catBits,float gravityScale)
{
	b2BodyDef bodyDef;
	
	if (mass == -1)
	{
		p_static = true;
		bodyDef.type = b2_kinematicBody;
	}
	else if (mass == 0)
	{
		p_static = true;
		bodyDef.type = b2_staticBody;
	}
	else
	{
		p_static = false;
		bodyDef.type = b2_dynamicBody;
	}
	
	bodyDef.position.Set(position.x,position.y);
	bodyDef.angle = D2R(rotation.z);
    if (gravityScale)
        bodyDef.gravityScale = gravityScale; // Set the gravity scale to zero so this body will float
    
	body = parent->world->CreateBody(&bodyDef);
	
	b2PolygonShape dynamicBox;
	dynamicBox.SetAsBox(dimx,dimy);
	
	b2FixtureDef fixtureDef;
	fixtureDef.filter.groupIndex	= groupIndex;
	fixtureDef.shape				= &dynamicBox;
	fixtureDef.density				= density;	
	fixtureDef.friction				= friction;		
	fixtureDef.filter.categoryBits	= catBits;
	fixtureDef.filter.maskBits		= catBits;
	body->CreateFixture(&fixtureDef);
	body->SetActive(true);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicAddBox(float dimx,float dimy,float mass,float density,float friction,int groupIndex,short catBits,float gravityScale)
{
    PhysicAdd( dimx, dimy, mass, density, friction, groupIndex, catBits, gravityScale);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicAddCircle(float radius,float mass,float density,float friction,int groupIndex,short catBits)
{
	b2BodyDef bodyDef;
	
	if (mass == -1)
	{
		p_static = true;
		bodyDef.type = b2_kinematicBody;
	}
	else if (mass == 0)
	{
		p_static = true;
		bodyDef.type = b2_staticBody;
	}
	else
	{
		p_static = false;
		bodyDef.type = b2_dynamicBody;
	}
	
	bodyDef.position.Set(position.x,position.y);
	bodyDef.angle = D2R(rotation.z);
	body = parent->world->CreateBody(&bodyDef);
	
	b2CircleShape dynCircle;
	dynCircle.m_p.Set(0,0);
	dynCircle.m_radius = radius;
	
	b2FixtureDef fixtureDef;
	fixtureDef.filter.groupIndex	= groupIndex;
	fixtureDef.shape				= &dynCircle;
	fixtureDef.density				= density;
	fixtureDef.friction				= friction;		
	fixtureDef.filter.categoryBits	= catBits;
	fixtureDef.filter.maskBits		= catBits;
	body->CreateFixture(&fixtureDef);
	body->SetActive(true);
}
//-------------------------------------------------------------------------
// POLYGON definisce un poligono convesso (vertici in senso antiorario)
//-------------------------------------------------------------------------
void cObj::PhysicAddPoly(b2Vec2* vertices,int vcount,float mass,float density,float friction,int groupIndex,short catBits)
{
	b2BodyDef bodyDef;
	
	if (mass == -1)
	{
		p_static = true;
		bodyDef.type = b2_kinematicBody;
	}
	else if (mass == 0)
	{
		p_static = true;
		bodyDef.type = b2_staticBody;
	}
	else
	{
		p_static = false;
		bodyDef.type = b2_dynamicBody;
	}
	
	bodyDef.position.Set(position.x,position.y);
	bodyDef.angle = D2R(rotation.z);
	body = parent->world->CreateBody(&bodyDef);

	b2PolygonShape dynamicPoly;
	dynamicPoly.Set(vertices, vcount);
	
	b2FixtureDef fixtureDef;
	fixtureDef.filter.groupIndex	= groupIndex;
	fixtureDef.shape				= &dynamicPoly;
	fixtureDef.density				= density;	
	fixtureDef.friction				= friction;	
	fixtureDef.filter.categoryBits	= catBits;
	fixtureDef.filter.maskBits		= catBits;
	body->CreateFixture(&fixtureDef);

	body->SetActive(true);
}
//-------------------------------------------------------------------------
// EDGE definisce una polilinea
//-------------------------------------------------------------------------
void cObj::PhysicAddEdge(b2Vec2* vertices,int vcount,float mass,float density,float friction,int groupIndex,short catBits)
{
	b2BodyDef bodyDef;
	
	if (mass == -1)
	{
		p_static = true;
		bodyDef.type = b2_kinematicBody;
	}
	else if (mass == 0)
	{
		p_static = true;
		bodyDef.type = b2_staticBody;
	}
	else
	{
		p_static = false;
		bodyDef.type = b2_dynamicBody;
	}
	
	bodyDef.position.Set(position.x,position.y);
	bodyDef.angle = D2R(rotation.z);
	body = parent->world->CreateBody(&bodyDef);

	b2FixtureDef fixtureDef;
	fixtureDef.filter.groupIndex	= groupIndex;
	fixtureDef.density				= density;	
	fixtureDef.friction				= friction;	
	fixtureDef.filter.categoryBits	= catBits;
	fixtureDef.filter.maskBits		= catBits;
	for (int i=0;i<vcount-1;i++)
	{
		b2EdgeShape dynamicPoly;
		dynamicPoly.Set(vertices[i],vertices[i+1]);
		fixtureDef.shape = &dynamicPoly;
		body->CreateFixture(&fixtureDef);
	}
	body->SetActive(true);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicState(bool tActive)
{
	if (body)
		body->SetActive(tActive);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicSetLinearVelocity(float x1,float y1)
{
	b2Vec2 velocity(x1,y1);
	body->b2Body::SetLinearVelocity(velocity);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
float cObj::PhysicGetHorizontalVelocity()
{
    return body->b2Body::GetLinearVelocity().x;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
float cObj::PhysicGetVerticalVelocity()
{
    return body->b2Body::GetLinearVelocity().y;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
float cObj::PhysicGetAngularVelocity()
{
    return body->b2Body::GetAngularVelocity();
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicSetFixedRotation(bool tRot)
{
	body->b2Body::SetFixedRotation(tRot);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicApplyAngularImpulse(float impulse)
{
	body->b2Body::ApplyAngularImpulse(impulse,true);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicApplyForce(float x1,float y1,float x2,float y2)
{
	b2Vec2 force(x1,y1);
	b2Vec2 forcePoint(x2,y2);
	body->b2Body::ApplyForce(force,forcePoint,true);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicApplyImpulse(float x1,float y1,float x2,float y2)
{
	b2Vec2 impulse(x1,y1);
	b2Vec2 point(x2,y2);
	body->b2Body::ApplyLinearImpulse(impulse,point,true);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicSetRestitution(float restitution)
{
	b2Fixture* f = body->GetFixtureList();
	if (f)
		f->SetRestitution(restitution);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicSetFriction(float friction)
{
	b2Fixture* f = body->GetFixtureList();
	if (f)
		f->SetFriction(friction);
}	
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::PhysicSetGravity(float gravx,float gravy)
{

	if (angle.z == 180)
		gravx *= -1.0f;

	if (angle.y == 180)
		gravx *= -1.0f;

#if TARGET_OS_IPHONE
	if (accelerometerX || accelerometerY)
	{

		b2Vec2 currGravity = world->GetGravity();
		float tVectorLength = sqrt(gravx*gravx + gravy*gravy);
		if (tVectorLength != 0.0f)
		{
			gravx  = (accelerometerX) ? (DEFAULT_GRAVITY*gravx / tVectorLength) : currGravity.x;
			gravy  = (accelerometerY) ? (DEFAULT_GRAVITY*gravy / tVectorLength) : currGravity.y;
			world->SetGravity(b2Vec2(gravx,gravy));	
		}
        else
            world->SetGravity(b2Vec2(0,0));

        return;
	}
#endif

	world->SetGravity(b2Vec2(gravx,gravy));	

}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cObj::PhysicSetDamping(float linear, float angular) //0  01;
{
	body->SetLinearDamping(linear);
	body->SetAngularDamping(angular);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------



#endif


