Removed experimental code

This commit is contained in:
Irlan 2019-06-02 11:03:19 -03:00
parent f2c7eb64ed
commit d89e658313
5 changed files with 16 additions and 653 deletions

View File

@ -54,7 +54,6 @@
#include <testbed/tests/pyramids.h>
#include <testbed/tests/ray_cast.h>
#include <testbed/tests/sensor_test.h>
#include <testbed/tests/character_test.h>
#include <testbed/tests/body_types.h>
#include <testbed/tests/varying_friction.h>
#include <testbed/tests/varying_restitution.h>
@ -64,7 +63,7 @@
#include <testbed/tests/pinned_cloth.h>
#include <testbed/tests/particle_types.h>
#include <testbed/tests/tension_mapping.h>
#include <testbed/tests/self_collision.h>
#include <testbed/tests/cloth_capsule.h>
#include <testbed/tests/rope_test.h>
#include <testbed/tests/beam.h>
#include <testbed/tests/pinned_softbody.h>
@ -107,7 +106,6 @@ TestEntry g_tests[] =
{ "Box Pyramid Rows", &Pyramids::Create },
{ "Ray Cast", &RayCast::Create },
{ "Sensor Test", &SensorTest::Create },
{ "Character", &CharacterTest::Create },
{ "Body Types", &BodyTypes::Create },
{ "Varying Friction", &VaryingFriction::Create },
{ "Varying Restitution", &VaryingRestitution::Create },
@ -118,7 +116,7 @@ TestEntry g_tests[] =
{ "Pinned Cloth", &PinnedCloth::Create },
{ "Particle Types", &ParticleTypes::Create },
{ "Tension Mapping", &TensionMapping::Create },
{ "Self-Collision", &SelfCollision::Create },
{ "Cloth and Capsule", &ClothCapsule::Create },
{ "Beam", &Beam::Create },
{ "Pinned Soft Body", &PinnedSoftBody::Create },
{ "Smash Soft Body", &SmashSoftBody::Create },

View File

@ -1,624 +0,0 @@
/*
* Copyright (c) 2016-2019 Irlan Robson https://irlanrobson.github.io
*
* 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 CHARACTER_TEST_H
#define CHARACTER_TEST_H
struct Plane
{
b3Vec3 n;
b3Vec3 p;
};
class CharacterController
{
public:
CharacterController(b3SphereShape* shape)
{
m_characterShape = shape;
m_characterBody = m_characterShape->GetBody();
m_world = m_characterBody->GetWorld();
m_translation.SetZero();
m_isGrounded = false;
UpdateGrounded();
}
~CharacterController()
{
}
bool IsGrounded() const
{
return m_isGrounded;
}
void Move(const b3Vec3& translation)
{
m_translation += translation;
}
void Step()
{
Solve();
UpdateGrounded();
}
private:
b3Sphere GetCharacterSphere() const
{
b3Sphere sphere;
sphere.vertex = m_characterBody->GetWorldPoint(m_characterShape->m_center);
sphere.radius = m_characterShape->m_radius;
return sphere;
}
void UpdateGrounded()
{
b3StackArray<b3Shape*, 32> shapes;
CollectStaticShapes(shapes);
b3StackArray<Plane, 32> planes;
CollectOverlapPlanes(planes, shapes);
m_isGrounded = false;
for (u32 i = 0; i < planes.Count(); ++i)
{
Plane plane = planes[i];
float32 cosine = b3Dot(b3Vec3_y, plane.n);
// ~80 degrees
const float32 kTol = 0.17f;
if (cosine > kTol)
{
m_isGrounded = true;
break;
}
}
}
void CollectStaticShapes(b3Array<b3Shape*>& shapes) const
{
for (b3Body* b = m_world->GetBodyList().m_head; b; b = b->GetNext())
{
if (b == m_characterBody)
{
continue;
}
if (b->GetType() != e_staticBody)
{
continue;
}
for (b3Shape* s = b->GetShapeList().m_head; s; s = s->GetNext())
{
shapes.PushBack(s);
}
}
}
void CollectOverlapPlanes(b3Array<Plane>& planes,
const b3Array<b3Shape*>& shapes) const
{
b3Sphere sphere2 = GetCharacterSphere();
for (u32 i = 0; i < shapes.Count(); ++i)
{
b3Shape* shape1 = shapes[i];
b3Body* body1 = shape1->GetBody();
b3Transform xf1 = body1->GetTransform();
if (shape1->GetType() == e_meshShape)
{
b3MeshShape* meshShape1 = (b3MeshShape*)shape1;
const b3Mesh* mesh1 = meshShape1->m_mesh;
for (u32 j = 0; j < mesh1->triangleCount; ++j)
{
b3TestSphereOutput output;
bool overlap = meshShape1->TestSphere(&output, sphere2, xf1, j);
if (overlap)
{
Plane plane;
plane.n = output.normal;
plane.p = output.point;
planes.PushBack(plane);
}
}
}
else
{
b3TestSphereOutput output;
bool overlap = shape1->TestSphere(&output, sphere2, xf1);
if (overlap)
{
Plane plane;
plane.n = output.normal;
plane.p = output.point;
planes.PushBack(plane);
}
}
}
}
void CollectSweepPlanes(b3Array<Plane>& planes,
const b3Array<b3Shape*>& shapes,
const b3Vec3& translation2) const
{
if (b3LengthSquared(translation2) < B3_EPSILON * B3_EPSILON)
{
return;
}
b3Transform xf2 = m_characterBody->GetTransform();
b3ShapeGJKProxy proxy2;
proxy2.Set(m_characterShape, 0);
for (u32 i = 0; i < shapes.Count(); ++i)
{
b3Shape* shape1 = shapes[i];
b3Body* body1 = shape1->GetBody();
b3Transform xf1 = body1->GetTransform();
if (shape1->GetType() == e_meshShape)
{
b3MeshShape* meshShape1 = (b3MeshShape*)shape1;
const b3Mesh* mesh1 = meshShape1->m_mesh;
for (u32 j = 0; j < mesh1->triangleCount; ++j)
{
b3ShapeGJKProxy proxy1;
proxy1.Set(shape1, j);
b3GJKShapeCastOutput output;
bool hit = b3GJKShapeCast(&output, xf1, proxy1, xf2, proxy2, translation2);
if (hit)
{
Plane plane;
plane.n = output.normal;
plane.p = output.point;
planes.PushBack(plane);
}
}
}
else
{
b3ShapeGJKProxy proxy1;
proxy1.Set(shape1, 0);
b3GJKShapeCastOutput output;
bool hit = b3GJKShapeCast(&output, xf1, proxy1, xf2, proxy2, translation2);
if (hit)
{
Plane plane;
plane.n = output.normal;
plane.p = output.point;
planes.PushBack(plane);
}
}
}
}
b3Vec3 SolvePositionConstraints(const b3Array<Plane>& planes, const b3Vec3& position) const
{
b3Vec3 localCenter = m_characterBody->GetLocalCenter();
b3Vec3 c = position;
b3Quat q = m_characterBody->GetOrientation();
const u32 kMaxPositionIterations = 10;
for (u32 i = 0; i < kMaxPositionIterations; ++i)
{
for (u32 j = 0; j < planes.Count(); ++j)
{
Plane nc = planes[j];
b3Plane plane(nc.n, nc.p);
b3Transform xf;
xf.rotation = b3QuatMat33(q);
xf.position = c - b3Mul(xf.rotation, localCenter);
b3Sphere sphere;
sphere.vertex = b3Mul(xf, m_characterShape->m_center);
sphere.radius = m_characterShape->m_radius;
float32 separation = b3Distance(sphere.vertex, plane);
if (separation > sphere.radius)
{
continue;
}
separation -= sphere.radius;
float32 C = b3Clamp(B3_BAUMGARTE * (separation + B3_LINEAR_SLOP), -B3_MAX_LINEAR_CORRECTION, 0.0f);
b3Vec3 normal = plane.normal;
b3Vec3 P = C * normal;
c -= P;
}
}
return c;
}
void Solve()
{
b3StackArray<b3Shape*, 32> shapes;
CollectStaticShapes(shapes);
// Collect collision planes
b3StackArray<Plane, 32> planes;
CollectOverlapPlanes(planes, shapes);
b3Vec3 startPosition = m_characterBody->GetWorldCenter();
b3Vec3 targetPosition = startPosition + m_translation;
m_translation.SetZero();
b3Vec3 solvePosition = SolvePositionConstraints(planes, targetPosition);
b3Vec3 oldSolvePosition = solvePosition;
for (;;)
{
// Collect collision planes
b3Vec3 translation = solvePosition - startPosition;
CollectSweepPlanes(planes, shapes, translation);
solvePosition = SolvePositionConstraints(planes, targetPosition);
const float32 tolerance = 0.05f;
if (b3DistanceSquared(oldSolvePosition, solvePosition) < tolerance * tolerance)
{
break;
}
oldSolvePosition = solvePosition;
}
// Synchronize body
b3Quat orientation = m_characterBody->GetOrientation();
b3Vec3 axis;
float32 angle;
orientation.GetAxisAngle(&axis, &angle);
m_characterBody->SetTransform(solvePosition, axis, angle);
}
b3World* m_world;
b3Body* m_characterBody;
b3SphereShape* m_characterShape;
b3Vec3 m_translation;
bool m_isGrounded;
};
class CharacterTest : public Test
{
public:
CharacterTest()
{
{
b3BodyDef bdef;
b3Body* body = m_world.CreateBody(bdef);
b3HullShape hs;
hs.m_hull = &m_groundHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(-10.0f, 3.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(2.0f, 2.0f, 5.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(-10.0f, 9.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(1.0f, 4.0f, 1.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(-10.0f, 2.7f, 7.0f);
bdef.orientation.Set(b3Vec3_x, 0.25f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(2.0f, 0.25f, 3.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(-10.0f, 2.7f, -7.0f);
bdef.orientation.Set(b3Vec3_x, -0.25f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(2.0f, 0.25f, 3.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(10.0f, 3.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(2.0f, 2.0f, 5.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(10.0f, 9.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(1.0f, 4.0f, 1.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(10.0f, 2.7f, 7.0f);
bdef.orientation.Set(b3Vec3_x, 0.25f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(2.0f, 0.25f, 3.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(10.0f, 2.7f, -7.0f);
bdef.orientation.Set(b3Vec3_x, -0.25f * B3_PI);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(2.0f, 0.25f, 3.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.position.Set(0.0f, 4.0f, 0.0f);
b3Body* body = m_world.CreateBody(bdef);
static b3BoxHull boxHull;
boxHull.Set(8.0f, 1.0f, 2.0f);
b3HullShape hs;
hs.m_hull = &boxHull;
b3ShapeDef sdef;
sdef.shape = &hs;
b3Shape* shape = body->CreateShape(sdef);
}
{
b3BodyDef bdef;
bdef.type = b3BodyType::e_kinematicBody;
bdef.position.Set(0.0f, 1.0f, 20.0f);
b3Body* body = m_world.CreateBody(bdef);
b3SphereShape sphere;
sphere.m_center.SetZero();
sphere.m_radius = 1.0f;
b3ShapeDef sdef;
sdef.shape = &sphere;
b3SphereShape* shape = (b3SphereShape*)body->CreateShape(sdef);
m_characterController = new CharacterController(shape);
}
}
~CharacterTest()
{
delete m_characterController;
}
void Step()
{
g_draw->DrawString(b3Color_white, "Arrows - Walk");
g_draw->DrawString(b3Color_white, "Space - Jump");
float32 dt = g_testSettings->inv_hertz;
const float32 walkSpeed = 10.0f;
const float32 jumpSpeed = 10.0f;
const float32 gravityAcc = 9.8f;
static b3Vec3 velocity = b3Vec3_zero;
velocity.x = 0.0f;
velocity.z = 0.0f;
extern GLFWwindow* g_window;
bool leftDown = glfwGetKey(g_window, GLFW_KEY_LEFT);
bool rightDown = glfwGetKey(g_window, GLFW_KEY_RIGHT);
bool downDown = glfwGetKey(g_window, GLFW_KEY_DOWN);
bool upDown = glfwGetKey(g_window, GLFW_KEY_UP);
bool spaceDown = glfwGetKey(g_window, GLFW_KEY_SPACE);
bool isGrounded = m_characterController->IsGrounded();
// Walk
if (leftDown)
{
velocity.x -= walkSpeed;
}
if (rightDown)
{
velocity.x += walkSpeed;
}
if (upDown)
{
velocity.z -= walkSpeed;
}
if (downDown)
{
velocity.z += walkSpeed;
}
if (isGrounded)
{
velocity.y = 0.0f;
// Jump
if (spaceDown)
{
velocity.y += jumpSpeed;
}
}
else
{
// Integrate gravity
velocity.y -= dt * gravityAcc;
}
// Compute translation
b3Vec3 translation = dt * velocity;
// Move character
m_characterController->Move(translation);
// Step controllers
m_characterController->Step();
// Step world
Test::Step();
}
static Test* Create()
{
return new CharacterTest();
}
CharacterController* m_characterController;
};
#endif

View File

@ -16,13 +16,13 @@
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SELF_COLLISION_H
#define SELF_COLLISION_H
#ifndef CLOTH_CAPSULE_H
#define CLOTH_CAPSULE_H
class SelfCollision : public Test
class ClothCapsule : public Test
{
public:
SelfCollision() : m_rectangleGarment(5.0f, 5.0f)
ClothCapsule() : m_rectangleGarment(5.0f, 5.0f)
{
// Generate 2D mesh
m_rectangleGarmentMesh.Set(&m_rectangleGarment, 1.0f);
@ -76,7 +76,7 @@ public:
m_clothDragger = new b3ClothDragger(&m_ray, m_cloth);
}
~SelfCollision()
~ClothCapsule()
{
delete m_cloth;
delete m_clothDragger;
@ -141,7 +141,7 @@ public:
static Test* Create()
{
return new SelfCollision();
return new ClothCapsule();
}
b3RectangleGarment m_rectangleGarment;

View File

@ -53,7 +53,7 @@ public:
for (b3Particle* p = m_cloth->GetParticleList().m_head; p; p = p->GetNext())
{
p->SetRadius(0.05f);
p->SetRadius(0.1f);
p->SetFriction(0.2f);
}

View File

@ -17,9 +17,7 @@
*/
#include <bounce/dynamics/shapes/mesh_shape.h>
#include <bounce/dynamics/shapes/hull_shape.h>
#include <bounce/collision/shapes/mesh.h>
#include <bounce/collision/shapes/triangle_hull.h>
b3MeshShape::b3MeshShape()
{
@ -92,20 +90,11 @@ bool b3MeshShape::TestSphere(b3TestSphereOutput* output, const b3Sphere& sphere,
bool b3MeshShape::TestSphere(b3TestSphereOutput* output, const b3Sphere& sphere, const b3Transform& xf, u32 index) const
{
B3_ASSERT(index < m_mesh->triangleCount);
b3Triangle* triangle = m_mesh->triangles + index;
b3Vec3 v1 = m_mesh->vertices[triangle->v1];
b3Vec3 v2 = m_mesh->vertices[triangle->v2];
b3Vec3 v3 = m_mesh->vertices[triangle->v3];
b3TriangleHull hull(v1, v2, v3);
b3HullShape hullShape;
hullShape.m_body = m_body;
hullShape.m_hull = &hull;
hullShape.m_radius = B3_HULL_RADIUS;
return hullShape.TestSphere(output, sphere, xf);
B3_NOT_USED(output);
B3_NOT_USED(sphere);
B3_NOT_USED(xf);
B3_NOT_USED(index);
return false;
}
bool b3MeshShape::RayCast(b3RayCastOutput* output, const b3RayCastInput& input, const b3Transform& xf, u32 index) const
@ -137,7 +126,7 @@ bool b3MeshShape::RayCast(b3RayCastOutput* output, const b3RayCastInput& input,
return false;
}
struct b3MeshRayCastCallback
struct b3MeshShapeRayCastCallback
{
float32 Report(const b3RayCastInput& subInput, u32 proxyId)
{
@ -169,7 +158,7 @@ struct b3MeshRayCastCallback
bool b3MeshShape::RayCast(b3RayCastOutput* output, const b3RayCastInput& input, const b3Transform& xf) const
{
b3MeshRayCastCallback callback;
b3MeshShapeRayCastCallback callback;
callback.input = input;
callback.mesh = this;
callback.xf = xf;