├── src ├── Dynamics │ ├── Joints │ │ └── LineJoint.cs │ └── Contacts │ │ ├── NullContact.cs │ │ ├── CircleContact.cs │ │ ├── PolyContact.cs │ │ └── PolyAndCircleContact.cs ├── Box2DX.nuspec ├── Properties │ └── AssemblyInfo.cs ├── Box2DXDebug.cs ├── Common │ ├── XForm.cs │ ├── Sweep.cs │ ├── Mat33.cs │ ├── Vec3.cs │ ├── Mat22.cs │ ├── Vec2.cs │ └── Settings.cs ├── Collision │ ├── Collision.TimeOfImpact.cs │ ├── Shapes │ │ └── CircleShape.cs │ └── Collision.CollideCircle.cs └── Box2DX.csproj ├── Libraries ├── Tao.OpenGl.dll └── Tao.Platform.Windows.dll ├── Examples ├── HelloWorld │ ├── app.config │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── HelloWorld.csproj │ └── Program.cs └── TestBed │ ├── app.config │ ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx │ ├── Program.cs │ ├── Tests │ ├── VaryingRestitution.cs │ ├── Pyramid.cs │ ├── Chain.cs │ ├── Bridge.cs │ ├── SimpleTest.cs │ ├── BipedTest.cs │ ├── ShapeEditing.cs │ ├── Pulleys.cs │ ├── CCDTest.cs │ ├── VerticalStack.cs │ ├── PolyCollision.cs │ ├── SensorTest.cs │ ├── TimeOfImpact.cs │ ├── VaryingFriction.cs │ ├── RaycastTest.cs │ ├── DistanceTest.cs │ ├── ApplyForce.cs │ ├── SliderCrank.cs │ ├── Gears.cs │ ├── MotorsAndLimits.cs │ ├── CompoundShapes.cs │ ├── CollisionFiltering.cs │ ├── PolyShapes.cs │ ├── Dominos.cs │ ├── CollisionProcessing.cs │ └── Car.cs │ └── MainForm.resx ├── Build └── VCS │ └── Box2DX.sln └── README.md /src/Dynamics/Joints/LineJoint.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Libraries/Tao.OpenGl.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colgreen/box2dx/HEAD/Libraries/Tao.OpenGl.dll -------------------------------------------------------------------------------- /Libraries/Tao.Platform.Windows.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/colgreen/box2dx/HEAD/Libraries/Tao.Platform.Windows.dll -------------------------------------------------------------------------------- /Examples/HelloWorld/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Examples/TestBed/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Examples/TestBed/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Box2DX.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Box2DX 5 | $version$ 6 | Box2DX physics engine. 7 | Ihar Kalasouski 8 | $author$ 9 | http://opensource.org/licenses/MIT 10 | https://github.com/colgreen/box2dx 11 | false 12 | $description$ 13 | First release of this clone of the Box2DX project. See project URL for details on why this release is being made. 14 | box2d 2Dphysics physicsengine physics c# .net 15 | 16 | -------------------------------------------------------------------------------- /Examples/TestBed/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TestBed.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Examples/TestBed/Program.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would be 15 | appreciated but is not required. 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 3. This notice may not be removed or altered from any source distribution. 19 | */ 20 | 21 | using System; 22 | using System.Windows.Forms; 23 | 24 | namespace TestBed 25 | { 26 | static class Program 27 | { 28 | /// 29 | /// The main entry point for the application. 30 | /// 31 | [STAThread] 32 | static void Main() 33 | { 34 | Application.EnableVisualStyles(); 35 | Application.SetCompatibleTextRenderingDefault(false); 36 | Application.Run(new MainForm()); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Dynamics/Contacts/NullContact.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Collision; 27 | using Box2DX.Common; 28 | 29 | namespace Box2DX.Dynamics 30 | { 31 | public class NullContact : Contact 32 | { 33 | public NullContact() { } 34 | public override void Evaluate(ContactListener listener) { } 35 | public override Manifold[] GetManifolds() { return null; } 36 | } 37 | } -------------------------------------------------------------------------------- /Examples/TestBed/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TestBed")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TestBed")] 13 | [assembly: AssemblyCopyright("Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3c722f9e-d904-4baf-a2c2-84179b2e4ec2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.0.1.*")] 36 | [assembly: AssemblyFileVersion("2.0.1.0")] 37 | -------------------------------------------------------------------------------- /Examples/HelloWorld/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("HelloWorld for Box2DX")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("HelloWorld")] 13 | [assembly: AssemblyCopyright("Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("d221c72a-53ff-4443-8c3b-03438808bd4f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Box2DX")] 9 | [assembly: AssemblyDescription("Box2DX physics engine. C# port of Box2D (original C++ project).")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Colin D. Green")] 12 | [assembly: AssemblyProduct("Box2DX")] 13 | [assembly: AssemblyCopyright("Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0164b8c9-6d35-419c-a4c1-05217f6f2f7a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.0.2.0")] 36 | [assembly: AssemblyFileVersion("2.0.2.0")] 37 | -------------------------------------------------------------------------------- /src/Box2DXDebug.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Text; 24 | using System.Diagnostics; 25 | using System.Collections.Generic; 26 | 27 | namespace Box2DX 28 | { 29 | public static class Box2DXDebug 30 | { 31 | [Conditional("DEBUG")] 32 | public static void Assert(bool condition) 33 | { 34 | Debug.Assert(condition); 35 | } 36 | 37 | [Conditional("DEBUG")] 38 | public static void Assert(bool condition, string message) 39 | { 40 | Debug.Assert(condition, message); 41 | } 42 | 43 | [Conditional("DEBUG")] 44 | public static void Assert(bool condition, string message, string detailMessage) 45 | { 46 | Debug.Assert(condition, message, detailMessage); 47 | } 48 | 49 | public static void ThrowBox2DXException(String message) 50 | { 51 | string msg = String.Format("Error: {0}", message); 52 | throw new Exception(msg); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Common/XForm.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | namespace Box2DX.Common 27 | { 28 | /// 29 | /// A transform contains translation and rotation. 30 | /// It is used to represent the position and orientation of rigid frames. 31 | /// 32 | public struct XForm 33 | { 34 | public Vec2 Position; 35 | public Mat22 R; 36 | 37 | /// 38 | /// Initialize using a position vector and a rotation matrix. 39 | /// 40 | /// 41 | /// 42 | public XForm(Vec2 position, Mat22 rotation) 43 | { 44 | Position = position; 45 | R = rotation; 46 | } 47 | 48 | /// 49 | /// Set this to the identity transform. 50 | /// 51 | public void SetIdentity() 52 | { 53 | Position.SetZero(); 54 | R.SetIdentity(); 55 | } 56 | 57 | public static XForm Identity { get { return new XForm(Vec2.Zero, Mat22.Identity); } } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Build/VCS/Box2DX.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.168 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Box2DX", "..\..\src\Box2DX.csproj", "{C157BCA5-BAC7-455F-A7DE-59D506D46ECF}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloWorld", "..\..\Examples\HelloWorld\HelloWorld.csproj", "{594CF883-9C7C-4320-A81E-ABED15E32217}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBed", "..\..\Examples\TestBed\TestBed.csproj", "{5F8CEECC-CF73-4057-9DC8-8001BECE71E2}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {C157BCA5-BAC7-455F-A7DE-59D506D46ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {C157BCA5-BAC7-455F-A7DE-59D506D46ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {C157BCA5-BAC7-455F-A7DE-59D506D46ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {C157BCA5-BAC7-455F-A7DE-59D506D46ECF}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {594CF883-9C7C-4320-A81E-ABED15E32217}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {594CF883-9C7C-4320-A81E-ABED15E32217}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {594CF883-9C7C-4320-A81E-ABED15E32217}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {594CF883-9C7C-4320-A81E-ABED15E32217}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {5F8CEECC-CF73-4057-9DC8-8001BECE71E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {5F8CEECC-CF73-4057-9DC8-8001BECE71E2}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {5F8CEECC-CF73-4057-9DC8-8001BECE71E2}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {5F8CEECC-CF73-4057-9DC8-8001BECE71E2}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | GlobalSection(ExtensibilityGlobals) = postSolution 35 | SolutionGuid = {2C999ABB-4E84-4EA3-A726-9BB0F398C3A5} 36 | EndGlobalSection 37 | EndGlobal 38 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/VaryingRestitution.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class VaryingRestitution : Test 33 | { 34 | public VaryingRestitution() 35 | { 36 | { 37 | PolygonDef sd = new PolygonDef(); 38 | sd.SetAsBox(50.0f, 10.0f); 39 | 40 | BodyDef bd = new BodyDef(); 41 | bd.Position.Set(0.0f, -10.0f); 42 | 43 | Body ground = _world.CreateBody(bd); 44 | ground.CreateShape(sd); 45 | } 46 | 47 | { 48 | CircleDef sd = new CircleDef(); 49 | sd.Radius = 1.0f; 50 | sd.Density = 1.0f; 51 | 52 | float[] restitution = new float[7] { 0.0f, 0.1f, 0.3f, 0.5f, 0.75f, 0.9f, 1.0f }; 53 | 54 | for (int i = 0; i < 7; ++i) 55 | { 56 | BodyDef bd = new BodyDef(); 57 | bd.Position.Set(-10.0f + 3.0f * i, 20.0f); 58 | 59 | Body body = _world.CreateBody(bd); 60 | 61 | sd.Restitution = restitution[i]; 62 | body.CreateShape(sd); 63 | body.SetMassFromShapes(); 64 | } 65 | } 66 | } 67 | 68 | public static Test Create() 69 | { 70 | return new VaryingRestitution(); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/Pyramid.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class Pyramid : Test 33 | { 34 | public Pyramid() 35 | { 36 | { 37 | PolygonDef sd = new PolygonDef(); 38 | sd.SetAsBox(50.0f, 10.0f); 39 | 40 | BodyDef bd = new BodyDef(); 41 | bd.Position.Set(0.0f, -10.0f); 42 | Body ground = _world.CreateBody(bd); 43 | ground.CreateShape(sd); 44 | } 45 | 46 | { 47 | PolygonDef sd = new PolygonDef(); 48 | float a = 0.5f; 49 | sd.SetAsBox(a, a); 50 | sd.Density = 5.0f; 51 | 52 | Vec2 x = new Vec2(-10.0f, 0.75f); 53 | Vec2 y; 54 | Vec2 deltaX = new Vec2(0.5625f, 2.0f); 55 | Vec2 deltaY = new Vec2(1.125f, 0.0f); 56 | 57 | for (int i = 0; i < 25; ++i) 58 | { 59 | y = x; 60 | 61 | for (int j = i; j < 25; ++j) 62 | { 63 | BodyDef bd = new BodyDef(); 64 | bd.Position = y; 65 | Body body = _world.CreateBody(bd); 66 | body.CreateShape(sd); 67 | body.SetMassFromShapes(); 68 | 69 | y += deltaY; 70 | } 71 | 72 | x += deltaX; 73 | } 74 | } 75 | } 76 | 77 | public static Test Create() 78 | { 79 | return new Pyramid(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/Chain.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class Chain : Test 33 | { 34 | public Chain() 35 | { 36 | Body ground = null; 37 | { 38 | BodyDef bd = new BodyDef(); 39 | bd.Position.Set(0.0f, -10.0f); 40 | ground = _world.CreateBody(bd); 41 | 42 | PolygonDef sd = new PolygonDef(); 43 | sd.SetAsBox(50.0f, 10.0f); 44 | ground.CreateShape(sd); 45 | } 46 | 47 | { 48 | PolygonDef sd = new PolygonDef(); 49 | sd.SetAsBox(0.6f, 0.125f); 50 | sd.Density = 20.0f; 51 | sd.Friction = 0.2f; 52 | 53 | RevoluteJointDef jd = new RevoluteJointDef(); 54 | jd.CollideConnected = false; 55 | 56 | const float y = 25.0f; 57 | Body prevBody = ground; 58 | for (int i = 0; i < 30; ++i) 59 | { 60 | BodyDef bd = new BodyDef(); 61 | bd.Position.Set(0.5f + i, y); 62 | Body body = _world.CreateBody(bd); 63 | body.CreateShape(sd); 64 | body.SetMassFromShapes(); 65 | 66 | Vec2 anchor = new Vec2(i, y); 67 | jd.Initialize(prevBody, body, anchor); 68 | _world.CreateJoint(jd); 69 | 70 | prevBody = body; 71 | } 72 | } 73 | } 74 | public static Test Create() 75 | { 76 | return new Chain(); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/Bridge.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class Bridge : Test 33 | { 34 | public Bridge() 35 | { 36 | Body ground = null; 37 | { 38 | PolygonDef sd = new PolygonDef(); 39 | sd.SetAsBox(50.0f, 10.0f); 40 | 41 | BodyDef bd = new BodyDef(); 42 | bd.Position.Set(0.0f, -10.0f); 43 | ground = _world.CreateBody(bd); 44 | ground.CreateShape(sd); 45 | } 46 | 47 | { 48 | PolygonDef sd = new PolygonDef(); 49 | sd.SetAsBox(0.5f, 0.125f); 50 | sd.Density = 20.0f; 51 | sd.Friction = 0.2f; 52 | 53 | RevoluteJointDef jd = new RevoluteJointDef(); 54 | const int numPlanks = 30; 55 | 56 | Body prevBody = ground; 57 | for (int i = 0; i < numPlanks; ++i) 58 | { 59 | BodyDef bd = new BodyDef(); 60 | bd.Position.Set(-14.5f + 1.0f * i, 5.0f); 61 | Body body = _world.CreateBody(bd); 62 | body.CreateShape(sd); 63 | body.SetMassFromShapes(); 64 | 65 | Vec2 anchor = new Vec2(-15.0f + 1.0f * i, 5.0f); 66 | jd.Initialize(prevBody, body, anchor); 67 | _world.CreateJoint(jd); 68 | 69 | prevBody = body; 70 | } 71 | 72 | Vec2 anchor_ = new Vec2(-15.0f + 1.0f * numPlanks, 5.0f); 73 | jd.Initialize(prevBody, ground, anchor_); 74 | _world.CreateJoint(jd); 75 | } 76 | } 77 | 78 | public static Test Create() 79 | { 80 | return new Bridge(); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Common/Sweep.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | //r175 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Text; 27 | 28 | namespace Box2DX.Common 29 | { 30 | public struct Sweep 31 | { 32 | public Vec2 LocalCenter; //local center of mass position 33 | public Vec2 C0, C; //local center of mass position 34 | public float A0, A; //world angles 35 | public float T0; //time interval = [T0,1], where T0 is in [0,1] 36 | 37 | /// 38 | /// Get the interpolated transform at a specific time. 39 | /// 40 | /// The normalized time in [0,1]. 41 | public void GetXForm(out XForm xf, float t) 42 | { 43 | xf = new XForm(); 44 | 45 | // center = p + R * LocalCenter 46 | if (1.0f - T0 > Math.FLOAT32_EPSILON) 47 | { 48 | float alpha = (t - T0) / (1.0f - T0); 49 | xf.Position = (1.0f - alpha) * C0 + alpha * C; 50 | float angle = (1.0f - alpha) * A0 + alpha * A; 51 | xf.R.Set(angle); 52 | } 53 | else 54 | { 55 | xf.Position = C; 56 | xf.R.Set(A); 57 | } 58 | 59 | // Shift to origin 60 | xf.Position -= Math.Mul(xf.R, LocalCenter); 61 | } 62 | 63 | /// 64 | /// Advance the sweep forward, yielding a new initial state. 65 | /// 66 | /// The new initial time. 67 | public void Advance(float t) 68 | { 69 | if (T0 < t && 1.0f - T0 > Math.FLOAT32_EPSILON) 70 | { 71 | float alpha = (t - T0) / (1.0f - T0); 72 | C0 = (1.0f - alpha) * C0 + alpha * C; 73 | A0 = (1.0f - alpha) * A0 + alpha * A; 74 | T0 = t; 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # colgreen/box2dx 2 | 3 | Box2DX is a C# port of the C++ Box2D project. 4 | 5 | Box2DX was created by Ihar Kalasouski and originally hosted at http://code.google.com/p/box2dx 6 | 7 | Ihar stopped contributing to the project in October 2008 shortly after releasing version 2.0.1.3-r175. Later google code shutdown although the URL is still available at time of writing (2016-02-7) for exporting the source code. 8 | 9 | Ihar appears to have made a few commits after r175 marked with the comment "!!!Do not update to this revision, it has problems!!!". The export of the repository to this github repository contains those latest commits, therefore I have created a branch point from the last commit representing r175 (r175-stable), although it may not be exactly the right commit I think it's close enough to not have any significant differences from the r175 release. 10 | 11 | r175-stable will remain untouched. My next step was to create branch 'resurrect' from r175-stable and check out that new branch. I have then loaded the solution into Visual Studio 2015 Update 1, updated the target framework in each C# project file to .Net 4.0 and compiled. So far so good and the test project is working as expected. 12 | 13 | ### Dependeny on Tao framework. 14 | 15 | It should be noted that the Box2DX assembly contains a 2D physics engine only, e.g the ability to define the bounds of a world, define gravity, surfaces, objects with mass etc. There is no code in that assembly for drawing the world to screen. To render the 2D world to a window there are hook points defined, and currently the test project connects these hook points to OpenGL using the Tao framework. 16 | 17 | The Tao framework appears to be yet another abandonned project: 18 | 19 | - Originally hosted at https://sourceforge.net/projects/taoframework/ 20 | - The sourceforge page states: Superseded by OpenTK: https://sourceforge.net/projects/opentk/ 21 | - The OpenTK main web site is live at http://www.opentk.com, but the project appears to have been maintained in recent by a different developer at https://github.com/opentk/opentk; In early 2016 the maintainer of that repository posted a README saying they are stepping down on the basis that the project owner is not available. 22 | 23 | That said, the OpenTK project on github appears to be far more up-to-date than the Tao framework it replaced, therefore it is probably not a bad idea to switch Box2DX to use the latest OpenTK version available from github. I had a quick attempt at referencing OpenTK (available as a nuget package); however that appears to not be a simple drop-in replacement to Tao, so I've backed away from that for now and I'm writing this README to remind me (and to inform others) of the where I had got to in updating Box2DX. 24 | 25 | Therefore there is still a dependency of the pre-built Tao framework binaries (included in this github repository). These are: 26 | 27 | - Tao.FreeGlut.dll (2.4.0.1) 28 | - Tao.FreeType.dll (2.3.5.0) 29 | - Tao.OpenGl.dll (2.1.0.4) 30 | - Tao.Platform.Windows.dll (1.0.0.4) 31 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/SimpleTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class SimpleTest : Test 33 | { 34 | public SimpleTest() 35 | { 36 | // Define the ground body. 37 | BodyDef groundBodyDef = new BodyDef(); 38 | groundBodyDef.Position.Set(0.0f, -10.0f); 39 | 40 | // Call the body factory which creates the ground box shape. 41 | // The body is also added to the world. 42 | Body groundBody = _world.CreateBody(groundBodyDef); 43 | 44 | // Define the ground box shape. 45 | PolygonDef groundShapeDef = new PolygonDef(); 46 | 47 | // The extents are the half-widths of the box. 48 | groundShapeDef.SetAsBox(50.0f, 10.0f); 49 | 50 | // Add the ground shape to the ground body. 51 | groundBody.CreateShape(groundShapeDef); 52 | 53 | for (int i = 0; i < 1; i++) 54 | { 55 | // Define the dynamic body. We set its position and call the body factory. 56 | BodyDef bodyDef = new BodyDef(); 57 | bodyDef.Position.Set(0.0f, 4.0f *(i+1)); 58 | Body body = _world.CreateBody(bodyDef); 59 | 60 | // Define another box shape for our dynamic body. 61 | PolygonDef shapeDef = new PolygonDef(); 62 | shapeDef.SetAsBox(1.0f, 1.0f); 63 | 64 | // Set the box density to be non-zero, so it will be dynamic. 65 | shapeDef.Density = 1.0f; 66 | 67 | // Override the default friction. 68 | shapeDef.Friction = 0.3f; 69 | 70 | // Add the shape to the body. 71 | body.CreateShape(shapeDef); 72 | 73 | // Now tell the dynamic body to compute it's mass properties base 74 | // on its shape. 75 | body.SetMassFromShapes(); 76 | } 77 | } 78 | 79 | public static Test Create() 80 | { 81 | return new SimpleTest(); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/BipedTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class BipedTest : Test, IDisposable 33 | { 34 | BipedTest() 35 | { 36 | const float k_restitution = 1.4f; 37 | 38 | { 39 | BodyDef bd = new BodyDef(); 40 | bd.Position.Set(0.0f, 20.0f); 41 | Body body = _world.CreateBody(bd); 42 | 43 | PolygonDef sd = new PolygonDef(); 44 | sd.Density = 0.0f; 45 | sd.Restitution = k_restitution; 46 | 47 | sd.SetAsBox(0.1f, 10.0f, new Vec2(-10.0f, 0.0f), 0.0f); 48 | body.CreateShape(sd); 49 | 50 | sd.SetAsBox(0.1f, 10.0f, new Vec2(10.0f, 0.0f), 0.0f); 51 | body.CreateShape(sd); 52 | 53 | sd.SetAsBox(0.1f, 10.0f, new Vec2(0.0f, -10.0f), 0.5f * Box2DX.Common.Settings.Pi); 54 | body.CreateShape(sd); 55 | 56 | sd.SetAsBox(0.1f, 10.0f, new Vec2(0.0f, 10.0f), -0.5f * Box2DX.Common.Settings.Pi); 57 | body.CreateShape(sd); 58 | } 59 | 60 | _biped = new Biped(_world, new Vec2(0.0f, 20.0f)); 61 | 62 | for (int i = 0; i < 8; ++i) 63 | { 64 | BodyDef bd = new BodyDef(); 65 | bd.Position.Set(5.0f, 20.0f + i); 66 | bd.IsBullet = true; 67 | Body body = _world.CreateBody(bd); 68 | body.SetLinearVelocity(new Vec2(0.0f, -100.0f)); 69 | body.SetAngularVelocity(Box2DX.Common.Math.Random(-50.0f, 50.0f)); 70 | 71 | CircleDef sd = new CircleDef(); 72 | sd.Radius = 0.25f; 73 | sd.Density = 15.0f; 74 | sd.Restitution = k_restitution; 75 | body.CreateShape(sd); 76 | body.SetMassFromShapes(); 77 | } 78 | } 79 | 80 | protected override void Dispose(bool state) { _biped.Dispose(); _biped = null; } 81 | 82 | public static Test Create() 83 | { 84 | return new BipedTest(); 85 | } 86 | 87 | Biped _biped; 88 | } 89 | } -------------------------------------------------------------------------------- /src/Common/Mat33.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | //r175 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Text; 27 | 28 | namespace Box2DX.Common 29 | { 30 | /// 31 | /// A 3-by-3 matrix. Stored in column-major order. 32 | /// 33 | public struct Mat33 34 | { 35 | /// 36 | /// Construct this matrix using columns. 37 | /// 38 | public Mat33(Vec3 c1, Vec3 c2, Vec3 c3) 39 | { 40 | Col1 = c1; 41 | Col2 = c2; 42 | Col3 = c3; 43 | } 44 | 45 | /// 46 | /// Set this matrix to all zeros. 47 | /// 48 | public void SetZero() 49 | { 50 | Col1.SetZero(); 51 | Col2.SetZero(); 52 | Col3.SetZero(); 53 | } 54 | 55 | /// 56 | /// Solve A * x = b, where b is a column vector. This is more efficient 57 | /// than computing the inverse in one-shot cases. 58 | /// 59 | public Vec3 Solve33(Vec3 b) 60 | { 61 | float det = Vec3.Dot(Col1, Vec3.Cross(Col2, Col3)); 62 | Box2DXDebug.Assert(det != 0.0f); 63 | det = 1.0f / det; 64 | Vec3 x = new Vec3(); 65 | x.X = det * Vec3.Dot(b, Vec3.Cross(Col2, Col3)); 66 | x.Y = det * Vec3.Dot(Col1, Vec3.Cross(b, Col3)); 67 | x.Z = det * Vec3.Dot(Col1, Vec3.Cross(Col2, b)); 68 | return x; 69 | } 70 | 71 | /// 72 | /// Solve A * x = b, where b is a column vector. This is more efficient 73 | /// than computing the inverse in one-shot cases. Solve only the upper 74 | /// 2-by-2 matrix equation. 75 | /// 76 | public Vec2 Solve22(Vec2 b) 77 | { 78 | float a11 = Col1.X, a12 = Col2.X, a21 = Col1.Y, a22 = Col2.Y; 79 | float det = a11 * a22 - a12 * a21; 80 | Box2DXDebug.Assert(det != 0.0f); 81 | det = 1.0f / det; 82 | Vec2 x = new Vec2(); 83 | x.X = det * (a22 * b.X - a12 * b.Y); 84 | x.Y = det * (a11 * b.Y - a21 * b.X); 85 | return x; 86 | } 87 | 88 | public Vec3 Col1, Col2, Col3; 89 | } 90 | } -------------------------------------------------------------------------------- /Examples/TestBed/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TestBed.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TestBed.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/ShapeEditing.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class ShapeEditing : Test 33 | { 34 | Body _body; 35 | Shape _shape1; 36 | Shape _shape2; 37 | 38 | public ShapeEditing() 39 | { 40 | { 41 | PolygonDef sd = new PolygonDef(); 42 | sd.SetAsBox(50.0f, 10.0f); 43 | 44 | BodyDef bd = new BodyDef(); 45 | bd.Position.Set(0.0f, -10.0f); 46 | 47 | Body ground = _world.CreateBody(bd); 48 | ground.CreateShape(sd); 49 | } 50 | 51 | BodyDef bodydef = new BodyDef(); 52 | bodydef.Position.Set(0.0f, 10.0f); 53 | _body = _world.CreateBody(bodydef); 54 | 55 | PolygonDef sd_ = new PolygonDef(); 56 | sd_.SetAsBox(4.0f, 4.0f, new Vec2(0.0f, 0.0f), 0.0f); 57 | sd_.Density = 10.0f; 58 | _shape1 = _body.CreateShape(sd_); 59 | _body.SetMassFromShapes(); 60 | 61 | _shape2 = null; 62 | } 63 | 64 | public override void Keyboard(System.Windows.Forms.Keys key) 65 | { 66 | switch (key) 67 | { 68 | case System.Windows.Forms.Keys.C: 69 | if (_shape2 == null) 70 | { 71 | CircleDef sd = new CircleDef(); 72 | sd.Radius = 3.0f; 73 | sd.Density = 10.0f; 74 | sd.LocalPosition.Set(0.5f, -4.0f); 75 | _shape2 = _body.CreateShape(sd); 76 | _body.SetMassFromShapes(); 77 | _body.WakeUp(); 78 | } 79 | break; 80 | 81 | case System.Windows.Forms.Keys.D: 82 | if (_shape2 != null) 83 | { 84 | _body.DestroyShape(_shape2); 85 | _shape2 = null; 86 | _body.SetMassFromShapes(); 87 | _body.WakeUp(); 88 | } 89 | break; 90 | } 91 | } 92 | 93 | public override void Step(Settings settings) 94 | { 95 | base.Step(settings); 96 | 97 | OpenGLDebugDraw.DrawString(5, _textLine, "Press: (c) create a shape, (d) destroy a shape."); 98 | _textLine += 15; 99 | } 100 | 101 | public static Test Create() 102 | { 103 | return new ShapeEditing(); 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/Pulleys.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class Pulleys : Test 33 | { 34 | PulleyJoint _joint1; 35 | 36 | public Pulleys() 37 | { 38 | Body ground = null; 39 | { 40 | PolygonDef sd = new PolygonDef(); 41 | sd.SetAsBox(50.0f, 10.0f); 42 | 43 | BodyDef bd = new BodyDef(); 44 | bd.Position.Set(0.0f, -10.0f); 45 | ground = _world.CreateBody(bd); 46 | ground.CreateShape(sd); 47 | } 48 | 49 | { 50 | float a = 2.0f; 51 | float b = 4.0f; 52 | float y = 16.0f; 53 | float L = 12.0f; 54 | 55 | PolygonDef sd = new PolygonDef(); 56 | sd.SetAsBox(a, b); 57 | sd.Density = 5.0f; 58 | 59 | BodyDef bd = new BodyDef(); 60 | 61 | bd.Position.Set(-10.0f, y); 62 | Body body1 = _world.CreateBody(bd); 63 | body1.CreateShape(sd); 64 | body1.SetMassFromShapes(); 65 | 66 | bd.Position.Set(10.0f, y); 67 | Body body2 = _world.CreateBody(bd); 68 | body2.CreateShape(sd); 69 | body2.SetMassFromShapes(); 70 | 71 | PulleyJointDef pulleyDef = new PulleyJointDef(); 72 | Vec2 anchor1 = new Vec2(-10.0f, y + b); 73 | Vec2 anchor2 = new Vec2(10.0f, y + b); 74 | Vec2 groundAnchor1 = new Vec2(-10.0f, y + b + L); 75 | Vec2 groundAnchor2 = new Vec2(10.0f, y + b + L); 76 | pulleyDef.Initialize(body1, body2, groundAnchor1, groundAnchor2, anchor1, anchor2, 2.0f); 77 | 78 | _joint1 = (PulleyJoint)_world.CreateJoint(pulleyDef); 79 | } 80 | } 81 | 82 | public override void Step(Settings settings) 83 | { 84 | base.Step(settings); 85 | 86 | float ratio = _joint1.Ratio; 87 | float L = _joint1.Length1 + ratio * _joint1.Length2; 88 | StringBuilder strBld = new StringBuilder(); 89 | strBld.AppendFormat("L1 + {0} * L2 = {1}", 90 | new object[] { ratio, L }); 91 | OpenGLDebugDraw.DrawString(5, _textLine, strBld.ToString()); 92 | _textLine += 15; 93 | } 94 | 95 | public override void Keyboard(System.Windows.Forms.Keys key) 96 | { 97 | base.Keyboard(key); 98 | } 99 | 100 | public static Test Create() 101 | { 102 | return new Pulleys(); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Common/Vec3.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | //r175 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Text; 27 | 28 | namespace Box2DX.Common 29 | { 30 | /// 31 | /// A 2D column vector with 3 elements. 32 | /// 33 | public struct Vec3 34 | { 35 | /// 36 | /// Construct using coordinates. 37 | /// 38 | public Vec3(float x, float y, float z) { X = x; Y = y; Z = z; } 39 | 40 | /// 41 | /// Set this vector to all zeros. 42 | /// 43 | public void SetZero() { X = 0.0f; Y = 0.0f; Z = 0.0f; } 44 | 45 | /// 46 | /// Set this vector to some specified coordinates. 47 | /// 48 | public void Set(float x, float y, float z) { X = x; Y = y; Z = z; } 49 | 50 | /// 51 | /// Perform the dot product on two vectors. 52 | /// 53 | public static float Dot(Vec3 a, Vec3 b) 54 | { 55 | return a.X * b.X + a.Y * b.Y + a.Z * b.Z; 56 | } 57 | 58 | /// 59 | /// Perform the cross product on two vectors. 60 | /// 61 | public static Vec3 Cross(Vec3 a, Vec3 b) 62 | { 63 | return new Vec3(a.Y * b.Z - a.Z * b.Y, a.Z * b.X - a.X * b.Z, a.X * b.Y - a.Y * b.X); 64 | } 65 | 66 | /// 67 | /// Negate this vector. 68 | /// 69 | public static Vec3 operator -(Vec3 v) 70 | { 71 | return new Vec3(-v.X, -v.Y, -v.Z); 72 | } 73 | 74 | /// 75 | /// Add two vectors component-wise. 76 | /// 77 | public static Vec3 operator +(Vec3 v1, Vec3 v2) 78 | { 79 | return new Vec3(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z); 80 | } 81 | 82 | /// 83 | /// Subtract two vectors component-wise. 84 | /// 85 | public static Vec3 operator -(Vec3 v1, Vec3 v2) 86 | { 87 | return new Vec3(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z); 88 | } 89 | 90 | /// 91 | /// Multiply this vector by a scalar. 92 | /// 93 | public static Vec3 operator *(Vec3 v, float s) 94 | { 95 | return new Vec3(v.X * s, v.Y * s, v.Z * s); 96 | } 97 | 98 | /// 99 | /// Multiply this vector by a scalar. 100 | /// 101 | public static Vec3 operator *(float s, Vec3 v) 102 | { 103 | return new Vec3(v.X * s, v.Y * s, v.Z * s); 104 | } 105 | 106 | public float X, Y, Z; 107 | } 108 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/CCDTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #define v1 23 | 24 | using System; 25 | using System.Collections.Generic; 26 | using System.Text; 27 | 28 | using Box2DX.Common; 29 | using Box2DX.Collision; 30 | using Box2DX.Dynamics; 31 | 32 | namespace TestBed 33 | { 34 | public class CCDTest : Test 35 | { 36 | public CCDTest() 37 | { 38 | const float k_restitution = 1.4f; 39 | 40 | { 41 | BodyDef bd = new BodyDef(); 42 | bd.Position.Set(0.0f, 20.0f); 43 | Body body = _world.CreateBody(bd); 44 | 45 | PolygonDef sd = new PolygonDef(); 46 | sd.Density = 0.0f; 47 | sd.Restitution = k_restitution; 48 | 49 | sd.SetAsBox(0.1f, 10.0f, new Vec2(-10.0f, 0.0f), 0.0f); 50 | body.CreateShape(sd); 51 | 52 | sd.SetAsBox(0.1f, 10.0f, new Vec2(10.0f, 0.0f), 0.0f); 53 | body.CreateShape(sd); 54 | 55 | sd.SetAsBox(0.1f, 10.0f, new Vec2(0.0f, -10.0f), 0.5f * Box2DX.Common.Settings.Pi); 56 | body.CreateShape(sd); 57 | 58 | sd.SetAsBox(0.1f, 10.0f, new Vec2(0.0f, 10.0f), -0.5f * Box2DX.Common.Settings.Pi); 59 | body.CreateShape(sd); 60 | } 61 | 62 | { 63 | PolygonDef sd_bottom = new PolygonDef(); 64 | sd_bottom.SetAsBox( 1.5f, 0.15f ); 65 | sd_bottom.Density = 4.0f; 66 | 67 | PolygonDef sd_left = new PolygonDef(); 68 | sd_left.SetAsBox(0.15f, 2.7f, new Vec2(-1.45f, 2.35f), 0.2f); 69 | sd_left.Density = 4.0f; 70 | 71 | PolygonDef sd_right = new PolygonDef(); 72 | sd_right.SetAsBox(0.15f, 2.7f, new Vec2(1.45f, 2.35f), -0.2f); 73 | sd_right.Density = 4.0f; 74 | 75 | BodyDef bd = new BodyDef(); 76 | bd.Position.Set( 0.0f, 15.0f ); 77 | Body body = _world.CreateBody(bd); 78 | body.CreateShape(sd_bottom); 79 | body.CreateShape(sd_left); 80 | body.CreateShape(sd_right); 81 | body.SetMassFromShapes(); 82 | } 83 | 84 | for (int i = 0; i < 0; ++i) 85 | { 86 | BodyDef bd = new BodyDef(); 87 | bd.Position.Set(0.0f, 15.0f + i); 88 | bd.IsBullet = true; 89 | Body body = _world.CreateBody(bd); 90 | body.SetAngularVelocity(Box2DX.Common.Math.Random(-50.0f, 50.0f)); 91 | 92 | CircleDef sd = new CircleDef(); 93 | sd.Radius = 0.25f; 94 | sd.Density = 1.0f; 95 | sd.Restitution = 0.0f; 96 | body.CreateShape(sd); 97 | body.SetMassFromShapes(); 98 | } 99 | } 100 | 101 | public static Test Create() 102 | { 103 | return new CCDTest(); 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/VerticalStack.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class VerticalStack : Test 33 | { 34 | Body _bullet; 35 | 36 | public VerticalStack() 37 | { 38 | { 39 | PolygonDef sd = new PolygonDef(); 40 | sd.SetAsBox(50.0f, 10.0f, new Vec2(0.0f, -10.0f), 0.0f); 41 | 42 | BodyDef bd = new BodyDef(); 43 | bd.Position.Set(0.0f, 0.0f); 44 | Body ground = _world.CreateBody(bd); 45 | ground.CreateShape(sd); 46 | 47 | sd.SetAsBox(0.1f, 10.0f, new Vec2(20.0f, 10.0f), 0.0f); 48 | ground.CreateShape(sd); 49 | } 50 | 51 | float[] xs = new float[5] { 0.0f, -10.0f, -5.0f, 5.0f, 10.0f }; 52 | 53 | for (int j = 0; j < 5; ++j) 54 | { 55 | PolygonDef sd = new PolygonDef(); 56 | sd.SetAsBox(0.5f, 0.5f); 57 | sd.Density = 1.0f; 58 | sd.Friction = 0.3f; 59 | 60 | for (int i = 0; i < 12; ++i) 61 | { 62 | BodyDef bd = new BodyDef(); 63 | 64 | // For this test we are using continuous physics for all boxes. 65 | // This is a stress test, you normally wouldn't do this for 66 | // performance reasons. 67 | bd.AllowSleep = true; 68 | bd.Position.Set(xs[j], 0.752f + 1.54f * i); 69 | Body body = _world.CreateBody(bd); 70 | 71 | body.CreateShape(sd); 72 | body.SetMassFromShapes(); 73 | } 74 | } 75 | 76 | _bullet = null; 77 | } 78 | 79 | public static Test Create() 80 | { 81 | return new VerticalStack(); 82 | } 83 | 84 | public override void Keyboard(System.Windows.Forms.Keys key) 85 | { 86 | switch (key) 87 | { 88 | case System.Windows.Forms.Keys.S: 89 | if (_bullet != null) 90 | { 91 | _world.DestroyBody(_bullet); 92 | _bullet = null; 93 | } 94 | { 95 | CircleDef sd = new CircleDef(); 96 | sd.Density = 20.0f; 97 | sd.Radius = 0.25f; 98 | sd.Restitution = 0.05f; 99 | 100 | BodyDef bd = new BodyDef(); 101 | bd.IsBullet = true; 102 | bd.AllowSleep = false; 103 | bd.Position.Set(-31.0f, 5.0f); 104 | 105 | _bullet = _world.CreateBody(bd); 106 | _bullet.CreateShape(sd); 107 | _bullet.SetMassFromShapes(); 108 | 109 | _bullet.SetLinearVelocity(new Vec2(400.0f, 0.0f)); 110 | } 111 | break; 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/PolyCollision.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class PolyCollision : Test 33 | { 34 | MyContactPoint[] _localPoints = new MyContactPoint[2]; 35 | 36 | Body _body1; 37 | Body _body2; 38 | 39 | public PolyCollision() 40 | { 41 | _localPoints[0].state = ContactState.ContactRemoved; 42 | _localPoints[1].state = ContactState.ContactRemoved; 43 | 44 | { 45 | PolygonDef sd = new PolygonDef(); 46 | sd.Vertices[0].Set(-9.0f, -1.1f); 47 | sd.Vertices[1].Set(7.0f, -1.1f); 48 | sd.Vertices[2].Set(5.0f, -0.9f); 49 | sd.Vertices[3].Set(-11.0f, -0.9f); 50 | sd.VertexCount = 4; 51 | sd.Density = 0.0f; 52 | 53 | BodyDef bd = new BodyDef(); 54 | bd.Position.Set(0.0f, 10.0f); 55 | _body1 = _world.CreateBody(bd); 56 | _body1.CreateShape(sd); 57 | } 58 | 59 | { 60 | PolygonDef sd = new PolygonDef(); 61 | sd.SetAsBox(0.5f, 0.5f); 62 | sd.Density = 1.0f; 63 | 64 | BodyDef bd = new BodyDef(); 65 | bd.Position.Set(0.0f, 10.0f); 66 | _body2 = _world.CreateBody(bd); 67 | _body2.CreateShape(sd); 68 | _body2.SetMassFromShapes(); 69 | } 70 | 71 | _world.Gravity = Vec2.Zero; 72 | } 73 | 74 | public override void Step(Settings settings) 75 | { 76 | settings.pause = 1; 77 | base.Step(settings); 78 | settings.pause = 0; 79 | } 80 | 81 | public override void Keyboard(System.Windows.Forms.Keys key) 82 | { 83 | Vec2 p = _body2.GetPosition(); 84 | float a = _body2.GetAngle(); 85 | 86 | switch (key) 87 | { 88 | case System.Windows.Forms.Keys.A: 89 | p.X -= 0.1f; 90 | break; 91 | 92 | case System.Windows.Forms.Keys.D: 93 | p.X += 0.1f; 94 | break; 95 | 96 | case System.Windows.Forms.Keys.S: 97 | p.Y -= 0.1f; 98 | break; 99 | 100 | case System.Windows.Forms.Keys.W: 101 | p.Y += 0.1f; 102 | break; 103 | 104 | case System.Windows.Forms.Keys.Q: 105 | a += 0.1f * Box2DX.Common.Settings.Pi; 106 | break; 107 | 108 | case System.Windows.Forms.Keys.E: 109 | a -= 0.1f * Box2DX.Common.Settings.Pi; 110 | break; 111 | } 112 | 113 | _body2.SetXForm(p, a); 114 | } 115 | 116 | public static Test Create() 117 | { 118 | return new PolyCollision(); 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/SensorTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class SensorTest : Test 33 | { 34 | Shape _sensor; 35 | 36 | public SensorTest() 37 | { 38 | { 39 | BodyDef bd = new BodyDef(); 40 | bd.Position.Set(0.0f, -10.0f); 41 | 42 | Body ground = _world.CreateBody(bd); 43 | 44 | PolygonDef sd = new PolygonDef(); 45 | sd.SetAsBox(50.0f, 10.0f); 46 | ground.CreateShape(sd); 47 | 48 | CircleDef cd = new CircleDef(); 49 | cd.IsSensor = true; 50 | cd.Radius = 5.0f; 51 | cd.LocalPosition.Set(0.0f, 20.0f); 52 | _sensor = ground.CreateShape(cd); 53 | } 54 | 55 | { 56 | CircleDef sd = new CircleDef(); 57 | sd.Radius = 1.0f; 58 | sd.Density = 1.0f; 59 | 60 | for (int i = 0; i < 7; ++i) 61 | { 62 | BodyDef bd = new BodyDef(); 63 | bd.Position.Set(-10.0f + 3.0f * i, 20.0f); 64 | 65 | Body body = _world.CreateBody(bd); 66 | 67 | body.CreateShape(sd); 68 | body.SetMassFromShapes(); 69 | } 70 | } 71 | } 72 | 73 | public override void Step(Settings settings) 74 | { 75 | base.Step(settings); 76 | // Traverse the contact results. Apply a force on shapes 77 | // that overlap the sensor. 78 | for (int i = 0; i < _pointCount; ++i) 79 | { 80 | MyContactPoint point = _points[i]; 81 | 82 | if ((int)point.state == 2) 83 | { 84 | continue; 85 | } 86 | 87 | Shape shape1 = point.shape1; 88 | Shape shape2 = point.shape2; 89 | Body other; 90 | 91 | if (shape1 == _sensor) 92 | { 93 | other = shape2.GetBody(); 94 | } 95 | else if (shape2 == _sensor) 96 | { 97 | other = shape1.GetBody(); 98 | } 99 | else 100 | { 101 | continue; 102 | } 103 | 104 | Body ground = _sensor.GetBody(); 105 | 106 | CircleShape circle = (CircleShape)_sensor; 107 | Vec2 center = ground.GetWorldPoint(circle.GetLocalPosition()); 108 | 109 | Vec2 d = center - point.position; 110 | if (d.LengthSquared() < Box2DX.Common.Settings.FLT_EPSILON * Box2DX.Common.Settings.FLT_EPSILON) 111 | { 112 | continue; 113 | } 114 | 115 | d.Normalize(); 116 | Vec2 F = 100.0f * d; 117 | other.ApplyForce(F, point.position); 118 | } 119 | } 120 | 121 | public static Test Create() 122 | { 123 | return new SensorTest(); 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/TimeOfImpact.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.Com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.Com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class TimeOfImpact : Test 33 | { 34 | Body _body1; 35 | Body _body2; 36 | Shape _shape1; 37 | PolygonShape _shape2; 38 | 39 | public TimeOfImpact() 40 | { 41 | { 42 | PolygonDef sd = new PolygonDef(); 43 | sd.Density = 0.0f; 44 | 45 | sd.SetAsBox(0.1f, 10.0f, new Vec2(10.0f, 0.0f), 0.0f); 46 | 47 | BodyDef bd = new BodyDef(); 48 | bd.Position.Set(0.0f, 20.0f); 49 | bd.Angle = 0.0f; 50 | _body1 = _world.CreateBody(bd); 51 | _shape1 = _body1.CreateShape(sd); 52 | } 53 | 54 | { 55 | PolygonDef sd = new PolygonDef(); 56 | sd.SetAsBox(0.25f, 0.25f); 57 | sd.Density = 1.0f; 58 | 59 | BodyDef bd = new BodyDef(); 60 | bd.Position.Set(9.6363468f, 28.050615f); 61 | bd.Angle = 1.6408679f; 62 | _body2 = _world.CreateBody(bd); 63 | _shape2 = (PolygonShape)_body2.CreateShape(sd); 64 | _body2.SetMassFromShapes(); 65 | } 66 | } 67 | 68 | public override void Step(Settings settings) 69 | { 70 | settings.pause = 1; 71 | base.Step(settings); 72 | settings.pause = 0; 73 | 74 | Sweep sweep1 = new Sweep(); 75 | sweep1.C0.Set(0.0f, 20.0f); 76 | sweep1.A0 = 0.0f; 77 | sweep1.C = sweep1.C0; 78 | sweep1.A = sweep1.A0; 79 | sweep1.T0 = 0.0f; 80 | sweep1.LocalCenter = _body1.GetLocalCenter(); 81 | 82 | Sweep sweep2 = new Sweep(); 83 | sweep2.C0.Set(9.6363468f, 28.050615f); 84 | sweep2.A0 = 1.6408679f; 85 | sweep2.C = sweep2.C0 + new Vec2(-0.075121880f, 0.27358246f); 86 | sweep2.A = sweep2.A0 - 10.434675f; 87 | sweep2.T0 = 0.0f; 88 | sweep2.LocalCenter = _body2.GetLocalCenter(); 89 | 90 | float toi = Collision.TimeOfImpact(_shape1, sweep1, _shape2, sweep2); 91 | 92 | OpenGLDebugDraw.DrawString(5, _textLine, "toi = " + toi.ToString()); 93 | _textLine += 15; 94 | 95 | XForm xf2 = new XForm(); 96 | sweep2.GetXForm(out xf2, toi); 97 | int vertexCount = _shape2.VertexCount; 98 | Vec2[] vertices = new Vec2[Box2DX.Common.Settings.MaxPolygonVertices]; 99 | Vec2[] localVertices = _shape2.GetVertices(); 100 | for (int i = 0; i < vertexCount; ++i) 101 | { 102 | vertices[i] = Box2DX.Common.Math.Mul(xf2, localVertices[i]); 103 | } 104 | _debugDraw.DrawPolygon(vertices, vertexCount, new Color(0.5f, 0.7f, 0.9f)); 105 | 106 | localVertices = _shape2.GetCoreVertices(); 107 | for (int i = 0; i < vertexCount; ++i) 108 | { 109 | vertices[i] = Box2DX.Common.Math.Mul(xf2, localVertices[i]); 110 | } 111 | _debugDraw.DrawPolygon(vertices, vertexCount, new Color(0.5f, 0.7f, 0.9f)); 112 | } 113 | 114 | public static Test Create() 115 | { 116 | return new TimeOfImpact(); 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/VaryingFriction.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class VaryingFriction : Test 33 | { 34 | public VaryingFriction() 35 | { 36 | { 37 | PolygonDef sd = new PolygonDef();; 38 | sd.SetAsBox(50.0f, 20.0f); 39 | 40 | BodyDef bd = new BodyDef() ; 41 | bd.Position.Set(0.0f, -20.0f); 42 | Body ground = _world.CreateBody(bd); 43 | ground.CreateShape(sd); 44 | } 45 | 46 | { 47 | PolygonDef sd = new PolygonDef();; 48 | sd.SetAsBox(13.0f, 0.25f); 49 | 50 | BodyDef bd = new BodyDef() ; 51 | bd.Position.Set(-4.0f, 22.0f); 52 | bd.Angle = -0.25f; 53 | 54 | Body ground = _world.CreateBody(bd); 55 | ground.CreateShape(sd); 56 | } 57 | 58 | { 59 | PolygonDef sd = new PolygonDef();; 60 | sd.SetAsBox(0.25f, 1.0f); 61 | 62 | BodyDef bd = new BodyDef() ; 63 | bd.Position.Set(10.5f, 19.0f); 64 | 65 | Body ground = _world.CreateBody(bd); 66 | ground.CreateShape(sd); 67 | } 68 | 69 | { 70 | PolygonDef sd = new PolygonDef();; 71 | sd.SetAsBox(13.0f, 0.25f); 72 | 73 | BodyDef bd = new BodyDef() ; 74 | bd.Position.Set(4.0f, 14.0f); 75 | bd.Angle = 0.25f; 76 | 77 | Body ground = _world.CreateBody(bd); 78 | ground.CreateShape(sd); 79 | } 80 | 81 | { 82 | PolygonDef sd = new PolygonDef();; 83 | sd.SetAsBox(0.25f, 1.0f); 84 | 85 | BodyDef bd = new BodyDef() ; 86 | bd.Position.Set(-10.5f, 11.0f); 87 | 88 | Body ground = _world.CreateBody(bd); 89 | ground.CreateShape(sd); 90 | } 91 | 92 | { 93 | PolygonDef sd = new PolygonDef();; 94 | sd.SetAsBox(13.0f, 0.25f); 95 | 96 | BodyDef bd = new BodyDef() ; 97 | bd.Position.Set(-4.0f, 6.0f); 98 | bd.Angle = -0.25f; 99 | 100 | Body ground = _world.CreateBody(bd); 101 | ground.CreateShape(sd); 102 | } 103 | 104 | { 105 | PolygonDef sd = new PolygonDef();; 106 | sd.SetAsBox(0.5f, 0.5f); 107 | sd.Density = 25.0f; 108 | 109 | float[] friction = new float[5]{0.75f, 0.5f, 0.35f, 0.1f, 0.0f}; 110 | 111 | for (int i = 0; i < 5; ++i) 112 | { 113 | BodyDef bd = new BodyDef() ; 114 | bd.Position.Set(-15.0f + 4.0f * i, 28.0f); 115 | Body body = _world.CreateBody(bd); 116 | 117 | sd.Friction = friction[i]; 118 | body.CreateShape(sd); 119 | body.SetMassFromShapes(); 120 | } 121 | } 122 | } 123 | 124 | public static Test Create() 125 | { 126 | return new VaryingFriction(); 127 | } 128 | } 129 | } -------------------------------------------------------------------------------- /Examples/HelloWorld/HelloWorld.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.21022 7 | 2.0 8 | {594CF883-9C7C-4320-A81E-ABED15E32217} 9 | Exe 10 | Properties 11 | HelloWorld 12 | HelloWorld 13 | v4.0 14 | 512 15 | 16 | 17 | 18 | 19 | 3.5 20 | 21 | publish\ 22 | true 23 | Disk 24 | false 25 | Foreground 26 | 7 27 | Days 28 | false 29 | false 30 | true 31 | 0 32 | 1.0.0.%2a 33 | false 34 | false 35 | true 36 | 37 | 38 | ..\..\Build\VCS\HelloWorld\obj\ 39 | true 40 | full 41 | false 42 | ..\..\Output\ 43 | DEBUG;TRACE 44 | prompt 45 | 4 46 | x86 47 | false 48 | 49 | 50 | ..\..\Build\VCS\HelloWorld\obj\ 51 | pdbonly 52 | true 53 | ..\..\Output\ 54 | TRACE 55 | prompt 56 | 4 57 | AnyCPU 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | {C157BCA5-BAC7-455F-A7DE-59D506D46ECF} 71 | Box2DX 72 | False 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | False 81 | .NET Framework 3.5 SP1 82 | true 83 | 84 | 85 | 86 | 93 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/RaycastTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class RaycastTest : Test 33 | { 34 | Body laserBody; 35 | 36 | public RaycastTest() 37 | { 38 | Body ground = null; 39 | { 40 | BodyDef bd = new BodyDef(); 41 | bd.Position.Set(0.0f, -10.0f); 42 | ground = _world.CreateBody(bd); 43 | 44 | PolygonDef sd = new PolygonDef(); 45 | sd.SetAsBox(50.0f, 10.0f); 46 | ground.CreateShape(sd); 47 | } 48 | 49 | { 50 | BodyDef bd = new BodyDef(); 51 | bd.Position.Set(0.0f, 1.0f); 52 | laserBody = _world.CreateBody(bd); 53 | 54 | PolygonDef sd = new PolygonDef(); 55 | sd.SetAsBox(5.0f, 1.0f); 56 | sd.Density = 4.0f; 57 | laserBody.CreateShape(sd); 58 | laserBody.SetMassFromShapes(); 59 | 60 | Body body; 61 | //Create a few shapes 62 | bd.Position.Set(-5.0f, 10.0f); 63 | body = _world.CreateBody(bd); 64 | 65 | CircleDef cd = new CircleDef(); 66 | cd.Radius = 3; 67 | body.CreateShape(cd); 68 | 69 | bd.Position.Set(5.0f, 10.0f); 70 | body = _world.CreateBody(bd); 71 | 72 | body.CreateShape(cd); 73 | } 74 | } 75 | 76 | public override void Keyboard(System.Windows.Forms.Keys key) 77 | { 78 | base.Keyboard(key); 79 | } 80 | 81 | public override void Step(Settings settings) 82 | { 83 | base.Step(settings); 84 | 85 | float segmentLength = 30.0f; 86 | 87 | Segment segment; 88 | Vec2 laserStart = new Vec2(5.0f - 0.1f, 0.0f); 89 | Vec2 laserDir = new Vec2(segmentLength, 0.0f); 90 | segment.P1 = laserBody.GetWorldPoint(laserStart); 91 | segment.P2 = laserBody.GetWorldVector(laserDir); 92 | segment.P2 += segment.P1; 93 | 94 | for (int rebounds = 0; rebounds < 10; rebounds++) 95 | { 96 | 97 | float lambda = 1; 98 | Vec2 normal; 99 | Shape shape = _world.RaycastOne(segment, out lambda, out normal, false, null); 100 | 101 | Color laserColor = new Color(255, 0, 0); 102 | 103 | if (shape != null) 104 | { 105 | _debugDraw.DrawSegment(segment.P1, (1 - lambda) * segment.P1 + lambda * segment.P2, laserColor); 106 | } 107 | else 108 | { 109 | _debugDraw.DrawSegment(segment.P1, segment.P2, laserColor); 110 | break; 111 | } 112 | //Bounce 113 | segmentLength *= (1 - lambda); 114 | if (segmentLength <= Box2DX.Common.Settings.FLT_EPSILON) 115 | break; 116 | laserStart = (1 - lambda) * segment.P1 + lambda * segment.P2; 117 | laserDir = segment.P2 - segment.P1; 118 | laserDir.Normalize(); 119 | laserDir = laserDir - 2 * Vec2.Dot(laserDir, normal) * normal; 120 | segment.P1 = laserStart - 0.1f * laserDir; 121 | segment.P2 = laserStart + segmentLength * laserDir; 122 | } 123 | } 124 | 125 | public static Test Create() 126 | { 127 | return new RaycastTest(); 128 | } 129 | } 130 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/DistanceTest.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class DistanceTest : Test 33 | { 34 | Body _body1; 35 | Body _body2; 36 | Shape _shape1; 37 | Shape _shape2; 38 | 39 | public DistanceTest() 40 | { 41 | PolygonDef sd = new PolygonDef(); 42 | sd.SetAsBox(1.0f, 1.0f); 43 | sd.Density = 0.0f; 44 | 45 | BodyDef bd = new BodyDef(); 46 | bd.Position.Set(0.0f, 10.0f); 47 | _body1 = _world.CreateBody(bd); 48 | _shape1 = _body1.CreateShape(sd); 49 | 50 | PolygonDef sd2 = new PolygonDef(); 51 | sd2.VertexCount = 3; 52 | sd2.Vertices[0].Set(-1.0f, 0.0f); 53 | sd2.Vertices[1].Set(1.0f, 0.0f); 54 | sd2.Vertices[2].Set(0.0f, 15.0f); 55 | sd2.Density = 1.0f; 56 | 57 | BodyDef bd2 = new BodyDef(); 58 | 59 | bd2.Position.Set(0.0f, 10.0f); 60 | 61 | _body2 = _world.CreateBody(bd2); 62 | _shape2 = _body2.CreateShape(sd2); 63 | _body2.SetMassFromShapes(); 64 | 65 | _world.Gravity = new Vec2(0.0f, 0.0f); 66 | } 67 | 68 | public override void Step(Settings settings) 69 | { 70 | settings.pause = 1; 71 | base.Step(settings); 72 | settings.pause = 0; 73 | 74 | Vec2 x1, x2; 75 | float distance = Collision.Distance(out x1, out x2, _shape1, _body1.GetXForm(), _shape2, _body2.GetXForm()); 76 | 77 | StringBuilder strBld = new StringBuilder(); 78 | strBld.AppendFormat("distance = {0}", new object[] { distance }); 79 | OpenGLDebugDraw.DrawString(5, _textLine, strBld.ToString()); 80 | _textLine += 15; 81 | 82 | strBld = new StringBuilder(); 83 | strBld.AppendFormat("iterations = {0}", new object[] { Collision.GJKIterations }); 84 | OpenGLDebugDraw.DrawString(5, _textLine, strBld.ToString()); 85 | _textLine += 15; 86 | 87 | OpenGLDebugDraw.DrawPoint(x1, 4.0f, new Color(1, 0, 0)); 88 | OpenGLDebugDraw.DrawSegment(x1, x2, new Color(1, 0, 0)); 89 | OpenGLDebugDraw.DrawPoint(x2, 4.0f, new Color(1, 0, 0)); 90 | } 91 | 92 | public override void Keyboard(System.Windows.Forms.Keys key) 93 | { 94 | Vec2 p = _body2.GetPosition(); 95 | float a = _body2.GetAngle(); 96 | 97 | switch (key) 98 | { 99 | case System.Windows.Forms.Keys.A: 100 | p.X -= 0.1f; 101 | break; 102 | 103 | case System.Windows.Forms.Keys.D: 104 | p.X += 0.1f; 105 | break; 106 | 107 | case System.Windows.Forms.Keys.S: 108 | p.Y -= 0.1f; 109 | break; 110 | 111 | case System.Windows.Forms.Keys.W: 112 | p.Y += 0.1f; 113 | break; 114 | 115 | case System.Windows.Forms.Keys.Q: 116 | a += 0.1f * Box2DX.Common.Settings.Pi; 117 | break; 118 | 119 | case System.Windows.Forms.Keys.E: 120 | a -= 0.1f * Box2DX.Common.Settings.Pi; 121 | break; 122 | } 123 | 124 | _body2.SetXForm(p, a); 125 | } 126 | 127 | public static Test Create() 128 | { 129 | return new DistanceTest(); 130 | } 131 | } 132 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/ApplyForce.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class ApplyForce : Test 33 | { 34 | Body _body; 35 | 36 | public ApplyForce() 37 | { 38 | _world.Gravity = new Vec2(0.0f, 0.0f); 39 | 40 | const float k_restitution = 0.4f; 41 | 42 | { 43 | BodyDef bd = new BodyDef(); 44 | bd.Position.Set(0.0f, 20.0f); 45 | Body ground = _world.CreateBody(bd); 46 | 47 | PolygonDef sd = new PolygonDef(); 48 | sd.Density = 0.0f; 49 | sd.Restitution = k_restitution; 50 | 51 | sd.SetAsBox(0.2f, 20.0f, new Vec2(-20.0f, 0.0f), 0.0f); 52 | ground.CreateShape(sd); 53 | 54 | sd.SetAsBox(0.2f, 20.0f, new Vec2(20.0f, 0.0f), 0.0f); 55 | ground.CreateShape(sd); 56 | 57 | sd.SetAsBox(0.2f, 20.0f, new Vec2(0.0f, -20.0f), 0.5f * Box2DX.Common.Settings.Pi); 58 | ground.CreateShape(sd); 59 | 60 | sd.SetAsBox(0.2f, 20.0f, new Vec2(0.0f, 20.0f), -0.5f * Box2DX.Common.Settings.Pi); 61 | ground.CreateShape(sd); 62 | } 63 | 64 | { 65 | XForm xf1 = new XForm(); 66 | xf1.R.Set(0.3524f * Box2DX.Common.Settings.Pi); 67 | xf1.Position = Box2DX.Common.Math.Mul(xf1.R, new Vec2(1.0f, 0.0f)); 68 | 69 | PolygonDef sd1 = new PolygonDef(); 70 | sd1.VertexCount = 3; 71 | sd1.Vertices[0] = Box2DX.Common.Math.Mul(xf1, new Vec2(-1.0f, 0.0f)); 72 | sd1.Vertices[1] = Box2DX.Common.Math.Mul(xf1, new Vec2(1.0f, 0.0f)); 73 | sd1.Vertices[2] = Box2DX.Common.Math.Mul(xf1, new Vec2(0.0f, 0.5f)); 74 | sd1.Density = 2.0f; 75 | 76 | XForm xf2 = new XForm(); 77 | xf2.R.Set(-0.3524f * Box2DX.Common.Settings.Pi); 78 | xf2.Position = Box2DX.Common.Math.Mul(xf2.R, new Vec2(-1.0f, 0.0f)); 79 | 80 | PolygonDef sd2 = new PolygonDef(); 81 | sd2.VertexCount = 3; 82 | sd2.Vertices[0] = Box2DX.Common.Math.Mul(xf2, new Vec2(-1.0f, 0.0f)); 83 | sd2.Vertices[1] = Box2DX.Common.Math.Mul(xf2, new Vec2(1.0f, 0.0f)); 84 | sd2.Vertices[2] = Box2DX.Common.Math.Mul(xf2, new Vec2(0.0f, 0.5f)); 85 | sd2.Density = 2.0f; 86 | 87 | BodyDef bd = new BodyDef(); 88 | bd.AngularDamping = 2.0f; 89 | bd.LinearDamping = 0.1f; 90 | 91 | bd.Position.Set(0.0f, 1.05f); 92 | bd.Angle = Box2DX.Common.Settings.Pi; 93 | _body = _world.CreateBody(bd); 94 | _body.CreateShape(sd1); 95 | _body.CreateShape(sd2); 96 | _body.SetMassFromShapes(); 97 | } 98 | } 99 | 100 | public override void Keyboard(System.Windows.Forms.Keys key) 101 | { 102 | switch (key) 103 | { 104 | case System.Windows.Forms.Keys.W: 105 | { 106 | Vec2 f = _body.GetWorldVector(new Vec2(0.0f, -200.0f)); 107 | Vec2 p = _body.GetWorldPoint(new Vec2(0.0f, 2.0f)); 108 | _body.ApplyForce(f, p); 109 | } 110 | break; 111 | 112 | case System.Windows.Forms.Keys.A: 113 | { 114 | _body.ApplyTorque(20.0f); 115 | } 116 | break; 117 | 118 | case System.Windows.Forms.Keys.D: 119 | { 120 | _body.ApplyTorque(-20.0f); 121 | } 122 | break; 123 | } 124 | } 125 | 126 | public static Test Create() 127 | { 128 | return new ApplyForce(); 129 | } 130 | } 131 | } -------------------------------------------------------------------------------- /Examples/HelloWorld/Program.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Dynamics; 27 | using Box2DX.Collision; 28 | using Box2DX.Common; 29 | 30 | namespace HelloWorld 31 | { 32 | class Program 33 | { 34 | // This is a simple example of building and running a simulation 35 | // using Box2DX. Here we create a large ground box and a small dynamic 36 | // box. 37 | static void Main(string[] args) 38 | { 39 | // Define the size of the world. Simulation will still work 40 | // if bodies reach the end of the world, but it will be slower. 41 | AABB worldAABB = new AABB(); 42 | worldAABB.LowerBound.Set(-100.0f, -100.0f); 43 | worldAABB.UpperBound.Set(100.0f, 100.0f); 44 | 45 | // Define the gravity vector. 46 | Vec2 gravity = new Vec2(0.0f, -10.0f); 47 | 48 | // Do we want to let bodies sleep? 49 | bool doSleep = true; 50 | 51 | // Construct a world object, which will hold and simulate the rigid bodies. 52 | World world = new World(worldAABB, gravity, doSleep); 53 | 54 | // Define the ground body. 55 | BodyDef groundBodyDef = new BodyDef(); 56 | groundBodyDef.Position.Set(0.0f, -10.0f); 57 | 58 | // Call the body factory which creates the ground box shape. 59 | // The body is also added to the world. 60 | Body groundBody = world.CreateBody(groundBodyDef); 61 | 62 | // Define the ground box shape. 63 | PolygonDef groundShapeDef = new PolygonDef(); 64 | 65 | // The extents are the half-widths of the box. 66 | groundShapeDef.SetAsBox(50.0f, 10.0f); 67 | 68 | // Add the ground shape to the ground body. 69 | groundBody.CreateShape(groundShapeDef); 70 | 71 | // Define the dynamic body. We set its position and call the body factory. 72 | BodyDef bodyDef = new BodyDef(); 73 | bodyDef.Position.Set(0.0f, 4.0f); 74 | Body body = world.CreateBody(bodyDef); 75 | 76 | // Define another box shape for our dynamic body. 77 | PolygonDef shapeDef = new PolygonDef(); 78 | shapeDef.SetAsBox(1.0f, 1.0f); 79 | 80 | // Set the box density to be non-zero, so it will be dynamic. 81 | shapeDef.Density = 1.0f; 82 | 83 | // Override the default friction. 84 | shapeDef.Friction = 0.3f; 85 | 86 | // Add the shape to the body. 87 | body.CreateShape(shapeDef); 88 | 89 | // Now tell the dynamic body to compute it's mass properties base 90 | // on its shape. 91 | body.SetMassFromShapes(); 92 | 93 | // Prepare for simulation. Typically we use a time step of 1/60 of a 94 | // second (60Hz) and 10 iterations. This provides a high quality simulation 95 | // in most game scenarios. 96 | float timeStep = 1.0f / 60.0f; 97 | int velocityIterations = 8; 98 | int positionIterations = 1; 99 | 100 | // This is our little game loop. 101 | for (int i = 0; i < 100; ++i) 102 | { 103 | // Instruct the world to perform a single step of simulation. It is 104 | // generally best to keep the time step and iterations fixed. 105 | world.Step(timeStep, velocityIterations, positionIterations); 106 | 107 | // Now print the position and angle of the body. 108 | Vec2 position = body.GetPosition(); 109 | float angle = body.GetAngle(); 110 | 111 | Console.WriteLine("Step: {3} - X: {0}, Y: {1}, Angle: {2}", new object[]{position.X.ToString(),position.Y.ToString(),angle.ToString(), i.ToString()}); 112 | } 113 | 114 | // When the world destructor is called, all bodies and joints are freed. This can 115 | // create orphaned pointers, so be careful about your world management. 116 | 117 | Console.ReadLine(); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/Dynamics/Contacts/CircleContact.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Collision; 27 | using Box2DX.Common; 28 | 29 | namespace Box2DX.Dynamics 30 | { 31 | public class CircleContact : Contact 32 | { 33 | public Manifold _manifold = new Manifold(); 34 | 35 | public override Manifold[] GetManifolds() 36 | { 37 | return new Manifold[] { _manifold }; 38 | } 39 | 40 | public CircleContact(Shape s1, Shape s2) 41 | : base(s1, s2) 42 | { 43 | Box2DXDebug.Assert(_shape1.GetType() == ShapeType.CircleShape); 44 | Box2DXDebug.Assert(_shape2.GetType() == ShapeType.CircleShape); 45 | _manifold.PointCount = 0; 46 | _manifold.Points[0].NormalImpulse = 0.0f; 47 | _manifold.Points[0].TangentImpulse = 0.0f; 48 | } 49 | 50 | public override void Evaluate(ContactListener listener) 51 | { 52 | Body b1 = _shape1.GetBody(); 53 | Body b2 = _shape2.GetBody(); 54 | #warning "needfix" 55 | //memcpy(&m0, &m_manifold, sizeof(b2Manifold)); 56 | Manifold m0 = _manifold.Clone(); 57 | 58 | Collision.Collision.CollideCircles(ref _manifold, (CircleShape)_shape1, b1.GetXForm(), 59 | (CircleShape)_shape2, b2.GetXForm()); 60 | 61 | ContactPoint cp = new ContactPoint(); 62 | cp.Shape1 = _shape1; 63 | cp.Shape2 = _shape2; 64 | cp.Friction = Settings.MixFriction(_shape1.Friction, _shape2.Friction); 65 | cp.Restitution = Settings.MixRestitution(_shape1.Restitution, _shape2.Restitution); 66 | 67 | if (_manifold.PointCount > 0) 68 | { 69 | _manifoldCount = 1; 70 | ManifoldPoint mp = _manifold.Points[0]; 71 | 72 | if (m0.PointCount == 0) 73 | { 74 | mp.NormalImpulse = 0.0f; 75 | mp.TangentImpulse = 0.0f; 76 | 77 | if (listener!=null) 78 | { 79 | cp.Position = b1.GetWorldPoint(mp.LocalPoint1); 80 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); 81 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); 82 | cp.Velocity = v2 - v1; 83 | cp.Normal = _manifold.Normal; 84 | cp.Separation = mp.Separation; 85 | cp.ID = mp.ID; 86 | listener.Add(cp); 87 | } 88 | } 89 | else 90 | { 91 | ManifoldPoint mp0 = m0.Points[0]; 92 | mp.NormalImpulse = mp0.NormalImpulse; 93 | mp.TangentImpulse = mp0.TangentImpulse; 94 | 95 | if (listener!=null) 96 | { 97 | cp.Position = b1.GetWorldPoint(mp.LocalPoint1); 98 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); 99 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); 100 | cp.Velocity = v2 - v1; 101 | cp.Normal = _manifold.Normal; 102 | cp.Separation = mp.Separation; 103 | cp.ID = mp.ID; 104 | listener.Persist(cp); 105 | } 106 | } 107 | } 108 | else 109 | { 110 | _manifoldCount = 0; 111 | if (m0.PointCount > 0 && listener!=null) 112 | { 113 | ManifoldPoint mp0 = m0.Points[0]; 114 | cp.Position = b1.GetWorldPoint(mp0.LocalPoint1); 115 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp0.LocalPoint1); 116 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp0.LocalPoint2); 117 | cp.Velocity = v2 - v1; 118 | cp.Normal = m0.Normal; 119 | cp.Separation = mp0.Separation; 120 | cp.ID = mp0.ID; 121 | listener.Remove(cp); 122 | } 123 | } 124 | } 125 | 126 | new public static Contact Create(Shape shape1, Shape shape2) 127 | { 128 | return new CircleContact(shape1, shape2); 129 | } 130 | 131 | new public static void Destroy(Contact contact) 132 | { 133 | contact = null; 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/Common/Mat22.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | namespace Box2DX.Common 27 | { 28 | /// 29 | /// A 2-by-2 matrix. Stored in column-major order. 30 | /// 31 | public struct Mat22 32 | { 33 | public Vec2 Col1, Col2; 34 | 35 | /// 36 | /// Construct this matrix using columns. 37 | /// 38 | public Mat22(Vec2 c1, Vec2 c2) 39 | { 40 | Col1 = c1; 41 | Col2 = c2; 42 | } 43 | 44 | /// 45 | /// Construct this matrix using scalars. 46 | /// 47 | public Mat22(float a11, float a12, float a21, float a22) 48 | { 49 | Col1.X = a11; Col1.Y = a21; 50 | Col2.X = a12; Col2.Y = a22; 51 | } 52 | 53 | /// 54 | /// Construct this matrix using an angle. 55 | /// This matrix becomes an orthonormal rotation matrix. 56 | /// 57 | public Mat22(float angle) 58 | { 59 | float c = (float)System.Math.Cos(angle), s = (float)System.Math.Sin(angle); 60 | Col1.X = c; Col2.X = -s; 61 | Col1.Y = s; Col2.Y = c; 62 | } 63 | 64 | /// 65 | /// Initialize this matrix using columns. 66 | /// 67 | public void Set(Vec2 c1, Vec2 c2) 68 | { 69 | Col1 = c1; 70 | Col2 = c2; 71 | } 72 | 73 | /// 74 | /// Initialize this matrix using an angle. 75 | /// This matrix becomes an orthonormal rotation matrix. 76 | /// 77 | public void Set(float angle) 78 | { 79 | float c = (float)System.Math.Cos(angle), s = (float)System.Math.Sin(angle); 80 | Col1.X = c; Col2.X = -s; 81 | Col1.Y = s; Col2.Y = c; 82 | } 83 | 84 | /// 85 | /// Set this to the identity matrix. 86 | /// 87 | public void SetIdentity() 88 | { 89 | Col1.X = 1.0f; Col2.X = 0.0f; 90 | Col1.Y = 0.0f; Col2.Y = 1.0f; 91 | } 92 | 93 | /// 94 | /// Set this matrix to all zeros. 95 | /// 96 | public void SetZero() 97 | { 98 | Col1.X = 0.0f; Col2.X = 0.0f; 99 | Col1.Y = 0.0f; Col2.Y = 0.0f; 100 | } 101 | 102 | /// 103 | /// Extract the angle from this matrix (assumed to be a rotation matrix). 104 | /// 105 | public float GetAngle() 106 | { 107 | return (float)System.Math.Atan2(Col1.Y, Col1.X); 108 | } 109 | 110 | /// 111 | /// Compute the inverse of this matrix, such that inv(A) * A = identity. 112 | /// 113 | public Mat22 Invert() 114 | { 115 | float a = Col1.X, b = Col2.X, c = Col1.Y, d = Col2.Y; 116 | Mat22 B = new Mat22(); 117 | float det = a * d - b * c; 118 | Box2DXDebug.Assert(det != 0.0f); 119 | det = 1.0f / det; 120 | B.Col1.X = det * d; B.Col2.X = -det * b; 121 | B.Col1.Y = -det * c; B.Col2.Y = det * a; 122 | return B; 123 | } 124 | 125 | /// 126 | /// Solve A * x = b, where b is a column vector. This is more efficient 127 | /// than computing the inverse in one-shot cases. 128 | /// 129 | public Vec2 Solve(Vec2 b) 130 | { 131 | float a11 = Col1.X, a12 = Col2.X, a21 = Col1.Y, a22 = Col2.Y; 132 | float det = a11 * a22 - a12 * a21; 133 | Box2DXDebug.Assert(det != 0.0f); 134 | det = 1.0f / det; 135 | Vec2 x = new Vec2(); 136 | x.X = det * (a22 * b.X - a12 * b.Y); 137 | x.Y = det * (a11 * b.Y - a21 * b.X); 138 | return x; 139 | } 140 | 141 | public static Mat22 Identity { get { return new Mat22(1, 0, 0, 1); } } 142 | 143 | public static Mat22 operator +(Mat22 A, Mat22 B) 144 | { 145 | Mat22 C = new Mat22(); 146 | C.Set(A.Col1 + B.Col1, A.Col2 + B.Col2); 147 | return C; 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/SliderCrank.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | // A motor driven slider crank with joint friction. 33 | public class SliderCrank : Test 34 | { 35 | public SliderCrank() 36 | { 37 | Body ground = null; 38 | { 39 | PolygonDef sd = new PolygonDef(); 40 | sd.SetAsBox(50.0f, 10.0f); 41 | 42 | BodyDef bd = new BodyDef(); 43 | bd.Position.Set(0.0f, -10.0f); 44 | ground = _world.CreateBody(bd); 45 | ground.CreateShape(sd); 46 | } 47 | 48 | { 49 | // Define crank. 50 | PolygonDef sd = new PolygonDef(); 51 | sd.SetAsBox(0.5f, 2.0f); 52 | sd.Density = 1.0f; 53 | 54 | RevoluteJointDef rjd = new RevoluteJointDef(); 55 | 56 | Body prevBody = ground; 57 | 58 | BodyDef bd = new BodyDef(); 59 | bd.Position.Set(0.0f, 7.0f); 60 | Body body = _world.CreateBody(bd); 61 | body.CreateShape(sd); 62 | body.SetMassFromShapes(); 63 | 64 | rjd.Initialize(prevBody, body, new Vec2(0.0f, 5.0f)); 65 | rjd.MotorSpeed = 1.0f * Box2DX.Common.Settings.Pi; 66 | rjd.MaxMotorTorque = 10000.0f; 67 | rjd.EnableMotor = true; 68 | _joint1 = (RevoluteJoint)_world.CreateJoint(rjd); 69 | 70 | prevBody = body; 71 | 72 | // Define follower. 73 | sd.SetAsBox(0.5f, 4.0f); 74 | bd.Position.Set(0.0f, 13.0f); 75 | body = _world.CreateBody(bd); 76 | body.CreateShape(sd); 77 | body.SetMassFromShapes(); 78 | 79 | rjd.Initialize(prevBody, body, new Vec2(0.0f, 9.0f)); 80 | rjd.EnableMotor = false; 81 | _world.CreateJoint(rjd); 82 | 83 | prevBody = body; 84 | 85 | // Define piston 86 | sd.SetAsBox(1.5f, 1.5f); 87 | bd.Position.Set(0.0f, 17.0f); 88 | body = _world.CreateBody(bd); 89 | body.CreateShape(sd); 90 | body.SetMassFromShapes(); 91 | 92 | rjd.Initialize(prevBody, body, new Vec2(0.0f, 17.0f)); 93 | _world.CreateJoint(rjd); 94 | 95 | PrismaticJointDef pjd = new PrismaticJointDef(); 96 | pjd.Initialize(ground, body, new Vec2(0.0f, 17.0f), new Vec2(0.0f, 1.0f)); 97 | 98 | pjd.MaxMotorForce = 1000.0f; 99 | pjd.EnableMotor = true; 100 | 101 | _joint2 = (PrismaticJoint)_world.CreateJoint(pjd); 102 | 103 | // Create a payload 104 | sd.Density = 2.0f; 105 | bd.Position.Set(0.0f, 23.0f); 106 | body = _world.CreateBody(bd); 107 | body.CreateShape(sd); 108 | body.SetMassFromShapes(); 109 | } 110 | } 111 | 112 | public override void Keyboard(System.Windows.Forms.Keys key) 113 | { 114 | switch (key) 115 | { 116 | case System.Windows.Forms.Keys.F: 117 | _joint2._enableMotor = !_joint2._enableMotor; 118 | _joint2.GetBody2().WakeUp(); 119 | break; 120 | 121 | case System.Windows.Forms.Keys.M: 122 | _joint1._enableMotor = !_joint1._enableMotor; 123 | _joint1.GetBody2().WakeUp(); 124 | break; 125 | } 126 | } 127 | 128 | public override void Step(Settings settings) 129 | { 130 | base.Step(settings); 131 | OpenGLDebugDraw.DrawString(5, _textLine, "Keys: (f) toggle friction, (m) toggle motor"); 132 | _textLine += 15; 133 | float torque = _joint1.MotorTorque; 134 | StringBuilder strBld = new StringBuilder(); 135 | strBld.AppendFormat("Motor Torque = {0}", 136 | new object[] { torque }); 137 | OpenGLDebugDraw.DrawString(5, _textLine, strBld.ToString()); 138 | _textLine += 15; 139 | } 140 | 141 | public static Test Create() 142 | { 143 | return new SliderCrank(); 144 | } 145 | 146 | RevoluteJoint _joint1; 147 | PrismaticJoint _joint2; 148 | } 149 | } -------------------------------------------------------------------------------- /src/Collision/Collision.TimeOfImpact.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | 28 | namespace Box2DX.Collision 29 | { 30 | public partial class Collision 31 | { 32 | // This algorithm uses conservative advancement to compute the time of 33 | // impact (TOI) of two shapes. 34 | // Refs: Bullet, Young Kim 35 | /// 36 | /// Compute the time when two shapes begin to touch or touch at a closer distance. 37 | /// warning the sweeps must have the same time interval. 38 | /// 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | /// The fraction between [0,1] in which the shapes first touch. 45 | /// fraction=0 means the shapes begin touching/overlapped, and fraction=1 means the shapes don't touch. 46 | /// 47 | #warning: "check params" 48 | public static float TimeOfImpact(Shape shape1, Sweep sweep1, Shape shape2, Sweep sweep2) 49 | { 50 | float r1 = shape1.GetSweepRadius(); 51 | float r2 = shape2.GetSweepRadius(); 52 | 53 | Box2DXDebug.Assert(sweep1.T0 == sweep2.T0); 54 | Box2DXDebug.Assert(1.0f - sweep1.T0 > Common.Settings.FLT_EPSILON); 55 | 56 | float t0 = sweep1.T0; 57 | Vec2 v1 = sweep1.C - sweep1.C0; 58 | Vec2 v2 = sweep2.C - sweep2.C0; 59 | float omega1 = sweep1.A - sweep1.A0; 60 | float omega2 = sweep2.A - sweep2.A0; 61 | 62 | float alpha = 0.0f; 63 | 64 | Vec2 p1, p2; 65 | int k_maxIterations = 20; // TODO_ERIN b2Settings 66 | int iter = 0; 67 | Vec2 normal = Vec2.Zero; 68 | float distance = 0.0f; 69 | float targetDistance = 0.0f; 70 | 71 | for (; ; ) 72 | { 73 | float t = (1.0f - alpha) * t0 + alpha; 74 | XForm xf1, xf2; 75 | sweep1.GetXForm(out xf1, t); 76 | sweep2.GetXForm(out xf2, t); 77 | 78 | // Get the distance between shapes. 79 | distance = Collision.Distance(out p1, out p2, shape1, xf1, shape2, xf2); 80 | 81 | if (iter == 0) 82 | { 83 | // Compute a reasonable target distance to give some breathing room 84 | // for conservative advancement. 85 | if (distance > 2.0f * Settings.ToiSlop) 86 | { 87 | targetDistance = 1.5f * Settings.ToiSlop; 88 | } 89 | else 90 | { 91 | targetDistance = Common.Math.Max(0.05f * Settings.ToiSlop, distance - 0.5f * Settings.ToiSlop); 92 | } 93 | } 94 | 95 | if (distance - targetDistance < 0.05f * Settings.ToiSlop || iter == k_maxIterations) 96 | { 97 | break; 98 | } 99 | 100 | normal = p2 - p1; 101 | normal.Normalize(); 102 | 103 | // Compute upper bound on remaining movement. 104 | float approachVelocityBound = Vec2.Dot(normal, v1 - v2) + 105 | Common.Math.Abs(omega1) * r1 + Common.Math.Abs(omega2) * r2; 106 | if (Common.Math.Abs(approachVelocityBound) < Common.Settings.FLT_EPSILON) 107 | { 108 | alpha = 1.0f; 109 | break; 110 | } 111 | 112 | // Get the conservative time increment. Don't advance all the way. 113 | float dAlpha = (distance - targetDistance) / approachVelocityBound; 114 | //float dt = (distance - 0.5f * Settings.LinearSlop) / approachVelocityBound; 115 | float newAlpha = alpha + dAlpha; 116 | 117 | // The shapes may be moving apart or a safe distance apart. 118 | if (newAlpha < 0.0f || 1.0f < newAlpha) 119 | { 120 | alpha = 1.0f; 121 | break; 122 | } 123 | 124 | // Ensure significant advancement. 125 | if (newAlpha < (1.0f + 100.0f * Common.Settings.FLT_EPSILON) * alpha) 126 | { 127 | break; 128 | } 129 | 130 | alpha = newAlpha; 131 | 132 | ++iter; 133 | } 134 | 135 | return alpha; 136 | } 137 | } 138 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/Gears.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class Gears : Test 33 | { 34 | RevoluteJoint _joint1; 35 | RevoluteJoint _joint2; 36 | PrismaticJoint _joint3; 37 | GearJoint _joint4; 38 | GearJoint _joint5; 39 | 40 | public Gears() 41 | { 42 | Body ground = null; 43 | { 44 | BodyDef bd = new BodyDef(); 45 | bd.Position.Set(0.0f, -10.0f); 46 | ground = _world.CreateBody(bd); 47 | 48 | PolygonDef sd = new PolygonDef(); 49 | sd.SetAsBox(50.0f, 10.0f); 50 | ground.CreateShape(sd); 51 | } 52 | 53 | { 54 | CircleDef circle1 = new CircleDef(); 55 | circle1.Radius = 1.0f; 56 | circle1.Density = 5.0f; 57 | 58 | CircleDef circle2 = new CircleDef(); 59 | circle2.Radius = 2.0f; 60 | circle2.Density = 5.0f; 61 | 62 | PolygonDef box = new PolygonDef(); 63 | box.SetAsBox(0.5f, 5.0f); 64 | box.Density = 5.0f; 65 | 66 | BodyDef bd1 = new BodyDef(); 67 | bd1.Position.Set(-3.0f, 12.0f); 68 | Body body1 = _world.CreateBody(bd1); 69 | body1.CreateShape(circle1); 70 | body1.SetMassFromShapes(); 71 | 72 | RevoluteJointDef jd1 = new RevoluteJointDef(); 73 | jd1.Body1 = ground; 74 | jd1.Body2 = body1; 75 | jd1.LocalAnchor1 = ground.GetLocalPoint(bd1.Position); 76 | jd1.LocalAnchor2 = body1.GetLocalPoint(bd1.Position); 77 | jd1.ReferenceAngle = body1.GetAngle() - ground.GetAngle(); 78 | _joint1 = (RevoluteJoint)_world.CreateJoint(jd1); 79 | 80 | BodyDef bd2 = new BodyDef(); 81 | bd2.Position.Set(0.0f, 12.0f); 82 | Body body2 = _world.CreateBody(bd2); 83 | body2.CreateShape(circle2); 84 | body2.SetMassFromShapes(); 85 | 86 | RevoluteJointDef jd2 = new RevoluteJointDef(); 87 | jd2.Initialize(ground, body2, bd2.Position); 88 | _joint2 = (RevoluteJoint)_world.CreateJoint(jd2); 89 | 90 | BodyDef bd3 = new BodyDef(); 91 | bd3.Position.Set(2.5f, 12.0f); 92 | Body body3 = _world.CreateBody(bd3); 93 | body3.CreateShape(box); 94 | body3.SetMassFromShapes(); 95 | 96 | PrismaticJointDef jd3 = new PrismaticJointDef(); 97 | jd3.Initialize(ground, body3, bd3.Position, new Vec2(0.0f, 1.0f)); 98 | jd3.LowerTranslation = -5.0f; 99 | jd3.UpperTranslation = 5.0f; 100 | jd3.EnableLimit = true; 101 | 102 | _joint3 = (PrismaticJoint)_world.CreateJoint(jd3); 103 | 104 | GearJointDef jd4 = new GearJointDef(); 105 | jd4.Body1 = body1; 106 | jd4.Body2 = body2; 107 | jd4.Joint1 = _joint1; 108 | jd4.Joint2 = _joint2; 109 | jd4.Ratio = circle2.Radius / circle1.Radius; 110 | _joint4 = (GearJoint)_world.CreateJoint(jd4); 111 | 112 | GearJointDef jd5 = new GearJointDef(); 113 | jd5.Body1 = body2; 114 | jd5.Body2 = body3; 115 | jd5.Joint1 = _joint2; 116 | jd5.Joint2 = _joint3; 117 | jd5.Ratio = -1.0f / circle2.Radius; 118 | _joint5 = (GearJoint)_world.CreateJoint(jd5); 119 | } 120 | } 121 | 122 | public static Test Create() 123 | { 124 | return new Gears(); 125 | } 126 | 127 | public override void Step(Settings settings) 128 | { 129 | base.Step(settings); 130 | 131 | float ratio, value; 132 | 133 | ratio = _joint4.Ratio; 134 | value = _joint1.JointAngle + ratio * _joint2.JointAngle; 135 | StringBuilder strBld = new StringBuilder(); 136 | strBld.AppendFormat("theta1 + {0} * theta2 = {1}", new object[]{ratio,value}); 137 | OpenGLDebugDraw.DrawString(5, _textLine, strBld.ToString()); 138 | _textLine += 15; 139 | 140 | ratio = _joint5.Ratio; 141 | value = _joint2.JointAngle + ratio * _joint3.JointTranslation; 142 | strBld = new StringBuilder(); 143 | strBld.AppendFormat("theta2 + {0} * delta = {1}", new object[] { ratio, value }); 144 | OpenGLDebugDraw.DrawString(5, _textLine, strBld.ToString()); 145 | _textLine += 15; 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/MotorsAndLimits.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class MotorsAndLimits : Test 33 | { 34 | RevoluteJoint _joint1; 35 | RevoluteJoint _joint2; 36 | PrismaticJoint _joint3; 37 | 38 | public MotorsAndLimits() 39 | { 40 | Body ground = null; 41 | { 42 | PolygonDef sd = new PolygonDef(); 43 | sd.SetAsBox(50.0f, 10.0f); 44 | 45 | BodyDef bd = new BodyDef(); 46 | bd.Position.Set(0.0f, -10.0f); 47 | ground = _world.CreateBody(bd); 48 | ground.CreateShape(sd); 49 | } 50 | 51 | { 52 | PolygonDef sd = new PolygonDef(); 53 | sd.SetAsBox(2.0f, 0.5f); 54 | sd.Density = 5.0f; 55 | sd.Friction = 0.05f; 56 | 57 | BodyDef bd = new BodyDef(); 58 | 59 | RevoluteJointDef rjd = new RevoluteJointDef(); 60 | 61 | Body body = null; 62 | Body prevBody = ground; 63 | const float y = 8.0f; 64 | 65 | bd.Position.Set(3.0f, y); 66 | body = _world.CreateBody(bd); 67 | body.CreateShape(sd); 68 | body.SetMassFromShapes(); 69 | 70 | rjd.Initialize(prevBody, body, new Vec2(0.0f, y)); 71 | rjd.MotorSpeed = 1.0f * Box2DX.Common.Settings.Pi; 72 | rjd.MaxMotorTorque = 10000.0f; 73 | rjd.EnableMotor = true; 74 | 75 | _joint1 = (RevoluteJoint)_world.CreateJoint(rjd); 76 | 77 | prevBody = body; 78 | 79 | bd.Position.Set(9.0f, y); 80 | body = _world.CreateBody(bd); 81 | body.CreateShape(sd); 82 | body.SetMassFromShapes(); 83 | 84 | rjd.Initialize(prevBody, body, new Vec2(6.0f, y)); 85 | rjd.MotorSpeed = 0.5f * Box2DX.Common.Settings.Pi; 86 | rjd.MaxMotorTorque = 2000.0f; 87 | rjd.EnableMotor = true; 88 | rjd.LowerAngle = -0.5f * Box2DX.Common.Settings.Pi; 89 | rjd.UpperAngle = 0.5f * Box2DX.Common.Settings.Pi; 90 | rjd.EnableLimit = true; 91 | 92 | _joint2 = (RevoluteJoint)_world.CreateJoint(rjd); 93 | 94 | bd.Position.Set(-10.0f, 10.0f); 95 | bd.Angle = 0.5f * Box2DX.Common.Settings.Pi; 96 | body = _world.CreateBody(bd); 97 | body.CreateShape(sd); 98 | body.SetMassFromShapes(); 99 | 100 | PrismaticJointDef pjd = new PrismaticJointDef(); 101 | pjd.Initialize(ground, body, new Vec2(-10.0f, 10.0f), new Vec2(1.0f, 0.0f)); 102 | pjd.MotorSpeed = 10.0f; 103 | pjd.MaxMotorForce = 1000.0f; 104 | pjd.EnableMotor = true; 105 | pjd.LowerTranslation = 0.0f; 106 | pjd.UpperTranslation = 20.0f; 107 | pjd.EnableLimit = true; 108 | 109 | _joint3 = (PrismaticJoint)_world.CreateJoint(pjd); 110 | } 111 | } 112 | 113 | public override void Step(Settings settings) 114 | { 115 | base.Step(settings); 116 | OpenGLDebugDraw.DrawString(5, _textLine, "Keys: (l) limits, (m) motors, (p) prismatic speed"); 117 | _textLine += 15; 118 | float torque1 = _joint1.MotorTorque; 119 | float torque2 = _joint2.MotorTorque; 120 | float force3 = _joint3.MotorForce; 121 | StringBuilder strBld = new StringBuilder(); 122 | strBld.AppendFormat("Motor Torque = {0}, {1} : Motor Force = {2}", 123 | new object[] { torque1, torque2, force3 }); 124 | OpenGLDebugDraw.DrawString(5, _textLine, strBld.ToString()); 125 | _textLine += 15; 126 | } 127 | 128 | public override void Keyboard(System.Windows.Forms.Keys key) 129 | { 130 | switch (key) 131 | { 132 | case System.Windows.Forms.Keys.L: 133 | _joint2.EnableLimit(!_joint2.IsLimitEnabled); 134 | _joint3.EnableLimit(!_joint3.IsLimitEnabled); 135 | _joint2.GetBody1().WakeUp(); 136 | _joint3.GetBody2().WakeUp(); 137 | break; 138 | 139 | case System.Windows.Forms.Keys.M: 140 | _joint1.EnableMotor(!_joint1.IsMotorEnabled); 141 | _joint2.EnableMotor(!_joint2.IsMotorEnabled); 142 | _joint3.EnableMotor(!_joint3.IsMotorEnabled); 143 | _joint2.GetBody1().WakeUp(); 144 | _joint3.GetBody2().WakeUp(); 145 | break; 146 | 147 | case System.Windows.Forms.Keys.P: 148 | _joint3.GetBody2().WakeUp(); 149 | _joint3.MotorSpeed = (-_joint3.MotorSpeed); 150 | break; 151 | } 152 | } 153 | 154 | public static Test Create() 155 | { 156 | return new MotorsAndLimits(); 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /src/Common/Vec2.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | namespace Box2DX.Common 27 | { 28 | /// 29 | /// A 2D column vector. 30 | /// 31 | public struct Vec2 32 | { 33 | public float X, Y; 34 | 35 | /// 36 | /// Construct using coordinates. 37 | /// 38 | public Vec2(float x, float y) 39 | { 40 | X = x; 41 | Y = y; 42 | } 43 | 44 | /// 45 | /// Set this vector to all zeros. 46 | /// 47 | public void SetZero() { X = 0.0f; Y = 0.0f; } 48 | 49 | /// 50 | /// Set this vector to some specified coordinates. 51 | /// 52 | public void Set(float x, float y) { X = x; Y = y; } 53 | 54 | /// 55 | /// Get the length of this vector (the norm). 56 | /// 57 | public float Length() 58 | { 59 | return (float)System.Math.Sqrt(X * X + Y * Y); 60 | } 61 | 62 | /// 63 | /// Get the length squared. For performance, use this instead of 64 | /// Length (if possible). 65 | /// 66 | public float LengthSquared() 67 | { 68 | return X * X + Y * Y; 69 | } 70 | 71 | /// 72 | /// Convert this vector into a unit vector. Returns the length. 73 | /// 74 | public float Normalize() 75 | { 76 | float length = Length(); 77 | if (length < Math.FLOAT32_EPSILON) 78 | { 79 | return 0.0f; 80 | } 81 | float invLength = 1.0f / length; 82 | X *= invLength; 83 | Y *= invLength; 84 | 85 | return length; 86 | } 87 | 88 | /// 89 | /// Does this vector contain finite coordinates? 90 | /// 91 | public bool IsValid 92 | { 93 | get { return Math.IsValid(X) && Math.IsValid(Y); } 94 | } 95 | 96 | /// 97 | /// Negate this vector. 98 | /// 99 | public static Vec2 operator -(Vec2 v1) 100 | { 101 | Vec2 v = new Vec2(); 102 | v.Set(-v1.X, -v1.Y); 103 | return v; 104 | } 105 | 106 | public static Vec2 operator +(Vec2 v1, Vec2 v2) 107 | { 108 | Vec2 v = new Vec2(); 109 | v.Set(v1.X + v2.X, v1.Y + v2.Y); 110 | return v; 111 | } 112 | 113 | public static Vec2 operator -(Vec2 v1, Vec2 v2) 114 | { 115 | Vec2 v = new Vec2(); 116 | v.Set(v1.X - v2.X, v1.Y - v2.Y); 117 | return v; 118 | } 119 | 120 | public static Vec2 operator *(Vec2 v1, float a) 121 | { 122 | Vec2 v = new Vec2(); 123 | v.Set(v1.X * a, v1.Y * a); 124 | return v; 125 | } 126 | 127 | public static Vec2 operator *(float a, Vec2 v1) 128 | { 129 | Vec2 v = new Vec2(); 130 | v.Set(v1.X * a, v1.Y * a); 131 | return v; 132 | } 133 | 134 | public static bool operator ==(Vec2 a, Vec2 b) 135 | { 136 | return a.X == b.X && a.Y == b.Y; 137 | } 138 | 139 | public static bool operator !=(Vec2 a, Vec2 b) 140 | { 141 | return a.X != b.X && a.Y != b.Y; 142 | } 143 | 144 | public static Vec2 Zero { get { return new Vec2(0, 0); } } 145 | 146 | /// 147 | /// Peform the dot product on two vectors. 148 | /// 149 | public static float Dot(Vec2 a, Vec2 b) 150 | { 151 | return a.X * b.X + a.Y * b.Y; 152 | } 153 | 154 | /// 155 | /// Perform the cross product on two vectors. In 2D this produces a scalar. 156 | /// 157 | public static float Cross(Vec2 a, Vec2 b) 158 | { 159 | return a.X * b.Y - a.Y * b.X; 160 | } 161 | 162 | /// 163 | /// Perform the cross product on a vector and a scalar. 164 | /// In 2D this produces a vector. 165 | /// 166 | public static Vec2 Cross(Vec2 a, float s) 167 | { 168 | Vec2 v = new Vec2(); 169 | v.Set(s * a.Y, -s * a.X); 170 | return v; 171 | } 172 | 173 | /// 174 | /// Perform the cross product on a scalar and a vector. 175 | /// In 2D this produces a vector. 176 | /// 177 | public static Vec2 Cross(float s, Vec2 a) 178 | { 179 | Vec2 v = new Vec2(); 180 | v.Set(-s * a.Y, s * a.X); 181 | return v; 182 | } 183 | 184 | public static float Distance(Vec2 a, Vec2 b) 185 | { 186 | Vec2 c = a - b; 187 | return c.Length(); 188 | } 189 | 190 | public static float DistanceSquared(Vec2 a, Vec2 b) 191 | { 192 | Vec2 c = a - b; 193 | return Vec2.Dot(c, c); 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/CompoundShapes.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class CompoundShapes : Test 33 | { 34 | public CompoundShapes() 35 | { 36 | { 37 | BodyDef bd = new BodyDef(); 38 | bd.Position.Set(0.0f, -10.0f); 39 | Body body = _world.CreateBody(bd); 40 | 41 | PolygonDef sd = new PolygonDef(); 42 | sd.SetAsBox(50.0f, 10.0f); 43 | body.CreateShape(sd); 44 | } 45 | 46 | { 47 | CircleDef sd1 = new CircleDef(); 48 | sd1.Radius = 0.5f; 49 | sd1.LocalPosition.Set(-0.5f, 0.5f); 50 | sd1.Density = 2.0f; 51 | 52 | CircleDef sd2 = new CircleDef(); 53 | sd2.Radius = 0.5f; 54 | sd2.LocalPosition.Set(0.5f, 0.5f); 55 | sd2.Density = 0.0f; // massless 56 | 57 | for (int i = 0; i < 10; ++i) 58 | { 59 | float x = Box2DX.Common.Math.Random(-0.1f, 0.1f); 60 | BodyDef bd = new BodyDef(); 61 | bd.Position.Set(x + 5.0f, 1.05f + 2.5f * i); 62 | bd.Angle = Box2DX.Common.Math.Random(-Box2DX.Common.Settings.Pi, Box2DX.Common.Settings.Pi); 63 | Body body = _world.CreateBody(bd); 64 | body.CreateShape(sd1); 65 | body.CreateShape(sd2); 66 | body.SetMassFromShapes(); 67 | } 68 | } 69 | 70 | { 71 | PolygonDef sd1 = new PolygonDef(); 72 | sd1.SetAsBox(0.25f, 0.5f); 73 | sd1.Density = 2.0f; 74 | 75 | PolygonDef sd2 = new PolygonDef(); 76 | sd2.SetAsBox(0.25f, 0.5f, new Vec2(0.0f, -0.5f), 0.5f * Box2DX.Common.Settings.Pi); 77 | sd2.Density = 2.0f; 78 | 79 | for (int i = 0; i < 10; ++i) 80 | { 81 | float x = Box2DX.Common.Math.Random(-0.1f, 0.1f); 82 | BodyDef bd = new BodyDef(); 83 | bd.Position.Set(x - 5.0f, 1.05f + 2.5f * i); 84 | bd.Angle = Box2DX.Common.Math.Random(-Box2DX.Common.Settings.Pi, Box2DX.Common.Settings.Pi); 85 | Body body = _world.CreateBody(bd); 86 | body.CreateShape(sd1); 87 | body.CreateShape(sd2); 88 | body.SetMassFromShapes(); 89 | } 90 | } 91 | 92 | { 93 | XForm xf1 = new XForm(); 94 | xf1.R.Set(0.3524f * Box2DX.Common.Settings.Pi); 95 | xf1.Position = Box2DX.Common.Math.Mul(xf1.R, new Vec2(1.0f, 0.0f)); 96 | 97 | PolygonDef sd1 = new PolygonDef(); 98 | sd1.VertexCount = 3; 99 | sd1.Vertices[0] = Box2DX.Common.Math.Mul(xf1, new Vec2(-1.0f, 0.0f)); 100 | sd1.Vertices[1] = Box2DX.Common.Math.Mul(xf1, new Vec2(1.0f, 0.0f)); 101 | sd1.Vertices[2] = Box2DX.Common.Math.Mul(xf1, new Vec2(0.0f, 0.5f)); 102 | sd1.Density = 2.0f; 103 | 104 | XForm xf2 = new XForm(); 105 | xf2.R.Set(-0.3524f * Box2DX.Common.Settings.Pi); 106 | xf2.Position = Box2DX.Common.Math.Mul(xf2.R, new Vec2(-1.0f, 0.0f)); 107 | 108 | PolygonDef sd2 = new PolygonDef(); 109 | sd2.VertexCount = 3; 110 | sd2.Vertices[0] = Box2DX.Common.Math.Mul(xf2, new Vec2(-1.0f, 0.0f)); 111 | sd2.Vertices[1] = Box2DX.Common.Math.Mul(xf2, new Vec2(1.0f, 0.0f)); 112 | sd2.Vertices[2] = Box2DX.Common.Math.Mul(xf2, new Vec2(0.0f, 0.5f)); 113 | sd2.Density = 2.0f; 114 | 115 | for (int i = 0; i < 10; ++i) 116 | { 117 | float x = Box2DX.Common.Math.Random(-0.1f, 0.1f); 118 | BodyDef bd = new BodyDef(); 119 | bd.Position.Set(x, 2.05f + 2.5f * i); 120 | bd.Angle = 0.0f; 121 | Body body = _world.CreateBody(bd); 122 | body.CreateShape(sd1); 123 | body.CreateShape(sd2); 124 | body.SetMassFromShapes(); 125 | } 126 | } 127 | 128 | { 129 | PolygonDef sd_bottom = new PolygonDef(); 130 | sd_bottom.SetAsBox(1.5f, 0.15f); 131 | sd_bottom.Density = 4.0f; 132 | 133 | PolygonDef sd_left = new PolygonDef(); 134 | sd_left.SetAsBox(0.15f, 2.7f, new Vec2(-1.45f, 2.35f), 0.2f); 135 | sd_left.Density = 4.0f; 136 | 137 | PolygonDef sd_right = new PolygonDef(); 138 | sd_right.SetAsBox(0.15f, 2.7f, new Vec2(1.45f, 2.35f), -0.2f); 139 | sd_right.Density = 4.0f; 140 | 141 | BodyDef bd = new BodyDef(); 142 | bd.Position.Set(0.0f, 2.0f); 143 | Body body = _world.CreateBody(bd); 144 | body.CreateShape(sd_bottom); 145 | body.CreateShape(sd_left); 146 | body.CreateShape(sd_right); 147 | body.SetMassFromShapes(); 148 | } 149 | } 150 | 151 | public static Test Create() 152 | { 153 | return new CompoundShapes(); 154 | } 155 | } 156 | } -------------------------------------------------------------------------------- /src/Dynamics/Contacts/PolyContact.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Collision; 27 | using Box2DX.Common; 28 | 29 | namespace Box2DX.Dynamics 30 | { 31 | public class PolygonContact : Contact 32 | { 33 | public Manifold _manifold = new Manifold(); 34 | 35 | public override Manifold[] GetManifolds() 36 | { 37 | return new Manifold[] { _manifold }; 38 | } 39 | 40 | public PolygonContact(Shape s1, Shape s2) 41 | : base(s1, s2) 42 | { 43 | Box2DXDebug.Assert(_shape1.GetType() == ShapeType.PolygonShape); 44 | Box2DXDebug.Assert(_shape2.GetType() == ShapeType.PolygonShape); 45 | _manifold.PointCount = 0; 46 | } 47 | 48 | public override void Evaluate(ContactListener listener) 49 | { 50 | Body b1 = _shape1.GetBody(); 51 | Body b2 = _shape2.GetBody(); 52 | #warning "needfix" 53 | //memcpy(&m0, &m_manifold, sizeof(b2Manifold)); 54 | Manifold m0 = _manifold.Clone(); 55 | 56 | Collision.Collision.CollidePolygons(ref _manifold, (PolygonShape)_shape1, b1.GetXForm(), 57 | (PolygonShape)_shape2, b2.GetXForm()); 58 | 59 | bool[] persisted = new bool[] { false, false }; 60 | 61 | ContactPoint cp = new ContactPoint(); 62 | cp.Shape1 = _shape1; 63 | cp.Shape2 = _shape2; 64 | cp.Friction = Settings.MixFriction(_shape1.Friction, _shape2.Friction); 65 | cp.Restitution = Settings.MixRestitution(_shape1.Restitution, _shape2.Restitution); 66 | 67 | // Match contact ids to facilitate warm starting. 68 | if (_manifold.PointCount > 0) 69 | { 70 | // Match old contact ids to new contact ids and copy the 71 | // stored impulses to warm start the solver. 72 | for (int i = 0; i < _manifold.PointCount; ++i) 73 | { 74 | ManifoldPoint mp = _manifold.Points[i]; 75 | mp.NormalImpulse = 0.0f; 76 | mp.TangentImpulse = 0.0f; 77 | bool found = false; 78 | ContactID id = mp.ID; 79 | 80 | for (int j = 0; j < m0.PointCount; ++j) 81 | { 82 | if (persisted[j] == true) 83 | { 84 | continue; 85 | } 86 | 87 | ManifoldPoint mp0 = m0.Points[j]; 88 | 89 | if (mp0.ID.Key == id.Key) 90 | { 91 | persisted[j] = true; 92 | mp.NormalImpulse = mp0.NormalImpulse; 93 | mp.TangentImpulse = mp0.TangentImpulse; 94 | 95 | // A persistent point. 96 | found = true; 97 | 98 | // Report persistent point. 99 | if (listener != null) 100 | { 101 | cp.Position = b1.GetWorldPoint(mp.LocalPoint1); 102 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); 103 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); 104 | cp.Velocity = v2 - v1; 105 | cp.Normal = _manifold.Normal; 106 | cp.Separation = mp.Separation; 107 | cp.ID = id; 108 | listener.Persist(cp); 109 | } 110 | break; 111 | } 112 | } 113 | 114 | // Report added point. 115 | if (found == false && listener != null) 116 | { 117 | cp.Position = b1.GetWorldPoint(mp.LocalPoint1); 118 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); 119 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); 120 | cp.Velocity = v2 - v1; 121 | cp.Normal = _manifold.Normal; 122 | cp.Separation = mp.Separation; 123 | cp.ID = id; 124 | listener.Add(cp); 125 | } 126 | } 127 | 128 | _manifoldCount = 1; 129 | } 130 | else 131 | { 132 | _manifoldCount = 0; 133 | } 134 | 135 | if (listener == null) 136 | { 137 | return; 138 | } 139 | 140 | // Report removed points. 141 | for (int i = 0; i < m0.PointCount; ++i) 142 | { 143 | if (persisted[i]) 144 | { 145 | continue; 146 | } 147 | 148 | ManifoldPoint mp0 = m0.Points[i]; 149 | cp.Position = b1.GetWorldPoint(mp0.LocalPoint1); 150 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp0.LocalPoint1); 151 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp0.LocalPoint2); 152 | cp.Velocity = v2 - v1; 153 | cp.Normal = m0.Normal; 154 | cp.Separation = mp0.Separation; 155 | cp.ID = mp0.ID; 156 | listener.Remove(cp); 157 | } 158 | } 159 | 160 | new public static Contact Create(Shape shape1, Shape shape2) 161 | { 162 | return new PolygonContact(shape1, shape2); 163 | } 164 | 165 | new public static void Destroy(Contact contact) 166 | { 167 | contact = null; 168 | } 169 | } 170 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/CollisionFiltering.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.Google.Com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.Gphysics.Com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class CollisionFiltering : Test 33 | { 34 | // This is a test of collision filtering. 35 | // There is a triangle, a box, and a circle. 36 | // There are 6 shapes. 3 large and 3 small. 37 | // The 3 small ones always collide. 38 | // The 3 large ones never collide. 39 | // The boxes don't collide with triangles (except if both are small). 40 | const short k_smallGroup = 1; 41 | const short k_largeGroup = -1; 42 | 43 | const ushort k_defaultCategory = 0x0001; 44 | const ushort k_triangleCategory = 0x0002; 45 | const ushort k_boxCategory = 0x0004; 46 | const ushort k_circleCategory = 0x0008; 47 | 48 | const ushort k_triangleMask = 0xFFFF; 49 | readonly ushort k_boxMask = 0xFFFF ^ k_triangleCategory; 50 | const ushort k_circleMask = 0xFFFF; 51 | 52 | public CollisionFiltering() 53 | { 54 | // Ground body 55 | { 56 | PolygonDef sd = new PolygonDef(); 57 | sd.SetAsBox(50.0f, 10.0f); 58 | sd.Friction = 0.3f; 59 | 60 | BodyDef bd = new BodyDef(); 61 | bd.Position.Set(0.0f, -10.0f); 62 | 63 | Body ground = _world.CreateBody(bd); 64 | ground.CreateShape(sd); 65 | } 66 | 67 | // Small triangle 68 | PolygonDef triangleShapeDef = new PolygonDef(); 69 | triangleShapeDef.VertexCount = 3; 70 | triangleShapeDef.Vertices[0].Set(-1.0f, 0.0f); 71 | triangleShapeDef.Vertices[1].Set(1.0f, 0.0f); 72 | triangleShapeDef.Vertices[2].Set(0.0f, 2.0f); 73 | triangleShapeDef.Density = 1.0f; 74 | 75 | triangleShapeDef.Filter.GroupIndex = k_smallGroup; 76 | triangleShapeDef.Filter.CategoryBits = k_triangleCategory; 77 | triangleShapeDef.Filter.MaskBits = k_triangleMask; 78 | 79 | BodyDef triangleBodyDef = new BodyDef(); 80 | triangleBodyDef.Position.Set(-5.0f, 2.0f); 81 | 82 | Body body1 = _world.CreateBody(triangleBodyDef); 83 | body1.CreateShape(triangleShapeDef); 84 | body1.SetMassFromShapes(); 85 | 86 | // Large triangle (recycle definitions) 87 | triangleShapeDef.Vertices[0] *= 2.0f; 88 | triangleShapeDef.Vertices[1] *= 2.0f; 89 | triangleShapeDef.Vertices[2] *= 2.0f; 90 | triangleShapeDef.Filter.GroupIndex = k_largeGroup; 91 | triangleBodyDef.Position.Set(-5.0f, 6.0f); 92 | triangleBodyDef.FixedRotation = true; // look at me! 93 | 94 | Body body2 = _world.CreateBody(triangleBodyDef); 95 | body2.CreateShape(triangleShapeDef); 96 | body2.SetMassFromShapes(); 97 | 98 | // Small box 99 | PolygonDef boxShapeDef = new PolygonDef(); 100 | boxShapeDef.SetAsBox(1.0f, 0.5f); 101 | boxShapeDef.Density = 1.0f; 102 | 103 | boxShapeDef.Filter.GroupIndex = k_smallGroup; 104 | boxShapeDef.Filter.CategoryBits = k_boxCategory; 105 | boxShapeDef.Filter.MaskBits = k_boxMask; 106 | 107 | BodyDef boxBodyDef = new BodyDef(); 108 | boxBodyDef.Position.Set(0.0f, 2.0f); 109 | 110 | Body body3 = _world.CreateBody(boxBodyDef); 111 | body3.CreateShape(boxShapeDef); 112 | body3.SetMassFromShapes(); 113 | 114 | // Large box (recycle definitions) 115 | boxShapeDef.SetAsBox(2.0f, 1.0f); 116 | boxShapeDef.Filter.GroupIndex = k_largeGroup; 117 | boxBodyDef.Position.Set(0.0f, 6.0f); 118 | 119 | Body body4 = _world.CreateBody(boxBodyDef); 120 | body4.CreateShape(boxShapeDef); 121 | body4.SetMassFromShapes(); 122 | 123 | // Small circle 124 | CircleDef circleShapeDef = new CircleDef(); 125 | circleShapeDef.Radius = 1.0f; 126 | circleShapeDef.Density = 1.0f; 127 | 128 | circleShapeDef.Filter.GroupIndex = k_smallGroup; 129 | circleShapeDef.Filter.CategoryBits = k_circleCategory; 130 | circleShapeDef.Filter.MaskBits = k_circleMask; 131 | 132 | BodyDef circleBodyDef = new BodyDef(); 133 | circleBodyDef.Position.Set(5.0f, 2.0f); 134 | 135 | Body body5 = _world.CreateBody(circleBodyDef); 136 | body5.CreateShape(circleShapeDef); 137 | body5.SetMassFromShapes(); 138 | 139 | // Large circle 140 | circleShapeDef.Radius *= 2.0f; 141 | circleShapeDef.Filter.GroupIndex = k_largeGroup; 142 | circleBodyDef.Position.Set(5.0f, 6.0f); 143 | 144 | Body body6 = _world.CreateBody(circleBodyDef); 145 | body6.CreateShape(circleShapeDef); 146 | body6.SetMassFromShapes(); 147 | } 148 | 149 | public static Test Create() 150 | { 151 | return new CollisionFiltering(); 152 | } 153 | } 154 | } -------------------------------------------------------------------------------- /src/Dynamics/Contacts/PolyAndCircleContact.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Collision; 27 | using Box2DX.Common; 28 | 29 | namespace Box2DX.Dynamics 30 | { 31 | public class PolyAndCircleContact : Contact 32 | { 33 | public Manifold _manifold = new Manifold(); 34 | 35 | public override Manifold[] GetManifolds() 36 | { 37 | return new Manifold[] { _manifold }; 38 | } 39 | 40 | public PolyAndCircleContact(Shape s1, Shape s2) 41 | : base(s1, s2) 42 | { 43 | Box2DXDebug.Assert(_shape1.GetType() == ShapeType.PolygonShape); 44 | Box2DXDebug.Assert(_shape2.GetType() == ShapeType.CircleShape); 45 | _manifold.PointCount = 0; 46 | } 47 | 48 | public override void Evaluate(ContactListener listener) 49 | { 50 | Body b1 = _shape1.GetBody(); 51 | Body b2 = _shape2.GetBody(); 52 | #warning "needfix" 53 | //memcpy(&m0, &m_manifold, sizeof(b2Manifold)); 54 | Manifold m0 = _manifold.Clone(); 55 | 56 | Collision.Collision.CollidePolygonAndCircle(ref _manifold, (PolygonShape)_shape1, b1.GetXForm(), 57 | (CircleShape)_shape2, b2.GetXForm()); 58 | 59 | bool[] persisted = new bool[] { false, false }; 60 | 61 | ContactPoint cp = new ContactPoint(); 62 | cp.Shape1 = _shape1; 63 | cp.Shape2 = _shape2; 64 | cp.Friction = Settings.MixFriction(_shape1.Friction, _shape2.Friction); 65 | cp.Restitution = Settings.MixRestitution(_shape1.Restitution, _shape2.Restitution); 66 | 67 | // Match contact ids to facilitate warm starting. 68 | if (_manifold.PointCount > 0) 69 | { 70 | // Match old contact ids to new contact ids and copy the 71 | // stored impulses to warm start the solver. 72 | for (int i = 0; i < _manifold.PointCount; ++i) 73 | { 74 | ManifoldPoint mp = _manifold.Points[i]; 75 | mp.NormalImpulse = 0.0f; 76 | mp.TangentImpulse = 0.0f; 77 | bool found = false; 78 | ContactID id = mp.ID; 79 | 80 | for (int j = 0; j < m0.PointCount; ++j) 81 | { 82 | if (persisted[j] == true) 83 | { 84 | continue; 85 | } 86 | 87 | ManifoldPoint mp0 = m0.Points[j]; 88 | 89 | if (mp0.ID.Key == id.Key) 90 | { 91 | persisted[j] = true; 92 | mp.NormalImpulse = mp0.NormalImpulse; 93 | mp.TangentImpulse = mp0.TangentImpulse; 94 | 95 | // A persistent point. 96 | found = true; 97 | 98 | // Report persistent point. 99 | if (listener != null) 100 | { 101 | cp.Position = b1.GetWorldPoint(mp.LocalPoint1); 102 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); 103 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); 104 | cp.Velocity = v2 - v1; 105 | cp.Normal = _manifold.Normal; 106 | cp.Separation = mp.Separation; 107 | cp.ID = id; 108 | listener.Persist(cp); 109 | } 110 | break; 111 | } 112 | } 113 | 114 | // Report added point. 115 | if (found == false && listener != null) 116 | { 117 | cp.Position = b1.GetWorldPoint(mp.LocalPoint1); 118 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp.LocalPoint1); 119 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp.LocalPoint2); 120 | cp.Velocity = v2 - v1; 121 | cp.Normal = _manifold.Normal; 122 | cp.Separation = mp.Separation; 123 | cp.ID = id; 124 | listener.Add(cp); 125 | } 126 | } 127 | 128 | _manifoldCount = 1; 129 | } 130 | else 131 | { 132 | _manifoldCount = 0; 133 | } 134 | 135 | if (listener == null) 136 | { 137 | return; 138 | } 139 | 140 | // Report removed points. 141 | for (int i = 0; i < m0.PointCount; ++i) 142 | { 143 | if (persisted[i]) 144 | { 145 | continue; 146 | } 147 | 148 | ManifoldPoint mp0 = m0.Points[i]; 149 | cp.Position = b1.GetWorldPoint(mp0.LocalPoint1); 150 | Vec2 v1 = b1.GetLinearVelocityFromLocalPoint(mp0.LocalPoint1); 151 | Vec2 v2 = b2.GetLinearVelocityFromLocalPoint(mp0.LocalPoint2); 152 | cp.Velocity = v2 - v1; 153 | cp.Normal = m0.Normal; 154 | cp.Separation = mp0.Separation; 155 | cp.ID = mp0.ID; 156 | listener.Remove(cp); 157 | } 158 | } 159 | 160 | new public static Contact Create(Shape shape1, Shape shape2) 161 | { 162 | return new PolyAndCircleContact(shape1, shape2); 163 | } 164 | 165 | new public static void Destroy(Contact contact) 166 | { 167 | contact = null; 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /Examples/TestBed/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/PolyShapes.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class PolyShapes : Test 33 | { 34 | const int k_maxBodies = 256; 35 | 36 | int bodyIndex; 37 | Body[] bodies = new Body[k_maxBodies]; 38 | PolygonDef[] sds = new PolygonDef[4]; 39 | CircleDef circleDef = new CircleDef(); 40 | 41 | public PolyShapes() 42 | { 43 | // Ground body 44 | { 45 | PolygonDef sd = new PolygonDef(); 46 | sd.SetAsBox(50.0f, 10.0f); 47 | sd.Friction = 0.3f; 48 | sd.Filter.CategoryBits = 0x0001; 49 | 50 | BodyDef bd = new BodyDef(); 51 | bd.Position.Set(0.0f, -10.0f); 52 | Body ground = _world.CreateBody(bd); 53 | ground.CreateShape(sd); 54 | } 55 | 56 | for (int i = 0; i < 4; i++) 57 | { 58 | sds[i] = new PolygonDef(); 59 | } 60 | 61 | sds[0].VertexCount = 3; 62 | sds[0].Vertices[0].Set(-0.5f, 0.0f); 63 | sds[0].Vertices[1].Set(0.5f, 0.0f); 64 | sds[0].Vertices[2].Set(0.0f, 1.5f); 65 | sds[0].Density = 1.0f; 66 | sds[0].Friction = 0.3f; 67 | sds[0].Filter.CategoryBits = 0x0002; 68 | //sds[0].MaskBits = 0x0003; 69 | 70 | sds[1].VertexCount = 3; 71 | sds[1].Vertices[0].Set(-0.1f, 0.0f); 72 | sds[1].Vertices[1].Set(0.1f, 0.0f); 73 | sds[1].Vertices[2].Set(0.0f, 1.5f); 74 | sds[1].Density = 1.0f; 75 | sds[1].Friction = 0.3f; 76 | sds[1].Filter.CategoryBits = 0x0004; 77 | 78 | sds[2].VertexCount = 8; 79 | float w = 1.0f; 80 | float b = w / (2.0f + (float)System.Math.Sqrt(2.0f)); 81 | float s = (float)System.Math.Sqrt(2.0f) * b; 82 | sds[2].Vertices[0].Set(0.5f * s, 0.0f); 83 | sds[2].Vertices[1].Set(0.5f * w, b); 84 | sds[2].Vertices[2].Set(0.5f * w, b + s); 85 | sds[2].Vertices[3].Set(0.5f * s, w); 86 | sds[2].Vertices[4].Set(-0.5f * s, w); 87 | sds[2].Vertices[5].Set(-0.5f * w, b + s); 88 | sds[2].Vertices[6].Set(-0.5f * w, b); 89 | sds[2].Vertices[7].Set(-0.5f * s, 0.0f); 90 | sds[2].Density = 1.0f; 91 | sds[2].Friction = 0.3f; 92 | sds[2].Filter.CategoryBits = 0x0004; 93 | 94 | sds[3].VertexCount = 4; 95 | sds[3].Vertices[0].Set(-0.5f, 0.0f); 96 | sds[3].Vertices[1].Set(0.5f, 0.0f); 97 | sds[3].Vertices[2].Set(0.5f, 1.0f); 98 | sds[3].Vertices[3].Set(-0.5f, 1.0f); 99 | sds[3].Density = 1.0f; 100 | sds[3].Friction = 0.3f; 101 | sds[3].Filter.CategoryBits = 0x0004; 102 | 103 | circleDef.Radius = 0.5f; 104 | circleDef.Density = 1.0f; 105 | 106 | bodyIndex = 0; 107 | //memset(bodies, 0, sizeof(bodies)); 108 | } 109 | 110 | public void Create(int index) 111 | { 112 | if (bodies[bodyIndex] != null) 113 | { 114 | _world.DestroyBody(bodies[bodyIndex]); 115 | bodies[bodyIndex] = null; 116 | } 117 | 118 | BodyDef bd = new BodyDef(); 119 | 120 | float x = Box2DX.Common.Math.Random(-2.0f, 2.0f); 121 | bd.Position.Set(x, 10.0f); 122 | bd.Angle = Box2DX.Common.Math.Random(-Box2DX.Common.Settings.Pi, Box2DX.Common.Settings.Pi); 123 | 124 | if (index == 4) 125 | { 126 | bd.AngularDamping = 0.02f; 127 | } 128 | 129 | bodies[bodyIndex] = _world.CreateBody(bd); 130 | 131 | if (index < 4) 132 | { 133 | bodies[bodyIndex].CreateShape(sds[index]); 134 | } 135 | else 136 | { 137 | bodies[bodyIndex].CreateShape(circleDef); 138 | } 139 | bodies[bodyIndex].SetMassFromShapes(); 140 | 141 | bodyIndex = (bodyIndex + 1) % k_maxBodies; 142 | } 143 | 144 | public void DestroyBody() 145 | { 146 | for (int i = 0; i < k_maxBodies; ++i) 147 | { 148 | if (bodies[i] != null) 149 | { 150 | _world.DestroyBody(bodies[i]); 151 | bodies[i] = null; 152 | return; 153 | } 154 | } 155 | } 156 | 157 | public override void Step(Settings settings) 158 | { 159 | base.Step(settings); 160 | OpenGLDebugDraw.DrawString(5, _textLine, "Press 1-5 to drop stuff"); 161 | _textLine += 15; 162 | } 163 | 164 | public override void Keyboard(System.Windows.Forms.Keys key) 165 | { 166 | int keyKode = 0; 167 | switch (key) 168 | { 169 | case System.Windows.Forms.Keys.D1: 170 | keyKode = 1; 171 | break; 172 | case System.Windows.Forms.Keys.D2: 173 | keyKode = 2; 174 | break; 175 | case System.Windows.Forms.Keys.D3: 176 | keyKode = 3; 177 | break; 178 | case System.Windows.Forms.Keys.D4: 179 | keyKode = 4; 180 | break; 181 | case System.Windows.Forms.Keys.D5: 182 | keyKode = 5; 183 | break; 184 | case System.Windows.Forms.Keys.D: 185 | DestroyBody(); 186 | return; 187 | default: 188 | return; 189 | } 190 | Create(keyKode - 1); 191 | return; 192 | } 193 | 194 | public static Test Create() 195 | { 196 | return new PolyShapes(); 197 | } 198 | } 199 | } -------------------------------------------------------------------------------- /src/Collision/Shapes/CircleShape.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | 28 | namespace Box2DX.Collision 29 | { 30 | /// 31 | /// This structure is used to build circle shapes. 32 | /// 33 | public class CircleDef : ShapeDef 34 | { 35 | public Vec2 LocalPosition; 36 | public float Radius; 37 | 38 | public CircleDef() 39 | { 40 | Type = ShapeType.CircleShape; 41 | LocalPosition = Vec2.Zero; 42 | Radius = 1.0f; 43 | } 44 | } 45 | 46 | /// 47 | /// A circle shape. 48 | /// 49 | public class CircleShape : Shape 50 | { 51 | // Local position in parent body 52 | private Vec2 _localPosition; 53 | // Radius of this circle. 54 | private float _radius; 55 | 56 | internal CircleShape(ShapeDef def) 57 | : base(def) 58 | { 59 | Box2DXDebug.Assert(def.Type == ShapeType.CircleShape); 60 | CircleDef circleDef = (CircleDef)def; 61 | 62 | _type = ShapeType.CircleShape; 63 | _localPosition = circleDef.LocalPosition; 64 | _radius = circleDef.Radius; 65 | } 66 | 67 | internal override void UpdateSweepRadius(Vec2 center) 68 | { 69 | // Update the sweep radius (maximum radius) as measured from 70 | // a local center point. 71 | Vec2 d = _localPosition - center; 72 | _sweepRadius = d.Length() + _radius - Settings.ToiSlop; 73 | } 74 | 75 | public override bool TestPoint(XForm transform, Vec2 p) 76 | { 77 | Vec2 center = transform.Position + Common.Math.Mul(transform.R, _localPosition); 78 | Vec2 d = p - center; 79 | return Vec2.Dot(d, d) <= _radius * _radius; 80 | } 81 | 82 | // Collision Detection in Interactive 3D Environments by Gino van den Bergen 83 | // From Section 3.1.2 84 | // x = s + a * r 85 | // norm(x) = radius 86 | public override SegmentCollide TestSegment(XForm transform, out float lambda, out Vec2 normal, Segment segment, float maxLambda) 87 | { 88 | lambda = 0f; 89 | normal = Vec2.Zero; 90 | 91 | Vec2 position = transform.Position + Common.Math.Mul(transform.R, _localPosition); 92 | Vec2 s = segment.P1 - position; 93 | float b = Vec2.Dot(s, s) - _radius * _radius; 94 | 95 | // Does the segment start inside the circle? 96 | if (b < 0.0f) 97 | { 98 | lambda = 0f; 99 | return SegmentCollide.StartInsideCollide; 100 | } 101 | 102 | // Solve quadratic equation. 103 | Vec2 r = segment.P2 - segment.P1; 104 | float c = Vec2.Dot(s, r); 105 | float rr = Vec2.Dot(r, r); 106 | float sigma = c * c - rr * b; 107 | 108 | // Check for negative discriminant and short segment. 109 | if (sigma < 0.0f || rr < Common.Settings.FLT_EPSILON) 110 | { 111 | return SegmentCollide.MissCollide; 112 | } 113 | 114 | // Find the point of intersection of the line with the circle. 115 | float a = -(c + Common.Math.Sqrt(sigma)); 116 | 117 | // Is the intersection point on the segment? 118 | if (0.0f <= a && a <= maxLambda * rr) 119 | { 120 | a /= rr; 121 | lambda = a; 122 | normal = s + a * r; 123 | normal.Normalize(); 124 | return SegmentCollide.HitCollide; 125 | } 126 | 127 | return SegmentCollide.MissCollide; 128 | } 129 | 130 | public override void ComputeAABB(out AABB aabb, XForm transform) 131 | { 132 | aabb = new AABB(); 133 | 134 | Vec2 p = transform.Position + Common.Math.Mul(transform.R, _localPosition); 135 | aabb.LowerBound.Set(p.X - _radius, p.Y - _radius); 136 | aabb.UpperBound.Set(p.X + _radius, p.Y + _radius); 137 | } 138 | 139 | public override void ComputeSweptAABB(out AABB aabb, XForm transform1, XForm transform2) 140 | { 141 | aabb = new AABB(); 142 | 143 | Vec2 p1 = transform1.Position + Common.Math.Mul(transform1.R, _localPosition); 144 | Vec2 p2 = transform2.Position + Common.Math.Mul(transform2.R, _localPosition); 145 | Vec2 lower = Common.Math.Min(p1, p2); 146 | Vec2 upper = Common.Math.Max(p1, p2); 147 | 148 | aabb.LowerBound.Set(lower.X - _radius, lower.Y - _radius); 149 | aabb.UpperBound.Set(upper.X + _radius, upper.Y + _radius); 150 | } 151 | 152 | public override void ComputeMass(out MassData massData) 153 | { 154 | massData = new MassData(); 155 | 156 | massData.Mass = _density * Settings.Pi * _radius * _radius; 157 | massData.Center = _localPosition; 158 | 159 | // inertia about the local origin 160 | massData.I = massData.Mass * (0.5f * _radius * _radius + Vec2.Dot(_localPosition, _localPosition)); 161 | } 162 | 163 | /// 164 | /// Get the local position of this circle in its parent body. 165 | /// 166 | /// 167 | public Vec2 GetLocalPosition() 168 | { 169 | return _localPosition; 170 | } 171 | 172 | /// 173 | /// Get the radius of this circle. 174 | /// 175 | /// 176 | public float GetRadius() 177 | { 178 | return _radius; 179 | } 180 | } 181 | } -------------------------------------------------------------------------------- /src/Box2DX.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | ..\Build\VCS\Box2DX\obj\ 7 | 9.0.30729 8 | 2.0 9 | {C157BCA5-BAC7-455F-A7DE-59D506D46ECF} 10 | Library 11 | Properties 12 | Box2DX 13 | Box2DX 14 | v4.0 15 | 512 16 | 17 | 18 | 19 | 20 | 3.5 21 | 22 | publish\ 23 | true 24 | Disk 25 | false 26 | Foreground 27 | 7 28 | Days 29 | false 30 | false 31 | true 32 | 0 33 | 1.0.0.%2a 34 | false 35 | false 36 | true 37 | 38 | 39 | ..\Build\VCS\Box2DX\obj\ 40 | true 41 | full 42 | false 43 | ..\Output\ 44 | DEBUG;TRACE 45 | prompt 46 | 4 47 | AnyCPU 48 | true 49 | false 50 | Auto 51 | 52 | 53 | ..\Build\VCS\Box2DX\obj\ 54 | pdbonly 55 | true 56 | ..\Output\ 57 | TRACE 58 | prompt 59 | 4 60 | AnyCPU 61 | true 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | False 110 | .NET Framework 3.5 SP1 111 | true 112 | 113 | 114 | 115 | 116 | 117 | 118 | 125 | -------------------------------------------------------------------------------- /src/Collision/Collision.CollideCircle.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | 28 | namespace Box2DX.Collision 29 | { 30 | public partial class Collision 31 | { 32 | public static void CollideCircles(ref Manifold manifold, 33 | CircleShape circle1, XForm xf1, CircleShape circle2, XForm xf2) 34 | { 35 | manifold.PointCount = 0; 36 | 37 | Vec2 p1 = Common.Math.Mul(xf1, circle1.GetLocalPosition()); 38 | Vec2 p2 = Common.Math.Mul(xf2, circle2.GetLocalPosition()); 39 | 40 | Vec2 d = p2 - p1; 41 | float distSqr = Vec2.Dot(d, d); 42 | float r1 = circle1.GetRadius(); 43 | float r2 = circle2.GetRadius(); 44 | float radiusSum = r1 + r2; 45 | if (distSqr > radiusSum * radiusSum) 46 | { 47 | return; 48 | } 49 | 50 | float separation; 51 | if (distSqr < Common.Settings.FLT_EPSILON) 52 | { 53 | separation = -radiusSum; 54 | manifold.Normal.Set(0.0f, 1.0f); 55 | } 56 | else 57 | { 58 | float dist = Common.Math.Sqrt(distSqr); 59 | separation = dist - radiusSum; 60 | float a = 1.0f / dist; 61 | manifold.Normal.X = a * d.X; 62 | manifold.Normal.Y = a * d.Y; 63 | } 64 | 65 | manifold.PointCount = 1; 66 | manifold.Points[0].ID.Key = 0; 67 | manifold.Points[0].Separation = separation; 68 | 69 | p1 += r1 * manifold.Normal; 70 | p2 -= r2 * manifold.Normal; 71 | 72 | Vec2 p = 0.5f * (p1 + p2); 73 | 74 | manifold.Points[0].LocalPoint1 = Common.Math.MulT(xf1, p); 75 | manifold.Points[0].LocalPoint2 = Common.Math.MulT(xf2, p); 76 | } 77 | 78 | public static void CollidePolygonAndCircle(ref Manifold manifold, 79 | PolygonShape polygon, XForm xf1, CircleShape circle, XForm xf2) 80 | { 81 | manifold.PointCount = 0; 82 | 83 | // Compute circle position in the frame of the polygon. 84 | Vec2 c = Common.Math.Mul(xf2, circle.GetLocalPosition()); 85 | Vec2 cLocal = Common.Math.MulT(xf1, c); 86 | 87 | // Find the min separating edge. 88 | int normalIndex = 0; 89 | float separation = -Settings.FLT_MAX; 90 | float radius = circle.GetRadius(); 91 | int vertexCount = polygon.VertexCount; 92 | Vec2[] vertices = polygon.GetVertices(); 93 | Vec2[] normals = polygon.Normals; 94 | 95 | for (int i = 0; i < vertexCount; ++i) 96 | { 97 | float s = Vec2.Dot(normals[i], cLocal - vertices[i]); 98 | if (s > radius) 99 | { 100 | // Early out. 101 | return; 102 | } 103 | 104 | if (s > separation) 105 | { 106 | separation = s; 107 | normalIndex = i; 108 | } 109 | } 110 | 111 | // If the center is inside the polygon ... 112 | if (separation < Common.Settings.FLT_EPSILON) 113 | { 114 | manifold.PointCount = 1; 115 | manifold.Normal = Common.Math.Mul(xf1.R, normals[normalIndex]); 116 | manifold.Points[0].ID.Features.IncidentEdge = (byte)normalIndex; 117 | manifold.Points[0].ID.Features.IncidentVertex = Collision.NullFeature; 118 | manifold.Points[0].ID.Features.ReferenceEdge = 0; 119 | manifold.Points[0].ID.Features.Flip = 0; 120 | Vec2 position = c - radius * manifold.Normal; 121 | manifold.Points[0].LocalPoint1 = Common.Math.MulT(xf1, position); 122 | manifold.Points[0].LocalPoint2 = Common.Math.MulT(xf2, position); 123 | manifold.Points[0].Separation = separation - radius; 124 | return; 125 | } 126 | 127 | // Project the circle center onto the edge segment. 128 | int vertIndex1 = normalIndex; 129 | int vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0; 130 | Vec2 e = vertices[vertIndex2] - vertices[vertIndex1]; 131 | 132 | float length = e.Normalize(); 133 | Box2DXDebug.Assert(length > Settings.FLT_EPSILON); 134 | 135 | // Project the center onto the edge. 136 | float u = Vec2.Dot(cLocal - vertices[vertIndex1], e); 137 | Vec2 p; 138 | if (u <= 0.0f) 139 | { 140 | p = vertices[vertIndex1]; 141 | manifold.Points[0].ID.Features.IncidentEdge = Collision.NullFeature; 142 | manifold.Points[0].ID.Features.IncidentVertex = (byte)vertIndex1; 143 | } 144 | else if (u >= length) 145 | { 146 | p = vertices[vertIndex2]; 147 | manifold.Points[0].ID.Features.IncidentEdge = Collision.NullFeature; 148 | manifold.Points[0].ID.Features.IncidentVertex = (byte)vertIndex2; 149 | } 150 | else 151 | { 152 | p = vertices[vertIndex1] + u * e; 153 | manifold.Points[0].ID.Features.IncidentEdge = (byte)normalIndex; 154 | manifold.Points[0].ID.Features.IncidentVertex = Collision.NullFeature; 155 | } 156 | 157 | Vec2 d = cLocal - p; 158 | float dist = d.Normalize(); 159 | if (dist > radius) 160 | { 161 | return; 162 | } 163 | 164 | manifold.PointCount = 1; 165 | manifold.Normal = Common.Math.Mul(xf1.R, d); 166 | Vec2 position_ = c - radius * manifold.Normal; 167 | manifold.Points[0].LocalPoint1 = Common.Math.MulT(xf1, position_); 168 | manifold.Points[0].LocalPoint2 = Common.Math.MulT(xf2, position_); 169 | manifold.Points[0].Separation = dist - radius; 170 | manifold.Points[0].ID.Features.ReferenceEdge = 0; 171 | manifold.Points[0].ID.Features.Flip = 0; 172 | } 173 | } 174 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/Dominos.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class Dominos : Test 33 | { 34 | public Dominos() 35 | { 36 | Body b1; 37 | { 38 | PolygonDef sd = new PolygonDef(); 39 | sd.SetAsBox(50.0f, 10.0f); 40 | 41 | BodyDef bd = new BodyDef(); 42 | bd.Position.Set(0.0f, -10.0f); 43 | b1 = _world.CreateBody(bd); 44 | b1.CreateShape(sd); 45 | } 46 | 47 | { 48 | PolygonDef sd = new PolygonDef(); 49 | sd.SetAsBox(6.0f, 0.25f); 50 | 51 | BodyDef bd = new BodyDef(); 52 | bd.Position.Set(-1.5f, 10.0f); 53 | Body ground = _world.CreateBody(bd); 54 | ground.CreateShape(sd); 55 | } 56 | 57 | { 58 | PolygonDef sd = new PolygonDef(); 59 | sd.SetAsBox(0.1f, 1.0f); 60 | sd.Density = 20.0f; 61 | sd.Friction = 0.1f; 62 | 63 | for (int i = 0; i < 10; ++i) 64 | { 65 | BodyDef bd = new BodyDef(); 66 | bd.Position.Set(-6.0f + 1.0f * i, 11.25f); 67 | Body body = _world.CreateBody(bd); 68 | body.CreateShape(sd); 69 | body.SetMassFromShapes(); 70 | } 71 | } 72 | 73 | { 74 | PolygonDef sd = new PolygonDef(); 75 | sd.SetAsBox(7.0f, 0.25f, Vec2.Zero, 0.3f); 76 | 77 | BodyDef bd = new BodyDef(); 78 | bd.Position.Set(1.0f, 6.0f); 79 | Body ground = _world.CreateBody(bd); 80 | ground.CreateShape(sd); 81 | } 82 | 83 | Body b2; 84 | { 85 | PolygonDef sd = new PolygonDef(); 86 | sd.SetAsBox(0.25f, 1.5f); 87 | 88 | BodyDef bd = new BodyDef(); 89 | bd.Position.Set(-7.0f, 4.0f); 90 | b2 = _world.CreateBody(bd); 91 | b2.CreateShape(sd); 92 | } 93 | 94 | Body b3; 95 | { 96 | PolygonDef sd = new PolygonDef(); 97 | sd.SetAsBox(6.0f, 0.125f); 98 | sd.Density = 10.0f; 99 | 100 | BodyDef bd = new BodyDef(); 101 | bd.Position.Set(-0.9f, 1.0f); 102 | bd.Angle = -0.15f; 103 | 104 | b3 = _world.CreateBody(bd); 105 | b3.CreateShape(sd); 106 | b3.SetMassFromShapes(); 107 | } 108 | 109 | RevoluteJointDef jd = new RevoluteJointDef(); 110 | Vec2 anchor = new Vec2(); 111 | 112 | anchor.Set(-2.0f, 1.0f); 113 | jd.Initialize(b1, b3, anchor); 114 | jd.CollideConnected = true; 115 | _world.CreateJoint(jd); 116 | 117 | Body b4; 118 | { 119 | PolygonDef sd = new PolygonDef(); 120 | sd.SetAsBox(0.25f, 0.25f); 121 | sd.Density = 10.0f; 122 | 123 | BodyDef bd = new BodyDef(); 124 | bd.Position.Set(-10.0f, 15.0f); 125 | b4 = _world.CreateBody(bd); 126 | b4.CreateShape(sd); 127 | b4.SetMassFromShapes(); 128 | } 129 | 130 | anchor.Set(-7.0f, 15.0f); 131 | jd.Initialize(b2, b4, anchor); 132 | _world.CreateJoint(jd); 133 | 134 | Body b5; 135 | { 136 | BodyDef bd = new BodyDef(); 137 | bd.Position.Set(6.5f, 3.0f); 138 | b5 = _world.CreateBody(bd); 139 | 140 | PolygonDef sd = new PolygonDef(); 141 | sd.Density = 10.0f; 142 | sd.Friction = 0.1f; 143 | 144 | sd.SetAsBox(1.0f, 0.1f, new Vec2(0.0f, -0.9f), 0.0f); 145 | b5.CreateShape(sd); 146 | 147 | sd.SetAsBox(0.1f, 1.0f, new Vec2(-0.9f, 0.0f), 0.0f); 148 | b5.CreateShape(sd); 149 | 150 | sd.SetAsBox(0.1f, 1.0f, new Vec2(0.9f, 0.0f), 0.0f); 151 | b5.CreateShape(sd); 152 | 153 | b5.SetMassFromShapes(); 154 | } 155 | 156 | anchor.Set(6.0f, 2.0f); 157 | jd.Initialize(b1, b5, anchor); 158 | _world.CreateJoint(jd); 159 | 160 | Body b6; 161 | { 162 | PolygonDef sd = new PolygonDef(); 163 | sd.SetAsBox(1.0f, 0.1f); 164 | sd.Density = 30.0f; 165 | sd.Friction = 0.2f; 166 | 167 | BodyDef bd = new BodyDef(); 168 | bd.Position.Set(6.5f, 4.1f); 169 | b6 = _world.CreateBody(bd); 170 | b6.CreateShape(sd); 171 | b6.SetMassFromShapes(); 172 | } 173 | 174 | anchor.Set(7.5f, 4.0f); 175 | jd.Initialize(b5, b6, anchor); 176 | _world.CreateJoint(jd); 177 | 178 | Body b7; 179 | { 180 | PolygonDef sd = new PolygonDef(); 181 | sd.SetAsBox(0.1f, 1.0f); 182 | sd.Density = 10.0f; 183 | 184 | BodyDef bd = new BodyDef(); 185 | bd.Position.Set(7.4f, 1.0f); 186 | 187 | b7 = _world.CreateBody(bd); 188 | b7.CreateShape(sd); 189 | b7.SetMassFromShapes(); 190 | } 191 | 192 | DistanceJointDef djd = new DistanceJointDef(); 193 | djd.Body1 = b3; 194 | djd.Body2 = b7; 195 | djd.LocalAnchor1.Set(6.0f, 0.0f); 196 | djd.LocalAnchor2.Set(0.0f, -1.0f); 197 | Vec2 d = djd.Body2.GetWorldPoint(djd.LocalAnchor2) - djd.Body1.GetWorldPoint(djd.LocalAnchor1); 198 | djd.Length = d.Length(); 199 | _world.CreateJoint(djd); 200 | 201 | { 202 | CircleDef sd = new CircleDef(); 203 | sd.Radius = 0.2f; 204 | sd.Density = 10.0f; 205 | 206 | for (int i = 0; i < 4; ++i) 207 | { 208 | BodyDef bd = new BodyDef(); 209 | bd.Position.Set(5.9f + 2.0f * sd.Radius * i, 2.4f); 210 | Body body = _world.CreateBody(bd); 211 | body.CreateShape(sd); 212 | body.SetMassFromShapes(); 213 | } 214 | } 215 | } 216 | 217 | public static Test Create() 218 | { 219 | return new Dominos(); 220 | } 221 | } 222 | } -------------------------------------------------------------------------------- /Examples/TestBed/MainForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | True 122 | 123 | 124 | 17, 17 125 | 126 | -------------------------------------------------------------------------------- /src/Common/Settings.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | namespace Box2DX.Common 27 | { 28 | public class Settings 29 | { 30 | #if TARGET_FLOAT32_IS_FIXED 31 | public static readonly float FLT_EPSILON = FIXED_EPSILON; 32 | public static readonly float FLT_MAX = FIXED_MAX; 33 | public static float FORCE_SCALE2(x){ return x<<7;} 34 | public static float FORCE_INV_SCALE2(x) {return x>>7;} 35 | #else 36 | public static readonly float FLT_EPSILON = 1.192092896e-07F; 37 | public static readonly float FLT_MAX = 3.402823466e+38F; 38 | public static float FORCE_SCALE(float x) { return x; } 39 | public static float FORCE_INV_SCALE(float x) { return x; } 40 | #endif 41 | 42 | public static readonly float Pi = 3.14159265359f; 43 | 44 | // Global tuning constants based on meters-kilograms-seconds (MKS) units. 45 | 46 | // Collision 47 | public static readonly int MaxManifoldPoints = 2; 48 | public static readonly int MaxPolygonVertices = 8; 49 | public static readonly int MaxProxies = 512; // this must be a power of two 50 | public static readonly int MaxPairs = 8 * MaxProxies; // this must be a power of two 51 | 52 | // Dynamics 53 | 54 | /// 55 | /// A small length used as a collision and constraint tolerance. Usually it is 56 | /// chosen to be numerically significant, but visually insignificant. 57 | /// 58 | public static readonly float LinearSlop = 0.005f; // 0.5 cm 59 | 60 | /// 61 | /// A small angle used as a collision and constraint tolerance. Usually it is 62 | /// chosen to be numerically significant, but visually insignificant. 63 | /// 64 | public static readonly float AngularSlop = 2.0f / 180.0f * Pi; // 2 degrees 65 | 66 | /// 67 | /// Continuous collision detection (CCD) works with core, shrunken shapes. This is amount 68 | /// by which shapes are automatically shrunk to work with CCD. 69 | /// This must be larger than LinearSlop. 70 | /// 71 | public static readonly float ToiSlop = 8.0f * LinearSlop; 72 | 73 | /// 74 | /// Maximum number of contacts to be handled to solve a TOI island. 75 | /// 76 | public static readonly int MaxTOIContactsPerIsland = 32; 77 | 78 | /// 79 | /// Maximum number of joints to be handled to solve a TOI island. 80 | /// 81 | public static readonly int MaxTOIJointsPerIsland = 32; 82 | 83 | /// 84 | /// A velocity threshold for elastic collisions. Any collision with a relative linear 85 | /// velocity below this threshold will be treated as inelastic. 86 | /// 87 | public static readonly float VelocityThreshold = 1.0f; // 1 m/s 88 | 89 | /// 90 | /// The maximum linear position correction used when solving constraints. 91 | /// This helps to prevent overshoot. 92 | /// 93 | public static readonly float MaxLinearCorrection = 0.2f; // 20 cm 94 | 95 | /// 96 | /// The maximum angular position correction used when solving constraints. 97 | /// This helps to prevent overshoot. 98 | /// 99 | public static readonly float MaxAngularCorrection = 8.0f / 180.0f * Pi; // 8 degrees 100 | 101 | /// 102 | /// The maximum linear velocity of a body. This limit is very large and is used 103 | /// to prevent numerical problems. You shouldn't need to adjust this. 104 | /// 105 | #if TARGET_FLOAT32_IS_FIXED 106 | public static readonly float MaxLinearVelocity = 100.0f; 107 | #else 108 | public static readonly float MaxLinearVelocity = 200.0f; 109 | public static readonly float MaxLinearVelocitySquared = MaxLinearVelocity * MaxLinearVelocity; 110 | #endif 111 | /// 112 | /// The maximum angular velocity of a body. This limit is very large and is used 113 | /// to prevent numerical problems. You shouldn't need to adjust this. 114 | /// 115 | public static readonly float MaxAngularVelocity = 250.0f; 116 | #if !TARGET_FLOAT32_IS_FIXED 117 | public static readonly float MaxAngularVelocitySquared = MaxAngularVelocity * MaxAngularVelocity; 118 | #endif 119 | /// 120 | /// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so 121 | /// that overlap is removed in one time step. However using values close to 1 often lead to overshoot. 122 | /// 123 | public static readonly float ContactBaumgarte = 0.2f; 124 | 125 | // Sleep 126 | 127 | /// 128 | /// The time that a body must be still before it will go to sleep. 129 | /// 130 | public static readonly float TimeToSleep = 0.5f; // half a second 131 | 132 | /// 133 | /// A body cannot sleep if its linear velocity is above this tolerance. 134 | /// 135 | public static readonly float LinearSleepTolerance = 0.01f; // 1 cm/s 136 | 137 | /// 138 | /// A body cannot sleep if its angular velocity is above this tolerance. 139 | /// 140 | public static readonly float AngularSleepTolerance = 2.0f / 180.0f; // 2 degrees/s 141 | 142 | /// 143 | /// Friction mixing law. Feel free to customize this. 144 | /// 145 | public static float MixFriction(float friction1, float friction2) 146 | { 147 | return (float)System.Math.Sqrt(friction1 * friction2); 148 | } 149 | 150 | /// 151 | /// Restitution mixing law. Feel free to customize this. 152 | /// 153 | public static float MixRestitution(float restitution1, float restitution2) 154 | { 155 | return restitution1 > restitution2 ? restitution1 : restitution2; 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /Examples/TestBed/Tests/CollisionProcessing.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.Google.Com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2008 Erin Catto http://www.Gphysics.Com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | // This test shows collision processing and tests 33 | // deferred body destruction. 34 | public class CollisionProcessing : Test 35 | { 36 | public CollisionProcessing() 37 | { 38 | // Ground body 39 | { 40 | PolygonDef sd = new PolygonDef(); 41 | sd.SetAsBox(50.0f, 10.0f); 42 | sd.Friction = 0.3f; 43 | 44 | BodyDef bd = new BodyDef(); 45 | bd.Position.Set(0.0f, -10.0f); 46 | 47 | Body ground = _world.CreateBody(bd); 48 | ground.CreateShape(sd); 49 | } 50 | 51 | float xLo = -5.0f, xHi = 5.0f; 52 | float yLo = 2.0f, yHi = 35.0f; 53 | 54 | // Small triangle 55 | PolygonDef triangleShapeDef = new PolygonDef(); 56 | triangleShapeDef.VertexCount = 3; 57 | triangleShapeDef.Vertices[0].Set(-1.0f, 0.0f); 58 | triangleShapeDef.Vertices[1].Set(1.0f, 0.0f); 59 | triangleShapeDef.Vertices[2].Set(0.0f, 2.0f); 60 | triangleShapeDef.Density = 1.0f; 61 | 62 | BodyDef triangleBodyDef = new BodyDef(); 63 | //triangleBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), Box2DX.Common.Math.Random(yLo, yHi)); 64 | triangleBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), 35f); 65 | 66 | Body body1 = _world.CreateBody(triangleBodyDef); 67 | body1.CreateShape(triangleShapeDef); 68 | body1.SetMassFromShapes(); 69 | 70 | // Large triangle (recycle definitions) 71 | triangleShapeDef.Vertices[0] *= 2.0f; 72 | triangleShapeDef.Vertices[1] *= 2.0f; 73 | triangleShapeDef.Vertices[2] *= 2.0f; 74 | //triangleBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), Box2DX.Common.Math.Random(yLo, yHi)); 75 | triangleBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), 30f); 76 | 77 | Body body2 = _world.CreateBody(triangleBodyDef); 78 | body2.CreateShape(triangleShapeDef); 79 | body2.SetMassFromShapes(); 80 | 81 | // Small box 82 | PolygonDef boxShapeDef = new PolygonDef(); 83 | boxShapeDef.SetAsBox(1.0f, 0.5f); 84 | boxShapeDef.Density = 1.0f; 85 | 86 | BodyDef boxBodyDef = new BodyDef(); 87 | //boxBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), Box2DX.Common.Math.Random(yLo, yHi)); 88 | boxBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), 25f); 89 | 90 | Body body3 = _world.CreateBody(boxBodyDef); 91 | body3.CreateShape(boxShapeDef); 92 | body3.SetMassFromShapes(); 93 | 94 | // Large box (recycle definitions) 95 | boxShapeDef.SetAsBox(2.0f, 1.0f); 96 | //boxBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), Box2DX.Common.Math.Random(yLo, yHi)); 97 | boxBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), 15f); 98 | 99 | Body body4 = _world.CreateBody(boxBodyDef); 100 | body4.CreateShape(boxShapeDef); 101 | body4.SetMassFromShapes(); 102 | 103 | // Small circle 104 | CircleDef circleShapeDef = new CircleDef(); 105 | circleShapeDef.Radius = 1.0f; 106 | circleShapeDef.Density = 1.0f; 107 | 108 | BodyDef circleBodyDef = new BodyDef(); 109 | //circleBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), Box2DX.Common.Math.Random(yLo, yHi)); 110 | circleBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), 10f); 111 | 112 | Body body5 = _world.CreateBody(circleBodyDef); 113 | body5.CreateShape(circleShapeDef); 114 | body5.SetMassFromShapes(); 115 | 116 | // Large circle 117 | circleShapeDef.Radius *= 2.0f; 118 | //circleBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), Box2DX.Common.Math.Random(yLo, yHi)); 119 | circleBodyDef.Position.Set(Box2DX.Common.Math.Random(xLo, xHi), 5f); 120 | 121 | Body body6 = _world.CreateBody(circleBodyDef); 122 | body6.CreateShape(circleShapeDef); 123 | body6.SetMassFromShapes(); 124 | } 125 | 126 | public override void Step(Settings settings) 127 | { 128 | base.Step(settings); 129 | // We are going to destroy some bodies according to contact 130 | // points. We must buffer the bodies that should be destroyed 131 | // because they may belong to multiple contact points. 132 | const int k_maxNuke = 6; 133 | Dictionary nuke = new Dictionary(k_maxNuke); 134 | int nukeCount = 0; 135 | 136 | // Traverse the contact results. Destroy bodies that 137 | // are touching heavier bodies. 138 | for (int i = 0; i < _pointCount; ++i) 139 | { 140 | MyContactPoint point = _points[i]; 141 | 142 | Body body1 = point.shape1.GetBody(); 143 | Body body2 = point.shape2.GetBody(); 144 | float mass1 = body1.GetMass(); 145 | float mass2 = body2.GetMass(); 146 | 147 | if (mass1 > 0.0f && mass2 > 0.0f) 148 | { 149 | if (mass2 > mass1) 150 | { 151 | int hc = body1.GetHashCode(); 152 | if (!nuke.ContainsKey(hc)) 153 | nuke.Add(hc, body1);//nuke[nukeCount++] = body1; 154 | } 155 | else 156 | { 157 | int hc = body2.GetHashCode(); 158 | if (!nuke.ContainsKey(hc)) 159 | nuke.Add(hc, body2);//nuke[nukeCount++] = body2; 160 | } 161 | 162 | if (nukeCount == k_maxNuke) 163 | { 164 | break; 165 | } 166 | } 167 | } 168 | 169 | // Sort the nuke array to group duplicates. 170 | //Array.Sort(nuke); 171 | 172 | // Destroy the bodies, skipping duplicates. 173 | /*int i_ = 0; 174 | while (i_ < nukeCount) 175 | { 176 | Body b = nuke[i_++]; 177 | while (i_ < nukeCount && nuke[i_] == b) 178 | { 179 | ++i_; 180 | } 181 | 182 | _world.DestroyBody(b); 183 | }*/ 184 | 185 | foreach (KeyValuePair kvp in nuke) 186 | _world.DestroyBody(nuke[kvp.Key]); 187 | } 188 | 189 | public static Test Create() 190 | { 191 | return new CollisionProcessing(); 192 | } 193 | } 194 | } -------------------------------------------------------------------------------- /Examples/TestBed/Tests/Car.cs: -------------------------------------------------------------------------------- 1 | /* 2 | Box2DX Copyright (c) 2008 Ihar Kalasouski http://code.google.com/p/box2dx 3 | Box2D original C++ version Copyright (c) 2006-2007 Erin Catto http://www.gphysics.com 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | using System; 23 | using System.Collections.Generic; 24 | using System.Text; 25 | 26 | using Box2DX.Common; 27 | using Box2DX.Collision; 28 | using Box2DX.Dynamics; 29 | 30 | namespace TestBed 31 | { 32 | public class Car : Test 33 | { 34 | Body _leftWheel; 35 | Body _rightWheel; 36 | Body _vehicle; 37 | RevoluteJoint _leftJoint; 38 | RevoluteJoint _rightJoint; 39 | 40 | public Car() 41 | { 42 | { // car body 43 | PolygonDef poly1 = new PolygonDef(), poly2 = new PolygonDef(); 44 | 45 | // bottom half 46 | poly1.VertexCount = 5; 47 | poly1.Vertices[4].Set(-2.2f, -0.74f); 48 | poly1.Vertices[3].Set(-2.2f, 0); 49 | poly1.Vertices[2].Set(1.0f, 0); 50 | poly1.Vertices[1].Set(2.2f, -0.2f); 51 | poly1.Vertices[0].Set(2.2f, -0.74f); 52 | poly1.Filter.GroupIndex = -1; 53 | 54 | poly1.Density = 20.0f; 55 | poly1.Friction = 0.68f; 56 | poly1.Filter.GroupIndex = -1; 57 | 58 | // top half 59 | poly2.VertexCount = 4; 60 | poly2.Vertices[3].Set(-1.7f, 0); 61 | poly2.Vertices[2].Set(-1.3f, 0.7f); 62 | poly2.Vertices[1].Set(0.5f, 0.74f); 63 | poly2.Vertices[0].Set(1.0f, 0); 64 | poly2.Filter.GroupIndex = -1; 65 | 66 | poly2.Density = 5.0f; 67 | poly2.Friction = 0.68f; 68 | poly2.Filter.GroupIndex = -1; 69 | 70 | BodyDef bd = new BodyDef(); 71 | bd.Position.Set(-35.0f, 2.8f); 72 | 73 | _vehicle = _world.CreateBody(bd); 74 | _vehicle.CreateShape(poly1); 75 | _vehicle.CreateShape(poly2); 76 | _vehicle.SetMassFromShapes(); 77 | } 78 | 79 | { // vehicle wheels 80 | CircleDef circ = new CircleDef(); 81 | circ.Density = 40.0f; 82 | circ.Radius = 0.38608f; 83 | circ.Friction = 0.8f; 84 | circ.Filter.GroupIndex = -1; 85 | 86 | BodyDef bd = new BodyDef(); 87 | bd.AllowSleep = false; 88 | bd.Position.Set(-33.8f, 2.0f); 89 | 90 | _rightWheel = _world.CreateBody(bd); 91 | _rightWheel.CreateShape(circ); 92 | _rightWheel.SetMassFromShapes(); 93 | 94 | bd.Position.Set(-36.2f, 2.0f); 95 | _leftWheel = _world.CreateBody(bd); 96 | _leftWheel.CreateShape(circ); 97 | _leftWheel.SetMassFromShapes(); 98 | } 99 | 100 | { // join wheels to chassis 101 | Vec2 anchor = new Vec2(); 102 | RevoluteJointDef jd = new RevoluteJointDef(); 103 | jd.Initialize(_vehicle, _leftWheel, _leftWheel.GetWorldCenter()); 104 | jd.CollideConnected = false; 105 | jd.EnableMotor = true; 106 | jd.MaxMotorTorque = 10.0f; 107 | jd.MotorSpeed = 0.0f; 108 | _leftJoint = (RevoluteJoint)_world.CreateJoint(jd); 109 | 110 | jd.Initialize(_vehicle, _rightWheel, _rightWheel.GetWorldCenter()); 111 | jd.CollideConnected = false; 112 | _rightJoint = (RevoluteJoint)_world.CreateJoint(jd); 113 | } 114 | 115 | { // ground 116 | PolygonDef box = new PolygonDef(); 117 | box.SetAsBox(19.5f, 0.5f); 118 | box.Friction = 0.62f; 119 | 120 | BodyDef bd = new BodyDef(); 121 | bd.Position.Set(-25.0f, 1.0f); 122 | 123 | Body ground = _world.CreateBody(bd); 124 | ground.CreateShape(box); 125 | } 126 | 127 | { // more ground 128 | PolygonDef box = new PolygonDef(); 129 | BodyDef bd = new BodyDef(); 130 | 131 | box.SetAsBox(9.5f, 0.5f, Vec2.Zero, 0.1f * Box2DX.Common.Settings.Pi); 132 | box.Friction = 0.62f; 133 | bd.Position.Set(27.0f - 30.0f, 3.1f); 134 | 135 | Body ground = _world.CreateBody(bd); 136 | ground.CreateShape(box); 137 | } 138 | 139 | { // more ground 140 | PolygonDef box = new PolygonDef(); 141 | BodyDef bd = new BodyDef(); 142 | 143 | box.SetAsBox(9.5f, 0.5f, Vec2.Zero, -0.1f * Box2DX.Common.Settings.Pi); 144 | box.Friction = 0.62f; 145 | bd.Position.Set(55.0f - 30.0f, 3.1f); 146 | 147 | Body ground = _world.CreateBody(bd); 148 | ground.CreateShape(box); 149 | } 150 | 151 | { // more ground 152 | PolygonDef box = new PolygonDef(); 153 | BodyDef bd = new BodyDef(); 154 | 155 | box.SetAsBox(9.5f, 0.5f, Vec2.Zero, 0.03f * Box2DX.Common.Settings.Pi); 156 | box.Friction = 0.62f; 157 | bd.Position.Set(41.0f, 2.0f); 158 | 159 | Body ground = _world.CreateBody(bd); 160 | ground.CreateShape(box); 161 | } 162 | 163 | { // more ground 164 | PolygonDef box = new PolygonDef(); 165 | BodyDef bd = new BodyDef(); 166 | 167 | box.SetAsBox(5.0f, 0.5f, Vec2.Zero, 0.15f * Box2DX.Common.Settings.Pi); 168 | box.Friction = 0.62f; 169 | bd.Position.Set(50.0f, 4.0f); 170 | 171 | Body ground = _world.CreateBody(bd); 172 | ground.CreateShape(box); 173 | } 174 | 175 | { // more ground 176 | PolygonDef box = new PolygonDef(); 177 | BodyDef bd = new BodyDef(); 178 | 179 | box.SetAsBox(20.0f, 0.5f); 180 | box.Friction = 0.62f; 181 | bd.Position.Set(85.0f, 2.0f); 182 | 183 | Body ground = _world.CreateBody(bd); 184 | ground.CreateShape(box); 185 | } 186 | } 187 | 188 | public static Test Create() 189 | { 190 | return new Car(); 191 | } 192 | 193 | public override void Keyboard(System.Windows.Forms.Keys key) 194 | { 195 | switch (key) 196 | { 197 | case System.Windows.Forms.Keys.A: 198 | _leftJoint.SetMaxMotorTorque(800.0f); 199 | _leftJoint.MotorSpeed = 12.0f; 200 | break; 201 | 202 | case System.Windows.Forms.Keys.S: 203 | _leftJoint.SetMaxMotorTorque(100.0f); 204 | _leftJoint.MotorSpeed = 0.0f; 205 | break; 206 | 207 | case System.Windows.Forms.Keys.D: 208 | _leftJoint.SetMaxMotorTorque(1200.0f); 209 | _leftJoint.MotorSpeed = -36.0f; 210 | break; 211 | } 212 | } 213 | 214 | public override void Step(Settings settings) 215 | { 216 | OpenGLDebugDraw.DrawString(5, _textLine, "Keys: left = a, brake = s, right = d"); 217 | _textLine += 15; 218 | 219 | base.Step(settings); 220 | } 221 | } 222 | } --------------------------------------------------------------------------------