Added Box2D

This commit is contained in:
Julian Nießner
2018-05-06 12:43:20 +02:00
parent cb5469bb89
commit d175d433a8
351 changed files with 123545 additions and 1 deletions

View File

@@ -0,0 +1,32 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
namespace Box2D
{
namespace Net
{
public ref class AABB
{
public:
Vector ^lowerBound, ^upperBound;
bool IsValid()
{
return getAABB().IsValid();
}
AABB(Vector^ min, Vector^ max) : lowerBound(gcnew Vector(min)), upperBound(gcnew Vector(max)) { }
AABB() : lowerBound(gcnew Vector()), upperBound(gcnew Vector()) { }
b2AABB getAABB()
{
b2AABB returnme;
returnme.lowerBound = lowerBound->getVec2();
returnme.upperBound = upperBound->getVec2();
return returnme;
}
};
}
}

View File

@@ -0,0 +1,40 @@
#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute("Box2DNet")];
[assembly:AssemblyDescriptionAttribute("A .NET wrapper for the Box2D physics library")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("")];
[assembly:AssemblyProductAttribute("Box2DNet")];
[assembly:AssemblyCopyrightAttribute("Copyright (c) Jay Lemmon 2008")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];

View File

@@ -0,0 +1,243 @@
#pragma once
#include "Stdafx.h"
#include "Vector.cpp"
#include "Shape.cpp"
#include "ShapeDef.cpp"
namespace Box2D
{
namespace Net
{
/// <summary>
/// A rigid body. Internal computation are done in terms
/// of the center of mass position. The center of mass may
/// be offset from the body's origin.
/// </summary>
public ref class Body
{
internal:
b2Body *body;
Body(b2Body *bodyRef) : body(bodyRef) { }
public:
/// <summary>
/// Set the position of the body's origin and rotation (radians).
/// This breaks any contacts and wakes the other bodies.
/// </summary>
void SetXForm(Vector^ position, float32 rotation)
{
body->SetXForm(position->getVec2(), rotation);
}
/// <summary>
/// Get the position of the body's origin. The body's origin does not
/// necessarily coincide with the center of mass. It depends on how the
/// shapes are created.
/// </summary>
XForm^ GetXForm()
{
return gcnew XForm(body->GetXForm());
}
///<summary>Accesses the linear velocity of the center of mass.</summary>
property Vector^ LinearVelocity
{
Vector^ get()
{
return gcnew Vector(body->GetLinearVelocity());
}
void set(Vector^ value)
{
body->SetLinearVelocity(value->getVec2());
}
}
///<summary>Accesses the angular velocity.</summary>
property float32 AngularVelocity
{
float32 get()
{
return body->GetAngularVelocity();
}
void set(float32 value)
{
body->SetAngularVelocity(value);
}
}
///<summary> Apply a force at a world point. Additive. </summary>
void ApplyForce(Vector^ Force, Vector^ Point)
{
body->ApplyForce(Force->getVec2(), Point->getVec2());
}
///<summary> Apply a torque. Additive. </summary>
void ApplyTorque(float32 Torque)
{
body->ApplyTorque(Torque);
}
///<summary> Apply an impulse at a point. This immediately modifies the velocity. </summary>
void ApplyImpulse(Vector^ Impulse, Vector^ Point)
{
body->ApplyImpulse(Impulse->getVec2(), Point->getVec2());
}
///<summary>Accesses the Mass.</summary>
property float32 Mass
{
float32 get()
{
return body->GetMass();
}
}
///<summary>Accesses the Mass.</summary>
property float32 Inertia
{
float32 get()
{
return body->GetInertia();
}
}
/// <summary>
/// Get the world coordinates of a point give the local coordinates
/// relative to the body's center of mass.
/// </summary>
Vector^ GetWorldPoint(Vector^ LocalPoint)
{
return gcnew Vector(body->GetWorldPoint(LocalPoint->getVec2()));
}
/// <summary>
/// Get the world coordinates of a vector given the local coordinates.
/// </summary>
Vector^ GetWorldVector(Vector^ LocalVector)
{
return gcnew Vector(body->GetWorldVector(LocalVector->getVec2()));
}
/// <summary>
/// Returns a local point relative to the center of mass given a world point.
/// </summary>
Vector^ GetLocalPoint(Vector^ WorldPoint)
{
return gcnew Vector(body->GetLocalPoint(WorldPoint->getVec2()));
}
/// <summary>
/// Returns a local vector given a world vector.
/// </summary>
Vector^ GetLocalVector(Vector^ WorldVector)
{
return gcnew Vector(body->GetLocalVector(WorldVector->getVec2()));
}
///<summary>Is this body static (immovable)</summary>
property bool Static
{
bool get()
{
return body->IsStatic();
}
}
///<summary>Is this body frozen</summary>
property bool Frozen
{
bool get()
{
return body->IsFrozen();
}
}
///<summary>Is this body sleeping</summary>
property bool Sleeping
{
bool get()
{
return body->IsSleeping();
}
}
///<summary>You can disable sleeping on this particular body.</summary>
property bool AllowSleeping
{
bool get()
{
return body->IsSleeping();
}
void set(bool value)
{
body->AllowSleeping(value);
}
}
property bool Bullet
{
bool get()
{
return body->IsBullet();
}
void set(bool value)
{
body->SetBullet(value);
}
}
void WakeUp()
{
body->WakeUp();
}
///<summary> Get the list of all shapes attached to this body.</summary>
property IList<Shape^>^ Shapes
{
IList<Shape^>^ get()
{
List<Shape^>^ list = gcnew List<Shape^>();
for(b2Shape *shape = body->GetShapeList(); shape; shape = shape->GetNext())
list->Add(gcnew Shape(shape));
return list;
}
}
void CreateShape(ShapeDef^ def)
{
body->CreateShape(def->def);
}
void DestroyShape(Shape^ shape)
{
body->DestroyShape(shape->shape);
}
void SetMassFromShapes()
{
body->SetMassFromShapes();
}
//TODO:
//void* GetUserData();
//const b2Mat22& GetRotationMatrix() const;
};
}
}
/*
TODO:
public:
// Get the list of all contacts attached to this body.
b2ContactNode* GetContactList();
// Get the list of all joints attached to this body.
b2JointNode* GetJointList();
*/

View File

@@ -0,0 +1,168 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
#include "ShapeDef.cpp"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
/// The type of body.
public enum class BodyType
{
e_staticBody = ::b2BodyDef::e_staticBody, ///< A static body should not move and has infinite mass.
e_dynamicBody = ::b2BodyDef::e_dynamicBody ///< A regular moving body.
};
public ref class BodyDef
{
internal:
b2BodyDef *def;
public:
BodyDef() : def(new b2BodyDef()) { }
virtual ~BodyDef()
{
delete def;
}
property Vector^ Position
{
Vector^ get()
{
return gcnew Vector(def->position);
}
void set(Vector^ value)
{
def->position = value->getVec2();
}
}
property float32 Angle
{
float32 get()
{
return def->angle;
}
void set(float32 value)
{
def->angle = value;
}
}
property float32 LinearDamping
{
float32 get()
{
return def->linearDamping;
}
void set(float32 value)
{
def->linearDamping = value;
}
}
property float32 AngularDamping
{
float32 get()
{
return def->angularDamping;
}
void set(float32 value)
{
def->angularDamping = value;
}
}
property bool AllowSleep
{
bool get()
{
return def->allowSleep;
}
void set(bool value)
{
def->allowSleep = value;
}
}
property bool IsBullet
{
bool get()
{
return def->isBullet;
}
void set(bool value)
{
def->isBullet = value;
}
}
property bool IsSleeping
{
bool get()
{
return def->isSleeping;
}
void set(bool value)
{
def->isSleeping = value;
}
}
property bool FixedRotation
{
bool get()
{
return def->fixedRotation;
}
void set(bool value)
{
def->fixedRotation = value;
}
}
property BodyType BodyType
{
Box2D::Net::BodyType get()
{
return (Box2D::Net::BodyType)def->type;
}
void set(Box2D::Net::BodyType value)
{
def->type = ((::b2BodyDef::Type)value);
}
}
//TODO:
/*property Object^ UserData
{
Object^ get()
{
Object^ ReturnMe;
System::Runtime::InteropServices::Marshal::PtrToStructure((System::IntPtr)def->userData, ReturnMe);
return ReturnMe;
}
void set(Object^ value)
{
def->userData = value;
}
}*/
};
}
}

View File

@@ -0,0 +1,291 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="Box2D.Net"
ProjectGUID="{0E95DBB9-EA97-407B-811C-810B225E79D2}"
RootNamespace="Box2DNet"
Keyword="ManagedCProj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\Include\"
PreprocessorDefinitions="WIN32;_DEBUG"
RuntimeLibrary="3"
UsePrecompiledHeader="1"
GenerateXMLDocumentationFiles="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(NoInherit)"
LinkIncremental="2"
GenerateDebugInformation="true"
AssemblyDebug="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\Include\"
PreprocessorDefinitions="WIN32;NDEBUG"
RuntimeLibrary="2"
UsePrecompiledHeader="1"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(NoInherit)"
LinkIncremental="1"
GenerateDebugInformation="true"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
<AssemblyReference
RelativePath="System.dll"
AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
/>
<AssemblyReference
RelativePath="System.Data.dll"
AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
/>
<AssemblyReference
RelativePath="System.XML.dll"
AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\AssemblyInfo.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\Stdafx.h"
>
</File>
</Filter>
<Filter
Name="Wrappers"
>
<File
RelativePath=".\AABB.cpp"
>
</File>
<File
RelativePath=".\Body.cpp"
>
</File>
<File
RelativePath=".\BodyDef.cpp"
>
</File>
<File
RelativePath=".\Contact.cpp"
>
</File>
<File
RelativePath=".\Delegates.cpp"
>
</File>
<File
RelativePath=".\Joint.cpp"
>
</File>
<File
RelativePath=".\JointDef.cpp"
>
</File>
<File
RelativePath=".\Manifold.cpp"
>
</File>
<File
RelativePath=".\ManifoldPoint.cpp"
>
</File>
<File
RelativePath=".\MassData.cpp"
>
</File>
<File
RelativePath=".\Matrix.cpp"
>
</File>
<File
RelativePath=".\RevoluteJoint.cpp"
>
</File>
<File
RelativePath=".\Shape.cpp"
>
</File>
<File
RelativePath=".\Shape.h"
>
</File>
<File
RelativePath=".\ShapeDef.cpp"
>
</File>
<File
RelativePath=".\ShapeType.cpp"
>
</File>
<File
RelativePath=".\VariousImplementations.cpp"
>
</File>
<File
RelativePath=".\Vector.cpp"
>
</File>
<File
RelativePath=".\World.cpp"
>
</File>
<File
RelativePath=".\XForm.cpp"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,53 @@
#pragma once
#include "stdafx.h"
#include "Shape.cpp"
#include "Manifold.cpp"
namespace Box2D
{
namespace Net
{
public ref class Contact
{
internal:
b2Contact *contact;
Contact(b2Contact *contactRef) : contact(contactRef) { }
public:
property Shape^ Shape1
{
Shape^ get()
{
return gcnew Shape(contact->GetShape1());
}
}
property Shape^ Shape2
{
Shape^ get()
{
return gcnew Shape(contact->GetShape2());
}
}
Contact^ GetNext()
{
return gcnew Contact(contact->GetNext());
}
Manifold^ GetManifolds()
{
return gcnew Manifold(contact->GetManifolds());
}
property int ManifoldCount
{
int get()
{
return contact->GetManifoldCount();
}
}
};
}
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include "stdafx.h"
#include "Joint.cpp"
#include "Body.cpp"
namespace Box2D
{
namespace Net
{
/// <summary>
/// If a body is destroyed, then any joints attached to it are also destroyed.
/// This prevents memory leaks, but you may unexpectedly be left with an
/// orphaned joint pointer.
/// Box2D will notify you when a joint is implicitly destroyed.
/// It is NOT called if you directly destroy a joint.
/// DO NOT modify the Box2D world inside this callback.
/// </summary>
public delegate void NotifyJointDestroyed(Joint);
/// <summary>
/// Return true if collision calculations should be performed between shape1 and shape2
/// Box2D has a default implementation for this, so only add a new delegate if you
/// want to override the default behavior.
/// </summary>
public delegate bool CollisionFilter(Shape shape1, Shape shape2);
}
}

View File

@@ -0,0 +1,106 @@
#pragma once
#include "stdafx.h"
#include "Body.cpp"
#include "JointDef.cpp"
namespace Box2D
{
namespace Net
{
public ref class Joint
{
internal:
b2Joint *joint;
Joint(b2Joint *jointRef) : joint(jointRef) { }
public:
property JointType JointType
{
Box2D::Net::JointType get()
{
return (Box2D::Net::JointType) joint->GetType();
}
}
property Body^ Body1
{
Body^ get()
{
return gcnew Body(joint->GetBody1());
}
}
property Body^ Body2
{
Body^ get()
{
return gcnew Body(joint->GetBody2());
}
}
property Vector^ Anchor1
{
Vector^ get()
{
return gcnew Vector(joint->GetAnchor1());
}
}
property Vector^ Anchor2
{
Vector^ get()
{
return gcnew Vector(joint->GetAnchor2());
}
}
Vector^ GetReactionForce()
{
return gcnew Vector(joint->GetReactionForce());
}
float32 GetReactionTorque()
{
return joint->GetReactionTorque();
}
Joint^ GetNext()
{
return gcnew Joint(joint->GetNext());
}
//TODO:
/*
void* GetUserData();
*/
};
public ref class MouseJoint : public Joint
{
internal:
b2MouseJoint *mouseJoint;
MouseJoint(b2MouseJoint *joint) : Joint(joint), mouseJoint(joint) { }
public:
MouseJoint(Joint^ joint) : Joint(joint->joint), mouseJoint(0)
{
if(joint->JointType == Box2D::Net::JointType::e_mouseJoint &&
reinterpret_cast<b2MouseJoint *>(joint->joint))
{
mouseJoint = reinterpret_cast<b2MouseJoint *>(joint->joint);
}
else
{
throw gcnew System::Exception("Attempting to convert a Joint to a MouseJoint, "
"but the joint is not a mouse joint.");
}
}
void SetTarget(Vector^ Target)
{
mouseJoint->SetTarget(Target->getVec2());
}
};
}
}

View File

@@ -0,0 +1,178 @@
#pragma once
#include "stdafx.h"
#include "Body.cpp"
#include "Vector.cpp"
using namespace System::Runtime::InteropServices;
namespace Box2D
{
namespace Net
{
//TODO: is there a way to automatically include the b2JointType as an enum here?
public enum class JointType
{
e_unknownJoint = ::e_unknownJoint,
e_revoluteJoint = ::e_revoluteJoint,
e_prismaticJoint = ::e_prismaticJoint,
e_distanceJoint = ::e_distanceJoint,
e_pulleyJoint = ::e_pulleyJoint,
e_mouseJoint = ::e_mouseJoint,
e_gearJoint = ::e_gearJoint
};
public ref class JointDef
{
internal:
b2JointDef *def;
JointDef() : def(new b2JointDef()) { }
JointDef(b2JointDef *justBuilt) : def(justBuilt) { }
virtual ~JointDef()
{
delete def;
}
public:
property JointType Type
{
JointType get()
{
return (JointType)def->type;
}
void set(JointType value)
{
def->type = (b2JointType)value;
}
}
property Object^ UserData
{
Object^ get()
{
return System::Runtime::InteropServices::GCHandle::FromIntPtr((System::IntPtr)def->userData).Target;
}
void set(Object^ value)
{
GCHandle^ gch = GCHandle::Alloc(value);
def->userData = (void *)gch->ToIntPtr(*gch);
}
}
property Body^ Body1
{
Body^ get()
{
return gcnew Body(def->body1);
}
void set(Body^ value)
{
def->body1 = value->body;
}
}
property Body^ Body2
{
Body^ get()
{
return gcnew Body(def->body2);
}
void set(Body^ value)
{
def->body2 = value->body;
}
}
property bool CollideConnected
{
bool get()
{
return def->collideConnected;
}
void set(bool value)
{
def->collideConnected = value;
}
}
};
public ref class MouseJointDef : public JointDef
{
internal:
b2MouseJointDef *mouseJoint;
public:
MouseJointDef() : JointDef(mouseJoint = new b2MouseJointDef()) { }
property Vector^ Target
{
Vector^ get()
{
return gcnew Vector(mouseJoint->target);
}
void set(Vector^ value)
{
mouseJoint->target = value->getVec2();
}
}
property float32 MaxForce
{
float32 get()
{
return mouseJoint->maxForce;
}
void set(float32 value)
{
mouseJoint->maxForce = value;
}
}
property float32 FrequencyHz
{
float32 get()
{
return mouseJoint->frequencyHz;
}
void set(float32 value)
{
mouseJoint->frequencyHz = value;
}
}
property float32 DampingRatio
{
float32 get()
{
return mouseJoint->dampingRatio;
}
void set(float32 value)
{
mouseJoint->dampingRatio = value;
}
}
property float32 TimeStep
{
float32 get()
{
return mouseJoint->timeStep;
}
void set(float32 value)
{
mouseJoint->timeStep = value;
}
}
};
}
}

View File

@@ -0,0 +1,44 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
//#include "ContactPoint.cpp"
#include "ManifoldPoint.cpp"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
public ref class Manifold
{
internal:
b2Manifold *fold;
Manifold(b2Manifold *foldRef) : fold(foldRef) { }
public:
property Vector^ Normal
{
Vector^ get()
{
return gcnew Vector(fold->normal);
}
}
property IList<ManifoldPoint^ >^ Points
{
IList<ManifoldPoint^ >^ get()
{
//TODO: implement
List<ManifoldPoint^>^ list = gcnew List<ManifoldPoint^>;
for(int x = 0; x < fold->pointCount; ++x)
list->Add(gcnew ManifoldPoint(&fold->points[x]));
return list;
}
}
};
}
}

View File

@@ -0,0 +1,100 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
namespace Box2D
{
namespace Net
{
//TODO: is this class really necessary for the public interface?
public ref class ManifoldPoint
{
internal:
b2ManifoldPoint *point;
ManifoldPoint(b2ManifoldPoint *pointRef) : point(pointRef) { }
public:
property Vector^ LocalPoint1
{
Vector^ get()
{
return gcnew Vector(point->localPoint1);
}
void set(Vector^ value)
{
point->localPoint1 = value->getVec2();
}
}
property Vector^ LocalPoint2
{
Vector^ get()
{
return gcnew Vector(point->localPoint2);
}
void set(Vector^ value)
{
point->localPoint2 = value->getVec2();
}
}
property float32 Separation
{
float32 get()
{
return point->separation;
}
void set(float32 value)
{
point->separation = value;
}
}
property float32 NormalForce
{
float32 get()
{
return point->normalForce;
}
void set(float32 value)
{
point->normalForce = value;
}
}
property float32 TangentForce
{
float32 get()
{
return point->tangentForce;
}
void set(float32 value)
{
point->tangentForce = value;
}
}
//TODO: marshall b2ContactID
/*
property b2ContactID ID
{
b2ContactID get()
{
return point->id;
}
void set(b2ContactID value)
{
point->id = value;
}
}
*/
};
}
}

View File

@@ -0,0 +1,64 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
namespace Box2D
{
namespace Net
{
public ref class MassData
{
internal:
bool DeleteWhenDone;
b2MassData *data;
MassData(b2MassData *dataRef) : data(dataRef), DeleteWhenDone(false) { }
public:
MassData() : data(new b2MassData()), DeleteWhenDone(true) { }
virtual ~MassData()
{
if(DeleteWhenDone)
delete data;
}
property float32 Mass
{
float32 get()
{
return data->mass;
}
void set(float32 value)
{
data->mass = value;
}
}
property float32 I
{
float32 get()
{
return data->I;
}
void set(float32 value)
{
data->I = value;
}
}
property Vector^ Center
{
Vector^ get()
{
return gcnew Vector(data->center);
}
void set(Vector^ value)
{
data->center = value->getVec2();
}
}
};
}
}

View File

@@ -0,0 +1,94 @@
#pragma once
#include "Stdafx.h"
#include "Vector.cpp"
namespace Box2D
{
namespace Net
{
public ref class Matrix
{
internal:
Matrix(const b2Mat22 &matrix) : col1(gcnew Vector(matrix.col1)), col2(gcnew Vector(matrix.col2)) { }
b2Mat22 getMat22()
{
return b2Mat22(col1->getVec2(), col2->getVec2());
}
public:
Vector ^col1, ^col2;
Matrix() : col1(gcnew Vector()), col2(gcnew Vector()) {}
Matrix(Vector^ c1, Vector^ c2) : col1(gcnew Vector(c1)), col2(gcnew Vector(c2)) { }
explicit Matrix(float32 angle)
{
Set(angle);
}
void Set(Vector^ c1, Vector^ c2)
{
col1->X = c1->X;
col1->Y = c1->Y;
col2->X = c2->X;
col2->Y = c2->Y;
}
void Set(float32 angle)
{
float32 c = cosf(angle), s = sinf(angle);
col1->X = c; col2->X = -s;
col1->Y = s; col2->Y = c;
}
void SetIdentity()
{
col1->X = 1; col2->X = 0;
col1->Y = 0; col2->Y = 1;
}
static Vector^ operator * (Matrix^ mat, Vector^ a)
{
return gcnew Vector(b2Mul(mat->getMat22(), a->getVec2()));
}
};
}
}
/*
struct b2Mat22
{
void SetZero()
{
col1.x = 0.0f; col2.x = 0.0f;
col1.y = 0.0f; col2.y = 0.0f;
}
b2Mat22 Invert() const
{
float32 a = col1.x, b = col2.x, c = col1.y, d = col2.y;
b2Mat22 B;
float32 det = a * d - b * c;
b2Assert(det != 0.0f);
det = 1.0f / det;
B.col1.x = det * d; B.col2.x = -det * b;
B.col1.y = -det * c; B.col2.y = det * a;
return B;
}
// Solve A * x = b
b2Vec2 Solve(const b2Vec2& b) const
{
float32 a11 = col1.x, a12 = col2.x, a21 = col1.y, a22 = col2.y;
float32 det = a11 * a22 - a12 * a21;
b2Assert(det != 0.0f);
det = 1.0f / det;
b2Vec2 x;
x.x = det * (a22 * b.x - a12 * b.y);
x.y = det * (a11 * b.y - a21 * b.x);
return x;
}
b2Vec2 col1, col2;
};
*/

View File

@@ -0,0 +1,190 @@
#pragma once
#include "stdafx.h"
#include "Joint.cpp"
#include "JointDef.cpp"
namespace Box2D
{
namespace Net
{
public ref class RevoluteJointDef : public JointDef
{
public:
RevoluteJointDef() : JointDef(new b2RevoluteJointDef()) { }
property Vector^ LocalAnchor1
{
Vector^ get()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJointDef *>(def)->localAnchor1);
}
void set(Vector^ value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->localAnchor1 = value->getVec2();
}
}
property Vector^ LocalAnchor2
{
Vector^ get()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJointDef *>(def)->localAnchor2);
}
void set(Vector^ value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->localAnchor2 = value->getVec2();
}
}
property float32 LowerAngle
{
float32 get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->lowerAngle;
}
void set(float32 value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->lowerAngle = value;
}
}
property float32 UpperAngle
{
float32 get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->upperAngle;
}
void set(float32 value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->upperAngle = value;
}
}
property float32 MotorTorque
{
float32 get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->maxMotorTorque;
}
void set(float32 value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->maxMotorTorque = value;
}
}
property float32 MotorSpeed
{
float32 get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->motorSpeed;
}
void set(float32 value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->motorSpeed = value;
}
}
property bool EnableLimit
{
bool get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->enableLimit;
}
void set(bool value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->enableLimit = value;
}
}
property bool EnableMotor
{
bool get()
{
return reinterpret_cast<b2RevoluteJointDef *>(def)->enableMotor;
}
void set(bool value)
{
reinterpret_cast<b2RevoluteJointDef *>(def)->enableMotor = value;
}
}
void Initialize(Body^ body1, Body^ body2, Vector^ Anchor)
{
reinterpret_cast<b2RevoluteJointDef*>(def)->Initialize(body1->body, body2->body, Anchor->getVec2());
}
};
public ref class RevoluteJoint : public Joint
{
internal:
RevoluteJoint(b2RevoluteJoint *jointRef) : Joint(jointRef) { }
public:
property Vector^ Anchor1
{
Vector^ get()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJoint*>(joint)->GetAnchor1());
}
}
property Vector^ Anchor2
{
Vector^ get()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJoint*>(joint)->GetAnchor2());
}
}
Vector^ GetReactionForce()
{
return gcnew Vector(reinterpret_cast<b2RevoluteJoint*>(joint)->GetReactionForce());
}
float32 GetReactionTorque()
{
return (reinterpret_cast<b2RevoluteJoint*>(joint)->GetReactionTorque());
}
property float32 JointAngle
{
float32 get()
{
return (reinterpret_cast<b2RevoluteJoint*>(joint)->GetJointAngle());
}
}
property float32 JointSpeed
{
float32 get()
{
return (reinterpret_cast<b2RevoluteJoint*>(joint)->GetJointSpeed());
}
}
float32 GetMotorTorque()
{
return reinterpret_cast<b2RevoluteJoint*>(joint)->GetMotorTorque();
}
void SetMotorSpeed(float32 speed)
{
reinterpret_cast<b2RevoluteJoint*>(joint)->SetMotorSpeed(speed);
}
void SetMotorTorque(float32 torque)
{
reinterpret_cast<b2RevoluteJoint*>(joint)->SetMaxMotorTorque(torque);
}
};
}
}

View File

@@ -0,0 +1,153 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
#include "Matrix.cpp"
#include "ShapeType.cpp"
#include "XForm.cpp"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
ref class Body;
public ref class Shape
{
internal:
b2Shape *shape;
Shape(b2Shape *shapeRef) : shape(shapeRef) { }
public:
bool TestPoint(XForm^ xf, Vector^ p)
{
return shape->TestPoint(xf->getXForm(), p->getVec2());
}
property ShapeType ShapeType
{
Box2D::Net::ShapeType get()
{
return (Box2D::Net::ShapeType)shape->GetType();
}
}
/// <summary>
/// Get the parent body of this shape.
/// </summary>
property Body^ Body
{
Box2D::Net::Body^ get();
}
/*
/// <summary>
/// Get the world position.
/// </summary>
property Vector^ Position
{
Vector^ get()
{
return gcnew Vector(shape->Get->GetPosition());
}
}
*/
/*
property Matrix^ Rotation
{
Matrix^ get()
{
return gcnew Matrix(shape->GetRotationMatrix());
}
}
*/
//TODO:
//void* GetUserData();
//
// Remove and then add proxy from the broad-phase.
// This is used to refresh the collision filters.
//virtual void ResetProxy(b2BroadPhase* broadPhase) = 0;
/// <summary>
/// Get the next shape in the parent body's shape list.
/// </summary>
Shape^ GetNext()
{
return gcnew Shape(shape->GetNext());
}
};
public ref class CircleShape : public Shape
{
internal:
b2CircleShape *circleShape;
CircleShape(b2CircleShape *shapeRef) : Shape(shapeRef), circleShape(shapeRef) { }
public:
CircleShape(Shape^ shape) : Shape(shape->shape), circleShape(0)
{
if(shape->ShapeType == Box2D::Net::ShapeType::e_circleShape &&
reinterpret_cast<b2CircleShape *>(shape->shape))
{
circleShape = reinterpret_cast<b2CircleShape*>(shape->shape);
}
else
{
throw gcnew System::Exception("Attempting to convert a Shape to a CircleShape,"
"but the Shape is not a circle shape.");
}
}
//TODO: this is not technically part of the "public" interface for CircleShape
property float32 Radius
{
float32 get()
{
return circleShape->m_radius;
}
void set(float32 value)
{
circleShape->m_radius = value;
}
}
};
public ref class PolyShape : public Shape
{
internal:
b2PolygonShape *polyShape;
PolyShape(b2PolygonShape *shapeRef) : Shape(shapeRef), polyShape(shapeRef) { }
public:
PolyShape(Shape^ shape) : Shape(shape->shape), polyShape(0)
{
if(shape->ShapeType == Box2D::Net::ShapeType::e_polygonShape &&
reinterpret_cast<b2PolygonShape *>(shape->shape))
{
polyShape = reinterpret_cast<b2PolygonShape*>(shape->shape);
}
else
{
throw gcnew System::Exception("Attempting to convert a Shape to a PolyShape,"
"but the Shape is not a poly shape.");
}
}
property IList<Vector^>^ Vertices
{
IList<Vector^>^ get()
{
List<Vector^>^ list = gcnew List<Vector^>();
for(int x = 0; x < polyShape->m_vertexCount; ++x)
list->Add(gcnew Vector(polyShape->m_vertices[x]));
return list;
}
}
};
}
}

View File

@@ -0,0 +1,125 @@
#pragma once
#include "stdafx.h"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
ref class Body;
enum class ShapeType;
ref class Vector;
ref class Matrix;
public ref class Shape
{
internal:
b2Shape *shape;
Shape(b2Shape *shapeRef) : shape(shapeRef) { }
public:
bool TestPoint(Vector^ p);
property ShapeType ShapeType
{
ShapeType get();
}
/// <summary>
/// Get the parent body of this shape.
/// </summary>
property Body^ Body;
/// <summary>
/// Get the world position.
/// </summary>
property Vector^ Position;
property Matrix^ Rotation;
//TODO:
//void* GetUserData();
//
// Remove and then add proxy from the broad-phase.
// This is used to refresh the collision filters.
//virtual void ResetProxy(b2BroadPhase* broadPhase) = 0;
/// <summary>
/// Get the next shape in the parent body's shape list.
/// </summary>
Shape^ GetNext();
};
public ref class CircleShape : public Shape
{
internal:
b2CircleShape *circleShape;
CircleShape(b2CircleShape *shapeRef) : Shape(shapeRef), circleShape(shapeRef) { }
public:
CircleShape(Shape^ shape) : Shape(shape->shape), circleShape(0)
{
if(shape->ShapeType == Box2D::Net::ShapeType::e_circleShape &&
reinterpret_cast<b2CircleShape *>(shape->shape))
{
circleShape = reinterpret_cast<b2CircleShape*>(shape->shape);
}
else
{
throw gcnew System::Exception("Attempting to convert a Shape to a CircleShape,"
"but the Shape is not a circle shape.");
}
}
//TODO: this is not technically part of the "public" interface for CircleShape
property float32 Radius
{
float32 get()
{
return circleShape->m_radius;
}
void set(float32 value)
{
circleShape->m_radius = value;
}
}
};
public ref class PolyShape : public Shape
{
internal:
b2PolyShape *polyShape;
PolyShape(b2PolyShape *shapeRef) : Shape(shapeRef), polyShape(shapeRef) { }
public:
PolyShape(Shape^ shape) : Shape(shape->shape), polyShape(0)
{
if(shape->ShapeType == Box2D::Net::ShapeType::e_polyShape &&
reinterpret_cast<b2PolyShape *>(shape->shape))
{
polyShape = reinterpret_cast<b2PolyShape*>(shape->shape);
}
else
{
throw gcnew System::Exception("Attempting to convert a Shape to a PolyShape,"
"but the Shape is not a poly shape.");
}
}
property IList<Vector^>^ Vertices
{
IList<Vector^>^ get()
{
List<Vector^>^ list = gcnew List<Vector^>();
for(int x = 0; x < polyShape->m_vertexCount; ++x)
list->Add(gcnew Vector(polyShape->m_vertices[x]));
return list;
}
}
};
}
}

View File

@@ -0,0 +1,202 @@
#pragma once
#include "stdafx.h"
#include "MassData.cpp"
#include "ShapeType.cpp"
using namespace System::Collections::Generic;
namespace Box2D
{
namespace Net
{
public ref class ShapeDef
{
internal:
bool DeleteOnDtor;
b2ShapeDef *def;
ShapeDef(b2ShapeDef *defRef) : def(defRef), DeleteOnDtor(false) { }
//Needs to work for derivative types, too
b2ShapeDef GetShapeDef()
{
return *def;
}
public:
virtual ~ShapeDef()
{
if(DeleteOnDtor)
delete def;
}
property ShapeType ShapeType
{
Box2D::Net::ShapeType get()
{
return (Box2D::Net::ShapeType) def->type;
}
void set(Box2D::Net::ShapeType value)
{
def->type = b2ShapeType(value);
}
}
property float32 Friction
{
float32 get()
{
return def->friction;
}
void set(float32 value)
{
def->friction = value;
}
}
property float32 Restitution
{
float32 get()
{
return def->restitution;
}
void set(float32 value)
{
def->restitution = value;
}
}
property float32 Density
{
float32 get()
{
return def->density;
}
void set(float32 value)
{
def->density = value;
}
}
/// <summary>
/// The collision category bits. Normally you would just set one bit.
/// </summary>
property unsigned __int16 CategoryBits
{
unsigned __int16 get()
{
return def->categoryBits;
}
void set(unsigned __int16 value)
{
def->categoryBits = value;
}
}
/// <summary>
/// The collision mask bits. This states the categories that this
/// shape would accept for collision.
/// </summary>
property unsigned __int16 MaskBits
{
unsigned __int16 get()
{
return def->maskBits;
}
void set(unsigned __int16 value)
{
def->maskBits = value;
}
}
/// <summary>
/// Collision groups allow a certain group of objects to never collide (negative)
/// or always collide (positive). Zero means no collision group. Non-zero group
/// filtering always wins against the mask bits.
/// </summary>
property unsigned __int16 GroupIndex
{
unsigned __int16 get()
{
return def->groupIndex;
}
void set(unsigned __int16 value)
{
def->groupIndex = value;
}
}
//TODO:
//void* userData;
};
public ref class CircleDef : public ShapeDef
{
public:
CircleDef() : ShapeDef(new b2CircleDef())
{
ShapeDef::DeleteOnDtor = (true);
}
property float32 Radius
{
float32 get()
{
return reinterpret_cast<b2CircleDef*>(def)->radius;
}
void set(float32 value)
{
reinterpret_cast<b2CircleDef*>(def)->radius = value;
}
}
};
public ref class PolygonDef : public ShapeDef
{
public:
PolygonDef() : ShapeDef(new b2PolygonDef())
{
DeleteOnDtor = (true);
}
void SetAsBox(float X, float Y)
{
reinterpret_cast<b2PolygonDef*>(def)->SetAsBox(X, Y);
}
void SetAsBox(float X, float Y, Vector^ Center, float Angle)
{
reinterpret_cast<b2PolygonDef*>(def)->SetAsBox(X, Y, Center->getVec2(), Angle);
}
property IList<Vector^>^ Verticies
{
IList<Vector^>^ get()
{
List<Vector^>^ list = gcnew List<Vector^>();
for(int x = 0; x < reinterpret_cast<b2PolygonDef*>(def)->vertexCount; ++x)
{
list->Add(gcnew Vector(reinterpret_cast<b2PolygonDef*>(def)->vertices[x]));
}
return list;
}
void set(IList<Vector^>^ value)
{
b2PolygonDef* Def = reinterpret_cast<b2PolygonDef*>(def);
for(int x = 0; x < value->Count; ++x)
Def->vertices[x] = value[x]->getVec2();
}
}
};
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include "stdafx.h"
namespace Box2D
{
namespace Net
{
//TODO: is there a way to auto incorporate shape types?
public enum class ShapeType
{
e_unknownShape = ::e_unknownShape,
e_circleShape = ::e_circleShape,
e_polygonShape = ::e_polygonShape,
e_shapeTypeCount = ::e_shapeTypeCount
};
}
}

View File

@@ -0,0 +1,8 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently
#pragma once
#include "Box2D.h"

View File

@@ -0,0 +1,16 @@
#pragma once
#include "stdafx.h"
#include "Shape.cpp"
#include "Body.cpp"
namespace Box2D
{
namespace Net
{
Body^ Shape::Body::get()
{
return gcnew Box2D::Net::Body(shape->GetBody());
}
}
}

View File

@@ -0,0 +1,81 @@
#pragma once
#include "Stdafx.h"
namespace Box2D
{
namespace Net
{
public ref class Vector
{
internal:
b2Vec2 getVec2()
{
return b2Vec2(X, Y);
}
public:
//TODO: this needs to be read only outside the class,
//because if you have a vector as a get property, and
//try to set the X,Y components, it won't take to the
//original vector:
//
//ie: Shape.Extents.X += 10;
//won't behave like you think it should (or will it?)
float32 X, Y;
Vector() : X(0), Y(0) { }
Vector(float32 x, float32 y) : X(x), Y(y) { }
Vector(Vector^ other) : X(other->X), Y(other->Y) { }
Vector(const b2Vec2 &other) : X(other.x), Y(other.y) { }
/*
Vector^ Set(float32 x, float32 y)
{
X = x;
Y = y;
return this;
}
*/
///Defines basic vector addition
static Vector^ operator +(Vector^ a, Vector^ b)
{
return gcnew Vector(a->X + b->X, a->Y + b->Y);
}
///<summary>Negates a vector (that is, returns (-X, -Y)</summary>
static Vector^ operator - (Vector^ a)
{
return gcnew Vector(-a->X, -a->Y);
}
///<summary>Defines basic vector subtraction</summary>
static Vector^ operator - (Vector^ a, Vector^ b)
{
return gcnew Vector(a->X - b->X, a->Y - b->Y);
}
///<summary>Scalar multiplication for a vector</summary>
static Vector^ operator * (Vector^ a, float32 b)
{
return gcnew Vector(a->X * b, a->Y * b);
}
/*
static Vector^ operator = (Vector^ a, Vector^ b)
{
a.X = b.X;
a.Y = b.Y;
}
*/
///<summary>Returns a string representation of this vector</summary>
virtual System::String^ ToString() override
{
return gcnew System::String("<" + X + ", " + Y + ">");
}
};
}
}

View File

@@ -0,0 +1,162 @@
#pragma once
#include "Stdafx.h"
#include "AABB.cpp"
#include "Body.cpp"
#include "BodyDef.cpp"
#include "Joint.cpp"
#include "JointDef.cpp"
#include "Contact.cpp"
namespace Box2D
{
namespace Net
{
public ref class World
{
b2World *world;
public:
World(AABB^ worldAABB, Vector^ gravity, bool doSleep) : world(new b2World(
worldAABB->getAABB(), gravity->getVec2(), doSleep)) { }
~World()
{
delete world;
}
/// <summary> Create rigid body from a definition </summary>
Body^ CreateBody(BodyDef^ def)
{
return gcnew Body(world->CreateBody(def->def));
}
///<summary>
/// Destroy rigid bodies. Destruction is deferred until the the next call to Step.
/// This is done so that bodies may be destroyed while you iterate through the contact list.
///</summary>
void DestroyBody(Body^ body)
{
world->DestroyBody(body->body);
}
/// <summary>
/// The world provides a single ground body with no collision shapes. You
/// can use this to simplify the creation of joints.
/// </summary>
Body^ GetGroundBody()
{
return gcnew Body(world->GetGroundBody());
}
void Step(float32 timeStep, int32 iterations)
{
world->Step(timeStep, iterations);
}
Joint^ CreateJoint(JointDef^ def)
{
return gcnew Joint(world->CreateJoint(def->def));
}
void DestroyJoint(Joint^ joint)
{
world->DestroyJoint(joint->joint);
}
property IList<Body^>^ Bodies
{
IList<Body^>^ get()
{
List<Body^>^ list = gcnew List<Body^>();
for(b2Body *body = world->GetBodyList(); body; body = body->GetNext())
list->Add(gcnew Body(body));
return list;
}
}
property IList<Joint^>^ Joints
{
IList<Joint^>^ get()
{
List<Joint^>^ list = gcnew List<Joint^>();
for(b2Joint *joint = world->GetJointList(); joint; joint = joint->GetNext())
list->Add(gcnew Joint(joint));
return list;
}
}
Joint^ GetJointList()
{
return gcnew Joint(world->GetJointList());
}
///<summary> You can use these to iterate over all the bodies, joints, and contacts. </summary>
/*
Contact^ GetContactList()
{
return gcnew Contact(world->C>GetContactList());
}
*/
/// <summary>
/// Query the world for all shapes that potentially overlap the
/// provided AABB. You provide a shape pointer buffer of specified
/// size. The number of shapes found is returned.
/// </summary>
IList<Shape^>^ Query(AABB^ aabb)
{
const int32 k_maxCount = 25;
b2Shape* shapes[k_maxCount];
int32 count = world->Query(aabb->getAABB(), shapes, k_maxCount);
List<Shape^>^ list = gcnew List<Shape^>();
for(int x = 0; x < count; ++x)
list->Add(gcnew Shape(shapes[x]));
return list;
}
static property bool PositionCorrection
{
bool get()
{
return b2World::s_enablePositionCorrection == 1;
}
void set(bool value)
{
b2World::s_enablePositionCorrection = value ? 1 : 0;
}
}
static property bool WarmStarting
{
bool get()
{
return b2World::s_enableWarmStarting == 1;
}
void set(bool value)
{
b2World::s_enableWarmStarting = value ? 1 : 0;
}
}
};
}
}
/*
class b2World
{
public:
// Register a world listener to receive important events that can
// help prevent your code from crashing.
void SetListener(b2WorldListener* listener);
// Register a collision filter to provide specific control over collision.
// Otherwise the default filter is used (b2CollisionFilter).
void SetFilter(b2CollisionFilter* filter);
*/

View File

@@ -0,0 +1,47 @@
#pragma once
#include "stdafx.h"
#include "Vector.cpp"
#include "Matrix.cpp"
namespace Box2D
{
namespace Net
{
public ref class XForm
{
internal:
b2XForm *xform;
bool DeleteOnDtor;
XForm(b2XForm *XForm) : xform(XForm), DeleteOnDtor(false) { }
XForm(b2XForm XForm) : xform(new b2XForm(XForm)), DeleteOnDtor(false) { }
b2XForm getXForm()
{
return *xform;
}
public:
XForm() : xform(new b2XForm()), DeleteOnDtor(true) { }
~XForm()
{
if(DeleteOnDtor)
delete xform;
}
property Vector^ Position
{
Vector^ get()
{
return gcnew Vector(xform->position);
}
}
property Matrix^ Rotation
{
Matrix^ get()
{
return gcnew Matrix(xform->R);
}
}
};
}
}

View File

@@ -0,0 +1,220 @@
namespace TestBed.Net
{
partial class MainWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.panel1 = new System.Windows.Forms.Panel();
this.OpenGLControl = new Tao.Platform.Windows.SimpleOpenGlControl();
this.panel2 = new System.Windows.Forms.Panel();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.numericUpDown2 = new System.Windows.Forms.NumericUpDown();
this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
this.checkBox2 = new System.Windows.Forms.CheckBox();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.TestsComboBox = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.RedrawTimer = new System.Windows.Forms.Timer(this.components);
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
this.SuspendLayout();
//
// panel1
//
this.panel1.Controls.Add(this.OpenGLControl);
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(372, 242);
this.panel1.TabIndex = 3;
//
// OpenGLControl
//
this.OpenGLControl.AccumBits = ((byte)(0));
this.OpenGLControl.AutoCheckErrors = true;
this.OpenGLControl.AutoFinish = true;
this.OpenGLControl.AutoMakeCurrent = true;
this.OpenGLControl.AutoSwapBuffers = true;
this.OpenGLControl.BackColor = System.Drawing.Color.Black;
this.OpenGLControl.ColorBits = ((byte)(32));
this.OpenGLControl.DepthBits = ((byte)(16));
this.OpenGLControl.Location = new System.Drawing.Point(106, 62);
this.OpenGLControl.Name = "OpenGLControl";
this.OpenGLControl.Size = new System.Drawing.Size(137, 103);
this.OpenGLControl.StencilBits = ((byte)(0));
this.OpenGLControl.TabIndex = 1;
this.OpenGLControl.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler(this.OpenGLControl_PreviewKeyDown);
this.OpenGLControl.MouseDown += new System.Windows.Forms.MouseEventHandler(this.OpenGLControl_MouseDown);
this.OpenGLControl.MouseMove += new System.Windows.Forms.MouseEventHandler(this.OpenGLControl_MouseMove);
this.OpenGLControl.MouseUp += new System.Windows.Forms.MouseEventHandler(this.OpenGLControl_MouseUp);
//
// panel2
//
this.panel2.Controls.Add(this.label3);
this.panel2.Controls.Add(this.label2);
this.panel2.Controls.Add(this.numericUpDown2);
this.panel2.Controls.Add(this.numericUpDown1);
this.panel2.Controls.Add(this.checkBox2);
this.panel2.Controls.Add(this.checkBox1);
this.panel2.Controls.Add(this.TestsComboBox);
this.panel2.Controls.Add(this.label1);
this.panel2.Location = new System.Drawing.Point(390, 12);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(170, 242);
this.panel2.TabIndex = 4;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(18, 81);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(32, 13);
this.label3.TabIndex = 10;
this.label3.Text = "Hertz";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(18, 55);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(50, 13);
this.label2.TabIndex = 9;
this.label2.Text = "Iterations";
//
// numericUpDown2
//
this.numericUpDown2.Location = new System.Drawing.Point(71, 79);
this.numericUpDown2.Name = "numericUpDown2";
this.numericUpDown2.Size = new System.Drawing.Size(71, 20);
this.numericUpDown2.TabIndex = 8;
this.numericUpDown2.Value = new decimal(new int[] {
60,
0,
0,
0});
//
// numericUpDown1
//
this.numericUpDown1.Location = new System.Drawing.Point(71, 53);
this.numericUpDown1.Name = "numericUpDown1";
this.numericUpDown1.Size = new System.Drawing.Size(71, 20);
this.numericUpDown1.TabIndex = 7;
this.numericUpDown1.Value = new decimal(new int[] {
60,
0,
0,
0});
//
// checkBox2
//
this.checkBox2.AutoSize = true;
this.checkBox2.Checked = true;
this.checkBox2.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBox2.Location = new System.Drawing.Point(21, 128);
this.checkBox2.Name = "checkBox2";
this.checkBox2.Size = new System.Drawing.Size(93, 17);
this.checkBox2.TabIndex = 6;
this.checkBox2.Text = "Warm Starting";
this.checkBox2.UseVisualStyleBackColor = true;
//
// checkBox1
//
this.checkBox1.AutoSize = true;
this.checkBox1.Checked = true;
this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
this.checkBox1.Location = new System.Drawing.Point(21, 105);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(114, 17);
this.checkBox1.TabIndex = 5;
this.checkBox1.Text = "Position Correction";
this.checkBox1.UseVisualStyleBackColor = true;
//
// TestsComboBox
//
this.TestsComboBox.FormattingEnabled = true;
this.TestsComboBox.Location = new System.Drawing.Point(21, 26);
this.TestsComboBox.Name = "TestsComboBox";
this.TestsComboBox.Size = new System.Drawing.Size(121, 21);
this.TestsComboBox.TabIndex = 3;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(67, 10);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(33, 13);
this.label1.TabIndex = 4;
this.label1.Text = "Tests";
//
// RedrawTimer
//
this.RedrawTimer.Enabled = true;
this.RedrawTimer.Interval = 30;
this.RedrawTimer.Tag = "";
this.RedrawTimer.Tick += new System.EventHandler(this.RedrawTimer_Tick);
//
// MainWindow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(572, 457);
this.Controls.Add(this.panel2);
this.Controls.Add(this.panel1);
this.Name = "MainWindow";
this.Text = "MainWindow";
this.Resize += new System.EventHandler(this.MainWindow_Resize);
this.Load += new System.EventHandler(this.MainWindow_Load);
this.panel1.ResumeLayout(false);
this.panel2.ResumeLayout(false);
this.panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Panel panel1;
private Tao.Platform.Windows.SimpleOpenGlControl OpenGLControl;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox TestsComboBox;
private System.Windows.Forms.Timer RedrawTimer;
private System.Windows.Forms.CheckBox checkBox2;
private System.Windows.Forms.CheckBox checkBox1;
private System.Windows.Forms.NumericUpDown numericUpDown2;
private System.Windows.Forms.NumericUpDown numericUpDown1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
}
}

View File

@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Tao.OpenGl;
using Box2D.Net;
using System.Reflection;
namespace TestBed.Net
{
public partial class MainWindow : Form
{
private Settings Settings = new Settings();
private Test mCurrentTest;
public Test CurrentTest
{
get
{
return mCurrentTest;
}
set
{
//Call code to reset current test
mCurrentTest = value;
}
}
public MainWindow()
{
InitializeComponent();
//Find all Tests in this module
foreach (Type type in Assembly.GetExecutingAssembly().GetExportedTypes())
{
Test test = new Test();
if (type.IsSubclassOf(test.GetType()))
{
TestsComboBox.Items.Add(System.Activator.CreateInstance(type));
}
}
TestsComboBox.SelectedIndex = 0;
CurrentTest = (Test)System.Activator.CreateInstance(TestsComboBox.SelectedItem.GetType());
OpenGLControl.Dock = DockStyle.Fill;
}
private void MainWindow_Load(object sender, EventArgs e)
{
OpenGLControl.InitializeContexts();
panel1.Dock = DockStyle.Fill;
panel2.Dock = DockStyle.Right;
MainWindow_Resize(null, null);
RedrawTimer.Interval = (int)(1000.0f / (float)Settings.Hz);
RedrawTimer.Start();
}
private void MainWindow_Resize(object sender, EventArgs e)
{
Size size = new Size(OpenGLControl.Size.Width - panel2.Width, OpenGLControl.Size.Height);
Renderer.InitOpenGL(size, CurrentTest.Zoom, CurrentTest.ViewOffset);
Renderer.OpenGLDraw(CurrentTest);
}
private void OpenGLControl_Paint(object sender, PaintEventArgs e)
{
Renderer.OpenGLDraw(CurrentTest);
}
private Vector RelativeCoordinates(Point MousePoint)
{
float Height = (float)OpenGLControl.Size.Height;
float Width = (float)(OpenGLControl.Size.Width - panel2.Width);
if(Height <= 0)
Height = 1;
float AspectRatio = Width / Height;
Vector relative = new Vector(
(float)MousePoint.X / Width,
(float)MousePoint.Y / Height);
relative -= new Vector(.5f, .5f);
relative *= 2;
relative.Y *= -1;
relative.X *= AspectRatio;
return relative;
}
private void OpenGLControl_MouseMove(object sender, MouseEventArgs e)
{
CurrentTest.MouseMove(RelativeCoordinates(e.Location));
}
private void OpenGLControl_MouseUp(object sender, MouseEventArgs e)
{
CurrentTest.MouseUp(RelativeCoordinates(e.Location));
}
private void OpenGLControl_MouseDown(object sender, MouseEventArgs e)
{
CurrentTest.MouseDown(RelativeCoordinates(e.Location));
}
private void RedrawTimer_Tick(object sender, EventArgs e)
{
CurrentTest.Step(Settings);
Renderer.OpenGLDraw(CurrentTest);
OpenGLControl.Draw();
int errorCode = 0;
if ((errorCode = Gl.glGetError()) > 0)
{
RedrawTimer.Stop();
//Handled by the OpenGLControl
//MessageBox.Show(Glu.gluErrorString(errorCode));
}
}
private void OpenGLControl_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if(e.KeyCode == Keys.R)
CurrentTest = (Test)System.Activator.CreateInstance(CurrentTest.GetType());
else
CurrentTest.KeyPress(e.KeyCode);
}
}
}

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="RedrawTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Text;
using Box2D.Net;
using System.Windows.Forms;
namespace TestBed.Net
{
class Program
{
static void Main(string[] args)
{
Console.Title = "Box2D.Net Test Bed";
Application.EnableVisualStyles();
MainWindow win = new MainWindow();
Console.Write("Loading the OpenGL display window. Please be patient... ");
//Show above the console
win.Show();
win.BringToFront(); //Doesn't bring above the console?
win.TopMost = true; //Hacky fix instead:
win.TopMost = false;
Console.WriteLine("DONE");
Application.Run(win);
}
}
}

View File

@@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TestBed.Net")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TestBed.Net")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c08bf3be-733a-49ed-820b-ad4f13ff3a00")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tao.OpenGl;
using Box2D.Net;
using System.Windows.Forms;
namespace TestBed.Net
{
static class Renderer
{
public static void InitOpenGL(System.Drawing.Size WidthHeight, float viewZoom, Vector ViewOffset)
{
int Width = WidthHeight.Width;
int Height = WidthHeight.Height;
Height = Height > 0 ? Height : 1;
Gl.glDisable(Gl.GL_CULL_FACE);
Gl.glClearColor(.5f, .5f, .5f, 1);
float AspectRatio = (float)Width / (float)Height;
Gl.glViewport(0, 0, Width, Height);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluOrtho2D(-AspectRatio, AspectRatio, -1, 1);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
}
public static void OpenGLDraw(Test test)
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glScalef(1.0f / test.Zoom, 1.0f / test.Zoom, 1.0f / test.Zoom);
Gl.glTranslatef(-test.ViewOffset.X, -test.ViewOffset.Y, 0);
Gl.glPushMatrix();
DrawBodies(test.world.Bodies);
DrawJoints(test.world.Joints);
Gl.glPopMatrix();
}
public static void DrawJoints(IList<Joint> joints)
{
foreach (Joint joint in joints)
{
DrawJoint(joint, System.Drawing.Color.LawnGreen);
}
}
public static void DrawBodies(IList<Body> bodies)
{
foreach(Body body in bodies)
foreach (Shape shape in body.Shapes)
{
System.Drawing.Color color = System.Drawing.Color.White;
if (body.Static)
color = System.Drawing.Color.LightGreen; //Color(0.5f, 0.9f, 0.5f)
else if (body.Sleeping)
color = System.Drawing.Color.LightBlue;
//else if(body == bomb)
DrawShape(body.GetXForm(), shape, System.Drawing.Color.White);
}
}
public static void DrawShape(XForm xform, Shape shape, System.Drawing.Color c)
{
switch (shape.ShapeType)
{
case ShapeType.e_circleShape:
{
Vector x = xform.Position;
float r = (new CircleShape(shape)).Radius;
float segments = 16;
double increment = 2 * Math.PI / segments;
Gl.glColor3ub(c.R, c.G, c.B);
Gl.glBegin(Gl.GL_LINE_LOOP);
for (double i = 0, theta = 0; i < segments; ++i, theta += increment)
{
Vector d = new Vector(r * (float)Math.Cos(theta), r * (float)Math.Sin(theta));
Vector v = x + d;
Gl.glVertex2f(v.X, v.Y);
}
Gl.glEnd();
//Draw a line from the circle's center to it's right side
//so we can visually inspect rotations.
Gl.glBegin(Gl.GL_LINES);
Gl.glVertex2f(x.X, x.Y);
Vector ax = xform.Rotation.col1;
Gl.glVertex2f(x.X + r * ax.X, x.Y + r * ax.Y);
Gl.glEnd();
}
break;
case ShapeType.e_polygonShape:
{
Gl.glColor3ub(c.R, c.G, c.B);
Gl.glBegin(Gl.GL_LINE_LOOP);
foreach (Vector vertex in (new PolyShape(shape)).Vertices)
{
Vector vertprime = xform.Rotation * vertex + xform.Position;
Gl.glVertex2f(vertprime.X, vertprime.Y);
}
Gl.glEnd();
}
break;
}
}
public static void DrawAABB(AABB aabb, System.Drawing.Color c)
{
Gl.glColor3b(c.R, c.G, c.B);
Gl.glBegin(Gl.GL_LINE_LOOP);
Gl.glVertex2f(aabb.lowerBound.X, aabb.lowerBound.Y);
Gl.glVertex2f(aabb.upperBound.X, aabb.lowerBound.Y);
Gl.glVertex2f(aabb.upperBound.X, aabb.upperBound.Y);
Gl.glVertex2f(aabb.lowerBound.X, aabb.upperBound.Y);
Gl.glEnd();
}
public static void DrawJoint(Joint joint, System.Drawing.Color color)
{
Body b1 = joint.Body1;
Body b2 = joint.Body2;
Vector x1 = b1.GetXForm().Position;
Vector x2 = b2.GetXForm().Position;
Vector p1 = joint.Anchor2;
Vector p2 = joint.Anchor1;
Gl.glColor3ub(color.R, color.G, color.B);
Gl.glBegin(Gl.GL_LINES);
switch (joint.JointType)
{
case JointType.e_mouseJoint:
case JointType.e_distanceJoint:
Gl.glVertex2f(p1.X, p1.Y);
Gl.glVertex2f(p2.X, p2.Y);
break;
/*
* case JointType.e_pulleyJoint:
{
b2PulleyJoint* pulley = (b2PulleyJoint*)joint;
b2Vec2 s1 = pulley->GetGroundPoint1();
b2Vec2 s2 = pulley->GetGroundPoint2();
glVertex2f(s1.x, s1.y);
glVertex2f(p1.x, p1.y);
glVertex2f(s2.x, s2.y);
glVertex2f(p2.x, p2.y);
}
break;
*/
default:
Gl.glVertex2f(x1.X, x1.Y);
Gl.glVertex2f(p1.X, p1.Y);
Gl.glVertex2f(x2.X, x2.Y);
Gl.glVertex2f(p2.X, p2.Y);
break;
}
Gl.glEnd();
}
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace TestBed.Net
{
public class Settings
{
public float Hz = 60;
public int IterationCount = 10;
public bool DrawStats = false;
public bool DrawContacts = false;
public bool DrawImpulses = false;
public bool DrawAABBs = false;
public bool DrawPairs = false;
public bool WarmStarting = true;
public bool PositionCorrection = true;
public bool Pause = false;
}
}

View File

@@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using System.Text;
using Box2D.Net;
using Tao.OpenGl;
namespace TestBed.Net
{
public class Test
{
public World world;
public MouseJoint mouseJoint;
public Body bomb;
public float Zoom = 20;
public Vector ViewOffset = new Vector();
public Vector Mouse = null;
public Test()
{
AABB worldAABB = new AABB(new Vector(-100.0f, -100.0f), new Vector(100.0f, 200.0f));
Vector gravity = new Vector(0, -10);
bool doSleep = true;
world = new World(worldAABB, gravity, doSleep);
//m_textLine = 30;
//
//m_listener.test = this;
//m_world->SetListener(&m_listener);
}
public void Step(Settings settings)
{
if(settings.Pause)
return;
float timeStep = settings.Hz > 0 ? 1.0f / settings.Hz : 0;
World.WarmStarting = settings.WarmStarting;
World.PositionCorrection = settings.PositionCorrection;
world.Step(timeStep, settings.IterationCount);
//m_world->m_broadPhase->Validate();
}
Vector RelativeToWorld(Vector Relative)
{
Vector working = Relative;
working *= Zoom;
working -= ViewOffset;
return working;
}
/// <summary>
/// Handles what happens when a user clicks the mouse
/// </summary>
/// <param name="p">
/// The position of the mouse click in relative coordinates.
/// </param>
public void MouseDown(Vector point)
{
Vector p = RelativeToWorld(point);
if (mouseJoint != null)
throw new Exception("ASSERT: mouseJoint should be null");
// Make a small box.
Vector d = new Vector(.001f, .001f);
AABB aabb = new AABB(p - d, p + d);
// Query the world for overlapping shapes.
IList<Shape> shapes = world.Query(aabb);
Body body = null;
foreach (Shape shape in shapes)
{
if (shape.Body.Static == false &&
shape.TestPoint(shape.Body.GetXForm(), p))
{
body = shape.Body;
break;
}
}
if (body != null)
{
MouseJointDef md = new MouseJointDef();
md.Body1 = world.GetGroundBody();
md.Body2 = body;
md.Target = p;
md.MaxForce = 1000 * body.Mass;
mouseJoint = new MouseJoint(world.CreateJoint(md));
body.WakeUp();
}
}
public void MouseUp(Vector point)
{
Vector p = RelativeToWorld(point);
if (mouseJoint != null)
{
world.DestroyJoint(mouseJoint);
mouseJoint = null;
}
}
public void MouseMove(Vector point)
{
Vector p = RelativeToWorld(point);
if (mouseJoint != null)
mouseJoint.SetTarget(p);
}
public void KeyPress(System.Windows.Forms.Keys key)
{
switch (key)
{
case System.Windows.Forms.Keys.Space:
LaunchBomb();
break;
case System.Windows.Forms.Keys.Left:
ViewOffset.X -= 1;
break;
case System.Windows.Forms.Keys.Right:
ViewOffset.X += 1;
break;
case System.Windows.Forms.Keys.Up:
ViewOffset.Y += 1;
break;
case System.Windows.Forms.Keys.Down:
ViewOffset.Y -= 1;
break;
case System.Windows.Forms.Keys.X:
Zoom -= 1;
break;
case System.Windows.Forms.Keys.Z:
Zoom += 1;
break;
}
}
void LaunchBomb()
{
if (bomb != null)
{
world.DestroyBody(bomb);
bomb = null;
}
BodyDef bd = new BodyDef();
bd.BodyType = BodyType.e_dynamicBody;
bd.AllowSleep = true;
Random rand = new Random();
bd.Position = new Vector((float)rand.NextDouble() * 30 - 15, 30.0f);
bd.IsBullet = true;
bomb = world.CreateBody(bd);
bomb.LinearVelocity = bd.Position * -5;
CircleDef sd = new CircleDef();
sd.Radius = 0.3f;
sd.Density = 20.0f;
sd.Restitution = 0.1f;
bomb.CreateShape(sd);
bomb.SetMassFromShapes();
}
public override string ToString()
{
return GetType().Name;
}
};
}

View File

@@ -0,0 +1,74 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{B2F62680-048C-46AA-B1B2-7731252E1304}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TestBed.Net</RootNamespace>
<AssemblyName>TestBed.Net</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Tao.FreeGlut, Version=2.4.0.1, Culture=neutral, PublicKeyToken=6e602a6ad6c0d06d, processorArchitecture=MSIL" />
<Reference Include="Tao.OpenGl, Version=2.1.0.4, Culture=neutral, PublicKeyToken=1ca010269a4501ef, processorArchitecture=MSIL" />
<Reference Include="Tao.Platform.Windows, Version=1.0.0.4, Culture=neutral, PublicKeyToken=701104b2da67a104, processorArchitecture=MSIL" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainWindow.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainWindow.Designer.cs">
<DependentUpon>MainWindow.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Renderer.cs" />
<Compile Include="Settings.cs" />
<Compile Include="Test.cs" />
<Compile Include="Tests\Bridge.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Box2D.Net.vcproj">
<Project>{0E95DBB9-EA97-407B-811C-810B225E79D2}</Project>
<Name>Box2D.Net</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="MainWindow.resx">
<SubType>Designer</SubType>
<DependentUpon>MainWindow.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Text;
using Box2D.Net;
namespace TestBed.Net.Tests
{
public class Bridge : TestBed.Net.Test
{
public Bridge()
{
Body ground;
{
PolygonDef sd = new PolygonDef();
sd.ShapeType = ShapeType.e_polygonShape;
sd.SetAsBox(50.0f, 10.0f);
BodyDef bd = new BodyDef();
bd.Position = new Vector(0, -10);
ground = world.CreateBody(bd);
ground.CreateShape(sd);
}
{
PolygonDef sd = new PolygonDef();
sd.SetAsBox(0.5f, 0.125f);
sd.Density = 20.0f;
sd.Friction = 0.2f;
BodyDef bd = new BodyDef();
bd.BodyType = BodyType.e_dynamicBody;
RevoluteJointDef jd = new RevoluteJointDef();
const float numPlanks = 30;
Body prevBody = ground;
for (float i = 0; i < numPlanks; ++i)
{
bd.Position = new Vector(-14.5f + i, 5);
Body body = world.CreateBody(bd);
body.CreateShape(sd);
body.SetMassFromShapes();
Vector anchor = new Vector(-15 + i, 5);
jd.Initialize(prevBody, body, anchor);
world.CreateJoint(jd);
prevBody = body;
}
Vector anchor2 = new Vector(-15 + numPlanks, 5);
jd.Initialize(prevBody, ground, anchor2);
world.CreateJoint(jd);
}
}
}
}

View File

@@ -0,0 +1,36 @@
cmake_minimum_required(VERSION 2.6)
set(BOX2D_VERSION 2.1.0)
set(BOX2D_BUILD_STATIC true)
set(BOX2D_DIR ../../../Box2D)
subdirs(${BOX2D_DIR}/Box2D)
project(iPhoneTestbed)
include_directories(${BOX2D_DIR} ${BOX2D_DIR}/Testbed/Tests)
file(GLOB iPhoneTestbed_Classes_SRCS Classes/*.mm)
source_group(Classes FILES ${iPhoneTestbed_Classes_SRCS})
set(CMAKE_OSX_SYSROOT iphoneos)
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
set(CMAKE_OSX_ARCHITECTURES $(ARCHS_STANDARD_32_BIT))
set(CMAKE_EXE_LINKER_FLAGS "-framework Foundation -framework CoreGraphics -framework QuartzCore -framework OpenGLES -framework UIKit")
set(MACOSX_BUNDLE_PRODUCT_NAME \${PRODUCT_NAME})
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.mycompany.\${PRODUCT_NAME:identifier}")
add_executable(iPhoneTestbed MACOSX_BUNDLE
${iPhoneTestbed_Classes_SRCS}
main.m
)
target_link_libraries(iPhoneTestbed Box2D)
set_target_properties(iPhoneTestbed PROPERTIES MACOSX_BUNDLE_INFO_PLIST Info.plist.in XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer")
set(APP_NAME \${TARGET_BUILD_DIR}/\${FULL_PRODUCT_NAME})
find_program(IBTOOL ibtool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin")
set(NIB MainWindow)
add_custom_command(TARGET iPhoneTestbed POST_BUILD
COMMAND /Developer/Library/PrivateFrameworks/DevToolsCore.framework/Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -resolve-src-symlinks Resources/* ${APP_NAME}
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text --compile ${iPhoneTestbed_BINARY_DIR}/\${CONFIGURATION}/${PROJECT_NAME}.app/${NIB}.nib ${NIB}.xib
)

View File

@@ -0,0 +1,24 @@
//
// Box2DAppDelegate.h
// Box2D
//
// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
//
#import <UIKit/UIKit.h>
#import "TestEntriesViewController.h"
#import "Delegates.h"
@class Box2DView;
@interface Box2DAppDelegate : NSObject <UIApplicationDelegate,TestSelectDelegate> {
UIWindow *window;
Box2DView *glView;
TestEntriesViewController *testEntriesView;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet Box2DView *glView;
@end

View File

@@ -0,0 +1,62 @@
//
// Box2DAppDelegate.m
// Box2D
//
// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
//
#import <UIKit/UIKit.h>
#import "Box2DAppDelegate.h"
#import "Box2DView.h"
@implementation Box2DAppDelegate
@synthesize window;
@synthesize glView;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[application setStatusBarHidden:true];
[glView removeFromSuperview];
glView.animationInterval = 1.0 / 60.0;
testEntriesView=[[TestEntriesViewController alloc] initWithStyle:UITableViewStylePlain];
[testEntriesView setDelegate:self];
[glView setDelegate:self];
[window addSubview:[testEntriesView view]];
}
-(void) selectTest:(int) testIndex
{
[[testEntriesView view] removeFromSuperview];
[window addSubview:glView];
[glView startAnimation];
[glView selectTestEntry:testIndex];
}
-(void) leaveTest
{
[glView stopAnimation];
[glView removeFromSuperview];
[window addSubview:[testEntriesView view]];
}
- (void)applicationWillResignActive:(UIApplication *)application {
glView.animationInterval = 1.0 / 5.0;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
glView.animationInterval = 1.0 / 60.0;
}
- (void)dealloc {
[window release];
[glView release];
[super dealloc];
}
@end

View File

@@ -0,0 +1,63 @@
//
// Box2DView.h
// Box2D OpenGL View
//
// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
//
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import "iPhoneTest.h"
#import "Delegates.h"
/*
This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
The view content is basically an EAGL surface you render your OpenGL scene into.
Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
*/
@interface Box2DView : UIView <UIAccelerometerDelegate> {
@private
/* The pixel dimensions of the backbuffer */
GLint backingWidth;
GLint backingHeight;
EAGLContext *context;
/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
GLuint viewRenderbuffer, viewFramebuffer;
/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
GLuint depthRenderbuffer;
NSTimer *animationTimer;
NSTimeInterval animationInterval;
TestEntry* entry;
Test* test;
// Position offset and scale
float sceneScale;
CGPoint positionOffset;
CGPoint lastWorldTouch;
CGPoint lastScreenTouch;
bool panning;
int doubleClickValidCountdown;
id<TestSelectDelegate> _delegate;
}
@property(assign) id<TestSelectDelegate> delegate;
@property NSTimeInterval animationInterval;
- (void)startAnimation;
- (void)stopAnimation;
- (void)drawView;
-(void) selectTestEntry:(int) testIndex;
@end

View File

@@ -0,0 +1,299 @@
//
// Box2DView.mm
// Box2D OpenGL View
//
// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
//
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
#import "Box2DView.h"
#define USE_DEPTH_BUFFER 0
#define kAccelerometerFrequency 30
#define FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK 10
Settings settings;
// A class extension to declare private methods
@interface Box2DView ()
@property (nonatomic, retain) EAGLContext *context;
@property (nonatomic, assign) NSTimer *animationTimer;
- (BOOL) createFramebuffer;
- (void) destroyFramebuffer;
@end
@implementation Box2DView
@synthesize context;
@synthesize animationTimer;
@synthesize animationInterval;
@synthesize delegate=_delegate;
// You must implement this method
+ (Class)layerClass {
return [CAEAGLLayer class];
}
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithCoder:(NSCoder*)coder {
if ((self = [super initWithCoder:coder])) {
// Get the layer
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
eaglLayer.opaque = YES;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context]) {
[self release];
return nil;
}
animationInterval = 1.0 / 60.0;
sceneScale=10.0f;
positionOffset=CGPointMake(0, 0);
lastWorldTouch=CGPointMake(0, 0);
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
//[self setMultipleTouchEnabled:YES];
}
return self;
}
-(void) selectTestEntry:(int) testIndex
{
// Destroy existing scene
delete test;
entry = g_testEntries + testIndex;
test = entry->createFcn();
doubleClickValidCountdown=0;
sceneScale=10.0f;
positionOffset=CGPointMake(0, 0);
lastWorldTouch=CGPointMake(0, 0);
}
- (void)drawView {
if (doubleClickValidCountdown>0) doubleClickValidCountdown--;
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-sceneScale, sceneScale, -sceneScale*1.5f, sceneScale*1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(positionOffset.x, positionOffset.y,0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
test->Step(&settings);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (void)layoutSubviews {
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
[self drawView];
}
- (BOOL)createFramebuffer {
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if (USE_DEPTH_BUFFER) {
glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
}
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
- (void)destroyFramebuffer {
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
if(depthRenderbuffer) {
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
}
- (void)startAnimation {
self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
}
- (void)stopAnimation {
self.animationTimer = nil;
}
- (void)setAnimationTimer:(NSTimer *)newTimer {
[animationTimer invalidate];
animationTimer = newTimer;
}
- (void)setAnimationInterval:(NSTimeInterval)interval {
animationInterval = interval;
if (animationTimer) {
[self stopAnimation];
[self startAnimation];
}
}
- (void)dealloc {
[self stopAnimation];
if ([EAGLContext currentContext] == context) {
[EAGLContext setCurrentContext:nil];
}
[context release];
[super dealloc];
}
-(CGPoint) screenSpaceToWorldSpace:(CGPoint) screenLocation
{
screenLocation.x-=160;
screenLocation.y-=240;
screenLocation.x/=160;
screenLocation.y/=160;
screenLocation.x*=sceneScale;
screenLocation.y*=-sceneScale;
screenLocation.x-=positionOffset.x;
screenLocation.y-=positionOffset.y;
return screenLocation;
}
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
if (doubleClickValidCountdown>0)
{
[_delegate leaveTest];
return;
}
doubleClickValidCountdown=FRAMES_BETWEEN_PRESSES_FOR_DOUBLE_CLICK;
panning=false;
for (UITouch *touch in touches)
{
CGPoint touchLocation=[touch locationInView:self];
CGPoint worldPosition=[self screenSpaceToWorldSpace:touchLocation];
//printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
lastScreenTouch=touchLocation;
lastWorldTouch=worldPosition;
b2Vec2 p = b2Vec2(lastWorldTouch.x,lastWorldTouch.y);
test->MouseDown(p);
//test->ShiftMouseDown(p);
if (!test->m_mouseJoint) panning=true;
}
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
for (UITouch *touch in touches)
{
CGPoint touchLocation=[touch locationInView:self];
CGPoint worldPosition=[self screenSpaceToWorldSpace:touchLocation];
//printf("Screen touched %f,%f -> %f,%f\n",touchLocation.x,touchLocation.y,worldPosition.x,worldPosition.y);
CGPoint screenDistanceMoved=CGPointMake(touchLocation.x-lastScreenTouch.x,touchLocation.y-lastScreenTouch.y);
if (panning)
{
screenDistanceMoved.x/=160;
screenDistanceMoved.y/=160;
screenDistanceMoved.x*=sceneScale;
screenDistanceMoved.y*=-sceneScale;
positionOffset.x+=screenDistanceMoved.x;
positionOffset.y+=screenDistanceMoved.y;
}
lastScreenTouch=touchLocation;
lastWorldTouch=worldPosition;
test->MouseMove(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
}
}
- (void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
test->MouseUp(b2Vec2(lastWorldTouch.x,lastWorldTouch.y));
}
- (void) accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration
{
// Only run for valid values
if (acceleration.y!=0 && acceleration.x!=0)
{
if (test) test->SetGravity(acceleration.x,acceleration.y);
}
}
@end

View File

@@ -0,0 +1,14 @@
/*
* Delegates.h
* Box2D
*
* Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
*
*
*/
@protocol TestSelectDelegate <NSObject>
-(void) selectTest:(int) testIndex;
-(void) leaveTest;
@end

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef RENDER_H
#define RENDER_H
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#include <Box2D/Box2D.h>
struct b2AABB;
// This class implements debug drawing callbacks that are invoked
// inside b2World::Step.
class GLESDebugDraw : public b2Draw
{
public:
void DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
void DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color);
void DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color);
void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color);
void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color);
void DrawTransform(const b2Transform& xf);
void DrawPoint(const b2Vec2& p, float32 size, const b2Color& color);
void DrawString(int x, int y, const char* string, ...);
void DrawAABB(b2AABB* aabb, const b2Color& color);
};
#endif

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.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.
*/
#include "GLES-Render.h"
#include <cstdio>
#include <cstdarg>
#include <cstring>
void GLESDebugDraw::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
{
glColor4f(color.r, color.g, color.b,1);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
}
void GLESDebugDraw::DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
{
glVertexPointer(2, GL_FLOAT, 0, vertices);
glColor4f(color.r, color.g, color.b,0.5f);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);
glColor4f(color.r, color.g, color.b,1);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
}
void GLESDebugDraw::DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color)
{
const float32 k_segments = 16.0f;
int vertexCount=16;
const float32 k_increment = 2.0f * b2_pi / k_segments;
float32 theta = 0.0f;
GLfloat glVertices[vertexCount*2];
for (int32 i = 0; i < k_segments; ++i)
{
b2Vec2 v = center + radius * b2Vec2(cosf(theta), sinf(theta));
glVertices[i*2]=v.x;
glVertices[i*2+1]=v.y;
theta += k_increment;
}
glColor4f(color.r, color.g, color.b,1);
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);
}
void GLESDebugDraw::DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color)
{
const float32 k_segments = 16.0f;
int vertexCount=16;
const float32 k_increment = 2.0f * b2_pi / k_segments;
float32 theta = 0.0f;
GLfloat glVertices[vertexCount*2];
for (int32 i = 0; i < k_segments; ++i)
{
b2Vec2 v = center + radius * b2Vec2(cosf(theta), sinf(theta));
glVertices[i*2]=v.x;
glVertices[i*2+1]=v.y;
theta += k_increment;
}
glColor4f(color.r, color.g, color.b,0.5f);
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, vertexCount);
glColor4f(color.r, color.g, color.b,1);
glDrawArrays(GL_LINE_LOOP, 0, vertexCount);
// Draw the axis line
DrawSegment(center,center+radius*axis,color);
}
void GLESDebugDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color)
{
glColor4f(color.r, color.g, color.b,1);
GLfloat glVertices[] = {
p1.x,p1.y,p2.x,p2.y
};
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_LINES, 0, 2);
}
void GLESDebugDraw::DrawTransform(const b2Transform& xf)
{
b2Vec2 p1 = xf.position, p2;
const float32 k_axisScale = 0.4f;
p2 = p1 + k_axisScale * xf.R.col1;
DrawSegment(p1,p2,b2Color(1,0,0));
p2 = p1 + k_axisScale * xf.R.col2;
DrawSegment(p1,p2,b2Color(0,1,0));
}
void GLESDebugDraw::DrawPoint(const b2Vec2& p, float32 size, const b2Color& color)
{
glColor4f(color.r, color.g, color.b,1);
glPointSize(size);
GLfloat glVertices[] = {
p.x,p.y
};
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_POINTS, 0, 1);
glPointSize(1.0f);
}
void GLESDebugDraw::DrawString(int x, int y, const char *string, ...)
{
/* Unsupported as yet. Could replace with bitmap font renderer at a later date */
}
void GLESDebugDraw::DrawAABB(b2AABB* aabb, const b2Color& c)
{
glColor4f(c.r, c.g, c.b,1);
GLfloat glVertices[] = {
aabb->lowerBound.x, aabb->lowerBound.y,
aabb->upperBound.x, aabb->lowerBound.y,
aabb->upperBound.x, aabb->upperBound.y,
aabb->lowerBound.x, aabb->upperBound.y
};
glVertexPointer(2, GL_FLOAT, 0, glVertices);
glDrawArrays(GL_LINE_LOOP, 0, 8);
}

View File

@@ -0,0 +1,19 @@
//
// TestEntriesViewController.h
// Box2D
//
// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
//
#import <UIKit/UIKit.h>
#import "iPhoneTest.h"
#import "Delegates.h"
@interface TestEntriesViewController : UITableViewController {
int32 testCount;
id<TestSelectDelegate> _delegate;
}
@property(assign) id<TestSelectDelegate> delegate;
@end

View File

@@ -0,0 +1,75 @@
//
// TestEntriesViewController.m
// Box2D
//
// Box2D iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
//
#import "TestEntriesViewController.h"
@implementation TestEntriesViewController
@synthesize delegate=_delegate;
- (id)initWithStyle:(UITableViewStyle)style {
if (self = [super initWithStyle:style]) {
testCount = 0;
TestEntry* e = g_testEntries;
while (e->createFcn)
{
++testCount;
++e;
}
}
return self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return testCount;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
TestEntry* e = g_testEntries;
e+=indexPath.row;
cell.textLabel.text = [NSString stringWithUTF8String:e->name];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[_delegate selectTest:indexPath.row];
}
- (void)dealloc {
[super dealloc];
}
@end

View File

@@ -0,0 +1,189 @@
/*
* Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com
*
* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.com
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef TEST_H
#define TEST_H
#import <UIKit/UIKit.h>
#include <Box2D/Box2D.h>
#include "GLES-Render.h"
#include <cstdlib>
class Test;
struct Settings;
typedef Test* TestCreateFcn();
#define RAND_LIMIT 32767
/// Random number in range [-1,1]
inline float32 RandomFloat()
{
float32 r = (float32)(rand() & (RAND_LIMIT));
r /= RAND_LIMIT;
r = 2.0f * r - 1.0f;
return r;
}
/// Random floating point number in range [lo, hi]
inline float32 RandomFloat(float32 lo, float32 hi)
{
float32 r = (float32)(rand() & (RAND_LIMIT));
r /= RAND_LIMIT;
r = (hi - lo) * r + lo;
return r;
}
/// Test settings. Some can be controlled in the GUI.
struct Settings
{
Settings() :
viewCenter(0.0f, 20.0f),
hz(60.0f),
velocityIterations(8),
positionIterations(3),
drawShapes(1),
drawJoints(1),
drawAABBs(0),
drawPairs(0),
drawContactPoints(0),
drawContactNormals(0),
drawContactForces(0),
drawFrictionForces(0),
drawCOMs(0),
drawStats(0),
enableWarmStarting(1),
enableContinuous(1),
enableSubStepping(0),
pause(0),
singleStep(0)
{}
b2Vec2 viewCenter;
float32 hz;
int32 velocityIterations;
int32 positionIterations;
int32 drawShapes;
int32 drawJoints;
int32 drawAABBs;
int32 drawPairs;
int32 drawContactPoints;
int32 drawContactNormals;
int32 drawContactForces;
int32 drawFrictionForces;
int32 drawCOMs;
int32 drawStats;
int32 enableWarmStarting;
int32 enableContinuous;
int32 enableSubStepping;
int32 pause;
int32 singleStep;
};
struct TestEntry
{
const char *name;
TestCreateFcn *createFcn;
};
extern TestEntry g_testEntries[];
// This is called when a joint in the world is implicitly destroyed
// because an attached body is destroyed. This gives us a chance to
// nullify the mouse joint.
class DestructionListener : public b2DestructionListener
{
public:
void SayGoodbye(b2Fixture* fixture) { B2_NOT_USED(fixture); }
void SayGoodbye(b2Joint* joint);
Test* test;
};
const int32 k_maxContactPoints = 2048;
struct ContactPoint
{
b2Fixture* fixtureA;
b2Fixture* fixtureB;
b2Vec2 normal;
b2Vec2 position;
b2PointState state;
};
class Test : public b2ContactListener
{
public:
Test();
virtual ~Test();
void SetGravity(float x,float y);
void SetTextLine(int32 line) { m_textLine = line; }
void DrawTitle(int x, int y, const char *string);
virtual void Step(Settings* settings);
virtual void Keyboard(unsigned char key) { B2_NOT_USED(key); }
void ShiftMouseDown(const b2Vec2& p);
virtual void MouseDown(const b2Vec2& p);
virtual void MouseUp(const b2Vec2& p);
void MouseMove(const b2Vec2& p);
void LaunchBomb();
void LaunchBomb(const b2Vec2& position, const b2Vec2& velocity);
void SpawnBomb(const b2Vec2& worldPt);
void CompleteBombSpawn(const b2Vec2& p);
// Let derived tests know that a joint was destroyed.
virtual void JointDestroyed(b2Joint* joint) { B2_NOT_USED(joint); }
// Callbacks for derived classes.
virtual void BeginContact(b2Contact* contact) { B2_NOT_USED(contact); }
virtual void EndContact(b2Contact* contact) { B2_NOT_USED(contact); }
virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{
B2_NOT_USED(contact);
B2_NOT_USED(impulse);
}
protected:
friend class DestructionListener;
friend class BoundaryListener;
friend class ContactListener;
b2Body* m_groundBody;
b2AABB m_worldAABB;
ContactPoint m_points[k_maxContactPoints];
int32 m_pointCount;
DestructionListener m_destructionListener;
GLESDebugDraw m_debugDraw;
int32 m_textLine;
b2World* m_world;
b2Body* m_bomb;
b2MouseJoint* m_mouseJoint;
b2Vec2 m_bombSpawnPoint;
bool m_bombSpawning;
b2Vec2 m_mouseWorld;
int32 m_stepCount;
};
#endif

View File

@@ -0,0 +1,415 @@
/*
* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
*
* iPhone port by Simon Oliver - http://www.simonoliver.com - http://www.handcircus.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.
*/
#include "iPhoneTest.h"
#include "GLES-Render.h"
#include <cstdio>
void DestructionListener::SayGoodbye(b2Joint* joint)
{
if (test->m_mouseJoint == joint)
{
test->m_mouseJoint = NULL;
}
else
{
test->JointDestroyed(joint);
}
}
Test::Test()
: m_debugDraw()
{
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
bool doSleep = true;
m_world = new b2World(gravity, doSleep);
m_bomb = NULL;
m_textLine = 30;
m_mouseJoint = NULL;
m_pointCount = 0;
m_destructionListener.test = this;
m_world->SetDestructionListener(&m_destructionListener);
m_world->SetContactListener(this);
m_world->SetDebugDraw(&m_debugDraw);
m_bombSpawning = false;
m_stepCount = 0;
b2BodyDef bodyDef;
m_groundBody = m_world->CreateBody(&bodyDef);
}
Test::~Test()
{
// By deleting the world, we delete the bomb, mouse joint, etc.
delete m_world;
m_world = NULL;
}
void Test::SetGravity( float x, float y)
{
float tVectorLength=sqrt(x*x+y*y);
float newGravityX=9.81f*x/tVectorLength;
float newGravityY=9.81f*y/tVectorLength;
m_world->SetGravity(b2Vec2(newGravityX,newGravityY));
}
void Test::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{
const b2Manifold* manifold = contact->GetManifold();
if (manifold->pointCount == 0)
{
return;
}
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
b2PointState state1[b2_maxManifoldPoints], state2[b2_maxManifoldPoints];
b2GetPointStates(state1, state2, oldManifold, manifold);
b2WorldManifold worldManifold;
contact->GetWorldManifold(&worldManifold);
for (int32 i = 0; i < manifold->pointCount && m_pointCount < k_maxContactPoints; ++i)
{
ContactPoint* cp = m_points + m_pointCount;
cp->fixtureA = fixtureA;
cp->fixtureB = fixtureB;
cp->position = worldManifold.points[i];
cp->normal = worldManifold.normal;
cp->state = state2[i];
++m_pointCount;
}
}
void Test::DrawTitle(int x, int y, const char *string)
{
m_debugDraw.DrawString(x, y, string);
}
class QueryCallback : public b2QueryCallback
{
public:
QueryCallback(const b2Vec2& point)
{
m_point = point;
m_fixture = NULL;
}
bool ReportFixture(b2Fixture* fixture)
{
b2Body* body = fixture->GetBody();
if (body->GetType() == b2_dynamicBody)
{
bool inside = fixture->TestPoint(m_point);
if (inside)
{
m_fixture = fixture;
// We are done, terminate the query.
return false;
}
}
// Continue the query.
return true;
}
b2Vec2 m_point;
b2Fixture* m_fixture;
};
void Test::MouseDown(const b2Vec2& p)
{
m_mouseWorld = p;
if (m_mouseJoint != NULL)
{
return;
}
// Make a small box.
b2AABB aabb;
b2Vec2 d;
d.Set(0.001f, 0.001f);
aabb.lowerBound = p - d;
aabb.upperBound = p + d;
// Query the world for overlapping shapes.
QueryCallback callback(p);
m_world->QueryAABB(&callback, aabb);
if (callback.m_fixture)
{
b2Body* body = callback.m_fixture->GetBody();
b2MouseJointDef md;
md.bodyA = m_groundBody;
md.bodyB = body;
md.target = p;
#ifdef TARGET_FLOAT32_IS_FIXED
md.maxForce = (body->GetMass() < 16.0)?
(1000.0f * body->GetMass()) : float32(16000.0);
#else
md.maxForce = 1000.0f * body->GetMass();
#endif
m_mouseJoint = (b2MouseJoint*)m_world->CreateJoint(&md);
body->SetAwake(true);
}
}
void Test::SpawnBomb(const b2Vec2& worldPt)
{
m_bombSpawnPoint = worldPt;
m_bombSpawning = true;
}
void Test::CompleteBombSpawn(const b2Vec2& p)
{
if (m_bombSpawning == false)
{
return;
}
const float multiplier = 30.0f;
b2Vec2 vel = m_bombSpawnPoint - p;
vel *= multiplier;
LaunchBomb(m_bombSpawnPoint,vel);
m_bombSpawning = false;
}
void Test::ShiftMouseDown(const b2Vec2& p)
{
m_mouseWorld = p;
if (m_mouseJoint != NULL)
{
return;
}
SpawnBomb(p);
}
void Test::MouseUp(const b2Vec2& p)
{
if (m_mouseJoint)
{
m_world->DestroyJoint(m_mouseJoint);
m_mouseJoint = NULL;
}
if (m_bombSpawning)
{
CompleteBombSpawn(p);
}
}
void Test::MouseMove(const b2Vec2& p)
{
m_mouseWorld = p;
if (m_mouseJoint)
{
m_mouseJoint->SetTarget(p);
}
}
void Test::LaunchBomb()
{
b2Vec2 p(RandomFloat(-15.0f, 15.0f), 30.0f);
b2Vec2 v = -5.0f * p;
LaunchBomb(p, v);
}
void Test::LaunchBomb(const b2Vec2& position, const b2Vec2& velocity)
{
if (m_bomb)
{
m_world->DestroyBody(m_bomb);
m_bomb = NULL;
}
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position = position;
bd.bullet = true;
m_bomb = m_world->CreateBody(&bd);
m_bomb->SetLinearVelocity(velocity);
b2CircleShape circle;
circle.m_radius = 0.3f;
b2FixtureDef fd;
fd.shape = &circle;
fd.density = 20.0f;
fd.restitution = 0.0f;
b2Vec2 minV = position - b2Vec2(0.3f,0.3f);
b2Vec2 maxV = position + b2Vec2(0.3f,0.3f);
b2AABB aabb;
aabb.lowerBound = minV;
aabb.upperBound = maxV;
m_bomb->CreateFixture(&fd);
}
void Test::Step(Settings* settings)
{
float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz : float32(0.0f);
if (settings->pause)
{
if (settings->singleStep)
{
settings->singleStep = 0;
}
else
{
timeStep = 0.0f;
}
m_debugDraw.DrawString(5, m_textLine, "****PAUSED****");
m_textLine += 15;
}
uint32 flags = 0;
flags += settings->drawShapes * b2Draw::e_shapeBit;
flags += settings->drawJoints * b2Draw::e_jointBit;
flags += settings->drawAABBs * b2Draw::e_aabbBit;
flags += settings->drawPairs * b2Draw::e_pairBit;
flags += settings->drawCOMs * b2Draw::e_centerOfMassBit;
m_debugDraw.SetFlags(flags);
m_world->SetWarmStarting(settings->enableWarmStarting > 0);
m_world->SetContinuousPhysics(settings->enableContinuous > 0);
m_world->SetSubStepping(settings->enableSubStepping > 0);
m_pointCount = 0;
m_world->Step(timeStep, settings->velocityIterations, settings->positionIterations);
m_world->DrawDebugData();
if (timeStep > 0.0f)
{
++m_stepCount;
}
if (settings->drawStats)
{
m_debugDraw.DrawString(5, m_textLine, "bodies/contacts/joints/proxies = %d/%d/%d",
m_world->GetBodyCount(), m_world->GetContactCount(), m_world->GetJointCount(), m_world->GetProxyCount());
m_textLine += 15;
}
if (m_mouseJoint)
{
b2Vec2 p1 = m_mouseJoint->GetAnchorB();
b2Vec2 p2 = m_mouseJoint->GetTarget();
glPointSize(4.0f);
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
GLbyte verts1[2 * 3] = {
p1.x, p1.y, 0.0f,
p2.x, p2.y, 0.0f
};
glVertexPointer(3, GL_BYTE, 0, verts1);
glDrawArrays(GL_POINTS, 0, 2);
glPointSize(1.0f);
glColor4f(0.8f, 0.8f, 0.8f, 1.0f);
GLbyte verts2[2 * 3] = {
p1.x, p1.y, 0.0f,
p2.x, p2.y, 0.0f
};
glVertexPointer(3, GL_BYTE, 0, verts2);
glDrawArrays(GL_LINES, 0, 2);
}
if (m_bombSpawning)
{
glPointSize(4.0f);
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
GLbyte verts1[1 * 3] = {
m_bombSpawnPoint.x, m_bombSpawnPoint.y, 0.0f
};
glVertexPointer(3, GL_BYTE, 0, verts1);
glDrawArrays(GL_POINTS, 0, 1);
glColor4f(0.8f, 0.8f, 0.8f, 1.0f);
GLbyte verts2[2 * 3] = {
m_mouseWorld.x, m_mouseWorld.y, 0.0f,
m_bombSpawnPoint.x, m_bombSpawnPoint.y, 0.0f
};
glVertexPointer(3, GL_BYTE, 0, verts2);
glDrawArrays(GL_LINES, 0, 2);
}
if (settings->drawContactPoints)
{
//const float32 k_impulseScale = 0.1f;
const float32 k_axisScale = 0.3f;
for (int32 i = 0; i < m_pointCount; ++i)
{
ContactPoint* point = m_points + i;
if (point->state == b2_addState)
{
// Add
m_debugDraw.DrawPoint(point->position, 10.0f, b2Color(0.3f, 0.95f, 0.3f));
}
else if (point->state == b2_persistState)
{
// Persist
m_debugDraw.DrawPoint(point->position, 5.0f, b2Color(0.3f, 0.3f, 0.95f));
}
if (settings->drawContactNormals == 1)
{
b2Vec2 p1 = point->position;
b2Vec2 p2 = p1 + k_axisScale * point->normal;
m_debugDraw.DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.9f));
}
else if (settings->drawContactForces == 1)
{
//b2Vec2 p1 = point->position;
//b2Vec2 p2 = p1 + k_forceScale * point->normalForce * point->normal;
//DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
}
if (settings->drawFrictionForces == 1)
{
//b2Vec2 tangent = b2Cross(point->normal, 1.0f);
//b2Vec2 p1 = point->position;
//b2Vec2 p2 = p1 + k_forceScale * point->tangentForce * tangent;
//DrawSegment(p1, p2, b2Color(0.9f, 0.9f, 0.3f));
}
}
}
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
*
* 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.
*/
#include "iPhoneTest.h"
#include <cstring>
using namespace std;
#include "ApplyForce.h"
#include "BodyTypes.h"
#include "Breakable.h"
#include "Bridge.h"
#include "BulletTest.h"
#include "Cantilever.h"
#include "Car.h"
#include "ContinuousTest.h"
#include "Chain.h"
#include "CharacterCollision.h"
#include "CollisionFiltering.h"
#include "CollisionProcessing.h"
#include "CompoundShapes.h"
#include "Confined.h"
#include "DistanceTest.h"
#include "Dominos.h"
#include "DynamicTreeTest.h"
#include "EdgeShapes.h"
#include "EdgeTest.h"
#include "Gears.h"
#include "OneSidedPlatform.h"
#include "Pinball.h"
#include "PolyCollision.h"
#include "PolyShapes.h"
#include "Prismatic.h"
#include "Pulleys.h"
#include "Pyramid.h"
#include "RayCast.h"
#include "Revolute.h"
#include "Rope.h"
#include "RopeJoint.h"
#include "SensorTest.h"
#include "ShapeEditing.h"
#include "SliderCrank.h"
#include "SphereStack.h"
#include "TheoJansen.h"
#include "Tiles.h"
#include "TimeOfImpact.h"
#include "VaryingFriction.h"
#include "VaryingRestitution.h"
#include "VerticalStack.h"
#include "Web.h"
TestEntry g_testEntries[] =
{
{"Pulleys", Pulleys::Create},
{"SphereStack", SphereStack::Create},
{"Tiles", Tiles::Create},
{"Polygon Shapes", PolyShapes::Create},
{"Rope", Rope::Create},
{"Web", Web::Create},
{"Car", Car::Create},
{"Vertical Stack", VerticalStack::Create},
{"RopeJoint", RopeJoint::Create},
{"Character Collision", CharacterCollision::Create},
{"Edge Test", EdgeTest::Create},
{"One-Sided Platform", OneSidedPlatform::Create},
{"Pinball", Pinball::Create},
{"Bullet Test", BulletTest::Create},
{"Continuous Test", ContinuousTest::Create},
{"Time of Impact", TimeOfImpact::Create},
{"Ray-Cast", RayCast::Create},
{"Confined", Confined::Create},
{"Pyramid", Pyramid::Create},
{"Varying Restitution", VaryingRestitution::Create},
{"Theo Jansen's Walker", TheoJansen::Create},
{"Body Types", BodyTypes::Create},
{"Prismatic", Prismatic::Create},
{"Edge Shapes", EdgeShapes::Create},
{"PolyCollision", PolyCollision::Create},
{"Apply Force", ApplyForce::Create},
{"Cantilever", Cantilever::Create},
{"Bridge", Bridge::Create},
{"Breakable", Breakable::Create},
{"Chain", Chain::Create},
{"Collision Filtering", CollisionFiltering::Create},
{"Collision Processing", CollisionProcessing::Create},
{"Compound Shapes", CompoundShapes::Create},
{"Distance Test", DistanceTest::Create},
{"Dominos", Dominos::Create},
{"Dynamic Tree", DynamicTreeTest::Create},
{"Gears", Gears::Create},
{"Revolute", Revolute::Create},
{"Sensor Test", SensorTest::Create},
{"Shape Editing", ShapeEditing::Create},
{"Slider Crank", SliderCrank::Create},
{"Varying Friction", VaryingFriction::Create},
{NULL, NULL}
};

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleDisplayName</key>
<string>${MACOSX_BUNDLE_PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSMainNibFile</key>
<string>MainWindow</string>
</dict>
</plist>

View File

@@ -0,0 +1,232 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="7.03">
<data>
<int key="IBDocument.SystemTarget">528</int>
<string key="IBDocument.SystemVersion">9G55</string>
<string key="IBDocument.InterfaceBuilderVersion">677</string>
<string key="IBDocument.AppKitVersion">949.43</string>
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="8"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<object class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
</object>
<object class="IBProxyObject" id="191355593">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
</object>
<object class="IBUICustomObject" id="664661524"/>
<object class="IBUIWindow" id="380026005">
<reference key="NSNextResponder"/>
<int key="NSvFlags">1316</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIView" id="773737154">
<reference key="NSNextResponder" ref="380026005"/>
<int key="NSvFlags">1298</int>
<string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview" ref="380026005"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
</object>
</object>
<object class="NSPSMatrix" key="NSFrameMatrix"/>
<string key="NSFrameSize">{320, 480}</string>
<reference key="NSSuperview"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAxIDEAA</bytes>
</object>
<bool key="IBUIClearsContextBeforeDrawing">NO</bool>
<bool key="IBUIVisibleAtLaunch">YES</bool>
</object>
</object>
<object class="IBObjectContainer" key="IBDocument.Objects">
<object class="NSMutableArray" key="connectionRecords">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="664661524"/>
</object>
<int key="connectionID">4</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">window</string>
<reference key="source" ref="664661524"/>
<reference key="destination" ref="380026005"/>
</object>
<int key="connectionID">5</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">glView</string>
<reference key="source" ref="664661524"/>
<reference key="destination" ref="773737154"/>
</object>
<int key="connectionID">9</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBObjectRecord">
<int key="objectID">0</int>
<object class="NSArray" key="object" id="957960031">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="380026005"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="773737154"/>
</object>
<reference key="parent" ref="957960031"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="957960031"/>
<string type="base64-UTF8" key="objectName">RmlsZSdzIE93bmVyA</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">3</int>
<reference key="object" ref="664661524"/>
<reference key="parent" ref="957960031"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">8</int>
<reference key="object" ref="773737154"/>
<reference key="parent" ref="380026005"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="191355593"/>
<reference key="parent" ref="957960031"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>-1.CustomClassName</string>
<string>-2.CustomClassName</string>
<string>2.IBAttributePlaceholdersKey</string>
<string>2.IBEditorWindowLastContentRect</string>
<string>2.IBPluginDependency</string>
<string>3.CustomClassName</string>
<string>3.IBPluginDependency</string>
<string>8.CustomClassName</string>
<string>8.IBPluginDependency</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIApplication</string>
<string>UIResponder</string>
<object class="NSMutableDictionary">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<string>{{500, 343}, {320, 480}}</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>Box2DAppDelegate</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>Box2DView</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="activeLocalization"/>
<object class="NSMutableDictionary" key="localizations">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">9</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">Box2DAppDelegate</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>glView</string>
<string>window</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>Box2DView</string>
<string>UIWindow</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">Classes/Box2DAppDelegate.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">Box2DView</string>
<string key="superclassName">UIView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">Classes/Box2DView.h</string>
</object>
</object>
</object>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.LastKnownRelativeProjectPath">Box2D.xcodeproj</string>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
</data>
</archive>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,17 @@
//
// main.m
// Box2D
//
// Created by Simon Oliver on 14/01/2009.
// Copyright HandCircus 2009. All rights reserved.
//
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}