Continued working on the physics implementation. Need test a lot, but it's mostly implemented, at least, the basis.

This commit is contained in:
spartanj
2011-01-14 05:28:03 -03:00
parent 3879da9f26
commit 9b911a5e6f
39 changed files with 1257 additions and 533 deletions

View File

@@ -151,8 +151,39 @@
#define eeSAFE_FREE(p) { if(p) { eeFree ( (void*)p ); (p)=NULL; } }
#define eeSAFE_DELETE_ARRAY(p) { if(p) { eeDeleteArray(p); (p)=NULL; } }
#ifdef EE_64BIT
#define EE_USE_DOUBLES 1
#else
#define EE_USE_DOUBLE 0
#endif
namespace EE {
typedef float eeFloat; //! The internal floating point used on EE++. \n This can help to improve compatibility with some platforms. \n And helps for an easy change from single precision to double precision.
#if EE_USE_DOUBLES
typedef double eeFloat;
#define eesqrt sqrt
#define eesin sin
#define eecos cos
#define eeacos acos
#define eeatan2 atan2
#define eemod fmod
#define eeexp exp
#define efow pow
#define eefloor floor
#define eeceil ceil
#else
typedef float eeFloat; //! The internal floating point used on EE++. \n This can help to improve compatibility with some platforms. \n And helps for an easy change from single precision to double precision.
#define eesqrt sqrtf
#define eesin sinf
#define eecos cosf
#define eeacos acosf
#define eeatan2 atan2f
#define eemod fmodf
#define eeexp expf
#define eepow powf
#define eefloor floorf
#define eeceil ceilf
#endif
typedef double eeDouble; //! The internal double floating point. It's only used when the engine needs some very high precision floating point ( for example the timer )
typedef unsigned int eeUint;
typedef signed int eeInt;

View File

@@ -192,5 +192,7 @@
#include "physics/constraints/crotarylimitjoint.hpp"
#include "physics/constraints/csimplemotor.hpp"
#include "physics/constraints/cslidejoint.hpp"
#include "physics/moment.hpp"
#include "physics/area.hpp"
using namespace EE::Physics;
#endif

View File

@@ -829,10 +829,26 @@ void cBatchRenderer::SetLineWidth( const eeFloat& lineWidth ) {
glLineWidth( lineWidth );
}
eeFloat cBatchRenderer::GetLineWidth() {
float lw;
glGetFloatv( GL_LINE_WIDTH, &lw );
return lw;
}
void cBatchRenderer::SetPointSize( const eeFloat& pointSize ) {
glPointSize( pointSize );
}
eeFloat cBatchRenderer::GetPointSize() {
float ps;
glGetFloatv( GL_POINT_SIZE, &ps );
return ps;
}
void cBatchRenderer::ForceBlendModeChange( const bool& Force ) {
mForceBlendMode = Force;
}

View File

@@ -176,9 +176,15 @@ class EE_API cBatchRenderer {
/** Set the line width */
void SetLineWidth( const eeFloat& lineWidth );
/** @return The current line width */
eeFloat GetLineWidth();
/** Set the point size */
void SetPointSize( const eeFloat& pointSize );
/** @return The current point size */
eeFloat GetPointSize();
/** Batch a poligon adding one by one vector */
void BatchPolygonByPoint( const eeFloat& x, const eeFloat& y );

View File

@@ -52,6 +52,7 @@ eeColorAf cFrameBuffer::ClearColor() const {
void cFrameBuffer::Clear() {
glClearColor( mClearColor.R(), mClearColor.G(), mClearColor.B(), mClearColor.A() );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
cEngine::instance()->SetBackColor( cEngine::instance()->GetBackColor() );
}
void cFrameBuffer::SetBufferView() {

View File

@@ -150,7 +150,7 @@ cpArbiterGetPoint(const cpArbiter *arb, int i)
}
static inline cpFloat
cpArbiteGetDepth(const cpArbiter *arb, int i)
cpArbiterGetDepth(const cpArbiter *arb, int i)
{
return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);
}

27
src/physics/area.hpp Normal file
View File

@@ -0,0 +1,27 @@
#ifndef EE_PHYSICS_AREA_HPP
#define EE_PHYSICS_AREA_HPP
#include "base.hpp"
namespace EE { namespace Physics {
class Area {
public:
inline static cpFloat ForCircle( cpFloat r1, cpFloat r2 ) {
return cpAreaForCircle( r1, r2 );
}
inline static cpFloat ForSegment( cVect a, cVect b, cpFloat r ) {
return cpAreaForSegment( tocpv( a ), tocpv( b ), r );
}
inline static cpFloat ForPoly( const int numVerts, const cVect * verts ) {
return cpAreaForPoly( numVerts, constcasttocpv( verts ) );
}
};
}}
#endif

View File

@@ -13,11 +13,40 @@ using namespace EE::Window;
using namespace EE::System;
#include "../graphics/cprimitives.hpp"
#include "../graphics/cbatchrenderer.hpp"
#include "../graphics/cglobalbatchrenderer.hpp"
#define CP_ALLOW_PRIVATE_ACCESS 1
#include "../helper/chipmunk/chipmunk_private.h"
#include "../helper/chipmunk/chipmunk_unsafe.h"
#include "../helper/chipmunk/chipmunk.h"
#define USE_EE_VECTOR
#ifdef USE_EE_VECTOR
typedef Vector2<cpFloat> cVect;
inline static cVect toVect( cpVect vect ) {
return cVect( vect.x, vect.y );
}
#define tocpv( vect ) cpv( vect.x, vect.y )
#define tovect( vect ) toVect( vect )
#define casttocpv( vect ) reinterpret_cast<cpVect*>( vect )
#define constcasttocpv( vect ) reinterpret_cast<const cpVect*>( vect )
#define cVectZero cVect( 0, 0 )
#define cVectNew( x, y ) cVect( x, y )
#else
typedef cpVect cVect;
#define tocpv( vect ) vect
#define tovect( vect ) vect
#define casttocpv( vect ) vect
#define constcasttocpv( vect ) vect
#define cVectZero cpvzero
#define cVectNew( x, y ) cpv( x, y )
#endif
#include "physicshelper.hpp"

83
src/physics/carbiter.cpp Normal file
View File

@@ -0,0 +1,83 @@
#include "carbiter.hpp"
namespace EE { namespace Physics {
cArbiter::cArbiter( cpArbiter * arbiter ) {
mArbiter = arbiter;
}
cVect cArbiter::TotalImpulse() {
return tovect( cpArbiterTotalImpulse( mArbiter ) );
}
cVect cArbiter::TotalImpulseWithFriction() {
return tovect( cpArbiterTotalImpulseWithFriction( mArbiter ) );
}
void cArbiter::Ignore() {
return cpArbiterIgnore( mArbiter );
}
void cArbiter::GetShapes( cShape ** a, cShape ** b ) {
cpShape * tA = (*a)->Shape();
cpShape * tB = (*b)->Shape();
cpArbiterGetShapes( mArbiter, &tA, &tB );
if ( NULL != tA )
*a = reinterpret_cast<cShape*>( tA->data );
else
*a = NULL;
if ( NULL != tB )
*b = reinterpret_cast<cShape*>( tB->data );
else
*b = NULL;
}
void cArbiter::GetBodies( cBody ** a, cBody ** b) {
cpBody * tA = (*a)->Body();
cpBody * tB = (*b)->Body();
cpArbiterGetBodies( mArbiter, &tA, &tB );
if ( NULL != tA )
*a = reinterpret_cast<cBody*>( tA->data );
else
*a = NULL;
if ( NULL != tB )
*b = reinterpret_cast<cBody*>( tB->data );
else
*b = NULL;
}
bool cArbiter::IsFirstContact() {
return 0 != cpArbiterIsFirstContact( mArbiter );
}
int cArbiter::GetCount() {
return cpArbiterGetCount( mArbiter );
}
cVect cArbiter::GetNormal( int i ) {
return tovect( cpArbiterGetNormal( mArbiter, i ) );
}
cVect cArbiter::GetPoint( int i ) {
return tovect( cpArbiterGetPoint( mArbiter, i ) );
}
cpFloat cArbiter::GetDepth( int i ) {
return cpArbiterGetDepth( mArbiter, i );
}
cpContactPointSet cArbiter::GetContactPointSet() {
return cpArbiterGetContactPointSet( mArbiter );
}
cpArbiter * cArbiter::Arbiter() const {
return mArbiter;
}
}}

43
src/physics/carbiter.hpp Normal file
View File

@@ -0,0 +1,43 @@
#ifndef EE_PHYSICS_CARBITER_HPP
#define EE_PHYSICS_CARBITER_HPP
#include "base.hpp"
#include "cshape.hpp"
#include "cbody.hpp"
namespace EE { namespace Physics {
class cArbiter {
public:
cArbiter( cpArbiter * arbiter );
cVect TotalImpulse();
cVect TotalImpulseWithFriction();
void Ignore();
void GetShapes( cShape ** a, cShape ** b );
void GetBodies( cBody ** a, cBody ** b);
bool IsFirstContact();
int GetCount();
cVect GetNormal( int i );
cVect GetPoint( int i );
cpFloat GetDepth( int i );
cpContactPointSet GetContactPointSet();
cpArbiter * Arbiter() const;
protected:
cpArbiter * mArbiter;
};
}}
#endif

View File

@@ -2,6 +2,18 @@
namespace EE { namespace Physics {
cBody * cBody::New( cpFloat m, cpFloat i ) {
return eeNew( cBody, ( m, i ) );
}
cBody * cBody::New( cpBody * body ) {
return eeNew( cBody, ( body ) );
}
cBody * cBody::New() {
return eeNew( cBody, () );
}
cBody::cBody( cpBody * body ) {
mBody = body;
mBody->data = (void*)this;
@@ -63,28 +75,28 @@ void cBody::Moment( const cpFloat& i ) {
cpBodySetMoment( mBody, i );
}
cpVect cBody::Pos() const {
return cpBodyGetPos( mBody );
cVect cBody::Pos() const {
return tovect( cpBodyGetPos( mBody ) );
}
void cBody::Pos( const cpVect& pos ) {
cpBodySetPos( mBody, pos );
void cBody::Pos( const cVect& pos ) {
cpBodySetPos( mBody, tocpv( pos ) );
}
cpVect cBody::Vel() const {
return cpBodyGetVel( mBody );
cVect cBody::Vel() const {
return tovect( cpBodyGetVel( mBody ) );
}
void cBody::Vel( const cpVect& vel ) {
cpBodySetVel( mBody, vel );
void cBody::Vel( const cVect& vel ) {
cpBodySetVel( mBody, tocpv( vel ) );
}
cpVect cBody::Force() const {
return cpBodyGetForce( mBody );
cVect cBody::Force() const {
return tovect( cpBodyGetForce( mBody ) );
}
void cBody::Force( const cpVect& force ) {
cpBodySetForce( mBody, force );
void cBody::Force( const cVect& force ) {
cpBodySetForce( mBody, tocpv( force ) );
}
cpFloat cBody::Angle() const {
@@ -111,8 +123,8 @@ void cBody::AngVel( const cpFloat& rotVel ) {
cpBodySetAngVel( mBody, rotVel );
}
cpVect cBody::Rot() const {
return cpBodyGetRot( mBody );
cVect cBody::Rot() const {
return tovect( cpBodyGetRot( mBody ) );
}
cpFloat cBody::VelLimit() const {
@@ -131,36 +143,36 @@ void cBody::AngVelLimit( const cpFloat& speed ) {
cpBodySetAngVelLimit( mBody, speed );
}
void cBody::Slew( cpVect pos, cpFloat dt ) {
cpBodySlew( mBody, pos, dt );
void cBody::Slew( cVect pos, cpFloat dt ) {
cpBodySlew( mBody, tocpv( pos ), dt );
}
void cBody::UpdateVelocity( cpVect gravity, cpFloat damping, cpFloat dt ) {
cpBodyUpdateVelocity( mBody, gravity, damping, dt );
void cBody::UpdateVelocity( cVect gravity, cpFloat damping, cpFloat dt ) {
cpBodyUpdateVelocity( mBody, tocpv( gravity ), damping, dt );
}
void cBody::UpdatePosition( cpFloat dt ) {
cpBodyUpdatePosition( mBody, dt );
}
cpVect cBody::Local2World( const cpVect v ) {
return cpBodyLocal2World( mBody, v );
cVect cBody::Local2World( const cVect v ) {
return tovect( cpBodyLocal2World( mBody, tocpv( v ) ) );
}
cpVect cBody::World2Local( const cpVect v ) {
return cpBodyWorld2Local( mBody, v );
cVect cBody::World2Local( const cVect v ) {
return tovect( cpBodyWorld2Local( mBody, tocpv( v ) ) );
}
void cBody::ApplyImpulse( const cpVect j, const cpVect r ) {
cpBodyApplyImpulse( mBody, j, r );
void cBody::ApplyImpulse( const cVect j, const cVect r ) {
cpBodyApplyImpulse( mBody, tocpv( j ), tocpv( r ) );
}
void cBody::ResetForces() {
cpBodyResetForces( mBody );
}
void cBody::ApplyForce( const cpVect f, const cpVect r ) {
cpBodyApplyForce( mBody, f, r );
void cBody::ApplyForce( const cVect f, const cVect r ) {
cpBodyApplyForce( mBody, tocpv( f ), tocpv( r ) );
}
cpFloat cBody::KineticEnergy() {

View File

@@ -7,6 +7,12 @@ namespace EE { namespace Physics {
class cBody {
public:
static cBody * New( cpFloat m, cpFloat i );
static cBody * New( cpBody * body );
static cBody * New();
cBody( cpBody * body );
cBody( cpFloat m, cpFloat i );
@@ -37,17 +43,17 @@ class cBody {
void Moment( const cpFloat& i );
cpVect Pos() const;
cVect Pos() const;
void Pos( const cpVect& pos );
void Pos( const cVect& pos );
cpVect Vel() const;
cVect Vel() const;
void Vel( const cpVect& vel );
void Vel( const cVect& vel );
cpVect Force() const;
cVect Force() const;
void Force( const cpVect& force );
void Force( const cVect& force );
cpFloat Angle() const;
@@ -61,7 +67,7 @@ class cBody {
void AngVel( const cpFloat& angVel );
cpVect Rot() const;
cVect Rot() const;
cpFloat VelLimit() const;
@@ -71,21 +77,21 @@ class cBody {
void AngVelLimit( const cpFloat& speed );
void Slew( cpVect pos, cpFloat dt );
void Slew( cVect pos, cpFloat dt );
void UpdateVelocity( cpVect gravity, cpFloat damping, cpFloat dt );
void UpdateVelocity( cVect gravity, cpFloat damping, cpFloat dt );
void UpdatePosition( cpFloat dt );
cpVect Local2World( const cpVect v );
cVect Local2World( const cVect v );
cpVect World2Local( const cpVect v );
cVect World2Local( const cVect v );
void ApplyImpulse( const cpVect j, const cpVect r );
void ApplyImpulse( const cVect j, const cVect r );
void ResetForces();
void ApplyForce( const cpVect f, const cpVect r );
void ApplyForce( const cVect f, const cVect r );
cpFloat KineticEnergy();
protected:

View File

@@ -11,6 +11,7 @@ cConstraint::cConstraint() {
}
cConstraint::~cConstraint() {
cpConstraintFree( mConstraint );
}
void cConstraint::SetData() {

View File

@@ -2,25 +2,25 @@
namespace EE { namespace Physics {
cDampedSpring::cDampedSpring( cBody * a, cBody * b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping ) {
mConstraint = cpDampedSpringNew( a->Body(), b->Body(), anchr1, anchr2, restLength, stiffness, damping );
cDampedSpring::cDampedSpring( cBody * a, cBody * b, cVect anchr1, cVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping ) {
mConstraint = cpDampedSpringNew( a->Body(), b->Body(), tocpv( anchr1 ), tocpv( anchr2 ), restLength, stiffness, damping );
SetData();
}
cpVect cDampedSpring::Anchr1() {
return cpDampedSpringGetAnchr1( mConstraint );
cVect cDampedSpring::Anchr1() {
return tovect( cpDampedSpringGetAnchr1( mConstraint ) );
}
void cDampedSpring::Anchr1( const cpVect& anchr1 ) {
cpDampedSpringSetAnchr1( mConstraint, anchr1 );
void cDampedSpring::Anchr1( const cVect& anchr1 ) {
cpDampedSpringSetAnchr1( mConstraint, tocpv( anchr1 ) );
}
cpVect cDampedSpring::Anchr2() {
return cpDampedSpringGetAnchr2( mConstraint );
cVect cDampedSpring::Anchr2() {
return tovect( cpDampedSpringGetAnchr2( mConstraint ) );
}
void cDampedSpring::Anchr2( const cpVect& anchr2 ) {
cpDampedSpringSetAnchr2( mConstraint, anchr2 );
void cDampedSpring::Anchr2( const cVect& anchr2 ) {
cpDampedSpringSetAnchr2( mConstraint, tocpv( anchr2 ) );
}
cpFloat cDampedSpring::RestLength() {
@@ -52,8 +52,8 @@ void cDampedSpring::Draw() {
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cpVect a = cpvadd(body_a->p, cpvrotate(spring->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(spring->anchr2, body_b->rot));
cVect a = tovect( cpvadd(body_a->p, cpvrotate(spring->anchr1, body_a->rot)) );
cVect b = tovect( cpvadd(body_b->p, cpvrotate(spring->anchr2, body_b->rot)) );
glPointSize(5.0f);
glBegin(GL_POINTS); {
@@ -61,7 +61,7 @@ void cDampedSpring::Draw() {
glVertex2f(b.x, b.y);
} glEnd();
cpVect delta = cpvsub(b, a);
cVect delta = b - a;
glVertexPointer(2, GL_FLOAT, 0, springVAR);
glPushMatrix(); {
@@ -69,11 +69,11 @@ void cDampedSpring::Draw() {
GLfloat y = a.y;
GLfloat cos = delta.x;
GLfloat sin = delta.y;
GLfloat s = 1.0f/cpvlength(delta);
GLfloat s = 1.0f / cpvlength( tocpv( delta ) );
const GLfloat matrix[] = {
cos, sin, 0.0f, 0.0f,
-sin*s, cos*s, 0.0f, 0.0f,
-sin*s, cos*s, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
x, y, 0.0f, 1.0f,
};

View File

@@ -7,15 +7,15 @@ namespace EE { namespace Physics {
class cDampedSpring : public cConstraint {
public:
cDampedSpring( cBody * a, cBody * b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping );
cDampedSpring( cBody * a, cBody * b, cVect anchr1, cVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping );
cpVect Anchr1();
cVect Anchr1();
void Anchr1( const cpVect& anchr1 );
void Anchr1( const cVect& anchr1 );
cpVect Anchr2();
cVect Anchr2();
void Anchr2( const cpVect& anchr2 );
void Anchr2( const cVect& anchr2 );
cpFloat RestLength();

View File

@@ -2,53 +2,56 @@
namespace EE { namespace Physics {
cGrooveJoint::cGrooveJoint( cBody * a, cBody * b, cpVect groove_a, cpVect groove_b, cpVect anchr2 ) {
mConstraint = cpGrooveJointNew( a->Body(), b->Body(), groove_a, groove_b, anchr2 );
cGrooveJoint::cGrooveJoint( cBody * a, cBody * b, cVect groove_a, cVect groove_b, cVect anchr2 ) {
mConstraint = cpGrooveJointNew( a->Body(), b->Body(), tocpv( groove_a ), tocpv( groove_b ), tocpv( anchr2 ) );
SetData();
}
cpVect cGrooveJoint::Anchr2() {
return cpGrooveJointGetAnchr2( mConstraint );
cVect cGrooveJoint::Anchr2() {
return tovect( cpGrooveJointGetAnchr2( mConstraint ) );
}
void cGrooveJoint::Anchr2( const cpVect& anchr2 ) {
cpGrooveJointSetAnchr2( mConstraint, anchr2 );
void cGrooveJoint::Anchr2( const cVect& anchr2 ) {
cpGrooveJointSetAnchr2( mConstraint, tocpv( anchr2 ) );
}
cpVect cGrooveJoint::GrooveA() {
return cpGrooveJointGetGrooveA( mConstraint );
cVect cGrooveJoint::GrooveA() {
return tovect( cpGrooveJointGetGrooveA( mConstraint ) );
}
void cGrooveJoint::GrooveA( const cpVect& groove_a ) {
cpGrooveJointSetGrooveA( mConstraint, groove_a );
void cGrooveJoint::GrooveA( const cVect& groove_a ) {
cpGrooveJointSetGrooveA( mConstraint, tocpv( groove_a ) );
}
cpVect cGrooveJoint::GrooveB() {
return cpGrooveJointGetGrooveB( mConstraint );
cVect cGrooveJoint::GrooveB() {
return tovect( cpGrooveJointGetGrooveB( mConstraint ) );
}
void cGrooveJoint::GrooveB( const cpVect& groove_b ) {
cpGrooveJointSetGrooveB( mConstraint, groove_b );
void cGrooveJoint::GrooveB( const cVect& groove_b ) {
cpGrooveJointSetGrooveB( mConstraint, tocpv( groove_b ) );
}
void cGrooveJoint::Draw() {
cpGrooveJoint *joint = (cpGrooveJoint *)mConstraint;
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cpGrooveJoint *joint= (cpGrooveJoint *)mConstraint;
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cVect a = tovect( cpvadd(body_a->p, cpvrotate(joint->grv_a, body_a->rot)) );
cVect b = tovect( cpvadd(body_a->p, cpvrotate(joint->grv_b, body_a->rot)) );
cVect c = tovect( cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot)) );
cBatchRenderer * BR = cGlobalBatchRenderer::instance();
cpVect a = cpvadd(body_a->p, cpvrotate(joint->grv_a, body_a->rot));
cpVect b = cpvadd(body_a->p, cpvrotate(joint->grv_b, body_a->rot));
cpVect c = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
cpFloat ps = BR->GetPointSize();
BR->SetPointSize( 5.0f );
BR->PointsBegin();
BR->PointSetColor( eeColorA( 128, 255, 128, 255 ) );
BR->BatchPoint( c.x, c.y );
BR->Draw();
BR->LinesBegin();
BR->LinesSetColor( eeColorA( 128, 255, 128, 255 ) );
BR->BatchLine( a.x, a.y, b.x, b.y );
BR->Draw();
glPointSize(5.0f);
glBegin(GL_POINTS); {
glVertex2f(c.x, c.y);
} glEnd();
glBegin(GL_LINES); {
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
} glEnd();
BR->SetPointSize( ps );
}
}}

View File

@@ -7,19 +7,19 @@ namespace EE { namespace Physics {
class cGrooveJoint : public cConstraint {
public:
cGrooveJoint( cBody * a, cBody * b, cpVect groove_a, cpVect groove_b, cpVect anchr2 );
cGrooveJoint( cBody * a, cBody * b, cVect groove_a, cVect groove_b, cVect anchr2 );
cpVect Anchr2();
cVect Anchr2();
void Anchr2( const cpVect& anchr2 );
void Anchr2( const cVect& anchr2 );
cpVect GrooveA();
cVect GrooveA();
void GrooveA( const cpVect& groove_a );
void GrooveA( const cVect& groove_a );
cpVect GrooveB();
cVect GrooveB();
void GrooveB( const cpVect& groove_b );
void GrooveB( const cVect& groove_b );
virtual void Draw();
};

View File

@@ -2,25 +2,25 @@
namespace EE { namespace Physics {
cPinJoint::cPinJoint( cBody * a, cBody * b, cpVect anchr1, cpVect anchr2 ) {
mConstraint = cpPinJointNew( a->Body(), b->Body(), anchr1, anchr2 );
cPinJoint::cPinJoint( cBody * a, cBody * b, cVect anchr1, cVect anchr2 ) {
mConstraint = cpPinJointNew( a->Body(), b->Body(), tocpv( anchr1 ), tocpv( anchr2 ) );
SetData();
}
cpVect cPinJoint::Anchr1() {
return cpPinJointGetAnchr1( mConstraint );
cVect cPinJoint::Anchr1() {
return tovect( cpPinJointGetAnchr1( mConstraint ) );
}
void cPinJoint::Anchr1( const cpVect& anchr1 ) {
cpPinJointSetAnchr1( mConstraint, anchr1 );
void cPinJoint::Anchr1( const cVect& anchr1 ) {
cpPinJointSetAnchr1( mConstraint, tocpv( anchr1 ) );
}
cpVect cPinJoint::Anchr2() {
return cpPinJointGetAnchr2( mConstraint );
cVect cPinJoint::Anchr2() {
return tovect( cpPinJointGetAnchr2( mConstraint ) );
}
void cPinJoint::Anchr2( const cpVect& anchr2 ) {
cpPinJointSetAnchr2( mConstraint, anchr2 );
void cPinJoint::Anchr2( const cVect& anchr2 ) {
cpPinJointSetAnchr2( mConstraint, tocpv( anchr2 ) );
}
cpFloat cPinJoint::Dist() {
@@ -32,23 +32,27 @@ void cPinJoint::Dist( const cpFloat& dist ) {
}
void cPinJoint::Draw() {
cpPinJoint *joint = (cpPinJoint *)mConstraint;
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cpPinJoint *joint = (cpPinJoint *)mConstraint;
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cVect a = tovect( cpvadd( body_a->p, cpvrotate( joint->anchr1, body_a->rot ) ) );
cVect b = tovect( cpvadd( body_b->p, cpvrotate(joint->anchr2, body_b->rot ) ) );
cBatchRenderer * BR = cGlobalBatchRenderer::instance();
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
cpFloat ps = BR->GetPointSize();
BR->SetPointSize( 5.0f );
BR->PointsBegin();
BR->PointSetColor( eeColorA( 128, 255, 128, 255 ) );
BR->BatchPoint( a.x, a.y );
BR->BatchPoint( b.x, b.y );
BR->Draw();
glPointSize(5.0f);
glBegin(GL_POINTS); {
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
} glEnd();
BR->LinesBegin();
BR->LinesSetColor( eeColorA( 128, 255, 128, 255 ) );
BR->BatchLine( a.x, a.y, b.x, b.y );
BR->Draw();
glBegin(GL_LINES); {
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
} glEnd();
BR->SetPointSize( ps );
}
}}

View File

@@ -7,15 +7,15 @@ namespace EE { namespace Physics {
class cPinJoint : public cConstraint {
public:
cPinJoint( cBody * a, cBody * b, cpVect anchr1, cpVect anchr2 );
cPinJoint( cBody * a, cBody * b, cVect anchr1, cVect anchr2 );
cpVect Anchr1();
cVect Anchr1();
void Anchr1( const cpVect& anchr1 );
void Anchr1( const cVect& anchr1 );
cpVect Anchr2();
cVect Anchr2();
void Anchr2( const cpVect& anchr2 );
void Anchr2( const cVect& anchr2 );
cpFloat Dist();

View File

@@ -2,45 +2,48 @@
namespace EE { namespace Physics {
cPivotJoint::cPivotJoint( cBody * a, cBody * b, cpVect pivot ) {
mConstraint = cpPivotJointNew( a->Body(), b->Body(), pivot );
cPivotJoint::cPivotJoint( cBody * a, cBody * b, cVect pivot ) {
mConstraint = cpPivotJointNew( a->Body(), b->Body(), tocpv( pivot ) );
SetData();
}
cPivotJoint::cPivotJoint( cBody * a, cBody * b, cpVect anchr1, cpVect anchr2 ) {
mConstraint = cpPivotJointNew2( a->Body(), b->Body(), anchr1, anchr2 );
cPivotJoint::cPivotJoint( cBody * a, cBody * b, cVect anchr1, cVect anchr2 ) {
mConstraint = cpPivotJointNew2( a->Body(), b->Body(), tocpv( anchr1 ), tocpv( anchr2 ) );
SetData();
}
cpVect cPivotJoint::Anchr1() {
return cpPivotJointGetAnchr1( mConstraint );
cVect cPivotJoint::Anchr1() {
return tovect( cpPivotJointGetAnchr1( mConstraint ) );
}
void cPivotJoint::Anchr1( const cpVect& anchr1 ) {
cpPivotJointSetAnchr1( mConstraint, anchr1 );
void cPivotJoint::Anchr1( const cVect& anchr1 ) {
cpPivotJointSetAnchr1( mConstraint, tocpv( anchr1 ) );
}
cpVect cPivotJoint::Anchr2() {
return cpPivotJointGetAnchr2( mConstraint );
cVect cPivotJoint::Anchr2() {
return tovect( cpPivotJointGetAnchr2( mConstraint ) );
}
void cPivotJoint::Anchr2( const cpVect& anchr2 ) {
cpPivotJointSetAnchr2( mConstraint, anchr2 );
void cPivotJoint::Anchr2( const cVect& anchr2 ) {
cpPivotJointSetAnchr2( mConstraint, tocpv( anchr2 ) );
}
void cPivotJoint::Draw() {
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cpPivotJoint *joint = (cpPivotJoint *)mConstraint;
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cpPivotJoint* joint = (cpPivotJoint *)mConstraint;
cVect a = tovect( cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot)) );
cVect b = tovect( cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot)) );
cBatchRenderer * BR = cGlobalBatchRenderer::instance();
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
glPointSize(10.0f);
glBegin(GL_POINTS); {
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
} glEnd();
cpFloat ps = BR->GetPointSize();
BR->SetPointSize( 10.f );
BR->PointsBegin();
BR->PointSetColor( eeColorA( 128, 255, 128, 255 ) );
BR->BatchPoint( a.x, a.y );
BR->BatchPoint( b.x, b.y );
BR->Draw();
BR->SetPointSize( ps );
}
}}

View File

@@ -7,17 +7,17 @@ namespace EE { namespace Physics {
class cPivotJoint : public cConstraint {
public:
cPivotJoint( cBody * a, cBody * b, cpVect pivot );
cPivotJoint( cBody * a, cBody * b, cVect pivot );
cPivotJoint( cBody * a, cBody * b, cpVect anchr1, cpVect anchr2 );
cPivotJoint( cBody * a, cBody * b, cVect anchr1, cVect anchr2 );
cpVect Anchr1();
cVect Anchr1();
void Anchr1( const cpVect& anchr1 );
void Anchr1( const cVect& anchr1 );
cpVect Anchr2();
cVect Anchr2();
void Anchr2( const cpVect& anchr2 );
void Anchr2( const cVect& anchr2 );
virtual void Draw();
};

View File

@@ -2,25 +2,25 @@
namespace EE { namespace Physics {
cSlideJoint::cSlideJoint( cBody * a, cBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max ) {
mConstraint = cpSlideJointNew( a->Body(), b->Body(), anchr1, anchr2, min, max );
cSlideJoint::cSlideJoint( cBody * a, cBody *b, cVect anchr1, cVect anchr2, cpFloat min, cpFloat max ) {
mConstraint = cpSlideJointNew( a->Body(), b->Body(), tocpv( anchr1 ), tocpv( anchr2 ), min, max );
SetData();
}
cpVect cSlideJoint::Anchr1() {
return cpSlideJointGetAnchr1( mConstraint );
cVect cSlideJoint::Anchr1() {
return tovect( cpSlideJointGetAnchr1( mConstraint ) );
}
void cSlideJoint::Anchr1( const cpVect& anchr1 ) {
cpSlideJointSetAnchr1( mConstraint, anchr1 );
void cSlideJoint::Anchr1( const cVect& anchr1 ) {
cpSlideJointSetAnchr1( mConstraint, tocpv( anchr1 ) );
}
cpVect cSlideJoint::Anchr2() {
return cpSlideJointGetAnchr2( mConstraint );
cVect cSlideJoint::Anchr2() {
return tovect( cpSlideJointGetAnchr2( mConstraint ) );
}
void cSlideJoint::Anchr2( const cpVect& anchr2 ) {
cpSlideJointSetAnchr2( mConstraint, anchr2 );
void cSlideJoint::Anchr2( const cVect& anchr2 ) {
cpSlideJointSetAnchr2( mConstraint, tocpv( anchr2 ) );
}
cpFloat cSlideJoint::Min() {
@@ -40,23 +40,25 @@ void cSlideJoint::Max( const cpFloat& max ) {
}
void cSlideJoint::Draw() {
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cpBody * body_a = mConstraint->a;
cpBody * body_b = mConstraint->b;
cpSlideJoint *joint = (cpSlideJoint *)mConstraint;
cVect a = tovect( cpvadd( body_a->p, cpvrotate( joint->anchr1, body_a->rot ) ) );
cVect b = tovect( cpvadd( body_b->p, cpvrotate( joint->anchr2, body_b->rot ) ) );
cpVect a = cpvadd(body_a->p, cpvrotate(joint->anchr1, body_a->rot));
cpVect b = cpvadd(body_b->p, cpvrotate(joint->anchr2, body_b->rot));
cBatchRenderer * BR = cGlobalBatchRenderer::instance();
cpFloat ps = BR->GetPointSize();
glPointSize(5.0f);
glBegin(GL_POINTS); {
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
} glEnd();
glBegin(GL_LINES); {
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
} glEnd();
BR->SetPointSize( 5.0f );
BR->PointsBegin();
BR->PointSetColor( eeColorA( 128, 255, 128, 255 ) );
BR->BatchPoint( a.x, a.y );
BR->BatchPoint( b.x, b.y );
BR->DrawOpt();
BR->LinesBegin();
BR->BatchLine( a.x, a.y, b.x, b.y );
BR->Draw();
BR->SetPointSize( ps );
}
}}

View File

@@ -7,15 +7,15 @@ namespace EE { namespace Physics {
class cSlideJoint : public cConstraint {
public:
cSlideJoint( cBody * a, cBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max );
cSlideJoint( cBody * a, cBody *b, cVect anchr1, cVect anchr2, cpFloat min, cpFloat max );
cpVect Anchr1();
cVect Anchr1();
void Anchr1( const cpVect& anchr1 );
void Anchr1( const cVect& anchr1 );
cpVect Anchr2();
cVect Anchr2();
void Anchr2( const cpVect& anchr2 );
void Anchr2( const cVect& anchr2 );
cpFloat Min();

View File

@@ -27,12 +27,12 @@ cpBB cShape::CacheBB() {
return cpShapeCacheBB( mShape );
}
cpBB cShape::Update( cpVect pos, cpVect rot ) {
return cpShapeUpdate( mShape, pos, rot );
cpBB cShape::Update( cVect pos, cVect rot ) {
return cpShapeUpdate( mShape, tocpv( pos ), tocpv( rot ) );
}
bool cShape::PointQuery( cpVect p ) {
return 0 != cpShapePointQuery( mShape, p );
bool cShape::PointQuery( cVect p ) {
return 0 != cpShapePointQuery( mShape, tocpv( p ) );
}
cBody * cShape::Body() const {
@@ -67,6 +67,14 @@ void cShape::e( const cpFloat& e ) {
mShape->e = e;
}
cpFloat cShape::Elasticity() const {
return e();
}
void cShape::Elasticity( const cpFloat& e ) {
this->e( e );
}
cpFloat cShape::u() const {
return mShape->u;
}
@@ -75,12 +83,20 @@ void cShape::u( const cpFloat& u ) {
mShape->u = u;
}
cpVect cShape::SurfaceVel() const {
return mShape->surface_v;
cpFloat cShape::Friction() const {
return u();
}
void cShape::SurfaceVel( const cpVect& vel ) {
mShape->surface_v = vel;
void cShape::Friction( const cpFloat& u ) {
this->u( u );
}
cVect cShape::SurfaceVel() const {
return tovect( mShape->surface_v );
}
void cShape::SurfaceVel( const cVect& vel ) {
mShape->surface_v = tocpv( vel );
}
cpCollisionType cShape::CollisionType() const {
@@ -108,7 +124,7 @@ void cShape::Layers( const cpLayers& layers ) {
}
cpShapeType cShape::Type() const {
return mShape->klass->type;
return mShape->CP_PRIVATE(klass)->type;
}
cShapePoly * cShape::GetAsPoly() {
@@ -130,14 +146,12 @@ cShapeSegment * cShape::GetAsSegment() {
}
void cShape::DrawBB() {
glBegin(GL_LINE_LOOP);
glVertex2f(mShape->bb.l, mShape->bb.b);
glVertex2f(mShape->bb.l, mShape->bb.t);
glVertex2f(mShape->bb.r, mShape->bb.t);
glVertex2f(mShape->bb.r, mShape->bb.b);
glEnd();
cBatchRenderer * BR = cGlobalBatchRenderer::instance();
BR->LineLoopBegin();
BR->LineLoopSetColor( eeColorA( 76, 128, 76, 255 ) );
BR->BatchLineLoop( mShape->bb.l, mShape->bb.b, mShape->bb.l, mShape->bb.t );
BR->BatchLineLoop( mShape->bb.r, mShape->bb.t, mShape->bb.r, mShape->bb.b );
BR->DrawOpt();
}
}}

View File

@@ -35,13 +35,21 @@ class cShape {
void e( const cpFloat& e );
cpFloat Elasticity() const;
void Elasticity( const cpFloat& e );
cpFloat u() const;
void u( const cpFloat& u );
cpVect SurfaceVel() const;
cpFloat Friction() const;
void SurfaceVel( const cpVect& vel );
void Friction( const cpFloat& u );
cVect SurfaceVel() const;
void SurfaceVel( const cVect& vel );
cpCollisionType CollisionType() const;
@@ -57,9 +65,9 @@ class cShape {
cpBB CacheBB();
cpBB Update( cpVect pos, cpVect rot );
cpBB Update( cVect pos, cVect rot );
bool PointQuery( cpVect p );
bool PointQuery( cVect p );
cpShapeType Type() const;

View File

@@ -3,17 +3,21 @@
namespace EE { namespace Physics {
cShapeCircle::cShapeCircle( cBody * body, cpFloat radius, cpVect offset ) {
mShape = cpCircleShapeNew( body->Body(), radius, offset );
cShapeCircle * cShapeCircle::New( cBody * body, cpFloat radius, cVect offset ) {
return eeNew( cShapeCircle, ( body, radius, offset ) );
}
cShapeCircle::cShapeCircle( cBody * body, cpFloat radius, cVect offset ) {
mShape = cpCircleShapeNew( body->Body(), radius, tocpv( offset ) );
SetData();
}
cpVect cShapeCircle::Offset() {
return cpCircleShapeGetOffset( mShape );
cVect cShapeCircle::Offset() {
return tovect( cpCircleShapeGetOffset( mShape ) );
}
void cShapeCircle::Offset( const cpVect &offset ) {
cpCircleShapeSetOffset( mShape, offset );
void cShapeCircle::Offset( const cVect &offset ) {
cpCircleShapeSetOffset( mShape, tocpv( offset ) );
}
cpFloat cShapeCircle::Radius() {
@@ -28,30 +32,9 @@ void cShapeCircle::Draw( cSpace * space ) {
cPrimitives p;
cpCircleShape * cs = (cpCircleShape*)mShape;
p.SetColor( ColorForShape( mShape, space->Space() ) );
p.DrawCircle( cs->tc.x, cs->tc.y, cs->r );
/*glVertexPointer( 2, GL_FLOAT, 0, circleVAR );
cpCircleShape * cs = (cpCircleShape*)mShape;
glPushMatrix();
cpVect center = cs->tc;
glTranslatef( center.x, center.y, 0.0f );
glRotatef( space->StaticBody()->Body()->a * 180.0f / M_PI, 0.0f, 0.0f, 1.0f);
glScalef( cs->r, cs->r, 1.0f);
if(!cs->shape.sensor){
glColor_for_shape( mShape, space->Space() );
glDrawArrays(GL_TRIANGLE_FAN, 0, circleVAR_count - 1);
}
glColor3f(LINE_COLOR);
glDrawArrays(GL_LINE_STRIP, 0, circleVAR_count);
glPopMatrix();*/
p.DrawCircle( cs->CP_PRIVATE(tc).x, cs->CP_PRIVATE(tc).y, cs->CP_PRIVATE(r) );
}
}}

View File

@@ -7,11 +7,13 @@ namespace EE { namespace Physics {
class cShapeCircle : public cShape {
public:
cShapeCircle( cBody * body, cpFloat radius, cpVect offset );
static cShapeCircle * New( cBody * body, cpFloat radius, cVect offset );
cpVect Offset();
cShapeCircle( cBody * body, cpFloat radius, cVect offset );
void Offset( const cpVect& offset );
cVect Offset();
void Offset( const cVect& offset );
cpFloat Radius();

View File

@@ -3,8 +3,16 @@
namespace EE { namespace Physics {
cShapePoly::cShapePoly( cBody * body, int numVerts, cpVect *verts, cpVect offset ) {
mShape = cpPolyShapeNew( body->Body(), numVerts, verts, offset );
cShapePoly * cShapePoly::New( cBody * body, int numVerts, cVect *verts, cVect offset ) {
return eeNew( cShapePoly, ( body, numVerts, verts, offset ) );
}
cShapePoly * cShapePoly::New( cBody * body, cpFloat width, cpFloat height ) {
return eeNew( cShapePoly, ( body, width, height ) );
}
cShapePoly::cShapePoly( cBody * body, int numVerts, cVect *verts, cVect offset ) {
mShape = cpPolyShapeNew( body->Body(), numVerts, casttocpv( verts ), tocpv( offset ) );
SetData();
}
@@ -12,41 +20,61 @@ cShapePoly::cShapePoly( cBody * body, cpFloat width, cpFloat height ) :
cShape()
{
mShape = cpBoxShapeNew( body->Body(), width, height );
SetData();
}
bool cShapePoly::Validate( const cpVect * verts, const int numVerts ) {
return 0 != cpPolyValidate( verts, numVerts );
bool cShapePoly::Validate( const cVect * verts, const int numVerts ) {
return 0 != cpPolyValidate( constcasttocpv( verts ), numVerts );
}
int cShapePoly::GetNumVerts() {
return cpPolyShapeGetNumVerts( mShape );
}
cpVect cShapePoly::GetVert( int idx ) {
return cpPolyShapeGetVert( mShape, idx );
cVect cShapePoly::GetVert( int idx ) {
return tovect( cpPolyShapeGetVert( mShape, idx ) );
}
void cShapePoly::SetVerts( int numVerts, cpVect *verts, cpVect offset ) {
cpPolyShapeSetVerts( mShape, numVerts, verts, offset );
void cShapePoly::SetVerts( int numVerts, cVect *verts, cVect offset ) {
cpPolyShapeSetVerts( mShape, numVerts, casttocpv( verts ), tocpv( offset ) );
}
void cShapePoly::Recenter( int numVerts, cVect *verts ) {
cpRecenterPoly( numVerts, casttocpv( verts ) );
}
cVect cShapePoly::Centroid( int numVerts, const cVect * verts ) {
return tovect( cpCentroidForPoly( numVerts, constcasttocpv( verts ) ) );
}
void cShapePoly::Draw( cSpace * space ) {
cpPolyShape *poly = (cpPolyShape*)mShape;
cpPolyShape * poly = (cpPolyShape*)mShape;
int count = poly->numVerts;
#if CP_USE_DOUBLES
glVertexPointer(2, GL_DOUBLE, 0, poly->tVerts);
#else
glVertexPointer(2, GL_FLOAT, 0, poly->tVerts);
#endif
cBatchRenderer * BR = cGlobalBatchRenderer::instance();
if(!poly->shape.sensor){
glColor_for_shape((cpShape *)poly, space->Space());
glDrawArrays(GL_TRIANGLE_FAN, 0, count);
BR->SetTexture( NULL );
eeColorA Col = ColorForShape( (cpShape *)poly, space->Space() );
// Could be a triangle fan
BR->PointsBegin();
BR->PolygonSetColor( Col );
if( !poly->CP_PRIVATE(shape).sensor ){
for ( int i = 0; i < poly->CP_PRIVATE(numVerts); i++ ) {
BR->BatchPolygonByPoint( poly->CP_PRIVATE(tVerts)[i].x, poly->CP_PRIVATE(tVerts)[i].y );
}
BR->DrawOpt();
}
glColor3f(LINE_COLOR);
glDrawArrays(GL_LINE_LOOP, 0, count);
BR->LineLoopSetColor( Col );
for ( int i = 0; i < poly->CP_PRIVATE(numVerts); i++ ) {
BR->BatchLineLoop( poly->CP_PRIVATE(tVerts)[i].x, poly->CP_PRIVATE(tVerts)[i].y );
}
BR->DrawOpt();
}
}}

View File

@@ -7,19 +7,27 @@ namespace EE { namespace Physics {
class cShapePoly : public cShape {
public:
cShapePoly( cBody * body, int numVerts, cpVect *verts, cpVect offset );
static cShapePoly * New( cBody * body, int numVerts, cVect *verts, cVect offset );
static cShapePoly * New( cBody * body, cpFloat width, cpFloat height );
cShapePoly( cBody * body, int numVerts, cVect *verts, cVect offset );
cShapePoly( cBody * body, cpFloat width, cpFloat height );
static bool Validate( const cpVect * verts, const int numVerts );
static bool Validate( const cVect * verts, const int numVerts );
int GetNumVerts();
cpVect GetVert( int idx );
cVect GetVert( int idx );
void SetVerts( int numVerts, cpVect *verts, cpVect offset );
void SetVerts( int numVerts, cVect *verts, cVect offset );
virtual void Draw( cSpace * space );
static void Recenter( int numVerts, cVect * verts );
static cVect Centroid( int numVerts, const cVect * verts );
};
}}

View File

@@ -3,21 +3,25 @@
namespace EE { namespace Physics {
cShapeSegment::cShapeSegment( cBody * body, cpVect a, cpVect b, cpFloat radius ) {
mShape = cpSegmentShapeNew( body->Body(), a, b, radius );
cShapeSegment * cShapeSegment::New( cBody * body, cVect a, cVect b, cpFloat radius ) {
return eeNew( cShapeSegment, ( body, a, b, radius ) );
}
cShapeSegment::cShapeSegment( cBody * body, cVect a, cVect b, cpFloat radius ) {
mShape = cpSegmentShapeNew( body->Body(), tocpv( a ), tocpv( b ), radius );
SetData();
}
cpVect cShapeSegment::A() {
return cpSegmentShapeGetA( mShape );
cVect cShapeSegment::A() {
return tovect( cpSegmentShapeGetA( mShape ) );
}
cpVect cShapeSegment::B() {
return cpSegmentShapeGetB( mShape );
cVect cShapeSegment::B() {
return tovect( cpSegmentShapeGetB( mShape ) );
}
cpVect cShapeSegment::Normal() {
return cpSegmentShapeGetNormal( mShape );
cVect cShapeSegment::Normal() {
return tovect( cpSegmentShapeGetNormal( mShape ) );
}
cpFloat cShapeSegment::Radius() {
@@ -28,64 +32,66 @@ void cShapeSegment::Radius( const cpFloat& radius ) {
cpSegmentShapeSetRadius( mShape, radius );
}
void cShapeSegment::Endpoints( const cpVect& a, const cpVect& b ) {
cpSegmentShapeSetEndpoints( mShape, a, b );
void cShapeSegment::Endpoints( const cVect& a, const cVect& b ) {
cpSegmentShapeSetEndpoints( mShape, tocpv( a ), tocpv( b ) );
}
bool cShapeSegment::Query( cpVect a, cpVect b, cpSegmentQueryInfo * info ) {
return 0 != cpShapeSegmentQuery( mShape, a, b, info );
bool cShapeSegment::Query( cVect a, cVect b, cpSegmentQueryInfo * info ) {
return 0 != cpShapeSegmentQuery( mShape, tocpv( a ), tocpv( b ), info );
}
cpVect cShapeSegment::HitPoint( const cpVect start, const cpVect end, const cpSegmentQueryInfo info ) {
return cpSegmentQueryHitPoint( start, end, info );
cVect cShapeSegment::QueryHitPoint( const cVect start, const cVect end, const cpSegmentQueryInfo info ) {
return tovect( cpSegmentQueryHitPoint( tocpv( start ), tocpv( end ), info ) );
}
cpFloat cShapeSegment::HitDist( const cpVect start, const cpVect end, const cpSegmentQueryInfo info ) {
return cpSegmentQueryHitDist( start, end, info );
cpFloat cShapeSegment::QueryHitDist( const cVect start, const cVect end, const cpSegmentQueryInfo info ) {
return cpSegmentQueryHitDist( tocpv( start ), tocpv( end ), info );
}
void cShapeSegment::Draw( cSpace * space ) {
cPrimitives p;
cpSegmentShape * seg = (cpSegmentShape *)mShape;
cpVect a = seg->ta;
cpVect b = seg->tb;
cVect a = tovect( seg->CP_PRIVATE(ta) );
cVect b = tovect( seg->CP_PRIVATE(tb) );
p.DrawLine( eeVector2f( a.x, a.y ), eeVector2f( b.x, b.y ) );
/*cpSegmentShape * seg = (cpSegmentShape *)mShape;
if ( seg->CP_PRIVATE(r) ) {
glDisable( GL_TEXTURE_2D );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
cpVect a = seg->ta;
cpVect b = seg->tb;
if(seg->r){
glVertexPointer(3, GL_FLOAT, 0, pillVAR);
glPushMatrix(); {
cpVect d = cpvsub(b, a);
cpVect r = cpvmult(d, seg->r/cpvlength(d));
glPushMatrix();
const GLfloat matrix[] = {
r.x, r.y, 0.0f, 0.0f,
-r.y, r.x, 0.0f, 0.0f,
d.x, d.y, 0.0f, 0.0f,
a.x, a.y, 0.0f, 1.0f,
};
glMultMatrixf(matrix);
cVect d = b - a;
cVect r = d * ( seg->CP_PRIVATE(r) / cpvlength( tocpv( d ) ) );
if(!seg->shape.sensor){
glColor_for_shape((cpShape *)seg, space->Space());
glDrawArrays(GL_TRIANGLE_FAN, 0, pillVAR_count);
}
const GLfloat matrix[] = {
r.x, r.y, 0.0f, 0.0f,
-r.y, r.x, 0.0f, 0.0f,
d.x, d.y, 0.0f, 0.0f,
a.x, a.y, 0.0f, 1.0f,
};
glMultMatrixf(matrix);
glColor3f(LINE_COLOR);
glDrawArrays(GL_LINE_LOOP, 0, pillVAR_count);
} glPopMatrix();
if( !seg->CP_PRIVATE(shape).sensor ){
eeColorA C = ColorForShape( mShape, space->Space() );
glColor3ub( C.R(), C.B(), C.B() );
glDrawArrays(GL_TRIANGLE_FAN, 0, pillVAR_count);
}
glColor3f( 0.4f, 0.4f, 0.4f );
glDrawArrays( GL_LINE_LOOP, 0, pillVAR_count );
glPopMatrix();
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
glEnable( GL_TEXTURE_2D );
} else {
glColor3f(LINE_COLOR);
glBegin(GL_LINES); {
glVertex2f(a.x, a.y);
glVertex2f(b.x, b.y);
} glEnd();
}*/
cPrimitives p;
p.DrawLine( eeVector2f( a.x, a.y ), eeVector2f( b.x, b.y ) );
}
}
}}

View File

@@ -7,25 +7,27 @@ namespace EE { namespace Physics {
class cShapeSegment : public cShape {
public:
cShapeSegment( cBody * body, cpVect a, cpVect b, cpFloat radius );
static cShapeSegment * New( cBody * body, cVect a, cVect b, cpFloat radius );
cpVect A();
cShapeSegment( cBody * body, cVect a, cVect b, cpFloat radius );
cpVect B();
cVect A();
cpVect Normal();
cVect B();
cVect Normal();
cpFloat Radius();
void Radius( const cpFloat& radius );
void Endpoints( const cpVect& a, const cpVect& b );
void Endpoints( const cVect& a, const cVect& b );
bool Query( cpVect a, cpVect b, cpSegmentQueryInfo * info );
bool Query( cVect a, cVect b, cpSegmentQueryInfo * info );
static cpVect HitPoint( const cpVect start, const cpVect end, const cpSegmentQueryInfo info );
static cVect QueryHitPoint( const cVect start, const cVect end, const cpSegmentQueryInfo info );
static cpFloat HitDist( const cpVect start, const cpVect end, const cpSegmentQueryInfo info );
static cpFloat QueryHitDist( const cVect start, const cVect end, const cpSegmentQueryInfo info );
virtual void Draw( cSpace * space );
};

View File

@@ -3,6 +3,10 @@
namespace EE { namespace Physics {
cSpace * cSpace::New() {
return eeNew( cSpace, () );
}
cSpace::cSpace() {
mSpace = cpSpaceNew();
mSpace->data = (void*)this;
@@ -28,12 +32,12 @@ cSpace::~cSpace() {
eeSAFE_DELETE( mStaticBody );
}
void cSpace::Update( const cpFloat& dt ) {
void cSpace::Step( const cpFloat& dt ) {
cpSpaceStep( mSpace, dt );
}
void cSpace::Update() {
Update( cEngine::instance()->Elapsed() / 1000 );
Step( cEngine::instance()->Elapsed() / 1000 );
}
void cSpace::ResizeStaticHash( cpFloat dim, int count ) {
@@ -56,12 +60,12 @@ void cSpace::Iterations( const int& iterations ) {
mSpace->iterations = iterations;
}
const cpVect& cSpace::Gravity() const {
return mSpace->gravity;
cVect cSpace::Gravity() const {
return tovect( mSpace->gravity );
}
void cSpace::Gravity( const cpVect& gravity ) {
mSpace->gravity = gravity;
void cSpace::Gravity( const cVect& gravity ) {
mSpace->gravity = tocpv( gravity );
}
const cpFloat& cSpace::Damping() const {
@@ -136,6 +140,26 @@ void cSpace::RemoveConstraint( cConstraint * constraint ) {
mConstraints.remove( constraint );
}
cShape * cSpace::PointQueryFirst( cVect point, cpLayers layers, cpGroup group ) {
cpShape * shape = cpSpacePointQueryFirst( mSpace, tocpv( point ), layers, group );
if ( NULL != shape ) {
return reinterpret_cast<cShape*> ( shape->data );
}
return NULL;
}
cShape * cSpace::SegmentQueryFirst( cVect start, cVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo * out ) {
cpShape * shape = cpSpaceSegmentQueryFirst( mSpace, tocpv( start ), tocpv( end ), layers, group, out );
if ( NULL != shape ) {
return reinterpret_cast<cShape*> ( shape->data );
}
return NULL;
}
cpSpace * cSpace::Space() const {
return mSpace;
}
@@ -161,78 +185,269 @@ static void drawConstraint( cpConstraint *constraint ) {
}
void cSpace::Draw() {
cBatchRenderer * BR = cGlobalBatchRenderer::instance();
cPhysicsManager::cDrawSpaceOptions * options = cPhysicsManager::instance()->GetDrawOptions();
cpFloat lw = BR->GetLineWidth();
cpFloat ps = BR->GetPointSize();
if( options->DrawHash ) {
glColor3f(0.5, 0.5, 0.5);
//glColor3f(0.5, 0.5, 0.5);
//cpBBTreeRenderDebug( mSpace->staticShapes );
glColor3f(0, 1, 0);
//glColor3f(0, 1, 0);
//cpBBTreeRenderDebug( mSpace->activeShapes );
}
glLineWidth( options->LineThickness );
BR->SetLineWidth( options->LineThickness );
if( options->DrawShapes ) {
cpSpatialIndexEach( mSpace->activeShapes, (cpSpatialIndexIterator)drawObject, mSpace );
cpSpatialIndexEach( mSpace->staticShapes, (cpSpatialIndexIterator)drawObject, mSpace );
cpSpatialIndexEach( mSpace->CP_PRIVATE(activeShapes), (cpSpatialIndexIterator)drawObject, mSpace );
cpSpatialIndexEach( mSpace->CP_PRIVATE(staticShapes), (cpSpatialIndexIterator)drawObject, mSpace );
}
glLineWidth( 1.0f );
BR->SetLineWidth( lw );
if( options->DrawBBs ){
glColor3f( 0.3f, 0.5f, 0.3f );
cpSpatialIndexEach(mSpace->activeShapes, (cpSpatialIndexIterator)drawBB, NULL);
cpSpatialIndexEach(mSpace->staticShapes, (cpSpatialIndexIterator)drawBB, NULL);
cpSpatialIndexEach(mSpace->CP_PRIVATE(activeShapes), (cpSpatialIndexIterator)drawBB, NULL);
cpSpatialIndexEach(mSpace->CP_PRIVATE(staticShapes), (cpSpatialIndexIterator)drawBB, NULL);
}
cpArray * constraints = mSpace->constraints;
glColor3f(0.5f, 1.0f, 0.5f);
cpArray * constraints = mSpace->CP_PRIVATE(constraints);
for( int i=0, count = constraints->num; i<count; i++ ) {
drawConstraint( (cpConstraint *)constraints->arr[i] );
}
if( options->BodyPointSize ){
glPointSize( options->BodyPointSize );
if( options->BodyPointSize ) {
BR->SetPointSize( options->BodyPointSize );
BR->PointsBegin();
BR->PointSetColor( eeColorA( 255, 255, 255, 255 ) );
glBegin(GL_POINTS);
glColor3f(LINE_COLOR);
cpArray * bodies = mSpace->bodies;
cpArray * bodies = mSpace->CP_PRIVATE(bodies);
for( int i=0, count = bodies->num; i<count; i++ ) {
cpBody * body = (cpBody *)bodies->arr[i];
glVertex2f( body->p.x, body->p.y );
BR->BatchPoint( body->p.x, body->p.y );
}
glEnd();
BR->Draw();
}
if( options->CollisionPointSize ){
glPointSize( options->CollisionPointSize );
if ( options->CollisionPointSize ) {
BR->SetPointSize( options->CollisionPointSize );
BR->PointsBegin();
BR->PointSetColor( eeColorA( 255, 0, 0, 255 ) );
glBegin( GL_POINTS );
cpArray * arbiters = mSpace->arbiters;
cpArray * arbiters = mSpace->CP_PRIVATE(arbiters);
for( int i = 0; i < arbiters->num; i++ ){
cpArbiter *arb = (cpArbiter*)arbiters->arr[i];
glColor3f( COLLISION_COLOR );
for(int i=0; i<arb->numContacts; i++){
cpVect v = arb->contacts[i].p;
glVertex2f( v.x, v.y );
for( int i=0; i< arb->CP_PRIVATE(numContacts); i++ ){
cVect v = tovect( arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p) );
BR->BatchPoint( v.x, v.y );
}
}
glEnd();
BR->Draw();
}
BR->SetLineWidth( lw );
BR->SetPointSize( ps );
}
/** Collision Handling */
static cpBool RecieverCollisionBeginFunc( cpArbiter * arb, cpSpace * space, void * data ) {
cSpace * tspace = reinterpret_cast<cSpace*>( space->data );
cArbiter tarb( arb );
return tspace->OnCollisionBegin( &tarb, data );
}
static cpBool RecieverCollisionPreSolveFunc( cpArbiter * arb, cpSpace * space, void * data ) {
cSpace * tspace = reinterpret_cast<cSpace*>( space->data );
cArbiter tarb( arb );
return tspace->OnCollisionPreSolve( &tarb, data );
}
static void RecieverCollisionPostSolve( cpArbiter * arb, cpSpace * space, void * data ) {
cSpace * tspace = reinterpret_cast<cSpace*>( space->data );
cArbiter tarb( arb );
tspace->OnCollisionPostSolve( &tarb, data );
}
static void RecieverCollisionSeparateFunc( cpArbiter * arb, cpSpace * space, void * data ) {
cSpace * tspace = reinterpret_cast<cSpace*>( space->data );
cArbiter tarb( arb );
tspace->OnCollisionSeparate( &tarb, data );
}
static void RecieverPostStepCallback( cpSpace * space, void * obj, void * data ) {
cSpace * tspace = reinterpret_cast<cSpace*>( space->data );
tspace->OnPostStepCallback( obj, data );
}
static void RecieverBBQueryFunc( cpShape * shape, void * data ) {
cSpace::cBBQuery * query = reinterpret_cast<cSpace::cBBQuery*>( data );
query->Space->OnBBQuery( reinterpret_cast<cShape*>( shape->data ), query );
}
static void RecieverSegmentQueryFunc( cpShape *shape, cpFloat t, cpVect n, void * data ) {
cSpace::cSegmentQuery * query = reinterpret_cast<cSpace::cSegmentQuery*>( data );
query->Space->OnSegmentQuery( reinterpret_cast<cShape*>( shape->data ), t, tovect( n ), query );
}
static void RecieverPointQueryFunc( cpShape * shape, void * data ) {
cSpace::cPointQuery * query = reinterpret_cast<cSpace::cPointQuery*>( data );
query->Space->OnPointQuery( reinterpret_cast<cShape*>( shape->data ), query );
}
cpBool cSpace::OnCollisionBegin( cArbiter * arb, void * data ) {
std::map< cpHashValue, cCollisionHandler >::iterator it = mCollisions.find( arb->Arbiter()->CP_PRIVATE(contacts)->CP_PRIVATE(hash) );
cCollisionHandler handler = static_cast<cCollisionHandler>( it->second );
if ( it != mCollisions.end() && handler.begin.IsSet() )
return handler.begin( arb, this, data );
else if ( mCollisionsDefault.begin.IsSet() )
return mCollisionsDefault.begin( arb, this, data );
return 1;
}
cpBool cSpace::OnCollisionPreSolve( cArbiter * arb, void * data ) {
std::map< cpHashValue, cCollisionHandler >::iterator it = mCollisions.find( arb->Arbiter()->CP_PRIVATE(contacts)->CP_PRIVATE(hash) );
cCollisionHandler handler = static_cast<cCollisionHandler>( it->second );
if ( it != mCollisions.end() && handler.preSolve.IsSet() )
return handler.preSolve( arb, this, data );
else if ( mCollisionsDefault.preSolve.IsSet() )
return mCollisionsDefault.preSolve( arb, this, data );
return 1;
}
void cSpace::OnCollisionPostSolve( cArbiter * arb, void * data ) {
std::map< cpHashValue, cCollisionHandler >::iterator it = mCollisions.find( arb->Arbiter()->CP_PRIVATE(contacts)->CP_PRIVATE(hash) );
cCollisionHandler handler = static_cast<cCollisionHandler>( it->second );
if ( it != mCollisions.end() && handler.postSolve.IsSet() )
handler.postSolve( arb, this, data );
else if ( mCollisionsDefault.begin.IsSet() )
mCollisionsDefault.postSolve( arb, this, data );
}
void cSpace::OnCollisionSeparate( cArbiter * arb, void * data ) {
std::map< cpHashValue, cCollisionHandler >::iterator it = mCollisions.find( arb->Arbiter()->CP_PRIVATE(contacts)->CP_PRIVATE(hash) );
cCollisionHandler handler = static_cast<cCollisionHandler>( it->second );
if ( it != mCollisions.end() && handler.separate.IsSet() )
handler.separate( arb, this, data );
else if ( mCollisionsDefault.begin.IsSet() )
mCollisionsDefault.separate( arb, this, data );
}
void cSpace::OnPostStepCallback( void * obj, void * data ) {
cPostStepCallback * Cb = reinterpret_cast<cPostStepCallback *> ( data );
if ( Cb->Callback.IsSet() )
Cb->Callback( this, obj, Cb->Data );
mPostStepCallbacks.remove( Cb );
eeSAFE_DELETE( Cb );
}
void cSpace::OnBBQuery( cShape * shape, cBBQuery * query ) {
if ( query->Func.IsSet() )
query->Func( shape, query->Data );
}
void cSpace::OnSegmentQuery( cShape * shape, cpFloat t, cVect n , cSegmentQuery * query ) {
if ( query->Func.IsSet() )
query->Func( shape, t, n, query->Data );
}
void cSpace::OnPointQuery( cShape * shape, cPointQuery * query ) {
if ( query->Func.IsSet() )
query->Func( shape, query->Data );
}
void cSpace::AddCollisionHandler( cpCollisionType a, cpCollisionType b, CollisionBeginFunc begin, CollisionPreSolveFunc preSolve, CollisionPostSolveFunc postSolve, CollisionSeparateFunc separate, void * data ) {
cpSpaceAddCollisionHandler( mSpace, a, b, &RecieverCollisionBeginFunc, &RecieverCollisionPreSolveFunc, &RecieverCollisionPostSolve, &RecieverCollisionSeparateFunc, data );
cCollisionHandler handler;
handler.a = a;
handler.b = b;
handler.begin = begin;
handler.preSolve = preSolve;
handler.postSolve = postSolve;
handler.separate = separate;
handler.data = data;
mCollisions.erase( CP_HASH_PAIR( a, b ) );
mCollisions[ CP_HASH_PAIR( a, b ) ] = handler;
}
void cSpace::RemoveCollisionHandler( cpCollisionType a, cpCollisionType b ) {
cpSpaceRemoveCollisionHandler( mSpace, a, b );
mCollisions.erase( CP_HASH_PAIR( a, b ) );
}
void cSpace::SetDefaultCollisionHandler( CollisionBeginFunc begin, CollisionPreSolveFunc preSolve, CollisionPostSolveFunc postSolve, CollisionSeparateFunc separate, void * data ) {
cpSpaceSetDefaultCollisionHandler( mSpace, &RecieverCollisionBeginFunc, &RecieverCollisionPreSolveFunc, &RecieverCollisionPostSolve, &RecieverCollisionSeparateFunc, data );
mCollisionsDefault.begin = begin;
mCollisionsDefault.preSolve = preSolve;
mCollisionsDefault.postSolve = postSolve;
mCollisionsDefault.separate = separate;
mCollisionsDefault.data = data;
}
void cSpace::AddPostStepCallback( PostStepCallback postStep, void * obj, void * data ) {
cPostStepCallback * PostStepCb = eeNew( cPostStepCallback, () );
PostStepCb->Callback = postStep,
PostStepCb->Data = data;
cpSpaceAddPostStepCallback( mSpace, &RecieverPostStepCallback, obj, PostStepCb );
mPostStepCallbacks.push_back( PostStepCb );
}
void cSpace::BBQuery( cpBB bb, cpLayers layers, cpGroup group, BBQueryFunc func, void * data ) {
cBBQuery tBBQuery;
tBBQuery.Space = this;
tBBQuery.Data = data;
tBBQuery.Func = func;
cpSpaceBBQuery( mSpace, bb, layers, group, &RecieverBBQueryFunc, reinterpret_cast<void*>( &tBBQuery ) );
}
void cSpace::SegmentQuery( cVect start, cVect end, cpLayers layers, cpGroup group, SegmentQueryFunc func, void * data ) {
cSegmentQuery tSegmentQuery;
tSegmentQuery.Space = this;
tSegmentQuery.Data = data;
tSegmentQuery.Func = func;
cpSpaceSegmentQuery( mSpace, tocpv( start ), tocpv( end ), layers, group, &RecieverSegmentQueryFunc, reinterpret_cast<void*>( &tSegmentQuery ) );
}
void cSpace::PointQuery( cVect point, cpLayers layers, cpGroup group, PointQueryFunc func, void * data ) {
cPointQuery tPointQuery;
tPointQuery.Space = this;
tPointQuery.Data = data;
tPointQuery.Func = func;
cpSpacePointQuery( mSpace, tocpv( point ), layers, group, &RecieverPointQueryFunc, reinterpret_cast<void*>( &tPointQuery ) );
}
}}

View File

@@ -4,17 +4,89 @@
#include "base.hpp"
#include "cbody.hpp"
#include "cshape.hpp"
#include "carbiter.hpp"
#include "constraints/cconstraint.hpp"
namespace EE { namespace Physics {
class cSpace {
public:
typedef cb::Callback3<int , cArbiter *, cSpace * , void * > CollisionBeginFunc;
typedef cb::Callback3<int , cArbiter *, cSpace * , void * > CollisionPreSolveFunc;
typedef cb::Callback3<void , cArbiter *, cSpace * , void * > CollisionPostSolveFunc;
typedef cb::Callback3<void , cArbiter *, cSpace * , void * > CollisionSeparateFunc;
typedef cb::Callback3<void , cSpace * , void * , void * > PostStepCallback;
typedef cb::Callback2<void , cShape * , void * > BBQueryFunc;
typedef cb::Callback4<void , cShape * , cpFloat , cVect , void * > SegmentQueryFunc;
typedef cb::Callback2<void , cShape * , void * > PointQueryFunc;
class cCollisionHandler {
public:
cCollisionHandler() :
a( 0 ),
b( 0 ),
data( NULL )
{
}
cpCollisionType a;
cpCollisionType b;
CollisionBeginFunc begin;
CollisionPreSolveFunc preSolve;
CollisionPostSolveFunc postSolve;
CollisionSeparateFunc separate;
void * data;
};
class cPostStepCallback {
public:
cPostStepCallback() :
Data( NULL )
{}
PostStepCallback Callback;
void * Data;
};
class cBBQuery {
public:
cBBQuery() :
Data( NULL )
{}
cSpace * Space;
BBQueryFunc Func;
void * Data;
};
class cSegmentQuery {
public:
cSegmentQuery()
{}
cSpace * Space;
SegmentQueryFunc Func;
void * Data;
};
class cPointQuery {
public:
cPointQuery() :
Data( NULL )
{}
cSpace * Space;
PointQueryFunc Func;
void * Data;
};
static cSpace * New();
cSpace();
~cSpace();
void Update( const cpFloat& dt );
void Step( const cpFloat& dt );
void Update();
@@ -24,9 +96,9 @@ class cSpace {
void Iterations( const int& iterations );
const cpVect& Gravity() const;
cVect Gravity() const;
void Gravity( const cpVect& gravity );
void Gravity( const cVect& gravity );
const cpFloat& Damping() const;
@@ -69,12 +141,49 @@ class cSpace {
void ActivateShapesTouchingShape( cShape * shape );
virtual void Draw();
cShape * PointQueryFirst( cVect point, cpLayers layers, cpGroup group );
cShape * SegmentQueryFirst( cVect start, cVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo * out );
void AddCollisionHandler( cpCollisionType a, cpCollisionType b, CollisionBeginFunc begin, CollisionPreSolveFunc preSolve, CollisionPostSolveFunc postSolve, CollisionSeparateFunc separate, void * data );
void RemoveCollisionHandler( cpCollisionType a, cpCollisionType b );
void SetDefaultCollisionHandler( CollisionBeginFunc begin, CollisionPreSolveFunc preSolve, CollisionPostSolveFunc postSolve, CollisionSeparateFunc separate, void * data );
void AddPostStepCallback( PostStepCallback postStep, void * obj, void * data );
virtual cpBool OnCollisionBegin( cArbiter * arb, void * data );
virtual cpBool OnCollisionPreSolve( cArbiter * arb, void * data );
virtual void OnCollisionPostSolve( cArbiter * arb, void * data );
virtual void OnCollisionSeparate( cArbiter * arb, void * data );
virtual void OnPostStepCallback( void * obj, void * data );
virtual void OnBBQuery( cShape * shape, cBBQuery * query );
virtual void OnSegmentQuery( cShape * shape, cpFloat t, cVect n , cSegmentQuery * query );
virtual void OnPointQuery( cShape * shape, cPointQuery * query );
void BBQuery( cpBB bb, cpLayers layers, cpGroup group, BBQueryFunc func, void * data );
void SegmentQuery( cVect start, cVect end, cpLayers layers, cpGroup group, SegmentQueryFunc func, void * data );
void PointQuery( cVect point, cpLayers layers, cpGroup group, PointQueryFunc func, void * data );
protected:
cpSpace * mSpace;
cBody * mStaticBody;
std::list<cBody*> mBodys;
std::list<cShape*> mShapes;
std::list<cConstraint*> mConstraints;
cpSpace * mSpace;
cBody * mStaticBody;
std::list<cBody*> mBodys;
std::list<cShape*> mShapes;
std::list<cConstraint*> mConstraints;
std::map< cpHashValue, cCollisionHandler > mCollisions;
cCollisionHandler mCollisionsDefault;
std::list< cPostStepCallback* > mPostStepCallbacks;
};
}}

27
src/physics/moment.hpp Normal file
View File

@@ -0,0 +1,27 @@
#ifndef EE_PHYSICS_MOMENT_HPP
#define EE_PHYSICS_MOMENT_HPP
#include "base.hpp"
class Moment {
public:
public:
inline static cpFloat ForCircle( cpFloat m, cpFloat r1, cpFloat r2, cVect offset ) {
return cpMomentForCircle( m, r1, r2, tocpv( offset ) );
}
inline static cpFloat ForSegment( cpFloat m, cVect a, cVect b) {
return cpMomentForSegment( m, tocpv( a ), tocpv( b ) );
}
inline static cpFloat ForPoly( cpFloat m, int numVerts, const cVect *verts, cVect offset ) {
return cpMomentForPoly( m, numVerts, constcasttocpv( verts ), tocpv( offset ) );
}
inline static cpFloat ForBox( cpFloat m, cpFloat width, cpFloat height ) {
return cpMomentForBox( m, width, height );
}
};
#endif

View File

@@ -1,41 +1,6 @@
#ifndef EE_PHYSICS_HELPER
#define EE_PHYSICS_HELPER
#define LINE_COLOR 1.0f, 1.0f, 1.0f
#define COLLISION_COLOR 1.0f, 0.0f, 0.0f
#define BODY_COLOR 0.0f, 0.0f, 1.0f
static const GLfloat circleVAR[] = {
0.0000f, 1.0000f,
0.2588f, 0.9659f,
0.5000f, 0.8660f,
0.7071f, 0.7071f,
0.8660f, 0.5000f,
0.9659f, 0.2588f,
1.0000f, 0.0000f,
0.9659f, -0.2588f,
0.8660f, -0.5000f,
0.7071f, -0.7071f,
0.5000f, -0.8660f,
0.2588f, -0.9659f,
0.0000f, -1.0000f,
-0.2588f, -0.9659f,
-0.5000f, -0.8660f,
-0.7071f, -0.7071f,
-0.8660f, -0.5000f,
-0.9659f, -0.2588f,
-1.0000f, -0.0000f,
-0.9659f, 0.2588f,
-0.8660f, 0.5000f,
-0.7071f, 0.7071f,
-0.5000f, 0.8660f,
-0.2588f, 0.9659f,
0.0000f, 1.0000f,
0.0f, 0.0f, // For an extra line to see the rotation.
};
static const int circleVAR_count = sizeof(circleVAR)/sizeof(GLfloat)/2;
static const GLfloat pillVAR[] = {
0.0000f, 1.0000f, 1.0f,
0.2588f, 0.9659f, 1.0f,
@@ -67,7 +32,7 @@ static const GLfloat pillVAR[] = {
};
static const int pillVAR_count = sizeof(pillVAR)/sizeof(GLfloat)/3;
inline void glColor_from_pointer(void *ptr) {
inline eeColorA ColorFromPointer(void *ptr) {
unsigned long val = (long)ptr;
// hash the pointer up nicely
@@ -90,24 +55,26 @@ inline void glColor_from_pointer(void *ptr) {
g = (g*mult)/max + add;
b = (b*mult)/max + add;
glColor3ub(r, g, b);
return eeColorA(r, g, b, 255);
}
inline void glColor_for_shape( cpShape *shape, cpSpace *space ) {
inline eeColorA ColorForShape( cpShape *shape, cpSpace *space ) {
cpBody *body = shape->body;
int nc;
if(body){
if(cpBodyIsSleeping(body)){
GLfloat v = 0.25f;
glColor3f(v,v,v);
return;
} else if(body->node.idleTime > space->sleepTimeThreshold) {
nc = (int)( v * 255 );
return eeColorA( nc, nc, nc, 255 );
} else if(body->CP_PRIVATE(node).idleTime > space->sleepTimeThreshold) {
GLfloat v = 0.9f;
glColor3f(v,v,v);
return;
nc = (int)( v * 255 );
return eeColorA( nc, nc, nc, 255 );
}
}
glColor_from_pointer(shape);
return ColorFromPointer( shape );
}
static const GLfloat springVAR[] = {

View File

@@ -138,7 +138,7 @@ class cEETest : private cThread {
Int32 NH;
Uint8 Screen;
SceneCb Scenes[3];
SceneCb Scenes[4];
void Screen1();
void Screen2();
void Screen3();
@@ -221,12 +221,14 @@ class cEETest : private cThread {
cSpace * mSpace;
cBody * mMouseBody;
cpVect mMousePoint;
cpVect mMousePoint_last;
cVect mMousePoint;
cVect mMousePoint_last;
cConstraint * mMouseJoint;
void PhysicsCreate();
void PhysicsUpdate();
void PhysicsDestroy();
void SetScreen( Uint32 num );
};
void cEETest::CreateAquaTextureAtlas() {
@@ -247,7 +249,7 @@ void cEETest::CreateAquaTextureAtlas() {
void cEETest::Init() {
EE = cEngine::instance();
Screen = 0;
SetScreen( 0 );
run = false;
DrawBack = false;
MultiViewportMode = false;
@@ -299,9 +301,10 @@ void cEETest::Init() {
PS.resize(5);
Scenes[0] = cb::Make0( this, &cEETest::Screen1 );
Scenes[1] = cb::Make0( this, &cEETest::Screen2 );
Scenes[2] = cb::Make0( this, &cEETest::Screen3 );
Scenes[0] = cb::Make0( this, &cEETest::PhysicsUpdate );
Scenes[1] = cb::Make0( this, &cEETest::Screen1 );
Scenes[2] = cb::Make0( this, &cEETest::Screen2 );
Scenes[3] = cb::Make0( this, &cEETest::Screen3 );
InBuf.Start();
InBuf.SupportNewLine( true );
@@ -396,7 +399,7 @@ void cEETest::OnFontLoaded( cResourceLoader * ObjLoaded ) {
TTFB->ShrinkText( mBuda, 400 );
mBudaTC.Create( TTFB, mBuda, eeColorA(255,255,255,255) );
mEEText.Create( TTFB, L"Entropia Engine++\nCTRL + 1 = Screen 1 - CTRL + 2 = Screen 2\nCTRL + 3 = Screen 3" );
mEEText.Create( TTFB, L"Entropia Engine++\nCTRL + 1 = Physics\nCTRL + 2 = Screen 2 - CTRL + 3 = Screen 3\nCTRL + 4 = Screen 4" );
mFBOText.Create( TTFB, L"This is a VBO\nInside of a FBO" );
mInfoText.Create( FF, L"", eeColorA(255,255,255,150) );
@@ -648,6 +651,7 @@ void cEETest::CreateUI() {
Menu->Add( L"Show Screen 1" );
Menu->Add( L"Show Screen 2" );
Menu->Add( L"Show Screen 3" );
Menu->Add( L"Show Screen 4" );
Menu->AddSeparator();
Menu->AddCheckBox( L"Show Window" );
Menu->AddCheckBox( L"Multi Viewport" );
@@ -754,11 +758,13 @@ void cEETest::ItemClick( const cUIEvent * Event ) {
const std::wstring& txt = reinterpret_cast<cUIMenuItem*> ( Event->Ctrl() )->Text();
if ( L"Show Screen 1" == txt ) {
Screen = 0;
SetScreen( 0 );
} else if ( L"Show Screen 2" == txt ) {
Screen = 1;
SetScreen( 1 );
} else if ( L"Show Screen 3" == txt ) {
Screen = 2;
SetScreen( 2 );
} else if ( L"Show Screen 4" == txt ) {
SetScreen( 3 );
} else if ( L"Show Window" == txt ) {
cUIMenuCheckBox * Chk = reinterpret_cast<cUIMenuCheckBox*> ( Event->Ctrl() );
@@ -821,6 +827,16 @@ void cEETest::ButtonClick( const cUIEvent * Event ) {
}
}
void cEETest::SetScreen( Uint32 num ) {
if ( 0 == num )
EE->SetBackColor( eeColor( 240, 240, 240 ) );
else
EE->SetBackColor( eeColor( 0, 0, 0 ) );
if ( num < 4 )
Screen = num;
}
void cEETest::CmdSetPartsNum ( const std::vector < std::wstring >& params ) {
if ( params.size() >= 2 ) {
try {
@@ -1001,7 +1017,7 @@ void cEETest::Run() {
void cEETest::ParticlesThread() {
while ( cEngine::instance()->Running() ) {
if ( MultiViewportMode || Screen == 1 ) {
if ( MultiViewportMode || Screen == 2 ) {
PSElapsed = (eeFloat)cElapsed.Elapsed();
for ( Uint8 i = 0; i < PS.size(); i++ )
@@ -1299,8 +1315,6 @@ void cEETest::Render() {
}
}
PhysicsUpdate();
cUIManager::instance()->Update();
cUIManager::instance()->Draw();
@@ -1387,13 +1401,16 @@ void cEETest::Input() {
}
if ( KM->IsKeyUp(KEY_1) && KM->ControlPressed() )
Screen = 0;
SetScreen( 0 );
if ( KM->IsKeyUp(KEY_2) && KM->ControlPressed() )
Screen = 1;
SetScreen( 1 );
if ( KM->IsKeyUp(KEY_3) && KM->ControlPressed() )
Screen = 2;
SetScreen( 2 );
if ( KM->IsKeyUp(KEY_4) && KM->ControlPressed() )
SetScreen( 3 );
cJoystick * Joy = JM->GetJoystick(0);
@@ -1405,9 +1422,9 @@ void cEETest::Input() {
if ( Joy->IsButtonUp(1) ) KM->InjectButtonRelease(EE_BUTTON_RIGHT);
if ( Joy->IsButtonUp(2) ) KM->InjectButtonRelease(EE_BUTTON_WHEELUP);
if ( Joy->IsButtonUp(3) ) KM->InjectButtonRelease(EE_BUTTON_WHEELDOWN);
if ( Joy->IsButtonUp(4) ) Screen = 0;
if ( Joy->IsButtonUp(5) ) Screen = 1;
if ( Joy->IsButtonUp(6) ) Screen = 2;
if ( Joy->IsButtonUp(4) ) SetScreen( 0 );
if ( Joy->IsButtonUp(5) ) SetScreen( 1 );
if ( Joy->IsButtonUp(6) ) SetScreen( 2 );
if ( Joy->IsButtonUp(7) ) KM->InjectButtonRelease(EE_BUTTON_MIDDLE);
Int16 aX = Joy->GetAxis( AXIS_X );
@@ -1436,6 +1453,11 @@ void cEETest::Input() {
switch (Screen) {
case 0:
if ( KM->IsKeyUp( KEY_R ) ) {
PhysicsDestroy();
PhysicsCreate();
}
case 1:
if ( NULL != Joy ) {
Uint8 hat = Joy->GetHat();
@@ -1495,7 +1517,7 @@ void cEETest::Input() {
Map.SetTileHeight( P.x, P.y, 1, false );
}
break;
case 1:
case 2:
if ( KM->IsKeyUp(KEY_S) )
SP.SetRepeations(1);
@@ -1590,105 +1612,75 @@ void cEETest::PhysicsCreate() {
cPhysicsManager::CreateSingleton();
cPhysicsManager::instance()->CollisionSlop( 0.2 );
mMouseJoint = NULL;
mMouseJoint = NULL;
mMouseBody = eeNew( cBody, ( INFINITY, INFINITY ) );
mMouseBody = eeNew( cBody, ( INFINITY, INFINITY ) );
Physics::cShape::ResetShapeIdCounter();
// Create a space, a space is a simulation world. It simulates the motions of rigid bodies,
// handles collisions between them, and simulates the joints between them.
mSpace = eeNew( cSpace, () );
// Lets set some parameters of the space:
// More iterations make the simulation more accurate but slower
mSpace->Iterations( 10 );
// These parameters tune the efficiency of the collision detection.
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpSpace
mSpace->ResizeStaticHash( 30.0f, 1000 );
mSpace->ResizeActiveHash( 30.0f, 1000 );
// Give it some gravity
mSpace->Gravity( cpv(0, 1000) );
mSpace = Physics::cSpace::New();
mSpace->Iterations( 30 );
mSpace->ResizeStaticHash( 40.f, 1000 );
mSpace->ResizeActiveHash( 40.f, 1000 );
mSpace->Gravity( cVectNew( 0, 200 ) );
mSpace->SleepTimeThreshold( 0.5f );
// Create A ground segment along the bottom of the screen
// By attaching it to &space->staticBody instead of a body, we make it a static shape.
Physics::cShapeSegment * ground = eeNew( cShapeSegment, ( mSpace->StaticBody(), cpv(0,640), cpv(640, 640), 0.0f ) );
cBody *body, *staticBody = mSpace->StaticBody();
Physics::cShape * shape;
// Set some parameters of the shape.
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpShape
ground->e( 1.0f );
ground->u( 1.0f );
ground->Layers( NOT_GRABABLE_MASK ); // Used by the Demo mouse grabbing code
shape = mSpace->AddShape( cShapeSegment::New( staticBody, cVectNew( 0, EE->GetHeight() ), cVectNew( EE->GetWidth(), EE->GetHeight() ), 0.0f ) );
shape->e( 1.0f );
shape->u( 1.0f );
shape->Layers( NOT_GRABABLE_MASK );
// Add the shape to the space as a static shape
// If a shape never changes position, add it as static so Chipmunk knows it only needs to
// calculate collision information for it once when it is added.
// Do not change the postion of a static shape after adding it.
mSpace->AddShape( ground );
shape = mSpace->AddShape( cShapeSegment::New( staticBody, cVectNew( EE->GetWidth(), 100 ), cVectNew( EE->GetWidth(), EE->GetHeight() ), 0.0f ) );
shape->e( 1.0f );
shape->u( 1.0f );
shape->Layers( NOT_GRABABLE_MASK );
shape = mSpace->AddShape( cShapeSegment::New( staticBody, cVectNew( 0, 100 ), cVectNew( 0, EE->GetHeight() ), 0.0f ) );
shape->e( 1.0f );
shape->u( 1.0f );
shape->Layers( NOT_GRABABLE_MASK );
eeFloat hw = EE->GetWidth() / 2;
for(int i=0; i<14; i++){
for(int j=0; j<=i; j++){
body = mSpace->AddBody( cBody::New( 1.0f, Moment::ForBox( 1.0f, 30.0f, 30.0f ) ) );
body->Pos( cVectNew( hw + j * 32 - i * 16, 100 + i * 32 ) );
shape = mSpace->AddShape( cShapePoly::New( body, 30.f, 30.f ) );
shape->e( 0.0f );
shape->u( 0.8f );
}
}
// Add a moving circle object.
cpFloat radius = 15.0f;
cpFloat mass = 10.0f;
// This time we need to give a mass and moment of inertia when creating the circle.
cBody * ballBody = eeNew( cBody, ( mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero) ) );
body = mSpace->AddBody( cBody::New( 10.0f, Moment::ForCircle( 10.0f, 0.0f, radius, cVectZero ) ) );
body->Pos( cVectNew( hw, EE->GetHeight() - radius - 5 ) );
// Set some parameters of the body:
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpBody
ballBody->Pos( cpv(320, 240 + radius+50) );
ballBody->Vel( cpv(0, 20) );
// Add the body to the space so it will be simulated and move around.
mSpace->AddBody( ballBody );
// Add a circle shape for the ball.
// Shapes are always defined relative to the center of gravity of the body they are attached to.
// When the body moves or rotates, the shape will move with it.
// Additionally, all of the cpSpaceAdd*() functions return the thing they added so you can create and add in one go.
Physics::cShapeCircle * ballShape = eeNew( Physics::cShapeCircle, ( ballBody, radius, cpvzero ) );
mSpace->AddShape( ballShape );
ballShape->e( 0.0f );
ballShape->u( 0.9f );
ballBody = eeNew( cBody, ( mass, cpMomentForCircle( mass, 0.0f, radius, cpvzero ) ) );
// Set some parameters of the body:
// For more info: http://code.google.com/p/chipmunk-physics/wiki/cpBody
ballBody->Pos( cpv(320, 240 + radius + 50 + 200) );
ballBody->Vel( cpv(0, 20) );
// Add the body to the space so it will be simulated and move around.
mSpace->AddBody( ballBody );
// Add a circle shape for the ball.
// Shapes are always defined relative to the center of gravity of the body they are attached to.
// When the body moves or rotates, the shape will move with it.
// Additionally, all of the cpSpaceAdd*() functions return the thing they added so you can create and add in one go.
ballShape = eeNew( Physics::cShapeCircle, ( ballBody, radius, cpvzero ) );
ballShape->e( 0.0f );
ballShape->u( 0.9f );
mSpace->AddShape( ballShape );
shape = mSpace->AddShape( cShapeCircle::New( body, radius, cVectZero ) );
shape->e( 0.0f );
shape->u( 0.9f );
}
void cEETest::PhysicsUpdate() {
cGlobalBatchRenderer::instance()->Draw();
mMousePoint = cpv( KM->GetMousePosf().x, KM->GetMousePosf().y );
cpVect newPoint = cpvlerp(mMousePoint_last, mMousePoint, 0.25f);
mMousePoint = cVectNew( KM->GetMousePosf().x, KM->GetMousePosf().y );
cVect newPoint = tovect( cpvlerp( tocpv( mMousePoint_last ), tocpv( mMousePoint ), 0.25 ) );
mMouseBody->Pos( newPoint );
mMouseBody->Vel( cpvmult( cpvsub( newPoint, mMousePoint_last ), 60.0f ) );
mMouseBody->Vel( ( newPoint - mMousePoint_last ) * (cpFloat)EE->FPS() );
mMousePoint_last = newPoint;
if ( KM->MouseLeftPressed() ) {
if ( NULL == mMouseJoint ) {
cpVect point = cpv( KM->GetMousePosf().x, KM->GetMousePosf().y );
cVect point = cVectNew( KM->GetMousePosf().x, KM->GetMousePosf().y );
cpShape * shape = cpSpacePointQueryFirst( mSpace->Space(), point, GRABABLE_MASK_BIT, CP_NO_GROUP );
Physics::cShape * shape = mSpace->PointQueryFirst( point, GRABABLE_MASK_BIT, CP_NO_GROUP );
if( NULL != shape ){
mMouseJoint = eeNew( cPivotJoint, ( mMouseBody, shape->Body(), cVectZero, shape->Body()->World2Local( point ) ) );
if( shape ){
cpBody * body = shape->body;
mMouseJoint = eeNew( cConstraint, ( cpPivotJointNew2( mMouseBody->Body(), body, cpvzero, cpBodyWorld2Local( body, point ) ) ) );
mMouseJoint->MaxForce( 50000.0f );
mMouseJoint->BiasCoef( 0.15f );
mSpace->AddConstraint( mMouseJoint );
@@ -1696,7 +1688,6 @@ void cEETest::PhysicsUpdate() {
}
} else if ( NULL != mMouseJoint ) {
mSpace->RemoveConstraint( mMouseJoint );
cpConstraintFree( mMouseJoint->Constraint() );
eeSAFE_DELETE( mMouseJoint );
}

View File

@@ -7,31 +7,89 @@ template <typename T>
class Vector2 {
public :
Vector2();
Vector2(T X, T Y);
Vector2<T> Copy();
T Dot( const Vector2<T>& V2 );
T Cross( const Vector2<T>& V2 );
Vector2<T> Perp();
Vector2<T> RPerp();
Vector2<T> Rotate( const Vector2<T>& V2 );
Vector2<T> UnRotate( const Vector2<T>& V2 );
T Lenght();
T LenghtSq();
T Length();
T LengthSq();
void Normalize();
void Clamp( T len );
Vector2<T> forAngle( const T& a );
T toAngle();
void RotateVector( const T& Angle );
void RotateVectorCentered( const T& Angle, const Vector2<T>& RotationCenter );
T Distance( const Vector2<T>& Vec );
T DistanceSq( const Vector2<T>& Vec );
bool Near( const Vector2<T>& Vec, T Dist );
Vector2<T> SphericalLerp( const Vector2<T>& Vec, T Time );
Vector2<T> SphericalLerpConst( const Vector2<T>& Vec, T Angle );
Vector2<T> Lerp( const Vector2<T>& Vec, T Time );
Vector2<T> LerpConst( const Vector2<T>& Vec, T Dist );
T x;
T y;
void RotateVector( const T& Angle );
void RotateVectorCentered( const T& Angle, const Vector2<T>& RotationCenter );
T Distance( const Vector2<T>& Vec );
private:
T cosAng( const T& Ang );
T sinAng( const T& Ang );
};
template <typename T>
Vector2<T> Vector2<T>::Lerp( const Vector2<T>& Vec, T Time ) {
return *this * ( 1 - Time ) + Vec * Time;
}
template <typename T>
Vector2<T> Vector2<T>::LerpConst( const Vector2<T>& Vec, T Dist ) {
return *this + ( Vec - *this ).Clamp( Dist );
}
template <typename T>
Vector2<T> Vector2<T>::SphericalLerp( const Vector2<T>& Vec, T Time ) {
T omega = eeacos( Dot( Vec ) );
if( omega ) {
T denom = 1 / eesin( omega );
return ( Vector2<T>( x, y ) * ( eesin( ( 1 - Time ) * omega ) * denom ) + Vec * ( eesin( Time * omega ) * denom ) );
} else {
return Vector2<T>( x, y );
}
}
template <typename T>
Vector2<T> Vector2<T>::SphericalLerpConst( const Vector2<T>& Vec, T Angle ) {
T angle = eeacos( Dot( Vec ) );
return Lerp( Vec, ( ( Angle < angle ) ? Angle : angle ) / angle );
}
template <typename T>
Vector2<T>::Vector2() : x(0), y(0) {}
@@ -79,6 +137,11 @@ Vector2<T> operator *(T X, const Vector2<T>& V) {
return Vector2<T>(V.x * X, V.y * X);
}
template <typename T>
Vector2<T> operator *(const Vector2<T>& V1, const Vector2<T>& V2) {
return Vector2<T>(V1.x * V2.x, V1.y * V2.y);
}
template <typename T>
Vector2<T>& operator *=(Vector2<T>& V, T X) {
V.x *= X;
@@ -112,12 +175,12 @@ bool operator !=(const Vector2<T>& V1, const Vector2<T>& V2) {
template <typename T>
T Vector2<T>::cosAng( const T& Ang ) {
return cos(Ang * PId180);
return eecos(Ang * PId180);
}
template <typename T>
T Vector2<T>::sinAng( const T& Ang ) {
return sin(Ang * PId180);
return eesin(Ang * PId180);
}
template <typename T>
@@ -140,12 +203,12 @@ void Vector2<T>::RotateVectorCentered( const T& Angle, const Vector2<T>& Rotatio
template <typename T>
T Vector2<T>::Dot( const Vector2<T>& V2 ) {
return x * V2.x + y * V2.Y;
return x * V2.x + y * V2.y;
}
template <typename T>
T Vector2<T>::Cross( const Vector2<T>& V2 ) {
return x * V2.x - y * V2.Y;
return x * V2.x - y * V2.y;
}
template <typename T>
@@ -169,18 +232,18 @@ Vector2<T> Vector2<T>::UnRotate( const Vector2<T>& V2 ) {
}
template <typename T>
T Vector2<T>::Lenght() {
return sqrtf( Dot( Vector2<T>( x , y ) ) );
T Vector2<T>::Length() {
return eesqrt( Dot( Vector2<T>( x , y ) ) );
}
template <typename T>
T Vector2<T>::LenghtSq() {
T Vector2<T>::LengthSq() {
return Dot( Vector2<T>( x , y ) );
}
template <typename T>
void Vector2<T>::Normalize() {
T s = sqrt(x * x + y * y);
T s = eesqrt(x * x + y * y);
if (s == 0) {
x = 0;
y = 0;
@@ -192,23 +255,48 @@ void Vector2<T>::Normalize() {
template <typename T>
Vector2<T> Vector2<T>::forAngle( const T& a ) {
return Vector2<T>( cos(a), sin(a) );
return Vector2<T>( eecos(a), eesin(a) );
}
template <typename T>
T Vector2<T>::toAngle() {
return atan2( y, x );
return eeatan2( y, x );
}
template <typename T>
T Vector2<T>::Distance( const Vector2<T>& Vec ) {
return sqrt((x - Vec.x) * (x - Vec.x) + (y - Vec.y) * (y - Vec.y));
return eesqrt( ( x - Vec.x ) * ( x - Vec.x ) + ( y - Vec.y ) * ( y - Vec.y ) );
}
typedef Vector2<Int32> eeVector2if;
typedef Vector2<eeInt> eeVector2i;
typedef Vector2<eeFloat> eeVector2f;
typedef Vector2<eeDouble> eeVector2d;
template <typename T>
T Vector2<T>::DistanceSq( const Vector2<T>& Vec ) {
return LengthSq( *this - Vec );
}
template <typename T>
void Vector2<T>::Clamp( T len ) {
if ( Dot( Vector2<T>( x, y ) ) > len * len ) {
Normalize();
x *= len;
y *= len;
}
}
template <typename T>
bool Vector2<T>::Near( const Vector2<T>& Vec, T Dist ) {
return 0 != ( DistanceSq( Vec ) < Dist * Dist );
}
template <typename T>
Vector2<T> Vector2<T>::Copy() {
return Vector2<T>( x, y );
}
typedef Vector2<Int32> eeVector2if;
typedef Vector2<eeInt> eeVector2i;
typedef Vector2<eeFloat> eeVector2f;
typedef Vector2<eeDouble> eeVector2d;
}}

View File

@@ -402,6 +402,10 @@ void cEngine::SetBackColor(const eeColor& Color) {
glClearColor( static_cast<eeFloat>( mBackColor.R() ) / 255.0f, static_cast<eeFloat>( mBackColor.G() ) / 255.0f, static_cast<eeFloat>( mBackColor.B() ) / 255.0f, 255.0f );
}
const eeColor& cEngine::GetBackColor() const {
return mBackColor;
}
void cEngine::SetWindowCaption(const std::string& Caption) {
SDL_WM_SetCaption( Caption.c_str(), NULL );
}

View File

@@ -30,6 +30,9 @@ class EE_API cEngine : public tSingleton<cEngine> {
/** Set the window background color */
void SetBackColor(const eeColor& Color);
/** @return The background clear color */
const eeColor& GetBackColor() const;
/** Set the window caption */
void SetWindowCaption(const std::string& Caption);