261 lines
6.5 KiB
C++
261 lines
6.5 KiB
C++
/*
|
|
* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
|
|
*
|
|
* This software is provided 'as-is', without any express or implied
|
|
* warranty. In no event will the authors be held liable for any damages
|
|
* arising from the use of this software.
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute it
|
|
* freely, subject to the following restrictions:
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
* claim that you wrote the original software. If you use this software
|
|
* in a product, an acknowledgment in the product documentation would be
|
|
* appreciated but is not required.
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
* misrepresented as being the original software.
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
*/
|
|
|
|
// Contributed by caspin.
|
|
|
|
#ifndef CONTACT_CB_H
|
|
#define CONTACT_CB_H
|
|
|
|
#include <set>
|
|
#include <deque>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <iostream>
|
|
|
|
bool key_comp( const ContactPoint& lhs, const ContactPoint& rhs )
|
|
{
|
|
if( lhs.fixtureA < rhs.fixtureA ) return true;
|
|
if( lhs.fixtureA == rhs.fixtureA && lhs.fixtureB < rhs.fixtureB ) return true;
|
|
if( lhs.fixtureA == rhs.fixtureA && lhs.fixtureB == rhs.fixtureB && lhs.id.key < rhs.id.key ) return true;
|
|
return false;
|
|
}
|
|
|
|
class ContactCB : public Test
|
|
{
|
|
public:
|
|
|
|
ContactCB()
|
|
: m_set(&key_comp)
|
|
{
|
|
b2PolygonDef sd;
|
|
sd.friction = 0;
|
|
sd.vertexCount = 3;
|
|
|
|
sd.vertices[0].Set(10,10);
|
|
sd.vertices[1].Set(9,7);
|
|
sd.vertices[2].Set(10,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[0].Set(9,7);
|
|
sd.vertices[1].Set(8,0);
|
|
sd.vertices[2].Set(10,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[0].Set(9,7);
|
|
sd.vertices[1].Set(8,5);
|
|
sd.vertices[2].Set(8,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[0].Set(8,5);
|
|
sd.vertices[1].Set(7,4);
|
|
sd.vertices[2].Set(8,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[0].Set(7,4);
|
|
sd.vertices[1].Set(5,0);
|
|
sd.vertices[2].Set(8,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[0].Set(7,4);
|
|
sd.vertices[1].Set(5,3);
|
|
sd.vertices[2].Set(5,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[0].Set(5,3);
|
|
sd.vertices[1].Set(2,2);
|
|
sd.vertices[2].Set(5,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[0].Set(2,2);
|
|
sd.vertices[1].Set(0,0);
|
|
sd.vertices[2].Set(5,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[0].Set(2,2);
|
|
sd.vertices[1].Set(-2,2);
|
|
sd.vertices[2].Set(0,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[2].Set(-2,2);
|
|
sd.vertices[1].Set(0,0);
|
|
sd.vertices[0].Set(-5,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[2].Set(-5,3);
|
|
sd.vertices[1].Set(-2,2);
|
|
sd.vertices[0].Set(-5,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[2].Set(-7,4);
|
|
sd.vertices[1].Set(-5,3);
|
|
sd.vertices[0].Set(-5,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[2].Set(-7,4);
|
|
sd.vertices[1].Set(-5,0);
|
|
sd.vertices[0].Set(-8,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[2].Set(-8,5);
|
|
sd.vertices[1].Set(-7,4);
|
|
sd.vertices[0].Set(-8,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[2].Set(-9,7);
|
|
sd.vertices[1].Set(-8,5);
|
|
sd.vertices[0].Set(-8,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[2].Set(-9,7);
|
|
sd.vertices[1].Set(-8,0);
|
|
sd.vertices[0].Set(-10,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.vertices[2].Set(-10,10);
|
|
sd.vertices[1].Set(-9,7);
|
|
sd.vertices[0].Set(-10,0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.SetAsBox(.5,6,b2Vec2(10.5,6),0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
sd.SetAsBox(.5,6,b2Vec2(-10.5,6),0);
|
|
m_world->GetGroundBody()->CreateFixture(&sd);
|
|
|
|
b2BodyDef bd;
|
|
bd.position.Set(9.5,60);
|
|
b2Body* m_ball = m_world->CreateBody( &bd );
|
|
|
|
#if 1
|
|
b2PolygonDef cd;
|
|
cd.vertexCount = 8;
|
|
float32 w = 0.95f;
|
|
float32 b = w / (2.0f + sqrtf(2.0f));
|
|
float32 s = sqrtf(2.0f) * b;
|
|
cd.vertices[0].Set(0.5f * s, 0.0f);
|
|
cd.vertices[1].Set(0.5f * w, b);
|
|
cd.vertices[2].Set(0.5f * w, b + s);
|
|
cd.vertices[3].Set(0.5f * s, w);
|
|
cd.vertices[4].Set(-0.5f * s, w);
|
|
cd.vertices[5].Set(-0.5f * w, b + s);
|
|
cd.vertices[6].Set(-0.5f * w, b);
|
|
cd.vertices[7].Set(-0.5f * s, 0.0f);
|
|
cd.density = 1.0f;
|
|
#else
|
|
b2CircleDef cd;
|
|
cd.radius = 0.33f;
|
|
cd.friction = 0;
|
|
cd.density = 1;
|
|
#endif
|
|
|
|
m_ball_shape = m_ball->CreateFixture(&cd);
|
|
m_ball->SetMassFromShapes();
|
|
}
|
|
|
|
void Step(Settings* settings)
|
|
{
|
|
Test::Step(settings);
|
|
std::ostringstream oss;
|
|
oss << std::hex;
|
|
|
|
for (int32 i=0; i< m_pointCount; ++i)
|
|
{
|
|
#if 0
|
|
if (m_points[i].shape1 > m_points[i].shape2)
|
|
{
|
|
b2Swap(m_points[i].shape1, m_points[i].shape2);
|
|
m_points[i].normal *= -1.0f;
|
|
m_points[i].velocity *= -1.0f;
|
|
}
|
|
#endif
|
|
oss.str("");
|
|
switch( m_points[i].state )
|
|
{
|
|
case e_contactAdded:
|
|
{
|
|
if( ! m_set.insert( m_points[i] ).second )
|
|
{
|
|
oss << "ERROR ";
|
|
}
|
|
else
|
|
{
|
|
oss << " ";
|
|
}
|
|
oss << "added: " << m_points[i].fixtureA << " -> " << m_points[i].fixtureB;
|
|
oss << " : " << m_points[i].id.key;
|
|
m_strings.push_back( oss.str() );
|
|
std::cout << oss.str() << std::endl;
|
|
break;
|
|
}
|
|
case e_contactRemoved:
|
|
{
|
|
if( m_set.find( m_points[i] ) == m_set.end() )
|
|
{
|
|
oss << "ERROR ";
|
|
}
|
|
else
|
|
{
|
|
oss << " ";
|
|
}
|
|
oss << "removed: " << m_points[i].fixtureA << " -> " << m_points[i].fixtureB;
|
|
oss << " : " << m_points[i].id.key;
|
|
m_strings.push_back( oss.str() );
|
|
std::cout << oss.str() << std::endl;
|
|
m_set.erase( m_points[i] );
|
|
break;
|
|
}
|
|
case e_contactPersisted:
|
|
{
|
|
if( m_set.find( m_points[i] ) == m_set.end() )
|
|
{
|
|
oss << "ERROR persist: " << m_points[i].fixtureA << " -> ";
|
|
oss << m_points[i].fixtureB << " : " << m_points[i].id.key;
|
|
m_strings.push_back( oss.str() );
|
|
std::cout << oss.str() << std::endl;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
while( m_strings.size() > 15 )
|
|
{
|
|
m_strings.pop_front();
|
|
}
|
|
|
|
for( unsigned i=0; i<m_strings.size(); ++i )
|
|
{
|
|
m_debugDraw.DrawString(5, m_textLine, m_strings[i].c_str() );
|
|
m_textLine += 15;
|
|
}
|
|
}
|
|
|
|
static Test* Create()
|
|
{
|
|
return new ContactCB;
|
|
}
|
|
|
|
b2Body* m_ball;
|
|
b2Body* m_bullet;
|
|
b2Fixture* m_ball_shape;
|
|
std::set<ContactPoint,bool(*)(const ContactPoint&,const ContactPoint&)> m_set;
|
|
std::deque<std::string> m_strings;
|
|
|
|
};
|
|
|
|
#endif // CONTACT_CB_H
|