pass on rigid body name in btBulletWorldImporter, to make it easier to bind physics and graphics objects.

moved some obsolete files to Extras/obsolete, and removed freeglut
moved ColladaDemo to Dynamica Maya plugin repository (it has COLLADA_DOM and libxml), see http://dynamica.googlecode.com
Added new .bullet file
Minor update in Bullet_User_Manual.pdf, removed obsolete Bullet_Faq.pdf
This commit is contained in:
erwin.coumans
2010-02-20 15:39:09 +00:00
parent 890fd49813
commit 6ef37ab722
79 changed files with 19 additions and 23549 deletions

View File

@@ -0,0 +1,42 @@
//#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute("Scea.BulletPhysics")];
[assembly:AssemblyDescriptionAttribute("managed bullet physics engine C-API library ")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("")];
[assembly:AssemblyProductAttribute("Scea.BulletPhysics")];
[assembly:AssemblyCopyrightAttribute("Copyright (c) 2008")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:Guid("c3dfa120-9f17-11dd-ad8b-0800200c9a66")]
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];

View File

@@ -0,0 +1,198 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BulletPhysics", "BulletPhysics.vcproj", "{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}"
ProjectSection(ProjectDependencies) = postProject
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE} = {6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}
{61BD1097-CF2E-B296-DAA9-73A6FE135319} = {61BD1097-CF2E-B296-DAA9-73A6FE135319}
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A} = {7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BulletPhysicsapp", "BulletPhysicsapp.csproj", "{11E65486-3C29-4D36-B488-4E05D9E4B46B}"
ProjectSection(ProjectDependencies) = postProject
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239} = {5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbulletmath", "..\..\msvc\8\libbulletmath.vcproj", "{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbulletcollision", "..\..\msvc\8\libbulletcollision.vcproj", "{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libbulletdynamics", "..\..\msvc\8\libbulletdynamics.vcproj", "{61BD1097-CF2E-B296-DAA9-73A6FE135319}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
DebugDll|Any CPU = DebugDll|Any CPU
DebugDll|Mixed Platforms = DebugDll|Mixed Platforms
DebugDll|Win32 = DebugDll|Win32
DebugDoublePrecision|Any CPU = DebugDoublePrecision|Any CPU
DebugDoublePrecision|Mixed Platforms = DebugDoublePrecision|Mixed Platforms
DebugDoublePrecision|Win32 = DebugDoublePrecision|Win32
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
ReleaseDll|Any CPU = ReleaseDll|Any CPU
ReleaseDll|Mixed Platforms = ReleaseDll|Mixed Platforms
ReleaseDll|Win32 = ReleaseDll|Win32
ReleaseDoublePrecision|Any CPU = ReleaseDoublePrecision|Any CPU
ReleaseDoublePrecision|Mixed Platforms = ReleaseDoublePrecision|Mixed Platforms
ReleaseDoublePrecision|Win32 = ReleaseDoublePrecision|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Debug|Any CPU.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Debug|Win32.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Debug|Win32.Build.0 = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDll|Any CPU.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDll|Mixed Platforms.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDll|Mixed Platforms.Build.0 = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDll|Win32.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDll|Win32.Build.0 = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDoublePrecision|Any CPU.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDoublePrecision|Mixed Platforms.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDoublePrecision|Mixed Platforms.Build.0 = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.DebugDoublePrecision|Win32.Build.0 = Debug|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Release|Any CPU.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Release|Mixed Platforms.Build.0 = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Release|Win32.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.Release|Win32.Build.0 = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDll|Any CPU.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDll|Mixed Platforms.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDll|Mixed Platforms.Build.0 = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDll|Win32.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDll|Win32.Build.0 = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDoublePrecision|Any CPU.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDoublePrecision|Mixed Platforms.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDoublePrecision|Mixed Platforms.Build.0 = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Win32
{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}.ReleaseDoublePrecision|Win32.Build.0 = Release|Win32
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Debug|Win32.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDll|Any CPU.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDll|Any CPU.Build.0 = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDll|Mixed Platforms.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDll|Mixed Platforms.Build.0 = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDll|Win32.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDoublePrecision|Any CPU.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDoublePrecision|Any CPU.Build.0 = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDoublePrecision|Mixed Platforms.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDoublePrecision|Mixed Platforms.Build.0 = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.DebugDoublePrecision|Win32.ActiveCfg = Debug|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Release|Any CPU.Build.0 = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.Release|Win32.ActiveCfg = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDll|Any CPU.ActiveCfg = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDll|Any CPU.Build.0 = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDll|Mixed Platforms.ActiveCfg = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDll|Mixed Platforms.Build.0 = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDll|Win32.ActiveCfg = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDoublePrecision|Any CPU.ActiveCfg = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDoublePrecision|Any CPU.Build.0 = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDoublePrecision|Mixed Platforms.ActiveCfg = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDoublePrecision|Mixed Platforms.Build.0 = Release|Any CPU
{11E65486-3C29-4D36-B488-4E05D9E4B46B}.ReleaseDoublePrecision|Win32.ActiveCfg = Release|Any CPU
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Any CPU.ActiveCfg = Debug|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Win32.ActiveCfg = Debug|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Debug|Win32.Build.0 = Debug|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Any CPU.ActiveCfg = DebugDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Mixed Platforms.ActiveCfg = DebugDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Mixed Platforms.Build.0 = DebugDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDll|Win32.Build.0 = DebugDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Any CPU.ActiveCfg = DebugDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Mixed Platforms.ActiveCfg = DebugDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Mixed Platforms.Build.0 = DebugDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Win32.ActiveCfg = DebugDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.DebugDoublePrecision|Win32.Build.0 = DebugDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Any CPU.ActiveCfg = Release|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Mixed Platforms.Build.0 = Release|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Win32.ActiveCfg = Release|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.Release|Win32.Build.0 = Release|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Any CPU.ActiveCfg = ReleaseDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Mixed Platforms.ActiveCfg = ReleaseDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Mixed Platforms.Build.0 = ReleaseDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Any CPU.ActiveCfg = ReleaseDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Mixed Platforms.ActiveCfg = ReleaseDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Mixed Platforms.Build.0 = ReleaseDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Win32.ActiveCfg = ReleaseDoublePrecision|Win32
{7D6E339F-9C2C-31DA-FDB0-5EE50973CF2A}.ReleaseDoublePrecision|Win32.Build.0 = ReleaseDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Any CPU.ActiveCfg = Debug|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Win32.ActiveCfg = Debug|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Debug|Win32.Build.0 = Debug|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Any CPU.ActiveCfg = DebugDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Mixed Platforms.ActiveCfg = DebugDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Mixed Platforms.Build.0 = DebugDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDll|Win32.Build.0 = DebugDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Any CPU.ActiveCfg = DebugDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Mixed Platforms.ActiveCfg = DebugDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Mixed Platforms.Build.0 = DebugDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Win32.ActiveCfg = DebugDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.DebugDoublePrecision|Win32.Build.0 = DebugDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Any CPU.ActiveCfg = Release|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Mixed Platforms.Build.0 = Release|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Win32.ActiveCfg = Release|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.Release|Win32.Build.0 = Release|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Any CPU.ActiveCfg = ReleaseDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Mixed Platforms.ActiveCfg = ReleaseDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Mixed Platforms.Build.0 = ReleaseDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Any CPU.ActiveCfg = ReleaseDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Mixed Platforms.ActiveCfg = ReleaseDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Mixed Platforms.Build.0 = ReleaseDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Win32.ActiveCfg = ReleaseDoublePrecision|Win32
{6ADA430D-009C-2ED4-A787-2AC2D6FEB8CE}.ReleaseDoublePrecision|Win32.Build.0 = ReleaseDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Debug|Any CPU.ActiveCfg = Debug|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Debug|Win32.ActiveCfg = Debug|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Debug|Win32.Build.0 = Debug|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDll|Any CPU.ActiveCfg = DebugDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDll|Mixed Platforms.ActiveCfg = DebugDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDll|Mixed Platforms.Build.0 = DebugDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDll|Win32.ActiveCfg = DebugDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDll|Win32.Build.0 = DebugDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDoublePrecision|Any CPU.ActiveCfg = DebugDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDoublePrecision|Mixed Platforms.ActiveCfg = DebugDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDoublePrecision|Mixed Platforms.Build.0 = DebugDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDoublePrecision|Win32.ActiveCfg = DebugDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.DebugDoublePrecision|Win32.Build.0 = DebugDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Release|Any CPU.ActiveCfg = Release|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Release|Mixed Platforms.Build.0 = Release|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Release|Win32.ActiveCfg = Release|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.Release|Win32.Build.0 = Release|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDll|Any CPU.ActiveCfg = ReleaseDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDll|Mixed Platforms.ActiveCfg = ReleaseDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDll|Mixed Platforms.Build.0 = ReleaseDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDll|Win32.ActiveCfg = ReleaseDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDll|Win32.Build.0 = ReleaseDll|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDoublePrecision|Any CPU.ActiveCfg = ReleaseDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDoublePrecision|Mixed Platforms.ActiveCfg = ReleaseDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDoublePrecision|Mixed Platforms.Build.0 = ReleaseDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDoublePrecision|Win32.ActiveCfg = ReleaseDoublePrecision|Win32
{61BD1097-CF2E-B296-DAA9-73A6FE135319}.ReleaseDoublePrecision|Win32.Build.0 = ReleaseDoublePrecision|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,210 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="BulletPhysics"
ProjectGUID="{5EE4C1C4-4C81-46BB-A1C4-416F74BF9239}"
RootNamespace="bullet"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="obj/$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="4"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../src"
PreprocessorDefinitions="WIN32;_NDEBUG;_WINDOWS;_USRDLL;BULLET_EXPORTS"
MinimalRebuild="false"
BasicRuntimeChecks="0"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="false"
AssemblyDebug="0"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="obj/$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="4"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../src"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BULLET_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="false"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine=""
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\AssemblyInfo.cpp"
>
</File>
<File
RelativePath=".\BulletWrapper.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\BulletWrapper.h"
>
</File>
</Filter>
<File
RelativePath=".\Scea.BulletPhysics.dll.2.config"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,73 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{11E65486-3C29-4D36-B488-4E05D9E4B46B}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>bulletapp</RootNamespace>
<AssemblyName>bulletapp</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="BulletPhysics, Version=1.0.3316.31474, Culture=neutral, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>debug\BulletPhysics.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,21 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2008 SCEI
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
This is a C++/CLI wrapper of the high-level generic physics C-API.
You will be able to use it in C#
*/
#include "BulletWrapper.h"

View File

@@ -0,0 +1,422 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2008 SCEI
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
This is a C++/CLI wrapper of the high-level generic physics C-API.
You will be able to use it in C#
*/
#pragma once
#include "Bullet-C-Api.h"
namespace Scea
{
namespace BulletPhysics
{
/// <summary>
/// Base Bullet Class</summary>
public __gc class Bullet;
public __gc class RigidBodyHandle;
public __gc class CollisionShapeHandle;
public __gc class MeshInterfaceHandle;
/// <summary>
/// A Mesh Interface Handle for Bullet</summary>
public __gc class MeshInterfaceHandle
{
public:
/// <summary>
/// Constructor for Mesh Interface Handle</summary>
MeshInterfaceHandle(plMeshInterfaceHandle handle)
{
_plMeshInterfaceHandle = handle;
}
/// <summary>
/// Destructor for Mesh Interface Handle</summary>
~MeshInterfaceHandle()
{
_plMeshInterfaceHandle = 0;
};
plMeshInterfaceHandle _plMeshInterfaceHandle;
};
/// <summary>
/// A RigidBody handle for Bullet</summary>
public __gc class RigidBodyHandle
{
public:
/// <summary>
/// Constructor for RigidBody handle</summary>
RigidBodyHandle(plRigidBodyHandle handle)
{
_plRigidBodyHandle = handle;
}
/// <summary>
/// Destructor for RigidBody handle</summary>
~RigidBodyHandle()
{
_plRigidBodyHandle = 0;
};
plRigidBodyHandle _plRigidBodyHandle;
};
/// <summary>
/// A Collision Shape handle for Bullet</summary>
public __gc class CollisionShapeHandle
{
public:
/// <summary>
/// Constructor for Collision Shape handle</summary>
CollisionShapeHandle(plCollisionShapeHandle handle)
{
_plCollisionShapeHandle = handle;
}
/// <summary>
/// Destructor for Collision Shape handle</summary>
~CollisionShapeHandle()
{
_plCollisionShapeHandle = 0;
};
plCollisionShapeHandle _plCollisionShapeHandle;
};
/// <summary>
/// A RigidBody class in Bullet</summary>
public __gc class RigidBody
{
public:
/// <summary>
/// Constructor for RigidBody</summary>
/// <param name="mass">The mass of this RigidBody</param>
/// <param name="shape">The Collision Shape handle of this RigidBody</param>
/// <remarks>stationary object has mass=0.f</remarks>
RigidBody(float mass, CollisionShapeHandle * shape)
{
_plCollisionShapeHandle = shape->_plCollisionShapeHandle;
_plRigidBodyHandle = plCreateRigidBody(0, mass, _plCollisionShapeHandle);
}
/// <summary>
/// Destructor for RigidBody</summary>
~RigidBody()
{
if (_plRigidBodyHandle != 0)
{
plDeleteRigidBody(_plRigidBodyHandle );
_plRigidBodyHandle = 0;
}
}
/// <summary>
/// Dispose function for RigidBody</summary>
void Dispose()
{
if (_plRigidBodyHandle != 0)
{
plDeleteRigidBody(_plRigidBodyHandle );
_plRigidBodyHandle = 0;
}
}
/// <summary>
/// Get the Position for this RigidBody</summary>
/// <param name="float_array">The float[3] position of this RigidBody</param>
void GetPosition(float float_array __gc[])
{
float position[3];
plGetPosition(_plRigidBodyHandle, position);
for (int i=0; i<3; i++)
float_array[i] = position[i];
}
/// <summary>
/// Get the Open GL World Matrix for this RigidBody</summary>
/// <param name="float_array">The float[16] GL world matrix of this RigidBody</param>
void GetOpenGLMatrix(float float_array __gc[])
{
float matrix[16];
plGetOpenGLMatrix(_plRigidBodyHandle, matrix);
for (int i=0; i<16; i++)
float_array[i] = matrix[i];
}
/// <summary>
/// Get the orientation for this RigidBody</summary>
/// <param name="float_array">The float[4] orientation of this RigidBody</param>
void GetOrientation(float float_array __gc[])
{
float orientation[4];
plGetOrientation(_plRigidBodyHandle, orientation);
for (int i=0; i<4; i++)
float_array[i] = orientation[i];
}
/// <summary>
/// Set the position for this RigidBody</summary>
/// <param name="float_array">The float[3] position of this RigidBody</param>
void SetPosition(float float_array __gc[])
{
float position[3];
for (int i=0; i<3; i++)
position[i] = float_array[i];
plSetPosition(_plRigidBodyHandle, position);
}
/// <summary>
/// Set the orientation for this RigidBody</summary>
/// <param name="float_array">The float[3] orientation of this RigidBody</param>
void SetOrientation(float float_array __gc[])
{
float orientation[3];
for (int i=0; i<3; i++)
orientation[i] = float_array[i];
plSetOrientation(_plRigidBodyHandle, orientation);
}
/// <summary>
/// Set the orientation for this RigidBody</summary>
/// <param name="yaw">The yaw orientation of this RigidBody</param>
/// <param name="pitch">The pitch orientation of this RigidBody</param>
/// <param name="roll">The roll orientation of this RigidBody</param>
void SetOrientation(float yaw, float pitch, float roll)
{
float orient[4];
plSetEuler(yaw, pitch, roll, orient);
plSetOrientation(_plRigidBodyHandle, orient);
}
/// <summary>
/// Set the Open GL World Matrix for this RigidBody</summary>
/// <param name="float_array">The float[16] GL world matrix of this RigidBody</param>
void SetOpenGLMatrix(float float_array __gc[])
{
float matrix[16];
for (int i=0; i<16; i++)
matrix[i] = float_array[i];
plSetOpenGLMatrix(_plRigidBodyHandle, matrix);
}
plRigidBodyHandle _plRigidBodyHandle;
plCollisionShapeHandle _plCollisionShapeHandle;
};
/// <summary>
/// Base Bullet Class</summary>
public __gc class Bullet
{
public:
/// <summary>
/// Constructor for the Bullet</summary>
Bullet()
{
m_rigidbody_count = 0;
_plDynamicsWorldHandle = 0;
_plPhysicsSdkHandle = plNewBulletSdk();
}
/// <summary>
/// Destructor for the Bullet</summary>
~Bullet()
{
plDeletePhysicsSdk(_plPhysicsSdkHandle);
_plDynamicsWorldHandle = 0;
_plPhysicsSdkHandle = 0;
}
/// <summary>
/// Step Simulation for Bullet
/// </summary>
/// <param name="timeStep">The amount of time to step in this simulation</param>
void StepSimulation(plReal timeStep)
{
plStepSimulation(_plDynamicsWorldHandle, timeStep);
}
/// <summary>
/// Create collision shape handle for sphere
/// </summary>
/// <param name="radius">The radius of the sphere</param>
CollisionShapeHandle * CreateSphere(float radius)
{
return new CollisionShapeHandle(plNewSphereShape(radius));
}
/// <summary>
/// Create collision shape handle for Box
/// </summary>
/// <param name="x">extend x of the box</param>
/// <param name="y">extend y of the box</param>
/// <param name="z">extend z of the box</param>
CollisionShapeHandle * CreateBox(float x, float y, float z)
{
return new CollisionShapeHandle( plNewBoxShape(x, y, z));
}
/// <summary>
/// Create collision shape handle for Capsule
/// </summary>
/// <param name="radius">The radius of the capsule</param>
/// <param name="height">The height of the capsule</param>
CollisionShapeHandle * CreateCapsule(float radius, float height)
{
return new CollisionShapeHandle( plNewCapsuleShape(radius, height));
}
/// <summary>
/// Create collision shape handle for cone
/// </summary>
/// <param name="radius">The radius of the cone</param>
/// <param name="height">The height of the cone</param>
CollisionShapeHandle * CreateCone(float radius, float height)
{
return new CollisionShapeHandle( plNewConeShape(radius, height));
}
/// <summary>
/// Create collision shape handle for cylinder
/// </summary>
/// <param name="radius">The radius of the cylinder</param>
/// <param name="height">The height of the cylinder</param>
CollisionShapeHandle * CreateCylinder(float radius, float height)
{
return new CollisionShapeHandle( plNewCylinderShape(radius, height));
}
/// <summary>
/// Create a Compound Shape collision shape handle
/// </summary>
CollisionShapeHandle * CreateCompoundShape()
{
return new CollisionShapeHandle( plNewCompoundShape());
}
/// <summary>
/// Add shape to this Compound Shape collision shape handle
/// </summary>
/// <param name="compoundShape">compoundShape</param>
/// <param name="childShape">childShape</param>
/// <param name="childPos">childPos</param>
/// <param name="childOrn">childOrn</param>
void AddCompoundShape(CollisionShapeHandle * compoundShape, CollisionShapeHandle * childShape, plVector3 childPos,plQuaternion childOrn)
{
plAddChildShape(compoundShape->_plCollisionShapeHandle, childShape->_plCollisionShapeHandle, childPos,childOrn);
}
/// <summary>
/// Destroy a collision shape handle
/// </summary>
void DestroyShape(CollisionShapeHandle * shape)
{
plDeleteShape(shape->_plCollisionShapeHandle);
delete shape;
}
/// <summary>
/// Create collision shape handle for Convex Meshes
/// </summary>
CollisionShapeHandle * CreateConvexHull()
{
return new CollisionShapeHandle(plNewConvexHullShape());
}
/// <summary>
/// Add Convex Hull Vertex to the Convex Mesh shape handle
/// </summary>
void AddConvexHullVertex(CollisionShapeHandle * handle, float x, float y, float z)
{
plAddVertex(handle->_plCollisionShapeHandle, x, y, z);
}
/* CollisionShapeHandle * CreateTriangleMesh()
{
MeshInterfaceHandle * handle = new MeshInterfaceHandle(plNewMeshInterface());
return new CollisionShapeHandle(plNewStaticTriangleMeshShape(handle->_plMeshInterfaceHandle));
}
MeshInterfaceHandle * CreateMeshInterface()
{
return new MeshInterfaceHandle(plNewMeshInterface());
}
/*
void AddMeshTriangle(MeshInterfaceHandle * handle, float * v0, float * v1,float * v2)
{
plAddTriangle(handle->_plMeshInterfaceHandle, v0, v1, v2);
}
/*
CollisionShapeHandle * CreateTriangleMesh(MeshInterfaceHandle * handle)
{
return new CollisionShapeHandle(plNewStaticTriangleMeshShape(handle->_plMeshInterfaceHandle));
}
*/ /* Concave static triangle meshes */
/* extern void plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
extern plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
extern void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling);
*/
void SetEuler(float yaw, float pitch, float roll, float * orient)
{
plSetEuler(yaw, pitch, roll, orient);
}
/// <summary>
/// Add RigidBody, If won't haven't created a dynamic world, create one
/// </summary>
void AddRigidBody(RigidBody * body)
{
if (m_rigidbody_count == 0)
CreateDynamicsWorld();
plAddRigidBody(_plDynamicsWorldHandle, body->_plRigidBodyHandle);
m_rigidbody_count++;
}
/// <summary>
/// Remove RigidBody, If we remove everything in this dynamic world, we destroy the dynamic world
/// </summary>
void RemoveRigidBody(RigidBody * body)
{
plRemoveRigidBody(_plDynamicsWorldHandle, body->_plRigidBodyHandle);
m_rigidbody_count--;
if (m_rigidbody_count == 0)
DestroyDynamicsWorld();
}
private:
/// <summary>
/// Create a Dynamic World
/// </summary>
void CreateDynamicsWorld ()
{
_plDynamicsWorldHandle = plCreateDynamicsWorld(_plPhysicsSdkHandle);
}
/// <summary>
/// Destroy a Dynamic World
/// </summary>
void DestroyDynamicsWorld()
{
plDeleteDynamicsWorld(_plDynamicsWorldHandle);
}
// The count of rigidbody in this world.
int m_rigidbody_count;
plPhysicsSdkHandle _plPhysicsSdkHandle;
// This wrapper will let you support only one world at a time.
plDynamicsWorldHandle _plDynamicsWorldHandle;
};
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Scea.BulletPhysics;
namespace bulletapp
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Bullet bullet = new Bullet();
CollisionShapeHandle s_handle = bullet.CreateSphere(1);
RigidBody body = new RigidBody(1, s_handle);
float [] position = new float[3];
position[0] = 1.0f; position[1] = 1.1f; position[2] = 1.2f;
body.SetPosition(position);
body.SetOrientation(0.1f, 0.2f, 0.3f);
bullet.AddRigidBody(body);
System.Console.WriteLine("Original Position (" + position[0] + ", " + position[1] + ", " + position[2] + ")");
float[] new_position = new float[3];
for (int i = 0; i < 10; i++)
{
bullet.StepSimulation(0.1f);
System.Console.WriteLine("StepSimulation " + 0.1);
body.GetPosition(new_position);
System.Console.WriteLine("New Position (" + new_position[0] + ", " + new_position[1] + ", " + new_position[2] + ")");
}
float[] matrix = new float[16];
body.GetOpenGLMatrix(matrix);
System.Console.WriteLine("GetOpenGLMatrix (" +
matrix[0] + ", " + matrix[1] + ", " + matrix[2] + ", " + matrix[3] + ", " +
matrix[4] + ", " + matrix[5] + ", " + matrix[6] + ", " + matrix[7] + ", " +
matrix[8] + ", " + matrix[9] + ", " + matrix[10] + ", " + matrix[11] + ", " +
matrix[12] + ", " + matrix[13] + ", " + matrix[14] + ", " + matrix[15] + ")"
);
float[] quot = new float[4];
body.GetOrientation(quot);
System.Console.WriteLine("GetOrientation (" + quot[0] + ", " + quot[1] + ", " + quot[2] + ", " + quot[3] + ")");
}
}
}

View File

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

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace bulletapp.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("bulletapp.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

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

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1433
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace bulletapp.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "8.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

569
Extras/obsolete/EPA/Epa.cpp Normal file
View File

@@ -0,0 +1,569 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "LinearMath/btScalar.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btPoint3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMinMax.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include <vector>
#include <list>
#include <algorithm>
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
#include "EpaCommon.h"
#include "EpaVertex.h"
#include "EpaHalfEdge.h"
#include "EpaFace.h"
#include "EpaPolyhedron.h"
#include "Epa.h"
const btScalar EPA_MAX_RELATIVE_ERROR = 1e-2f;
const btScalar EPA_MAX_RELATIVE_ERROR_SQRD = EPA_MAX_RELATIVE_ERROR * EPA_MAX_RELATIVE_ERROR;
Epa::Epa( btConvexShape* pConvexShapeA, btConvexShape* pConvexShapeB,
const btTransform& transformA, const btTransform& transformB ) : m_pConvexShapeA( pConvexShapeA ),
m_pConvexShapeB( pConvexShapeB ),
m_transformA( transformA ),
m_transformB( transformB )
{
m_faceEntries.reserve( EPA_MAX_FACE_ENTRIES );
}
Epa::~Epa()
{
}
bool Epa::Initialize( btSimplexSolverInterface& simplexSolver )
{
// Run GJK on the enlarged shapes to obtain a simplex of the enlarged CSO
btVector3 v( 1, 0, 0 );
btScalar squaredDistance = SIMD_INFINITY;
btScalar delta = 0.f;
simplexSolver.reset();
int nbIterations = 0;
while ( true )
{
EPA_DEBUG_ASSERT( ( v.length2() > 0 ) ,"Warning : v has zero magnitude!" );
btVector3 seperatingAxisInA = -v * m_transformA.getBasis();
btVector3 seperatingAxisInB = v * m_transformB.getBasis();
btVector3 pInA = m_pConvexShapeA->localGetSupportingVertex( seperatingAxisInA );
btVector3 qInB = m_pConvexShapeB->localGetSupportingVertex( seperatingAxisInB );
btPoint3 pWorld = m_transformA( pInA );
btPoint3 qWorld = m_transformB( qInB );
btVector3 w = pWorld - qWorld;
delta = v.dot( w );
EPA_DEBUG_ASSERT( ( delta <= 0 ) ,"Shapes are disjoint, EPA should have never been called!" );
if ( delta > 0.f )
return false;
EPA_DEBUG_ASSERT( !simplexSolver.inSimplex( w ) ,"Shapes are disjoint, EPA should have never been called!" );
if (simplexSolver.inSimplex( w ))
return false;
// Add support point to simplex
simplexSolver.addVertex( w, pWorld, qWorld );
bool closestOk = simplexSolver.closest( v );
EPA_DEBUG_ASSERT( closestOk ,"Shapes are disjoint, EPA should have never been called!" );
if (!closestOk)
return false;
btScalar prevVSqrd = squaredDistance;
squaredDistance = v.length2();
// Is v converging to v(A-B) ?
EPA_DEBUG_ASSERT( ( ( prevVSqrd - squaredDistance ) > SIMD_EPSILON * prevVSqrd ) ,
"Shapes are disjoint, EPA should have never been called!" );
if (( ( prevVSqrd - squaredDistance ) <= SIMD_EPSILON * prevVSqrd ))
return false;
if ( simplexSolver.fullSimplex() || ( squaredDistance <= SIMD_EPSILON * simplexSolver.maxVertex() ) )
{
break;
}
++nbIterations;
}
btPoint3 simplexPoints[ 5 ];
btPoint3 wSupportPointsOnA[ 5 ];
btPoint3 wSupportPointsOnB[ 5 ];
int nbSimplexPoints = simplexSolver.getSimplex( wSupportPointsOnA, wSupportPointsOnB, simplexPoints );
// nbSimplexPoints can't be one because cases where the origin is on the boundary are handled
// by hybrid penetration depth
EPA_DEBUG_ASSERT( ( ( nbSimplexPoints > 1 ) ,( nbSimplexPoints <= 4 ) ) ,
"Hybrid Penetration Depth algorithm failed!" );
int nbPolyhedronPoints = nbSimplexPoints;
#ifndef EPA_POLYHEDRON_USE_PLANES
int initTetraIndices[ 4 ] = { 0, 1, 2, 3 };
#endif
// Prepare initial polyhedron to start EPA from
if ( nbSimplexPoints == 1 )
{
return false;
}
else if ( nbSimplexPoints == 2 )
{
// We have a line segment inside the CSO that contains the origin
// Create an hexahedron ( two tetrahedron glued together ) by adding 3 new points
btVector3 d = simplexPoints[ 0 ] - simplexPoints[ 1 ];
d.normalize();
btVector3 v1;
btVector3 v2;
btVector3 v3;
btVector3 e1;
btScalar absx = abs( d.getX() );
btScalar absy = abs( d.getY() );
btScalar absz = abs( d.getZ() );
if ( absx < absy )
{
if ( absx < absz )
{
e1.setX( 1 );
}
else
{
e1.setZ( 1 );
}
}
else
{
if ( absy < absz )
{
e1.setY( 1 );
}
else
{
e1.setZ( 1 );
}
}
v1 = d.cross( e1 );
v1.normalize();
v2 = v1.rotate( d, 120 * SIMD_RADS_PER_DEG );
v3 = v2.rotate( d, 120 * SIMD_RADS_PER_DEG );
nbPolyhedronPoints = 5;
btVector3 seperatingAxisInA = v1 * m_transformA.getBasis();
btVector3 seperatingAxisInB = -v1 * m_transformB.getBasis();
btVector3 p = m_pConvexShapeA->localGetSupportingVertex( seperatingAxisInA );
btVector3 q = m_pConvexShapeB->localGetSupportingVertex( seperatingAxisInB );
btPoint3 pWorld = m_transformA( p );
btPoint3 qWorld = m_transformB( q );
wSupportPointsOnA[ 2 ] = pWorld;
wSupportPointsOnB[ 2 ] = qWorld;
simplexPoints[ 2 ] = wSupportPointsOnA[ 2 ] - wSupportPointsOnB[ 2 ];
seperatingAxisInA = v2 * m_transformA.getBasis();
seperatingAxisInB = -v2 * m_transformB.getBasis();
p = m_pConvexShapeA->localGetSupportingVertex( seperatingAxisInA );
q = m_pConvexShapeB->localGetSupportingVertex( seperatingAxisInB );
pWorld = m_transformA( p );
qWorld = m_transformB( q );
wSupportPointsOnA[ 3 ] = pWorld;
wSupportPointsOnB[ 3 ] = qWorld;
simplexPoints[ 3 ] = wSupportPointsOnA[ 3 ] - wSupportPointsOnB[ 3 ];
seperatingAxisInA = v3 * m_transformA.getBasis();
seperatingAxisInB = -v3 * m_transformB.getBasis();
p = m_pConvexShapeA->localGetSupportingVertex( seperatingAxisInA );
q = m_pConvexShapeB->localGetSupportingVertex( seperatingAxisInB );
pWorld = m_transformA( p );
qWorld = m_transformB( q );
wSupportPointsOnA[ 4 ] = pWorld;
wSupportPointsOnB[ 4 ] = qWorld;
simplexPoints[ 4 ] = wSupportPointsOnA[ 4 ] - wSupportPointsOnB[ 4 ];
#ifndef EPA_POLYHEDRON_USE_PLANES
if ( TetrahedronContainsOrigin( simplexPoints[ 0 ], simplexPoints[ 2 ], simplexPoints[ 3 ], simplexPoints[ 4 ] ) )
{
initTetraIndices[ 1 ] = 2;
initTetraIndices[ 2 ] = 3;
initTetraIndices[ 3 ] = 4;
}
else
{
if ( TetrahedronContainsOrigin( simplexPoints[ 1 ], simplexPoints[ 2 ], simplexPoints[ 3 ], simplexPoints[ 4 ] ) )
{
initTetraIndices[ 0 ] = 1;
initTetraIndices[ 1 ] = 2;
initTetraIndices[ 2 ] = 3;
initTetraIndices[ 3 ] = 4;
}
else
{
// No tetrahedron contains the origin
assert( false && "Unable to find an initial tetrahedron that contains the origin!" );
return false;
}
}
#endif
}
else if ( nbSimplexPoints == 3 )
{
// We have a triangle inside the CSO that contains the origin
// Create an hexahedron ( two tetrahedron glued together ) by adding 2 new points
btVector3 v0 = simplexPoints[ 2 ] - simplexPoints[ 0 ];
btVector3 v1 = simplexPoints[ 1 ] - simplexPoints[ 0 ];
btVector3 triangleNormal = v0.cross( v1 );
triangleNormal.normalize();
nbPolyhedronPoints = 5;
btVector3 seperatingAxisInA = triangleNormal * m_transformA.getBasis();
btVector3 seperatingAxisInB = -triangleNormal * m_transformB.getBasis();
btVector3 p = m_pConvexShapeA->localGetSupportingVertex( seperatingAxisInA );
btVector3 q = m_pConvexShapeB->localGetSupportingVertex( seperatingAxisInB );
btPoint3 pWorld = m_transformA( p );
btPoint3 qWorld = m_transformB( q );
wSupportPointsOnA[ 3 ] = pWorld;
wSupportPointsOnB[ 3 ] = qWorld;
simplexPoints[ 3 ] = wSupportPointsOnA[ 3 ] - wSupportPointsOnB[ 3 ];
#ifndef EPA_POLYHEDRON_USE_PLANES
// We place this check here because if the tetrahedron contains the origin
// there is no need to sample another support point
if ( !TetrahedronContainsOrigin( simplexPoints[ 0 ], simplexPoints[ 1 ], simplexPoints[ 2 ], simplexPoints[ 3 ] ) )
{
#endif
seperatingAxisInA = -triangleNormal * m_transformA.getBasis();
seperatingAxisInB = triangleNormal * m_transformB.getBasis();
p = m_pConvexShapeA->localGetSupportingVertex( seperatingAxisInA );
q = m_pConvexShapeB->localGetSupportingVertex( seperatingAxisInB );
pWorld = m_transformA( p );
qWorld = m_transformB( q );
wSupportPointsOnA[ 4 ] = pWorld;
wSupportPointsOnB[ 4 ] = qWorld;
simplexPoints[ 4 ] = wSupportPointsOnA[ 4 ] - wSupportPointsOnB[ 4 ];
#ifndef EPA_POLYHEDRON_USE_PLANES
if ( TetrahedronContainsOrigin( simplexPoints[ 0 ], simplexPoints[ 1 ], simplexPoints[ 2 ], simplexPoints[ 4 ] ) )
{
initTetraIndices[ 3 ] = 4;
}
else
{
// No tetrahedron contains the origin
assert( false && "Unable to find an initial tetrahedron that contains the origin!" );
return false;
}
}
#endif
}
#ifdef _DEBUG
else if ( nbSimplexPoints == 4 )
{
EPA_DEBUG_ASSERT( TetrahedronContainsOrigin( simplexPoints ) ,"Initial tetrahedron does not contain the origin!" );
}
#endif
#ifndef EPA_POLYHEDRON_USE_PLANES
btPoint3 wTetraPoints[ 4 ] = { simplexPoints[ initTetraIndices[ 0 ] ],
simplexPoints[ initTetraIndices[ 1 ] ],
simplexPoints[ initTetraIndices[ 2 ] ],
simplexPoints[ initTetraIndices[ 3 ] ] };
btPoint3 wTetraSupportPointsOnA[ 4 ] = { wSupportPointsOnA[ initTetraIndices[ 0 ] ],
wSupportPointsOnA[ initTetraIndices[ 1 ] ],
wSupportPointsOnA[ initTetraIndices[ 2 ] ],
wSupportPointsOnA[ initTetraIndices[ 3 ] ] };
btPoint3 wTetraSupportPointsOnB[ 4 ] = { wSupportPointsOnB[ initTetraIndices[ 0 ] ],
wSupportPointsOnB[ initTetraIndices[ 1 ] ],
wSupportPointsOnB[ initTetraIndices[ 2 ] ],
wSupportPointsOnB[ initTetraIndices[ 3 ] ] };
#endif
#ifdef EPA_POLYHEDRON_USE_PLANES
if ( !m_polyhedron.Create( simplexPoints, wSupportPointsOnA, wSupportPointsOnB, nbPolyhedronPoints ) )
#else
if ( !m_polyhedron.Create( wTetraPoints, wTetraSupportPointsOnA, wTetraSupportPointsOnB, 4 ) )
#endif
{
// Failed to create initial polyhedron
EPA_DEBUG_ASSERT( false ,"Failed to create initial polyhedron!" );
return false;
}
// Add initial faces to priority queue
#ifdef _DEBUG
//m_polyhedron._dbgSaveToFile( "epa_start.dbg" );
#endif
std::list< EpaFace* >& faces = m_polyhedron.GetFaces();
std::list< EpaFace* >::iterator facesItr( faces.begin() );
while ( facesItr != faces.end() )
{
EpaFace* pFace = *facesItr;
if ( !pFace->m_deleted )
{
//#ifdef EPA_POLYHEDRON_USE_PLANES
// if ( pFace->m_planeDistance >= 0 )
// {
// m_polyhedron._dbgSaveToFile( "epa_start.dbg" );
// assert( false && "Face's plane distance equal or greater than 0!" );
// }
//#endif
if ( pFace->IsAffinelyDependent() )
{
EPA_DEBUG_ASSERT( false ,"One initial face is affinely dependent!" );
return false;
}
if ( pFace->m_vSqrd <= 0 )
{
EPA_DEBUG_ASSERT( false ,"Face containing the origin!" );
return false;
}
if ( pFace->IsClosestPointInternal() )
{
m_faceEntries.push_back( pFace );
std::push_heap( m_faceEntries.begin(), m_faceEntries.end(), CompareEpaFaceEntries );
}
}
++facesItr;
}
#ifdef _DEBUG
//m_polyhedron._dbgSaveToFile( "epa_start.dbg" );
#endif
EPA_DEBUG_ASSERT( !m_faceEntries.empty() ,"No faces added to heap!" );
return true;
}
btScalar Epa::calcPenDepth( btPoint3& wWitnessOnA, btPoint3& wWitnessOnB )
{
btVector3 v;
btScalar upperBoundSqrd = SIMD_INFINITY;
btScalar vSqrd = 0;
#ifdef _DEBUG
btScalar prevVSqrd;
#endif
btScalar delta;
bool isCloseEnough = false;
EpaFace* pEpaFace = NULL;
int nbIterations = 0;
//int nbMaxIterations = 1000;
do
{
pEpaFace = m_faceEntries.front();
std::pop_heap( m_faceEntries.begin(), m_faceEntries.end(), CompareEpaFaceEntries );
m_faceEntries.pop_back();
if ( !pEpaFace->m_deleted )
{
#ifdef _DEBUG
prevVSqrd = vSqrd;
#endif
vSqrd = pEpaFace->m_vSqrd;
if ( pEpaFace->m_planeDistance >= 0 )
{
v = pEpaFace->m_planeNormal;
}
else
{
v = pEpaFace->m_v;
}
#ifdef _DEBUG
//assert_msg( vSqrd <= upperBoundSqrd, "A triangle was falsely rejected!" );
EPA_DEBUG_ASSERT( ( vSqrd >= prevVSqrd ) ,"vSqrd decreased!" );
#endif //_DEBUG
EPA_DEBUG_ASSERT( ( v.length2() > 0 ) ,"Zero vector not allowed!" );
btVector3 seperatingAxisInA = v * m_transformA.getBasis();
btVector3 seperatingAxisInB = -v * m_transformB.getBasis();
btVector3 p = m_pConvexShapeA->localGetSupportingVertex( seperatingAxisInA );
btVector3 q = m_pConvexShapeB->localGetSupportingVertex( seperatingAxisInB );
btPoint3 pWorld = m_transformA( p );
btPoint3 qWorld = m_transformB( q );
btPoint3 w = pWorld - qWorld;
delta = v.dot( w );
// Keep tighest upper bound
upperBoundSqrd = btMin( upperBoundSqrd, delta * delta / vSqrd );
//assert_msg( vSqrd <= upperBoundSqrd, "A triangle was falsely rejected!" );
isCloseEnough = ( upperBoundSqrd <= ( 1 + 1e-4f ) * vSqrd );
if ( !isCloseEnough )
{
std::list< EpaFace* > newFaces;
bool expandOk = m_polyhedron.Expand( w, pWorld, qWorld, pEpaFace, newFaces );
if ( expandOk )
{
EPA_DEBUG_ASSERT( !newFaces.empty() ,"EPA polyhedron not expanding ?" );
bool check = true;
bool areEqual = false;
while ( !newFaces.empty() )
{
EpaFace* pNewFace = newFaces.front();
EPA_DEBUG_ASSERT( !pNewFace->m_deleted ,"New face is deleted!" );
if ( !pNewFace->m_deleted )
{
EPA_DEBUG_ASSERT( ( pNewFace->m_vSqrd > 0 ) ,"Face containing the origin!" );
EPA_DEBUG_ASSERT( !pNewFace->IsAffinelyDependent() ,"Face is affinely dependent!" );
//#ifdef EPA_POLYHEDRON_USE_PLANES
//// if ( pNewFace->m_planeDistance >= 0 )
//// {
// // assert( false && "Face's plane distance greater than 0!" );
//#ifdef _DEBUG
//// m_polyhedron._dbgSaveToFile( "epa_beforeFix.dbg" );
//#endif
// //pNewFace->FixOrder();
//#ifdef _DEBUG
// //m_polyhedron._dbgSaveToFile( "epa_afterFix.dbg" );
//#endif
//// }
//#endif
//
//#ifdef EPA_POLYHEDRON_USE_PLANES
// //assert( ( pNewFace->m_planeDistance < 0 ) && "Face's plane distance equal or greater than 0!" );
//#endif
if ( pNewFace->IsClosestPointInternal() && ( vSqrd <= pNewFace->m_vSqrd ) && ( pNewFace->m_vSqrd <= upperBoundSqrd ) )
{
m_faceEntries.push_back( pNewFace );
std::push_heap( m_faceEntries.begin(), m_faceEntries.end(), CompareEpaFaceEntries );
}
}
newFaces.pop_front();
}
}
else
{
pEpaFace->CalcClosestPointOnA( wWitnessOnA );
pEpaFace->CalcClosestPointOnB( wWitnessOnB );
#ifdef _DEBUG
//m_polyhedron._dbgSaveToFile( "epa_end.dbg" );
#endif
return v.length();
}
}
}
++nbIterations;
}
while ( ( m_polyhedron.GetNbFaces() < EPA_MAX_FACE_ENTRIES ) &&/*( nbIterations < nbMaxIterations ) &&*/
!isCloseEnough && ( m_faceEntries.size() > 0 ) && ( m_faceEntries[ 0 ]->m_vSqrd <= upperBoundSqrd ) );
#ifdef _DEBUG
//m_polyhedron._dbgSaveToFile( "epa_end.dbg" );
#endif
EPA_DEBUG_ASSERT( pEpaFace ,"Invalid epa face!" );
pEpaFace->CalcClosestPointOnA( wWitnessOnA );
pEpaFace->CalcClosestPointOnB( wWitnessOnB );
return v.length();
}
bool Epa::TetrahedronContainsOrigin( const btPoint3& point0, const btPoint3& point1,
const btPoint3& point2, const btPoint3& point3 )
{
btVector3 facesNormals[ 4 ] = { ( point1 - point0 ).cross( point2 - point0 ),
( point2 - point1 ).cross( point3 - point1 ),
( point3 - point2 ).cross( point0 - point2 ),
( point0 - point3 ).cross( point1 - point3 ) };
return ( ( facesNormals[ 0 ].dot( point0 ) > 0 ) != ( facesNormals[ 0 ].dot( point3 ) > 0 ) ) &&
( ( facesNormals[ 1 ].dot( point1 ) > 0 ) != ( facesNormals[ 1 ].dot( point0 ) > 0 ) ) &&
( ( facesNormals[ 2 ].dot( point2 ) > 0 ) != ( facesNormals[ 2 ].dot( point1 ) > 0 ) ) &&
( ( facesNormals[ 3 ].dot( point3 ) > 0 ) != ( facesNormals[ 3 ].dot( point2 ) > 0 ) );
}
bool Epa::TetrahedronContainsOrigin( btPoint3* pPoints )
{
return TetrahedronContainsOrigin( pPoints[ 0 ], pPoints[ 1 ], pPoints[ 2 ], pPoints[ 3 ] );
}
bool CompareEpaFaceEntries( EpaFace* pFaceA, EpaFace* pFaceB )
{
return ( pFaceA->m_vSqrd > pFaceB->m_vSqrd );
}

68
Extras/obsolete/EPA/Epa.h Normal file
View File

@@ -0,0 +1,68 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EPA_H
#define EPA_H
#define EPA_MAX_FACE_ENTRIES 256
extern const btScalar EPA_MAX_RELATIVE_ERROR;
extern const btScalar EPA_MAX_RELATIVE_ERROR_SQRD;
class Epa
{
private :
//! Prevents copying objects from this class
Epa( const Epa& epa );
const Epa& operator = ( const Epa& epa );
public :
Epa( btConvexShape* pConvexShapeA, btConvexShape* pConvexShapeB,
const btTransform& transformA, const btTransform& transformB );
~Epa();
bool Initialize( btSimplexSolverInterface& simplexSolver );
btScalar calcPenDepth( btPoint3& wWitnessOnA, btPoint3& wWitnessOnB );
private :
bool TetrahedronContainsOrigin( btPoint3* pPoints );
bool TetrahedronContainsOrigin( const btPoint3& point0, const btPoint3& point1,
const btPoint3& point2, const btPoint3& point3 );
private :
//! Priority queue
std::vector< EpaFace* > m_faceEntries;
btConvexShape* m_pConvexShapeA;
btConvexShape* m_pConvexShapeB;
btTransform m_transformA;
btTransform m_transformB;
EpaPolyhedron m_polyhedron;
};
extern bool CompareEpaFaceEntries( EpaFace* pFaceA, EpaFace* pFaceB );
#endif

View File

@@ -0,0 +1,30 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EPA_COMMON_H
#define EPA_COMMON_H
#define EPA_POLYHEDRON_USE_PLANES
//#define EPA_DEBUG_ASSERT(c,a)
//#define EPA_DEBUG_ASSERT(c,a) assert(c && a)
#define EPA_DEBUG_ASSERT(c,a) if (!c) printf(a)
//#define EPA_USE_HYBRID
#endif

View File

@@ -0,0 +1,254 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "LinearMath/btScalar.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btPoint3.h"
#include "EpaCommon.h"
#include "EpaVertex.h"
#include "EpaHalfEdge.h"
#include "EpaFace.h"
#ifdef EPA_POLYHEDRON_USE_PLANES
btScalar PLANE_THICKNESS = 1e-5f;
#endif
EpaFace::EpaFace() : m_pHalfEdge( 0 ), m_deleted( false )
{
m_pVertices[ 0 ] = m_pVertices[ 1 ] = m_pVertices[ 2 ] = 0;
}
EpaFace::~EpaFace()
{
}
bool EpaFace::Initialize()
{
assert( m_pHalfEdge && "Must setup half-edge first!" );
CollectVertices( m_pVertices );
const btVector3 e0 = m_pVertices[ 1 ]->m_point - m_pVertices[ 0 ]->m_point;
const btVector3 e1 = m_pVertices[ 2 ]->m_point - m_pVertices[ 0 ]->m_point;
const btScalar e0Sqrd = e0.length2();
const btScalar e1Sqrd = e1.length2();
const btScalar e0e1 = e0.dot( e1 );
m_determinant = e0Sqrd * e1Sqrd - e0e1 * e0e1;
const btScalar e0v0 = e0.dot( m_pVertices[ 0 ]->m_point );
const btScalar e1v0 = e1.dot( m_pVertices[ 0 ]->m_point );
m_lambdas[ 0 ] = e0e1 * e1v0 - e1Sqrd * e0v0;
m_lambdas[ 1 ] = e0e1 * e0v0 - e0Sqrd * e1v0;
if ( IsAffinelyDependent() )
{
return false;
}
CalcClosestPoint();
#ifdef EPA_POLYHEDRON_USE_PLANES
if ( !CalculatePlane() )
{
return false;
}
#endif
return true;
}
#ifdef EPA_POLYHEDRON_USE_PLANES
bool EpaFace::CalculatePlane()
{
assert( ( m_pVertices[ 0 ] && m_pVertices[ 1 ] && m_pVertices[ 2 ] )
&& "Must setup vertices pointers first!" );
// Traditional method
const btVector3 v1 = m_pVertices[ 1 ]->m_point - m_pVertices[ 0 ]->m_point;
const btVector3 v2 = m_pVertices[ 2 ]->m_point - m_pVertices[ 0 ]->m_point;
m_planeNormal = v2.cross( v1 );
if ( m_planeNormal.length2() == 0 )
{
return false;
}
m_planeNormal.normalize();
m_planeDistance = m_pVertices[ 0 ]->m_point.dot( -m_planeNormal );
// Robust method
//btVector3 _v1 = m_pVertices[ 1 ]->m_point - m_pVertices[ 0 ]->m_point;
//btVector3 _v2 = m_pVertices[ 2 ]->m_point - m_pVertices[ 0 ]->m_point;
//btVector3 n;
//n = _v2.cross( _v1 );
//_v1 = m_pVertices[ 0 ]->m_point - m_pVertices[ 1 ]->m_point;
//_v2 = m_pVertices[ 2 ]->m_point - m_pVertices[ 1 ]->m_point;
//n += ( _v1.cross( _v2 ) );
//_v1 = m_pVertices[ 0 ]->m_point - m_pVertices[ 2 ]->m_point;
//_v2 = m_pVertices[ 1 ]->m_point - m_pVertices[ 2 ]->m_point;
//n += ( _v2.cross( _v1 ) );
//n /= 3;
//n.normalize();
//btVector3 c = ( m_pVertices[ 0 ]->m_point + m_pVertices[ 1 ]->m_point + m_pVertices[ 2 ]->m_point ) / 3;
//btScalar d = c.dot( -n );
//m_robustPlaneNormal = n;
//m_robustPlaneDistance = d;
// Compare results from both methods and check whether they disagree
//if ( d < 0 )
//{
// assert( ( m_planeDistance < 0 ) && "He he! Busted!" );
//}
//else
//{
// assert( ( m_planeDistance >= 0 ) && "He he! Busted!" );
//}
return true;
}
#endif
void EpaFace::CalcClosestPoint()
{
const btVector3 e0 = m_pVertices[ 1 ]->m_point - m_pVertices[ 0 ]->m_point;
const btVector3 e1 = m_pVertices[ 2 ]->m_point - m_pVertices[ 0 ]->m_point;
m_v = m_pVertices[ 0 ]->m_point +
( e0 * m_lambdas[ 0 ] + e1 * m_lambdas[ 1 ] ) / m_determinant;
m_vSqrd = m_v.length2();
}
void EpaFace::CalcClosestPointOnA( btVector3& closestPointOnA )
{
const btVector3 e0 = m_pVertices[ 1 ]->m_wSupportPointOnA - m_pVertices[ 0 ]->m_wSupportPointOnA;
const btVector3 e1 = m_pVertices[ 2 ]->m_wSupportPointOnA - m_pVertices[ 0 ]->m_wSupportPointOnA;
closestPointOnA = m_pVertices[ 0 ]->m_wSupportPointOnA +
( e0 * m_lambdas[ 0 ] + e1 * m_lambdas[ 1 ] ) /
m_determinant;
}
void EpaFace::CalcClosestPointOnB( btVector3& closestPointOnB )
{
const btVector3 e0 = m_pVertices[ 1 ]->m_wSupportPointOnB - m_pVertices[ 0 ]->m_wSupportPointOnB;
const btVector3 e1 = m_pVertices[ 2 ]->m_wSupportPointOnB - m_pVertices[ 0 ]->m_wSupportPointOnB;
closestPointOnB = m_pVertices[ 0 ]->m_wSupportPointOnB +
( e0 * m_lambdas[ 0 ] + e1 * m_lambdas[ 1 ] ) /
m_determinant;
}
bool EpaFace::IsAffinelyDependent() const
{
return ( m_determinant <= SIMD_EPSILON );
}
bool EpaFace::IsClosestPointInternal() const
{
return ( ( m_lambdas[ 0 ] >= 0 ) && ( m_lambdas[ 1 ] >= 0 ) && ( ( m_lambdas[ 0 ] + m_lambdas[ 1 ] <= m_determinant ) ) );
}
void EpaFace::CollectVertices( EpaVertex** ppVertices )
{
assert( m_pHalfEdge && "Invalid half-edge pointer!" );
int vertexIndex = 0;
EpaHalfEdge* pCurrentHalfEdge = m_pHalfEdge;
do
{
assert( ( ( vertexIndex >= 0 ) && ( vertexIndex < 3 ) ) &&
"Face is not a triangle!" );
assert( pCurrentHalfEdge->m_pVertex && "Half-edge has an invalid vertex pointer!" );
ppVertices[ vertexIndex++ ] = pCurrentHalfEdge->m_pVertex;
pCurrentHalfEdge = pCurrentHalfEdge->m_pNextCCW;
}
while( pCurrentHalfEdge != m_pHalfEdge );
}
//void EpaFace::FixOrder()
//{
// EpaHalfEdge* pHalfEdges[ 3 ];
//
// int halfEdgeIndex = 0;
//
// EpaHalfEdge* pCurrentHalfEdge = m_pHalfEdge;
//
// do
// {
// assert( ( ( halfEdgeIndex >= 0 ) && ( halfEdgeIndex < 3 ) ) &&
// "Face is not a triangle!" );
//
// pHalfEdges[ halfEdgeIndex++ ] = pCurrentHalfEdge;
//
// pCurrentHalfEdge = pCurrentHalfEdge->m_pNextCCW;
// }
// while( pCurrentHalfEdge != m_pHalfEdge );
//
// EpaVertex* pVertices[ 3 ] = { pHalfEdges[ 0 ]->m_pVertex,
// pHalfEdges[ 1 ]->m_pVertex,
// pHalfEdges[ 2 ]->m_pVertex };
//
// // Make them run in the opposite direction
// pHalfEdges[ 0 ]->m_pNextCCW = pHalfEdges[ 2 ];
// pHalfEdges[ 1 ]->m_pNextCCW = pHalfEdges[ 0 ];
// pHalfEdges[ 2 ]->m_pNextCCW = pHalfEdges[ 1 ];
//
// // Make half-edges point to their correct origin vertices
//
// pHalfEdges[ 1 ]->m_pVertex = pVertices[ 2 ];
// pHalfEdges[ 2 ]->m_pVertex = pVertices[ 0 ];
// pHalfEdges[ 0 ]->m_pVertex = pVertices[ 1 ];
//
// // Make vertices point to the correct half-edges
//
// //pHalfEdges[ 0 ]->m_pVertex->m_pHalfEdge = pHalfEdges[ 0 ];
// //pHalfEdges[ 1 ]->m_pVertex->m_pHalfEdge = pHalfEdges[ 1 ];
// //pHalfEdges[ 2 ]->m_pVertex->m_pHalfEdge = pHalfEdges[ 2 ];
//
// // Flip normal and change the sign of plane distance
//
//#ifdef EPA_POLYHEDRON_USE_PLANES
// m_planeNormal = -m_planeNormal;
// m_planeDistance = -m_planeDistance;
//#endif
//}

View File

@@ -0,0 +1,83 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EPA_FACE_H
#define EPA_FACE_H
class EpaVertex;
class EpaHalfEdge;
#ifdef EPA_POLYHEDRON_USE_PLANES
extern btScalar PLANE_THICKNESS;
#endif
//! Note : This class is not supposed to be a base class
class EpaFace
{
private :
//! Prevents copying objects from this class
EpaFace( const EpaFace& epaFace );
const EpaFace& operator = ( const EpaFace& epaFace );
public :
EpaFace();
~EpaFace();
bool Initialize();
#ifdef EPA_POLYHEDRON_USE_PLANES
bool CalculatePlane();
#endif
void CalcClosestPoint();
void CalcClosestPointOnA( btVector3& closestPointOnA );
void CalcClosestPointOnB( btVector3& closestPointOnB );
bool IsAffinelyDependent() const;
bool IsClosestPointInternal() const;
void CollectVertices( EpaVertex** ppVertices );
//void FixOrder();
public :
EpaHalfEdge* m_pHalfEdge;
// We keep vertices here so we don't need to call CollectVertices
// every time we need them
EpaVertex* m_pVertices[ 3 ];
#ifdef EPA_POLYHEDRON_USE_PLANES
btVector3 m_planeNormal;
btScalar m_planeDistance;
//btVector3 m_robustPlaneNormal;
//btScalar m_robustPlaneDistance;
#endif
btVector3 m_v;
btScalar m_vSqrd;
btScalar m_determinant;
btScalar m_lambdas[ 2 ];
bool m_deleted;
};
#endif

View File

@@ -0,0 +1,58 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EPA_HALF_EDGE_H
#define EPA_HALF_EDGE_H
class EpaFace;
class EpaVertex;
//! Note : This class is not supposed to be a base class
class EpaHalfEdge
{
private :
//! Prevents copying objects from this class
EpaHalfEdge( const EpaHalfEdge& epaHalfEdge );
const EpaHalfEdge& operator = ( const EpaHalfEdge& epaHalfEdge );
public :
EpaHalfEdge() : m_pTwin( 0 ), m_pNextCCW( 0 ), m_pFace( 0 ), m_pVertex( 0 )
{
}
~EpaHalfEdge()
{
}
public :
//! Twin half-edge link
EpaHalfEdge* m_pTwin;
//! Next half-edge in counter clock-wise ( CCW ) order
EpaHalfEdge* m_pNextCCW;
//! Parent face link
EpaFace* m_pFace;
//! Origin vertex link
EpaVertex* m_pVertex;
};
#endif

View File

@@ -0,0 +1,202 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "LinearMath/btScalar.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btPoint3.h"
#include "LinearMath/btTransform.h"
#include "LinearMath/btMinMax.h"
#include <list>
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
#include "EpaCommon.h"
#include "EpaVertex.h"
#include "EpaHalfEdge.h"
#include "EpaFace.h"
#include "EpaPolyhedron.h"
#include "Epa.h"
#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
#include "EpaPenetrationDepthSolver.h"
btScalar g_GJKMaxRelError = 1e-3f;
btScalar g_GJKMaxRelErrorSqrd = g_GJKMaxRelError * g_GJKMaxRelError;
bool EpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& simplexSolver,
btConvexShape* pConvexA, btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,
btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB,
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc )
{
EPA_DEBUG_ASSERT( pConvexA ,"Convex shape A is invalid!" );
EPA_DEBUG_ASSERT( pConvexB ,"Convex shape B is invalid!" );
btScalar penDepth;
#ifdef EPA_USE_HYBRID
bool needsEPA = !HybridPenDepth( simplexSolver, pConvexA, pConvexB, transformA, transformB,
wWitnessOnA, wWitnessOnB, penDepth, v );
if ( needsEPA )
{
#endif
penDepth = EpaPenDepth( simplexSolver, pConvexA, pConvexB,
transformA, transformB,
wWitnessOnA, wWitnessOnB );
EPA_DEBUG_ASSERT( ( penDepth > 0 ) ,"EPA or Hybrid Technique failed to calculate penetration depth!" );
#ifdef EPA_USE_HYBRID
}
#endif
return ( penDepth > 0 );
}
#ifdef EPA_USE_HYBRID
bool EpaPenetrationDepthSolver::HybridPenDepth( btSimplexSolverInterface& simplexSolver,
btConvexShape* pConvexA, btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,
btPoint3& wWitnessOnA, btPoint3& wWitnessOnB,
btScalar& penDepth, btVector3& v )
{
btScalar squaredDistance = SIMD_INFINITY;
btScalar delta = 0.f;
const btScalar margin = pConvexA->getMargin() + pConvexB->getMargin();
const btScalar marginSqrd = margin * margin;
simplexSolver.reset();
int nbIterations = 0;
while ( true )
{
assert( ( v.length2() > 0 ) && "Warning: v is the zero vector!" );
btVector3 seperatingAxisInA = -v * transformA.getBasis();
btVector3 seperatingAxisInB = v * transformB.getBasis();
btVector3 pInA = pConvexA->localGetSupportingVertexWithoutMargin( seperatingAxisInA );
btVector3 qInB = pConvexB->localGetSupportingVertexWithoutMargin( seperatingAxisInB );
btPoint3 pWorld = transformA( pInA );
btPoint3 qWorld = transformB( qInB );
btVector3 w = pWorld - qWorld;
delta = v.dot( w );
// potential exit, they don't overlap
if ( ( delta > 0 ) && ( ( delta * delta / squaredDistance ) > marginSqrd ) )
{
// Convex shapes do not overlap
// Returning true means that Hybrid's result is ok and there's no need to run EPA
penDepth = 0;
return true;
}
//exit 0: the new point is already in the simplex, or we didn't come any closer
if ( ( squaredDistance - delta <= squaredDistance * g_GJKMaxRelErrorSqrd ) || simplexSolver.inSimplex( w ) )
{
simplexSolver.compute_points( wWitnessOnA, wWitnessOnB );
assert( ( squaredDistance > 0 ) && "squaredDistance is zero!" );
btScalar vLength = sqrt( squaredDistance );
wWitnessOnA -= v * ( pConvexA->getMargin() / vLength );
wWitnessOnB += v * ( pConvexB->getMargin() / vLength );
penDepth = pConvexA->getMargin() + pConvexB->getMargin() - vLength;
// Returning true means that Hybrid's result is ok and there's no need to run EPA
return true;
}
//add current vertex to simplex
simplexSolver.addVertex( w, pWorld, qWorld );
//calculate the closest point to the origin (update vector v)
if ( !simplexSolver.closest( v ) )
{
simplexSolver.compute_points( wWitnessOnA, wWitnessOnB );
assert( ( squaredDistance > 0 ) && "squaredDistance is zero!" );
btScalar vLength = sqrt( squaredDistance );
wWitnessOnA -= v * ( pConvexA->getMargin() / vLength );
wWitnessOnB += v * ( pConvexB->getMargin() / vLength );
penDepth = pConvexA->getMargin() + pConvexB->getMargin() - vLength;
// Returning true means that Hybrid's result is ok and there's no need to run EPA
return true;
}
btScalar previousSquaredDistance = squaredDistance;
squaredDistance = v.length2();
//are we getting any closer ?
if ( previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance )
{
simplexSolver.backup_closest( v );
squaredDistance = v.length2();
simplexSolver.compute_points( wWitnessOnA, wWitnessOnB );
assert( ( squaredDistance > 0 ) && "squaredDistance is zero!" );
btScalar vLength = sqrt( squaredDistance );
wWitnessOnA -= v * ( pConvexA->getMargin() / vLength );
wWitnessOnB += v * ( pConvexB->getMargin() / vLength );
penDepth = pConvexA->getMargin() + pConvexB->getMargin() - vLength;
// Returning true means that Hybrid's result is ok and there's no need to run EPA
return true;
}
if ( simplexSolver.fullSimplex() || ( squaredDistance <= SIMD_EPSILON * simplexSolver.maxVertex() ) )
{
// Convex Shapes intersect - we need to run EPA
// Returning false means that Hybrid couldn't do anything for us
// and that we need to run EPA to calculate the pen depth
return false;
}
++nbIterations;
}
}
#endif
btScalar EpaPenetrationDepthSolver::EpaPenDepth( btSimplexSolverInterface& simplexSolver,
btConvexShape* pConvexA, btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,
btPoint3& wWitnessOnA, btPoint3& wWitnessOnB )
{
Epa epa( pConvexA, pConvexB, transformA, transformB );
if ( !epa.Initialize( simplexSolver ) )
{
EPA_DEBUG_ASSERT( false ,"Epa failed to initialize!" );
return 0;
}
return epa.calcPenDepth( wWitnessOnA, wWitnessOnB );
}

View File

@@ -0,0 +1,56 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EPA2_PENETRATION_DEPTH_H
#define EPA2_PENETRATION_DEPTH_H
/**
* EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to
* calculate the penetration depth between two convex shapes.
*/
extern btScalar g_GJKMaxRelError;
extern btScalar g_GJKMaxRelErrorSqrd;
//! Note : This class is not supposed to be a base class
class EpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver
{
public :
bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
btConvexShape* pConvexA, btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,
btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB,
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc );
private :
#ifdef EPA_USE_HYBRID
bool HybridPenDepth( btSimplexSolverInterface& simplexSolver,
btConvexShape* pConvexA, btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,
btPoint3& wWitnessOnA, btPoint3& wWitnessOnB,
btScalar& penDepth, btVector3& v );
#endif
btScalar EpaPenDepth( btSimplexSolverInterface& simplexSolver,
btConvexShape* pConvexA, btConvexShape* pConvexB,
const btTransform& transformA, const btTransform& transformB,
btPoint3& wWitnessOnA, btPoint3& wWitnessOnB );
};
#endif // EPA_PENETRATION_DEPTH_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,89 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EPA_POLYHEDRON_H
#define EPA_POLYHEDRON_H
class EpaFace;
class EpaVertex;
//! Note : This class is not supposed to be a base class
class EpaPolyhedron
{
private :
//! Prevents copying objects from this class
EpaPolyhedron( const EpaPolyhedron& epaPolyhedron );
const EpaPolyhedron& operator = ( const EpaPolyhedron& epaPolyhedron );
public :
EpaPolyhedron();
~EpaPolyhedron();
bool Create( btPoint3* pInitialPoints,
btPoint3* pSupportPointsOnA, btPoint3* pSupportPointsOnB,
const int nbInitialPoints );
void Destroy();
EpaFace* CreateFace();
EpaHalfEdge* CreateHalfEdge();
EpaVertex* CreateVertex( const btPoint3& wSupportPoint,
const btPoint3& wSupportPointOnA,
const btPoint3& wSupportPointOnB );
void DeleteFace( EpaFace* pFace );
void DestroyAllFaces();
void DestroyAllHalfEdges();
void DestroyAllVertices();
bool Expand( const btPoint3& wSupportPoint,
const btPoint3& wSupportPointOnA,
const btPoint3& wSupportPointOnB,
EpaFace* pFace, std::list< EpaFace* >& newFaces );
std::list< EpaFace* >& GetFaces();
int GetNbFaces() const;
private :
void DeleteVisibleFaces( const btPoint3& point, EpaFace* pFace,
std::list< EpaHalfEdge* >& coneBaseTwinHalfEdges );
void CreateCone( EpaVertex* pAppexVertex, std::list< EpaHalfEdge* >& baseTwinHalfEdges,
std::list< EpaFace* >& newFaces );
EpaFace* CreateConeFace( EpaVertex* pAppexVertex, EpaHalfEdge* pBaseTwinHalfEdge,
std::list< EpaHalfEdge* >& halfEdgesToLink );
#ifdef _DEBUG
public :
//! Please don't remove this method, it will help debugging if some problems arise in the future
bool _dbgSaveToFile( const char* pFileName );
#endif
private :
//! This is the number of valid faces, m_faces list also contain deleted faces
int m_nbFaces;
std::list< EpaFace* > m_faces;
std::list< EpaHalfEdge* > m_halfEdges;
std::list< EpaVertex* > m_vertices;
};
#endif

View File

@@ -0,0 +1,61 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
EPA Copyright (c) Ricardo Padrela 2006
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef EPA_VERTEX_H
#define EPA_VERTEX_H
class EpaHalfEdge;
//! Note : This class is not supposed to be a base class
class EpaVertex
{
private :
//! Prevents copying objects from this class
EpaVertex( const EpaVertex& epaVertex );
const EpaVertex& operator = ( const EpaVertex& epaVertex );
public :
EpaVertex( const btPoint3& point ) : /*m_pHalfEdge( 0 ),*/ m_point( point )
{
}
EpaVertex( const btPoint3& point,
const btPoint3& wSupportPointOnA,
const btPoint3& wSupportPointOnB ) : /*m_pHalfEdge( 0 ),*/ m_point( point ),
m_wSupportPointOnA( wSupportPointOnA ),
m_wSupportPointOnB( wSupportPointOnB )
{
}
~EpaVertex()
{
}
public :
//! This is not necessary
//EpaHalfEdge* m_pHalfEdge;
btPoint3 m_point;
btPoint3 m_wSupportPointOnA;
btPoint3 m_wSupportPointOnB;
};
#endif

View File

@@ -0,0 +1,10 @@
SubDir TOP Extras EPA ;
IncludeDir Extras/EPA ;
Library EPA : [ Wildcard *.h *.cpp ] ;
CFlags EPA : [ FIncludes $(TOP)/Extras/EPA ] ;
LibDepends EPA : ;
InstallHeader [ Wildcard *.h ] : EPA ;

View File

@@ -0,0 +1,227 @@
/*
* Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies.
* Erwin Coumans makes no representations about the suitability
* of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "CombinedSimplexSolver.h"
#include <stdio.h>
//switch off asserts
//#define MY_ASSERT assert
#define MY_ASSERT
bool useVoronoi = true;
CombinedSimplexSolver::CombinedSimplexSolver()
:m_useVoronoiSolver(useVoronoi)
{
}
void CombinedSimplexSolver::reset()
{
m_voronoiSolver.reset();
m_johnsonSolver.reset();
}
void CombinedSimplexSolver::addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q)
{
printf("addVertex (%f %f %f)\n",w[0],w[1],w[2]);
m_voronoiSolver.addVertex(w,p,q);
m_johnsonSolver.addVertex(w,p,q);
int i;
i=0;
btPoint3 vp1,vp2;
btPoint3 jp1,jp2;
/*
bool isClosest0 = m_voronoiSolver.closest(vp1);
bool isClosest1 = m_johnsonSolver.closest(vp1);
m_voronoiSolver.compute_points(vp1, vp2);
m_johnsonSolver.compute_points(jp1,jp2);
i=0;
*/
}
bool CombinedSimplexSolver::closest(btVector3& v)
{
bool result0 = 0;
bool result1 = 0;
btVector3 v0,v1;
result0 = m_voronoiSolver.closest(v0);
result1 = m_johnsonSolver.closest(v1);
if (result0 != result1)
{
result0 = m_voronoiSolver.closest(v0);
result1 = m_johnsonSolver.closest(v1);
int i;
i=0;
}
if (m_useVoronoiSolver)
{
v = v0;
return result0;
}
v = v1;
return result1;
}
btScalar CombinedSimplexSolver::maxVertex()
{
btScalar maxv0 = m_voronoiSolver.maxVertex();
btScalar maxv1 = m_johnsonSolver.maxVertex();
MY_ASSERT(maxv0 = maxv1);
if (m_useVoronoiSolver)
return maxv0;
return maxv1;
}
bool CombinedSimplexSolver::fullSimplex() const
{
bool fullSimplex0 = m_voronoiSolver.fullSimplex();
bool fullSimplex1 = m_johnsonSolver.fullSimplex();
MY_ASSERT(fullSimplex0 == fullSimplex1);
if (m_useVoronoiSolver)
return fullSimplex0;
return fullSimplex1;
}
int CombinedSimplexSolver::getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const
{
int simplex0 = m_voronoiSolver.getSimplex(pBuf, qBuf, yBuf);
int simplex1 = m_johnsonSolver.getSimplex(pBuf, qBuf, yBuf);
// MY_ASSERT(simplex0 == simplex1);
if (m_useVoronoiSolver)
{
return m_voronoiSolver.getSimplex(pBuf, qBuf, yBuf);
}
return simplex1;
}
void CombinedSimplexSolver::debugPrint()
{
btPoint3 pBuf0[4];
btPoint3 qBuf0[4];
btPoint3 yBuf0[4];
btPoint3 pBuf1[4];
btPoint3 qBuf1[4];
btPoint3 yBuf1[4];
int verts0,verts1;
verts0 = m_voronoiSolver.getSimplex(&pBuf0[0], &qBuf0[0], &yBuf0[0]);
verts1 = m_johnsonSolver.getSimplex(&pBuf1[0], &qBuf1[0], &yBuf1[0]);
printf("numverts0 = %d, numverts1 = %d\n",verts0,verts1);
for (int i=0;i<verts0;i++)
{
printf("vert0 pBuf %d = %f , %f , %f\n",i,pBuf0[i].x(),pBuf0[i].y(),pBuf0[i].z());
printf("vert0 qBuf %d = %f , %f , %f\n",i,qBuf0[i].x(),qBuf0[i].y(),qBuf0[i].z());
printf("vert0 yBuf %d = %f , %f , %f\n",i,yBuf0[i].x(),yBuf0[i].y(),yBuf0[i].z());
}
for (int i=0;i<verts1;i++)
{
printf("vert1 pBuf %d = %f , %f , %f\n",i,pBuf1[i].x(),pBuf1[i].y(),pBuf1[i].z());
printf("vert1 qBuf %d = %f , %f , %f\n",i,qBuf1[i].x(),qBuf1[i].y(),qBuf1[i].z());
printf("vert1 yBuf %d = %f , %f , %f\n",i,yBuf1[i].x(),yBuf1[i].y(),yBuf1[i].z());
}
}
bool CombinedSimplexSolver::inSimplex(const btVector3& w)
{
bool insimplex0 = m_voronoiSolver.inSimplex(w);
bool insimplex1 = m_johnsonSolver.inSimplex(w);
if (insimplex0 != insimplex1)
{
debugPrint();
}
if (m_useVoronoiSolver)
return insimplex0;
return insimplex1;
}
void CombinedSimplexSolver::backup_closest(btVector3& v)
{
btVector3 v0,v1;
m_voronoiSolver.backup_closest(v0);
m_johnsonSolver.backup_closest(v1);
if (m_useVoronoiSolver)
{
v = v0;
} else
{
v = v1;
}
}
bool CombinedSimplexSolver::emptySimplex() const
{
bool empty0 = m_voronoiSolver.emptySimplex();
bool empty1 = m_johnsonSolver.emptySimplex();
MY_ASSERT(empty0 == empty1);
if (m_useVoronoiSolver)
return empty0;
return empty1;
}
void CombinedSimplexSolver::compute_points(btPoint3& p1, btPoint3& p2)
{
btPoint3 tmpP1,tmpP2;
btPoint3 tmpJP1,tmpJP2;
m_voronoiSolver.compute_points(tmpP1,tmpP2);
m_johnsonSolver.compute_points(tmpJP1,tmpJP2);
if (m_useVoronoiSolver)
{
p1 = tmpP1;
p2 = tmpP2;
}
else
{
p1 = tmpJP1;
p2 = tmpJP2;
}
}
int CombinedSimplexSolver::numVertices() const
{
int numverts0 = m_voronoiSolver.numVertices();
int numverts1 = m_johnsonSolver.numVertices();
MY_ASSERT(numverts0==numverts1);
if (numverts0 != numverts1)
{
printf("--------- (numverts0 != numverts1) -----------------------\n");
}
printf("numverts0 = %d, numverts1 %d \n",numverts0,numverts1);
if (m_useVoronoiSolver)
return numverts0;
return numverts1;
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies.
* Erwin Coumans makes no representations about the suitability
* of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#ifndef COMBINED_SIMPLEX_SOLVER
#define COMBINED_SIMPLEX_SOLVER
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
#include "Solid3JohnsonSimplexSolver.h"
/// CombinedSimplexSolver runs both Solid and Voronoi Simplex Solver for comparison
class CombinedSimplexSolver: public btSimplexSolverInterface
{
btVoronoiSimplexSolver m_voronoiSolver;
// btVoronoiSimplexSolver m_johnsonSolver;
Solid3JohnsonSimplexSolver m_johnsonSolver;
bool m_useVoronoiSolver;
void debugPrint();
public:
CombinedSimplexSolver();
virtual ~CombinedSimplexSolver() {};
virtual void reset();
virtual void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q);
virtual bool closest(btVector3& v);
virtual btScalar maxVertex();
virtual bool fullSimplex() const;
virtual int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const;
virtual bool inSimplex(const btVector3& w);
virtual void backup_closest(btVector3& v) ;
virtual bool emptySimplex() const;
virtual void compute_points(btPoint3& p1, btPoint3& p2);
virtual int numVertices() const;
};
#endif //COMBINED_SIMPLEX_SOLVER

View File

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="ExtraSolid35"
ProjectGUID="{23F98301-2F09-4064-86CC-AB00D097BFB6}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\Bullet;..\..\LinearMath"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ExtraSolid35.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\Bullet;..\..\LinearMath"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ExtraSolid35.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\CombinedSimplexSolver.cpp">
</File>
<File
RelativePath=".\Solid3EpaPenetrationDepth.cpp">
</File>
<File
RelativePath=".\Solid3JohnsonSimplexSolver.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\CombinedSimplexSolver.h">
</File>
<File
RelativePath=".\Solid3EpaPenetrationDepth.h">
</File>
<File
RelativePath=".\Solid3JohnsonSimplexSolver.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
<File
RelativePath=".\ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,195 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="ExtraSolid35"
ProjectGUID="{23F98301-2F09-4064-86CC-AB00D097BFB6}"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="4"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\Bullet;..\..\LinearMath"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ExtraSolid35.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="4"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\Bullet;..\..\LinearMath"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/ExtraSolid35.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\CombinedSimplexSolver.cpp"
>
</File>
<File
RelativePath=".\Solid3EpaPenetrationDepth.cpp"
>
</File>
<File
RelativePath=".\Solid3JohnsonSimplexSolver.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CombinedSimplexSolver.h"
>
</File>
<File
RelativePath=".\Solid3EpaPenetrationDepth.h"
>
</File>
<File
RelativePath=".\Solid3JohnsonSimplexSolver.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,10 @@
SubDir TOP Extras ExtraSolid35 ;
IncludeDir Extras/ExtraSolid35 ;
Library ExtraSolid35 : [ Wildcard *.h *.cpp ] ;
CFlags ExtraSolid35 : [ FIncludes $(TOP)/Extras/ExtraSolid35 ] ;
LibDepends ExtraSolid35 : ;
InstallHeader [ Wildcard *.h ] : ExtraSolid35 ;

View File

@@ -0,0 +1,110 @@
The SOLID library is Copyright (C) 2001-2003 Dtecta.
You may use, distribute and copy the SOLID library under the terms of
the Q Public License, which is displayed below.
-------------------------------------------------------------------------
THE Q PUBLIC LICENSE
version 1.0
Copyright (C) 1999-2000 Trolltech AS, Norway.
Everyone is permitted to copy and
distribute this license document.
The intent of this license is to establish freedom to share and change the
software regulated by this license under the open source model.
This license applies to any software containing a notice placed by the
copyright holder saying that it may be distributed under the terms of
the Q Public License version 1.0. Such software is herein referred to as
the Software. This license covers modification and distribution of the
Software, use of third-party application programs based on the Software,
and development of free software which uses the Software.
Granted Rights
1. You are granted the non-exclusive rights set forth in this license
provided you agree to and comply with any and all conditions in this
license. Whole or partial distribution of the Software, or software
items that link with the Software, in any form signifies acceptance of
this license.
2. You may copy and distribute the Software in unmodified form provided
that the entire package, including - but not restricted to - copyright,
trademark notices and disclaimers, as released by the initial developer
of the Software, is distributed.
3. You may make modifications to the Software and distribute your
modifications, in a form that is separate from the Software, such as
patches. The following restrictions apply to modifications:
a. Modifications must not alter or remove any copyright notices in
the Software.
b. When modifications to the Software are released under this
license, a non-exclusive royalty-free right is granted to the
initial developer of the Software to distribute your modification
in future versions of the Software provided such versions remain
available under these terms in addition to any other license(s) of
the initial developer.
4. You may distribute machine-executable forms of the Software or
machine-executable forms of modified versions of the Software, provided
that you meet these restrictions:
a. You must include this license document in the distribution.
b. You must ensure that all recipients of the machine-executable forms
are also able to receive the complete machine-readable source code
to the distributed Software, including all modifications, without
any charge beyond the costs of data transfer, and place prominent
notices in the distribution explaining this.
c. You must ensure that all modifications included in the
machine-executable forms are available under the terms of this
license.
5. You may use the original or modified versions of the Software to
compile, link and run application programs legally developed by you
or by others.
6. You may develop application programs, reusable components and other
software items that link with the original or modified versions of the
Software. These items, when distributed, are subject to the following
requirements:
a. You must ensure that all recipients of machine-executable forms of
these items are also able to receive and use the complete
machine-readable source code to the items without any charge
beyond the costs of data transfer.
b. You must explicitly license all recipients of your items to use
and re-distribute original and modified versions of the items in
both machine-executable and source code forms. The recipients must
be able to do so without any charges whatsoever, and they must be
able to re-distribute to anyone they choose.
c. If the items are not available to the general public, and the
initial developer of the Software requests a copy of the items,
then you must supply one.
Limitations of Liability
In no event shall the initial developers or copyright holders be liable
for any damages whatsoever, including - but not restricted to - lost
revenue or profits or other direct, indirect, special, incidental or
consequential damages, even if they have been advised of the possibility
of such damages, except to the extent invariable law, if any, provides
otherwise.
No Warranty
The Software and this license document are provided AS IS with NO WARRANTY
OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
Choice of Law
This license is governed by the Laws of Norway. Disputes shall be settled
by Oslo City Court.

View File

@@ -0,0 +1,21 @@
========================================================================
STATIC LIBRARY : Solid35 Project Overview
========================================================================
AppWizard has created this Solid35 library project for you.
No source files were created as part of your project.
Solid35.vcproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="OptionalSolid35"
ProjectGUID="{698BA0FD-10D3-4F4C-8686-1303D6273D46}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/Solid35.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="4"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/Solid35.lib"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\Solid3EpaPenetrationDepth.cpp">
</File>
<File
RelativePath=".\Solid3JohnsonSimplexSolver.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\Solid3EpaPenetrationDepth.h">
</File>
<File
RelativePath=".\Solid3JohnsonSimplexSolver.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
</Filter>
<File
RelativePath=".\ReadMe.txt">
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,589 @@
/*
* SOLID - Software Library for Interference Detection
*
* Copyright (C) 2001-2003 Dtecta. All rights reserved.
*
* This library may be distributed under the terms of the Q Public License
* (QPL) as defined by Trolltech AS of Norway and appearing in the file
* LICENSE.QPL included in the packaging of this file.
*
* This library may be distributed and/or modified under the terms of the
* GNU bteral Public License (GPL) version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Commercial use or any other use of this library not covered by either
* the QPL or the GPL requires an additional license from Dtecta.
* Please contact info@dtecta.com for enquiries about the terms of commercial
* use of this library.
*/
#include "Solid3EpaPenetrationDepth.h"
#include <algorithm>
#include <vector>
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "LinearMath/btMinMax.h"
#define ASSERT_MESSAGE
class ReplaceMeAccuracy {
public:
static btScalar rel_error2; // squared relative error in the computed distance
static btScalar depth_tolerance; // terminate EPA if upper_bound <= depth_tolerance * dist2
static btScalar tol_error; // error tolerance if the distance is almost zero
static void setAccuracy(btScalar rel_error)
{
rel_error2 = rel_error * rel_error;
depth_tolerance = btScalar(1.0f) + btScalar(2.0f) * rel_error;
}
static void setTolerance(btScalar epsilon)
{
tol_error = epsilon;
}
};
static const btScalar rel_error = btScalar(1.0e-3);
btScalar ReplaceMeAccuracy::rel_error2 = rel_error * rel_error;
btScalar ReplaceMeAccuracy::depth_tolerance = btScalar(1.0) + btScalar(2.0) * rel_error;
btScalar ReplaceMeAccuracy::tol_error = SIMD_EPSILON;
class ReplaceMeFacet;
class ReplaceMeEdge {
public:
ReplaceMeEdge() {}
ReplaceMeEdge(ReplaceMeFacet *facet, int index) :
m_facet(facet),
m_index(index) {}
ReplaceMeFacet *getFacet() const { return m_facet; }
int getIndex() const { return m_index; }
int getSource() const;
int getTarget() const;
private:
ReplaceMeFacet *m_facet;
int m_index;
};
typedef std::vector<ReplaceMeEdge> ReplaceMeEdgeBuffer;
class ReplaceMeFacet {
public:
ReplaceMeFacet() {}
ReplaceMeFacet(int i0, int i1, int i2)
: m_obsolete(false)
{
m_indices[0] = i0;
m_indices[1] = i1;
m_indices[2] = i2;
}
inline int operator[](int i) const { return m_indices[i]; }
bool link(int edge0, ReplaceMeFacet *facet, int edge1);
bool isObsolete() const { return m_obsolete; }
bool computeClosest(const btVector3 *verts);
const btVector3& getClosest() const { return m_closest; }
bool isClosestInternal() const
{
return m_lambda1 >= btScalar(0.0) &&
m_lambda2 >= btScalar(0.0) &&
m_lambda1 + m_lambda2 <= m_det;
}
btScalar getDist2() const { return m_dist2; }
btPoint3 getClosestPoint(const btPoint3 *points) const
{
const btPoint3& p0 = points[m_indices[0]];
return p0 + (m_lambda1 * (points[m_indices[1]] - p0) +
m_lambda2 * (points[m_indices[2]] - p0)) / m_det;
}
void silhouette(const btVector3& w, ReplaceMeEdgeBuffer& edgeBuffer)
{
edgeBuffer.clear();
m_obsolete = true;
m_adjFacets[0]->silhouette(m_adjEdges[0], w, edgeBuffer);
m_adjFacets[1]->silhouette(m_adjEdges[1], w, edgeBuffer);
m_adjFacets[2]->silhouette(m_adjEdges[2], w, edgeBuffer);
}
private:
void silhouette(int index, const btVector3& w, ReplaceMeEdgeBuffer& edgeBuffer);
int m_indices[3];
bool m_obsolete;
ReplaceMeFacet *m_adjFacets[3];
int m_adjEdges[3];
btScalar m_det;
btScalar m_lambda1;
btScalar m_lambda2;
btVector3 m_closest;
btScalar m_dist2;
};
inline int incMod3(int i) { return ++i % 3; }
bool ReplaceMeFacet::link(int edge0, ReplaceMeFacet *facet, int edge1)
{
m_adjFacets[edge0] = facet;
m_adjEdges[edge0] = edge1;
facet->m_adjFacets[edge1] = this;
facet->m_adjEdges[edge1] = edge0;
bool b = m_indices[edge0] == facet->m_indices[incMod3(edge1)] &&
m_indices[incMod3(edge0)] == facet->m_indices[edge1];
return b;
}
bool ReplaceMeFacet::computeClosest(const btVector3 *verts)
{
const btVector3& p0 = verts[m_indices[0]];
btVector3 v1 = verts[m_indices[1]] - p0;
btVector3 v2 = verts[m_indices[2]] - p0;
btScalar v1dv1 = v1.length2();
btScalar v1dv2 = v1.dot(v2);
btScalar v2dv2 = v2.length2();
btScalar p0dv1 = p0.dot(v1);
btScalar p0dv2 = p0.dot(v2);
m_det = v1dv1 * v2dv2 - v1dv2 * v1dv2; // non-negative
//printf("m_det = %f\n",m_det);
//ASSERT(m_det >= 0.f);
if (m_det >= (SIMD_EPSILON*SIMD_EPSILON)) {
m_lambda1 = p0dv2 * v1dv2 - p0dv1 * v2dv2;
m_lambda2 = p0dv1 * v1dv2 - p0dv2 * v1dv1;
m_closest = p0 + (m_lambda1 * v1 + m_lambda2 * v2) / m_det;
m_dist2 = m_closest.length2();
return true;
}
return false;
}
void ReplaceMeFacet::silhouette(int index, const btVector3& w,
ReplaceMeEdgeBuffer& edgeBuffer)
{
if (!m_obsolete) {
if (m_closest.dot(w) < m_dist2) {
edgeBuffer.push_back(ReplaceMeEdge(this, index));
}
else {
m_obsolete = true; // Facet is visible
int next = incMod3(index);
m_adjFacets[next]->silhouette(m_adjEdges[next], w, edgeBuffer);
next = incMod3(next);
m_adjFacets[next]->silhouette(m_adjEdges[next], w, edgeBuffer);
}
}
}
inline int ReplaceMeEdge::getSource() const
{
return (*m_facet)[m_index];
}
inline int ReplaceMeEdge::getTarget() const
{
return (*m_facet)[incMod3(m_index)];
}
//#define DEBUG
const int MaxSupportPoints = 100;//1000;
const int MaxFacets = 200;//b2000;
static btPoint3 pBuf[MaxSupportPoints];
static btPoint3 qBuf[MaxSupportPoints];
static btVector3 yBuf[MaxSupportPoints];
static ReplaceMeFacet facetBuf[MaxFacets];
static int freeFacet = 0;
static ReplaceMeFacet *facetHeap[MaxFacets];
static int num_facets;
class ReplaceMeFacetComp {
public:
bool operator()(const ReplaceMeFacet *face1, const ReplaceMeFacet *face2)
{
return face1->getDist2() > face2->getDist2();
}
};
ReplaceMeFacetComp myFacetComp;
inline ReplaceMeFacet *addFacet(int i0, int i1, int i2,
btScalar lower2, btScalar upper2)
{
assert(i0 != i1 && i0 != i2 && i1 != i2);
if (freeFacet < MaxFacets)
{
ReplaceMeFacet *facet = new(&facetBuf[freeFacet++]) ReplaceMeFacet(i0, i1, i2);
#ifdef DEBUG
std::cout << "Facet " << i0 << ' ' << i1 << ' ' << i2;
#endif
if (facet->computeClosest(yBuf))
{
if (facet->isClosestInternal() &&
lower2 <= facet->getDist2() && facet->getDist2() <= upper2)
{
facetHeap[num_facets++] = facet;
ASSERT_MESSAGE(num_facets<MaxFacets,"Error in facet/pendepth");
std::push_heap(&facetHeap[0], &facetHeap[num_facets], myFacetComp);
#ifdef DEBUG
std::cout << " accepted" << std::endl;
#endif
}
else
{
#ifdef DEBUG
std::cout << " rejected, ";
if (!facet->isClosestInternal())
{
std::cout << "closest point not internal";
}
else if (lower2 > facet->getDist2())
{
std::cout << "facet is closer than orignal facet";
}
else
{
std::cout << "facet is further than upper bound";
}
std::cout << std::endl;
#endif
}
return facet;
}
}
return 0;
}
inline bool originInTetrahedron(const btVector3& p1, const btVector3& p2,
const btVector3& p3, const btVector3& p4)
{
btVector3 normal1 = (p2 - p1).cross(p3 - p1);
btVector3 normal2 = (p3 - p2).cross(p4 - p2);
btVector3 normal3 = (p4 - p3).cross(p1 - p3);
btVector3 normal4 = (p1 - p4).cross(p2 - p4);
return
(normal1.dot(p1) > btScalar(0.0)) != (normal1.dot(p4) > btScalar(0.0)) &&
(normal2.dot(p2) > btScalar(0.0)) != (normal2.dot(p1) > btScalar(0.0)) &&
(normal3.dot(p3) > btScalar(0.0)) != (normal3.dot(p2) > btScalar(0.0)) &&
(normal4.dot(p4) > btScalar(0.0)) != (normal4.dot(p3) > btScalar(0.0));
}
bool Solid3EpaPenetrationDepth::calcPenDepth( btSimplexSolverInterface& simplexSolver,
btConvexShape* convexA,btConvexShape* convexB,
const btTransform& transformA,const btTransform& transformB,
btVector3& v, btPoint3& pa, btPoint3& pb,
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
)
{
int num_verts = simplexSolver.getSimplex(pBuf, qBuf, yBuf);
switch (num_verts)
{
case 1:
// Touching contact. Yes, we have a collision,
// but no penetration.
return false;
case 2:
{
// We have a line segment inside the Minkowski sum containing the
// origin. Blow it up by adding three additional support points.
btVector3 dir = (yBuf[1] - yBuf[0]).normalized();
int axis = dir.furthestAxis();
static btScalar sin_60 = 0.8660254037f;//84438646763723170752941.22474487f;//13915890490986420373529;//
btQuaternion rot(dir[0] * sin_60, dir[1] * sin_60, dir[2] * sin_60, btScalar(0.5));
btMatrix3x3 rot_mat(rot);
btVector3 aux1 = dir.cross(btVector3(axis == 0, axis == 1, axis == 2));
btVector3 aux2 = rot_mat * aux1;
btVector3 aux3 = rot_mat * aux2;
pBuf[2] = transformA(convexA->localGetSupportingVertex(aux1*transformA.getBasis()));
qBuf[2] = transformB(convexB->localGetSupportingVertex((-aux1)*transformB.getBasis()));
yBuf[2] = pBuf[2] - qBuf[2];
pBuf[3] = transformA(convexA->localGetSupportingVertex(aux2*transformA.getBasis()));
qBuf[3] = transformB(convexB->localGetSupportingVertex((-aux2)*transformB.getBasis()));
yBuf[3] = pBuf[3] - qBuf[3];
pBuf[4] = transformA(convexA->localGetSupportingVertex(aux3*transformA.getBasis()));
qBuf[4] = transformB(convexB->localGetSupportingVertex((-aux3)*transformB.getBasis()));
yBuf[4] = pBuf[4] - qBuf[4];
if (originInTetrahedron(yBuf[0], yBuf[2], yBuf[3], yBuf[4]))
{
pBuf[1] = pBuf[4];
qBuf[1] = qBuf[4];
yBuf[1] = yBuf[4];
}
else if (originInTetrahedron(yBuf[1], yBuf[2], yBuf[3], yBuf[4]))
{
pBuf[0] = pBuf[4];
qBuf[0] = qBuf[4];
yBuf[0] = yBuf[4];
}
else
{
// Origin not in initial polytope
return false;
}
num_verts = 4;
break;
}
case 3:
{
// We have a triangle inside the Minkowski sum containing
// the origin. First blow it up.
btVector3 v1 = yBuf[1] - yBuf[0];
btVector3 v2 = yBuf[2] - yBuf[0];
btVector3 vv = v1.cross(v2);
pBuf[3] = transformA(convexA->localGetSupportingVertex(vv*transformA.getBasis()));
qBuf[3] = transformB(convexB->localGetSupportingVertex((-vv)*transformB.getBasis()));
yBuf[3] = pBuf[3] - qBuf[3];
pBuf[4] = transformA(convexA->localGetSupportingVertex((-vv)*transformA.getBasis()));
qBuf[4] = transformB(convexB->localGetSupportingVertex(vv*transformB.getBasis()));
yBuf[4] = pBuf[4] - qBuf[4];
if (originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[4]))
{
pBuf[3] = pBuf[4];
qBuf[3] = qBuf[4];
yBuf[3] = yBuf[4];
}
else if (!originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[3]))
{
// Origin not in initial polytope
return false;
}
num_verts = 4;
break;
}
}
// We have a tetrahedron inside the Minkowski sum containing
// the origin (if GJK did it's job right ;-)
if (!originInTetrahedron(yBuf[0], yBuf[1], yBuf[2], yBuf[3]))
{
// assert(false);
return false;
}
num_facets = 0;
freeFacet = 0;
ReplaceMeFacet *f0 = addFacet(0, 1, 2, btScalar(0.0), SIMD_INFINITY);
ReplaceMeFacet *f1 = addFacet(0, 3, 1, btScalar(0.0), SIMD_INFINITY);
ReplaceMeFacet *f2 = addFacet(0, 2, 3, btScalar(0.0), SIMD_INFINITY);
ReplaceMeFacet *f3 = addFacet(1, 3, 2, btScalar(0.0), SIMD_INFINITY);
if (!f0 || f0->getDist2() == btScalar(0.0) ||
!f1 || f1->getDist2() == btScalar(0.0) ||
!f2 || f2->getDist2() == btScalar(0.0) ||
!f3 || f3->getDist2() == btScalar(0.0))
{
return false;
}
f0->link(0, f1, 2);
f0->link(1, f3, 2);
f0->link(2, f2, 0);
f1->link(0, f2, 2);
f1->link(1, f3, 0);
f2->link(1, f3, 1);
if (num_facets == 0)
{
return false;
}
// at least one facet on the heap.
ReplaceMeEdgeBuffer edgeBuffer(20);
ReplaceMeFacet *facet = 0;
btScalar upper_bound2 = SIMD_INFINITY;
do {
facet = facetHeap[0];
std::pop_heap(&facetHeap[0], &facetHeap[num_facets], myFacetComp);
--num_facets;
if (!facet->isObsolete())
{
assert(facet->getDist2() > btScalar(0.0));
if (num_verts == MaxSupportPoints)
{
#ifdef DEBUG
std::cout << "Ouch, no convergence!!!" << std::endl;
#endif
ASSERT_MESSAGE(false,"Error: pendepth calc failed");
break;
}
pBuf[num_verts] = transformA(convexA->localGetSupportingVertex((facet->getClosest())*transformA.getBasis()));
qBuf[num_verts] = transformB(convexB->localGetSupportingVertex((-facet->getClosest())*transformB.getBasis()));
yBuf[num_verts] = pBuf[num_verts] - qBuf[num_verts];
int index = num_verts++;
btScalar far_dist2 = yBuf[index].dot(facet->getClosest());
// Make sure the support mapping is OK.
//assert(far_dist2 > btScalar(0.0));
//
// this is to avoid problems with implicit-sphere-touching contact
//
if (far_dist2 < btScalar(0.0))
{
return false;
}
GEN_set_min(upper_bound2, (far_dist2 * far_dist2) / facet->getDist2());
if (upper_bound2 <= ReplaceMeAccuracy::depth_tolerance * facet->getDist2()
#define CHECK_NEW_SUPPORT
#ifdef CHECK_NEW_SUPPORT
|| yBuf[index] == yBuf[(*facet)[0]]
|| yBuf[index] == yBuf[(*facet)[1]]
|| yBuf[index] == yBuf[(*facet)[2]]
#endif
)
{
break;
}
// Compute the silhouette cast by the new vertex
// Note that the new vertex is on the positive side
// of the current facet, so the current facet is will
// not be in the convex hull. Start local search
// from this facet.
facet->silhouette(yBuf[index], edgeBuffer);
if (edgeBuffer.empty())
{
return false;
}
ReplaceMeEdgeBuffer::const_iterator it = edgeBuffer.begin();
ReplaceMeFacet *firstFacet =
addFacet((*it).getTarget(), (*it).getSource(),
index, facet->getDist2(), upper_bound2);
if (!firstFacet)
{
break;
}
firstFacet->link(0, (*it).getFacet(), (*it).getIndex());
ReplaceMeFacet *lastFacet = firstFacet;
++it;
for (; it != edgeBuffer.end(); ++it)
{
ReplaceMeFacet *newFacet =
addFacet((*it).getTarget(), (*it).getSource(),
index, facet->getDist2(), upper_bound2);
if (!newFacet)
{
break;
}
if (!newFacet->link(0, (*it).getFacet(), (*it).getIndex()))
{
break;
}
if (!newFacet->link(2, lastFacet, 1))
{
break;
}
lastFacet = newFacet;
}
if (it != edgeBuffer.end())
{
break;
}
firstFacet->link(2, lastFacet, 1);
}
}
while (num_facets > 0 && facetHeap[0]->getDist2() <= upper_bound2);
#ifdef DEBUG
std::cout << "#facets left = " << num_facets << std::endl;
#endif
v = facet->getClosest();
pa = facet->getClosestPoint(pBuf);
pb = facet->getClosestPoint(qBuf);
return true;
}

View File

@@ -0,0 +1,44 @@
/*
* SOLID - Software Library for Interference Detection
*
* Copyright (C) 2001-2003 Dtecta. All rights reserved.
*
* This library may be distributed under the terms of the Q Public License
* (QPL) as defined by Trolltech AS of Norway and appearing in the file
* LICENSE.QPL included in the packaging of this file.
*
* This library may be distributed and/or modified under the terms of the
* GNU bteral Public License (GPL) version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Commercial use or any other use of this library not covered by either
* the QPL or the GPL requires an additional license from Dtecta.
* Please contact info@dtecta.com for enquiries about the terms of commercial
* use of this library.
*/
#ifndef SOLID3_EPA_PENETRATION_DEPTH_H
#define SOLID3_EPA_PENETRATION_DEPTH_H
#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
/// Solid3EpaPenetrationDepth contains the 'Expanding Polytope Algorithm' from Solid 3.5
class Solid3EpaPenetrationDepth : public btConvexPenetrationDepthSolver
{
public:
virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
btConvexShape* convexA,btConvexShape* convexB,
const btTransform& transA,const btTransform& transB,
btVector3& v, btPoint3& pa, btPoint3& pb,
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
);
};
#endif //SOLID3_EPA_PENETRATION_DEPTH_H

View File

@@ -0,0 +1,450 @@
/*
* SOLID - Software Library for Interference Detection
*
* Copyright (C) 2001-2003 Dtecta. All rights reserved.
*
* This library may be distributed under the terms of the Q Public License
* (QPL) as defined by Trolltech AS of Norway and appearing in the file
* LICENSE.QPL included in the packaging of this file.
*
* This library may be distributed and/or modified under the terms of the
* GNU bteral Public License (GPL) version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Commercial use or any other use of this library not covered by either
* the QPL or the GPL requires an additional license from Dtecta.
* Please contact info@dtecta.com for enquiries about the terms of commercial
* use of this library.
*/
#include "Solid3JohnsonSimplexSolver.h"
#include "LinearMath/btMinMax.h"
//#define USE_BACKUP_PROCEDURE
//#define FAST_CLOSEST
Solid3JohnsonSimplexSolver::Solid3JohnsonSimplexSolver()
:
m_bits1(0x0),
m_all_bits(0x0)
{
}
Solid3JohnsonSimplexSolver::~Solid3JohnsonSimplexSolver()
{
}
void Solid3JohnsonSimplexSolver::reset()
{
m_bits1 = 0x0;
m_all_bits = 0x0;
}
void Solid3JohnsonSimplexSolver::addVertex(const btVector3& w)
{
assert(!fullSimplex());
m_last = 0;
m_last_bit = 0x1;
while (contains(m_bits1, m_last_bit))
{
++m_last;
m_last_bit <<= 1;
}
m_y[m_last] = w;
m_ylen2[m_last] = w.length2();
m_all_bits = m_bits1 | m_last_bit;
update_cache();
compute_det();
}
void Solid3JohnsonSimplexSolver::addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q)
{
addVertex(w);
m_p[m_last] = p;
m_q[m_last] = q;
}
bool Solid3JohnsonSimplexSolver::emptySimplex() const
{
return m_bits1 == 0x0;
}
bool Solid3JohnsonSimplexSolver::fullSimplex() const
{
return m_bits1 == 0xf;
}
btScalar Solid3JohnsonSimplexSolver::maxVertex()
{
return m_maxlen2;
}
bool Solid3JohnsonSimplexSolver::closest(btVector3& v)
{
#ifdef FAST_CLOSEST
T_Bits s;
for (s = m_bits1; s != 0x0; --s)
{
if (subseteq(s, m_bits1) && valid(s | m_last_bit))
{
//update bits !
m_bits1 = s | m_last_bit;
compute_vector(m_bits1, v);
return true;
}
}
if (valid(m_last_bit))
{
//update bits !
m_bits1 = m_last_bit;
m_maxlen2 = m_ylen2[m_last];
v = m_y[m_last];
return true;
}
#else
T_Bits s;
for (s = m_all_bits; s != 0x0; --s)
{
if (subseteq(s, m_all_bits) && valid(s))
{
m_bits1 = s;
compute_vector(m_bits1, v);
return true;
}
}
#endif
// Original GJK calls the backup procedure at this point.
#ifdef USE_BACKUP_PROCEDURE
backup_closest(btVector3& v);
#endif
return false;
}
int Solid3JohnsonSimplexSolver::getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const
{
int num_verts = 0;
int i;
T_Bits bit;
for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
{
if (contains(m_bits1, bit))
{
pBuf[num_verts] = m_p[i];
qBuf[num_verts] = m_q[i];
yBuf[num_verts] = m_y[i];
#ifdef DEBUG
std::cout << "Point " << i << " = " << m_y[i] << std::endl;
#endif
++num_verts;
}
}
return num_verts;
}
bool Solid3JohnsonSimplexSolver::inSimplex(const btVector3& w)
{
int i;
T_Bits bit;
for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
{
if (contains(m_all_bits, bit) && w == m_y[i])
{
return true;
}
}
return false;
}
void Solid3JohnsonSimplexSolver::backup_closest(btVector3& v)
{
btScalar min_dist2 = SIMD_INFINITY;
T_Bits s;
for (s = m_all_bits; s != 0x0; --s)
{
if (subseteq(s, m_all_bits) && proper(s))
{
btVector3 u;
compute_vector(s, u);
btScalar dist2 = u.length2();
if (dist2 < min_dist2)
{
min_dist2 = dist2;
//update bits !
m_bits1 = s;
v = u;
}
}
}
}
void Solid3JohnsonSimplexSolver::compute_points(btPoint3& p1, btPoint3& p2)
{
btScalar sum = btScalar(0.0);
p1.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
p2.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
int i;
T_Bits bit;
for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
{
if (contains(m_bits1, bit))
{
sum += m_det[m_bits1][i];
p1 += m_p[i] * m_det[m_bits1][i];
p2 += m_q[i] * m_det[m_bits1][i];
}
}
assert(sum > btScalar(0.0));
btScalar s = btScalar(1.0) / sum;
p1 *= s;
p2 *= s;
}
int Solid3JohnsonSimplexSolver::numVertices() const
{
int numverts = 0;
int i,bit;
for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
{
if (contains(m_bits1, bit))
{
numverts++;
}
}
return numverts;
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//internal
inline void Solid3JohnsonSimplexSolver::update_cache()
{
int i;
T_Bits bit;
for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
{
if (contains(m_bits1, bit))
{
m_edge[i][m_last] = m_y[i] - m_y[m_last];
m_edge[m_last][i] = -m_edge[i][m_last];
#ifdef JOHNSON_ROBUST
m_norm[i][m_last] = m_norm[m_last][i] = m_edge[i][m_last].length2();
#endif
}
}
}
bool Solid3JohnsonSimplexSolver::valid(T_Bits s)
{
int i;
T_Bits bit;
for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
{
if (contains(m_all_bits, bit))
{
if (contains(s, bit))
{
if (m_det[s][i] <= btScalar(0.0))
{
return false;
}
}
else if (m_det[s | bit][i] > btScalar(0.0))
{
return false;
}
}
}
return true;
}
bool Solid3JohnsonSimplexSolver::proper(T_Bits s)
{
int i;
T_Bits bit;
for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
{
if (contains(s, bit) && m_det[s][i] <= btScalar(0.0))
{
return false;
}
}
return true;
}
void Solid3JohnsonSimplexSolver::compute_vector(T_Bits s, btVector3& v)
{
m_maxlen2 = btScalar(0.0);
btScalar sum = btScalar(0.0);
v .setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
int i;
T_Bits bit;
for (i = 0, bit = 0x1; i < 4; ++i, bit <<= 1)
{
if (contains(s, bit))
{
sum += m_det[s][i];
GEN_set_max(m_maxlen2, m_ylen2[i]);
v += m_y[i] * m_det[s][i];
}
}
assert(sum > btScalar(0.0));
v /= sum;
}
#ifdef JOHNSON_ROBUST
inline void Solid3JohnsonSimplexSolver::compute_det()
{
m_det[m_last_bit][m_last] = 1;
int i;
T_Bits si;
for (i = 0, si = 0x1; i < 4; ++i, si <<= 1)
{
if (contains(m_bits1, si))
{
T_Bits s2 = si | m_last_bit;
m_det[s2][i] = m_edge[m_last][i].dot(m_y[m_last]);
m_det[s2][m_last] = m_edge[i][m_last].dot(m_y[i]);
int j;
T_Bits sj;
for (j = 0, sj = 0x1; j < i; ++j, sj <<= 1)
{
if (contains(m_bits1, sj))
{
int k;
T_Bits s3 = sj | s2;
k = m_norm[i][j] < m_norm[m_last][j] ? i : m_last;
m_det[s3][j] = m_det[s2][i] * m_edge[k][j].dot(m_y[i]) +
m_det[s2][m_last] * m_edge[k][j].dot(m_y[m_last]);
k = m_norm[j][i] < m_norm[m_last][i] ? j : m_last;
m_det[s3][i] = m_det[sj|m_last_bit][j] * m_edge[k][i].dot(m_y[j]) +
m_det[sj|m_last_bit][m_last] * m_edge[k][i].dot(m_y[m_last]);
k = m_norm[i][m_last] < m_norm[j][m_last] ? i : j;
m_det[s3][m_last] = m_det[sj|si][j] * m_edge[k][m_last].dot(m_y[j]) +
m_det[sj|si][i] * m_edge[k][m_last].dot(m_y[i]);
}
}
}
}
if (m_all_bits == 0xf)
{
int k;
k = m_norm[1][0] < m_norm[2][0] ? (m_norm[1][0] < m_norm[3][0] ? 1 : 3) : (m_norm[2][0] < m_norm[3][0] ? 2 : 3);
m_det[0xf][0] = m_det[0xe][1] * m_edge[k][0].dot(m_y[1]) +
m_det[0xe][2] * m_edge[k][0].dot(m_y[2]) +
m_det[0xe][3] * m_edge[k][0].dot(m_y[3]);
k = m_norm[0][1] < m_norm[2][1] ? (m_norm[0][1] < m_norm[3][1] ? 0 : 3) : (m_norm[2][1] < m_norm[3][1] ? 2 : 3);
m_det[0xf][1] = m_det[0xd][0] * m_edge[k][1].dot(m_y[0]) +
m_det[0xd][2] * m_edge[k][1].dot(m_y[2]) +
m_det[0xd][3] * m_edge[k][1].dot(m_y[3]);
k = m_norm[0][2] < m_norm[1][2] ? (m_norm[0][2] < m_norm[3][2] ? 0 : 3) : (m_norm[1][2] < m_norm[3][2] ? 1 : 3);
m_det[0xf][2] = m_det[0xb][0] * m_edge[k][2].dot(m_y[0]) +
m_det[0xb][1] * m_edge[k][2].dot(m_y[1]) +
m_det[0xb][3] * m_edge[k][2].dot(m_y[3]);
k = m_norm[0][3] < m_norm[1][3] ? (m_norm[0][3] < m_norm[2][3] ? 0 : 2) : (m_norm[1][3] < m_norm[2][3] ? 1 : 2);
m_det[0xf][3] = m_det[0x7][0] * m_edge[k][3].dot(m_y[0]) +
m_det[0x7][1] * m_edge[k][3].dot(m_y[1]) +
m_det[0x7][2] * m_edge[k][3].dot(m_y[2]);
}
}
#else //JOHNSON_ROBUST
inline void Solid3JohnsonSimplexSolver::compute_det()
{
m_det[m_last_bit][m_last] = 1;
int i;
T_Bits si;
for (i = 0, si = 0x1; i < 4; ++i, si <<= 1)
{
if (contains(m_bits1, si))
{
T_Bits s2 = si | m_last_bit;
m_det[s2][i] = m_edge[m_last][i].dot(m_y[m_last]);
m_det[s2][m_last] = m_edge[i][m_last].dot(m_y[i]);
int j;
T_Bits sj;
for (j = 0, sj = 0x1; j < i; ++j, sj <<= 1)
{
if (contains(m_bits1, sj))
{
T_Bits s3 = sj | s2;
m_det[s3][j] = m_det[s2][i] * m_edge[i][j].dot(m_y[i]) +
m_det[s2][m_last] * m_edge[i][j].dot(m_y[m_last]);
m_det[s3][i] = m_det[sj|m_last_bit][j] * m_edge[j][i].dot(m_y[j]) +
m_det[sj|m_last_bit][m_last] * m_edge[j][i].dot(m_y[m_last]);
m_det[s3][m_last] = m_det[sj|si][j] * m_edge[j][m_last].dot(m_y[j]) +
m_det[sj|si][i] * m_edge[j][m_last].dot(m_y[i]);
}
}
}
}
if (m_all_bits == 0xf)
{
m_det[0xf][0] = m_det[0xe][1] * m_edge[1][0].dot(m_y[1]) +
m_det[0xe][2] * m_edge[1][0].dot(m_y[2]) +
m_det[0xe][3] * m_edge[1][0].dot(m_y[3]);
m_det[0xf][1] = m_det[0xd][0] * m_edge[0][1].dot(m_y[0]) +
m_det[0xd][2] * m_edge[0][1].dot(m_y[2]) +
m_det[0xd][3] * m_edge[0][1].dot(m_y[3]);
m_det[0xf][2] = m_det[0xb][0] * m_edge[0][2].dot(m_y[0]) +
m_det[0xb][1] * m_edge[0][2].dot(m_y[1]) +
m_det[0xb][3] * m_edge[0][2].dot(m_y[3]);
m_det[0xf][3] = m_det[0x7][0] * m_edge[0][3].dot(m_y[0]) +
m_det[0x7][1] * m_edge[0][3].dot(m_y[1]) +
m_det[0x7][2] * m_edge[0][3].dot(m_y[2]);
}
}
#endif //JOHNSON_ROBUST

View File

@@ -0,0 +1,105 @@
/*
* SOLID - Software Library for Interference Detection
*
* Copyright (C) 2001-2003 Dtecta. All rights reserved.
*
* This library may be distributed under the terms of the Q Public License
* (QPL) as defined by Trolltech AS of Norway and appearing in the file
* LICENSE.QPL included in the packaging of this file.
*
* This library may be distributed and/or modified under the terms of the
* GNU bteral Public License (GPL) version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Commercial use or any other use of this library not covered by either
* the QPL or the GPL requires an additional license from Dtecta.
* Please contact info@dtecta.com for enquiries about the terms of commercial
* use of this library.
*/
#ifndef SOLID3JOHNSON_SIMPLEX_SOLVER_H
#define SOLID3JOHNSON_SIMPLEX_SOLVER_H
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
//#define JOHNSON_ROBUST
/// Solid3JohnsonSimplexSolver contains Johnson subdistance algorithm from Solid 3.5 library
class Solid3JohnsonSimplexSolver : public btSimplexSolverInterface
{
private:
typedef unsigned int T_Bits;
inline static bool subseteq(T_Bits a, T_Bits b) { return (a & b) == a; }
inline static bool contains(T_Bits a, T_Bits b) { return (a & b) != 0x0; }
void update_cache();
void compute_det();
bool valid(T_Bits s);
bool proper(T_Bits s);
void compute_vector(T_Bits s, btVector3& v);
btScalar m_det[16][4]; // cached sub-determinants
btVector3 m_edge[4][4];
#ifdef JOHNSON_ROBUST
btScalar m_norm[4][4];
#endif
btPoint3 m_p[4]; // support points of object A in local coordinates
btPoint3 m_q[4]; // support points of object B in local coordinates
btVector3 m_y[4]; // support points of A - B in world coordinates
btScalar m_ylen2[4]; // Squared lengths support points y
btScalar m_maxlen2; // Maximum squared length to a vertex of the current
// simplex
T_Bits m_bits1; // identifies current simplex
T_Bits m_last; // identifies last found support point
T_Bits m_last_bit; // m_last_bit == 0x1 << last
T_Bits m_all_bits; // m_all_bits == m_bits | m_last_bit
private:
void addVertex(const btVector3& w);
public:
Solid3JohnsonSimplexSolver();
virtual ~Solid3JohnsonSimplexSolver();
virtual void reset();
virtual void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q);
virtual bool closest(btVector3& v);
virtual btScalar maxVertex();
virtual bool fullSimplex() const;
virtual int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const;
virtual bool inSimplex(const btVector3& w);
virtual void backup_closest(btVector3& v) ;
virtual bool emptySimplex() const ;
virtual void compute_points(btPoint3& p1, btPoint3& p2) ;
virtual int numVertices() const ;
};
#endif //SOLID3JOHNSON_SIMPLEX_SOLVER_H