Organize cloth contacts
This commit is contained in:
parent
6b92664c1e
commit
f7becc7ee7
64
include/bounce/cloth/cloth_contact.h
Normal file
64
include/bounce/cloth/cloth_contact.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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 B3_CLOTH_CONTACT_H
|
||||||
|
#define B3_CLOTH_CONTACT_H
|
||||||
|
|
||||||
|
#include <bounce/common/template/list.h>
|
||||||
|
|
||||||
|
class b3Particle;
|
||||||
|
struct b3ClothMeshTriangle;
|
||||||
|
struct b3ClothAABBProxy;
|
||||||
|
|
||||||
|
// Contact between particle and a triangle
|
||||||
|
class b3ParticleTriangleContact
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
private:
|
||||||
|
friend class b3Cloth;
|
||||||
|
friend class b3Particle;
|
||||||
|
friend class b3ClothContactManager;
|
||||||
|
friend class b3List2<b3ParticleTriangleContact>;
|
||||||
|
friend class b3ClothContactSolver;
|
||||||
|
|
||||||
|
b3ParticleTriangleContact() { }
|
||||||
|
~b3ParticleTriangleContact() { }
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
// Particle
|
||||||
|
b3Particle* m_p1;
|
||||||
|
|
||||||
|
// Triangle
|
||||||
|
b3ClothMeshTriangle* m_triangle;
|
||||||
|
b3ClothAABBProxy* m_triangleProxy;
|
||||||
|
b3Particle* m_p2;
|
||||||
|
b3Particle* m_p3;
|
||||||
|
b3Particle* m_p4;
|
||||||
|
|
||||||
|
float32 m_normalImpulse;
|
||||||
|
|
||||||
|
bool m_front;
|
||||||
|
|
||||||
|
bool m_active;
|
||||||
|
|
||||||
|
b3ParticleTriangleContact* m_prev;
|
||||||
|
b3ParticleTriangleContact* m_next;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -19,36 +19,12 @@
|
|||||||
#ifndef B3_CLOTH_CONTACT_MANAGER_H
|
#ifndef B3_CLOTH_CONTACT_MANAGER_H
|
||||||
#define B3_CLOTH_CONTACT_MANAGER_H
|
#define B3_CLOTH_CONTACT_MANAGER_H
|
||||||
|
|
||||||
|
#include <bounce/cloth/cloth_contact.h>
|
||||||
|
#include <bounce/collision/broad_phase.h>
|
||||||
#include <bounce/common/memory/block_pool.h>
|
#include <bounce/common/memory/block_pool.h>
|
||||||
#include <bounce/common/template/list.h>
|
#include <bounce/common/template/list.h>
|
||||||
#include <bounce/collision/broad_phase.h>
|
|
||||||
|
|
||||||
class b3Cloth;
|
class b3Cloth;
|
||||||
class b3Particle;
|
|
||||||
struct b3ClothMeshTriangle;
|
|
||||||
struct b3ClothAABBProxy;
|
|
||||||
|
|
||||||
// Contact between particle and a triangle
|
|
||||||
class b3ParticleTriangleContact
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
b3Particle* m_p1;
|
|
||||||
|
|
||||||
b3ClothMeshTriangle* m_triangle;
|
|
||||||
b3ClothAABBProxy* m_triangleProxy;
|
|
||||||
b3Particle* m_p2;
|
|
||||||
b3Particle* m_p3;
|
|
||||||
b3Particle* m_p4;
|
|
||||||
|
|
||||||
bool m_front;
|
|
||||||
|
|
||||||
bool m_active;
|
|
||||||
|
|
||||||
float32 m_normalImpulse;
|
|
||||||
|
|
||||||
b3ParticleTriangleContact* m_prev;
|
|
||||||
b3ParticleTriangleContact* m_next;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Contact delegator for b3Cloth.
|
// Contact delegator for b3Cloth.
|
||||||
class b3ClothContactManager
|
class b3ClothContactManager
|
||||||
@ -63,18 +39,13 @@ public:
|
|||||||
|
|
||||||
void UpdateContacts();
|
void UpdateContacts();
|
||||||
|
|
||||||
b3ParticleTriangleContact* Create();
|
b3ParticleTriangleContact* CreateParticleTriangleContact();
|
||||||
|
|
||||||
void Destroy(b3ParticleTriangleContact* c);
|
void Destroy(b3ParticleTriangleContact* c);
|
||||||
|
|
||||||
void Update(b3ParticleTriangleContact* c);
|
|
||||||
|
|
||||||
b3Cloth* m_cloth;
|
|
||||||
|
|
||||||
b3BlockPool m_particleTriangleContactBlocks;
|
b3BlockPool m_particleTriangleContactBlocks;
|
||||||
|
|
||||||
|
b3Cloth* m_cloth;
|
||||||
b3BroadPhase m_broadPhase;
|
b3BroadPhase m_broadPhase;
|
||||||
|
|
||||||
b3List2<b3ParticleTriangleContact> m_particleTriangleContactList;
|
b3List2<b3ParticleTriangleContact> m_particleTriangleContactList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
#ifndef B3_PARTICLE_H
|
#ifndef B3_PARTICLE_H
|
||||||
#define B3_PARTICLE_H
|
#define B3_PARTICLE_H
|
||||||
|
|
||||||
|
#include <bounce/cloth/force.h>
|
||||||
#include <bounce/common/math/transform.h>
|
#include <bounce/common/math/transform.h>
|
||||||
#include <bounce/common/math/vec2.h>
|
#include <bounce/common/math/vec2.h>
|
||||||
#include <bounce/common/template/list.h>
|
#include <bounce/common/template/list.h>
|
||||||
#include <bounce/cloth/force.h>
|
|
||||||
|
|
||||||
class b3Shape;
|
class b3Shape;
|
||||||
class b3Cloth;
|
class b3Cloth;
|
||||||
@ -91,12 +91,14 @@ struct b3ParticleBodyContactWorldPoint
|
|||||||
float32 separation;
|
float32 separation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Cloth primitive type
|
||||||
enum b3ClothAABBProxyType
|
enum b3ClothAABBProxyType
|
||||||
{
|
{
|
||||||
e_particleProxy,
|
e_particleProxy,
|
||||||
e_triangleProxy
|
e_triangleProxy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Cloth primitive broadphase proxy
|
||||||
struct b3ClothAABBProxy
|
struct b3ClothAABBProxy
|
||||||
{
|
{
|
||||||
b3ClothAABBProxyType type;
|
b3ClothAABBProxyType type;
|
||||||
@ -160,6 +162,7 @@ private:
|
|||||||
friend class b3Cloth;
|
friend class b3Cloth;
|
||||||
friend class b3ClothSolver;
|
friend class b3ClothSolver;
|
||||||
friend class b3ClothContactManager;
|
friend class b3ClothContactManager;
|
||||||
|
friend class b3ParticleTriangleContact;
|
||||||
friend class b3ClothContactSolver;
|
friend class b3ClothContactSolver;
|
||||||
friend class b3Force;
|
friend class b3Force;
|
||||||
friend class b3SpringForce;
|
friend class b3SpringForce;
|
||||||
@ -226,10 +229,8 @@ private:
|
|||||||
// AABB Proxy
|
// AABB Proxy
|
||||||
b3ClothAABBProxy m_aabbProxy;
|
b3ClothAABBProxy m_aabbProxy;
|
||||||
|
|
||||||
//
|
// Links to the cloth particle list.
|
||||||
b3Particle* m_prev;
|
b3Particle* m_prev;
|
||||||
|
|
||||||
//
|
|
||||||
b3Particle* m_next;
|
b3Particle* m_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
183
src/bounce/cloth/cloth_contact.cpp
Normal file
183
src/bounce/cloth/cloth_contact.cpp
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bounce/cloth/cloth_contact.h>
|
||||||
|
#include <bounce/cloth/cloth_mesh.h>
|
||||||
|
#include <bounce/cloth/particle.h>
|
||||||
|
#include <bounce/common/geometry.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
static void b3Solve3(float32 out[3],
|
||||||
|
const b3Vec3& A, const b3Vec3& B, const b3Vec3& C,
|
||||||
|
const b3Vec3& Q)
|
||||||
|
{
|
||||||
|
// Test vertex regions
|
||||||
|
float32 wAB[3], wBC[3], wCA[3];
|
||||||
|
b3BarycentricCoordinates(wAB, A, B, Q);
|
||||||
|
b3BarycentricCoordinates(wBC, B, C, Q);
|
||||||
|
b3BarycentricCoordinates(wCA, C, A, Q);
|
||||||
|
|
||||||
|
// R A
|
||||||
|
if (wAB[1] <= 0.0f && wCA[0] <= 0.0f)
|
||||||
|
{
|
||||||
|
out[0] = 1.0f;
|
||||||
|
out[1] = 0.0f;
|
||||||
|
out[2] = 0.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// R B
|
||||||
|
if (wAB[0] <= 0.0f && wBC[1] <= 0.0f)
|
||||||
|
{
|
||||||
|
out[0] = 0.0f;
|
||||||
|
out[1] = 1.0f;
|
||||||
|
out[2] = 0.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// R C
|
||||||
|
if (wBC[0] <= 0.0f && wCA[1] <= 0.0f)
|
||||||
|
{
|
||||||
|
out[0] = 0.0f;
|
||||||
|
out[1] = 0.0f;
|
||||||
|
out[2] = 1.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test edge regions
|
||||||
|
float32 wABC[4];
|
||||||
|
b3BarycentricCoordinates(wABC, A, B, C, Q);
|
||||||
|
|
||||||
|
// R AB
|
||||||
|
if (wAB[0] > 0.0f && wAB[1] > 0.0f && wABC[3] * wABC[2] <= 0.0f)
|
||||||
|
{
|
||||||
|
float32 divisor = wAB[2];
|
||||||
|
B3_ASSERT(divisor > 0.0f);
|
||||||
|
float32 s = 1.0f / divisor;
|
||||||
|
out[0] = s * wAB[0];
|
||||||
|
out[1] = s * wAB[1];
|
||||||
|
out[2] = 0.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// R BC
|
||||||
|
if (wBC[0] > 0.0f && wBC[1] > 0.0f && wABC[3] * wABC[0] <= 0.0f)
|
||||||
|
{
|
||||||
|
float32 divisor = wBC[2];
|
||||||
|
B3_ASSERT(divisor > 0.0f);
|
||||||
|
float32 s = 1.0f / divisor;
|
||||||
|
out[0] = 0.0f;
|
||||||
|
out[1] = s * wBC[0];
|
||||||
|
out[2] = s * wBC[1];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// R CA
|
||||||
|
if (wCA[0] > 0.0f && wCA[1] > 0.0f && wABC[3] * wABC[1] <= 0.0f)
|
||||||
|
{
|
||||||
|
float32 divisor = wCA[2];
|
||||||
|
B3_ASSERT(divisor > 0.0f);
|
||||||
|
float32 s = 1.0f / divisor;
|
||||||
|
out[0] = s * wCA[1];
|
||||||
|
out[1] = 0.0f;
|
||||||
|
out[2] = s * wCA[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// R ABC/ACB
|
||||||
|
float32 divisor = wABC[3];
|
||||||
|
if (divisor == 0.0f)
|
||||||
|
{
|
||||||
|
float32 s = 1.0f / 3.0f;
|
||||||
|
out[0] = s;
|
||||||
|
out[1] = s;
|
||||||
|
out[2] = s;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
B3_ASSERT(divisor > 0.0f);
|
||||||
|
float32 s = 1.0f / divisor;
|
||||||
|
out[0] = s * wABC[0];
|
||||||
|
out[1] = s * wABC[1];
|
||||||
|
out[2] = s * wABC[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
void b3ParticleTriangleContact::Update()
|
||||||
|
{
|
||||||
|
b3Vec3 A = m_p2->m_position;
|
||||||
|
b3Vec3 B = m_p3->m_position;
|
||||||
|
b3Vec3 C = m_p4->m_position;
|
||||||
|
|
||||||
|
b3Vec3 N = b3Cross(B - A, C - A);
|
||||||
|
float32 len = N.Normalize();
|
||||||
|
|
||||||
|
// Is ABC degenerate?
|
||||||
|
if (len == 0.0f)
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float32 r1 = m_p1->m_radius;
|
||||||
|
float32 r2 = 0.0f;
|
||||||
|
|
||||||
|
float32 totalRadius = r1 + r2;
|
||||||
|
|
||||||
|
b3Vec3 P1 = m_p1->m_position;
|
||||||
|
|
||||||
|
float32 distance = b3Dot(N, P1 - A);
|
||||||
|
|
||||||
|
// Is P1 below the plane?
|
||||||
|
if (distance < -totalRadius)
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is P1 above the plane?
|
||||||
|
if (distance > totalRadius)
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Closest point on ABC to P1
|
||||||
|
float32 wABC[3];
|
||||||
|
b3Solve3(wABC, A, B, C, P1);
|
||||||
|
|
||||||
|
b3Vec3 P2 = wABC[0] * A + wABC[1] * B + wABC[2] * C;
|
||||||
|
|
||||||
|
if (b3DistanceSquared(P1, P2) > totalRadius * totalRadius)
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate the contact
|
||||||
|
m_active = true;
|
||||||
|
|
||||||
|
// Is P1 in front or back of the plane?
|
||||||
|
if (distance >= 0.0f)
|
||||||
|
{
|
||||||
|
m_front = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_front = false;
|
||||||
|
}
|
||||||
|
}
|
@ -93,26 +93,23 @@ void b3ClothContactManager::AddPair(void* data1, void* data2)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new contact.
|
// Create a new contact.
|
||||||
b3ParticleTriangleContact* c = Create();
|
b3ParticleTriangleContact* c = CreateParticleTriangleContact();
|
||||||
|
|
||||||
c->m_p1 = p1;
|
c->m_p1 = p1;
|
||||||
|
c->m_triangle = triangle;
|
||||||
|
c->m_triangleProxy = proxy2;
|
||||||
c->m_p2 = p2;
|
c->m_p2 = p2;
|
||||||
c->m_p3 = p3;
|
c->m_p3 = p3;
|
||||||
c->m_p4 = p4;
|
c->m_p4 = p4;
|
||||||
c->m_triangle = triangle;
|
c->m_normalImpulse = 0.0f;
|
||||||
c->m_triangleProxy = proxy2;
|
|
||||||
|
|
||||||
c->m_front = false;
|
c->m_front = false;
|
||||||
c->m_active = false;
|
c->m_active = false;
|
||||||
|
|
||||||
c->m_normalImpulse = 0.0f;
|
|
||||||
|
|
||||||
// Add the contact to the cloth contact list.
|
// Add the contact to the cloth contact list.
|
||||||
m_particleTriangleContactList.PushFront(c);
|
m_particleTriangleContactList.PushFront(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
b3ParticleTriangleContact* b3ClothContactManager::Create()
|
b3ParticleTriangleContact* b3ClothContactManager::CreateParticleTriangleContact()
|
||||||
{
|
{
|
||||||
void* block = m_particleTriangleContactBlocks.Allocate();
|
void* block = m_particleTriangleContactBlocks.Allocate();
|
||||||
return new(block) b3ParticleTriangleContact();
|
return new(block) b3ParticleTriangleContact();
|
||||||
@ -127,177 +124,11 @@ void b3ClothContactManager::Destroy(b3ParticleTriangleContact* c)
|
|||||||
m_particleTriangleContactBlocks.Free(c);
|
m_particleTriangleContactBlocks.Free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void b3Solve3(float32 out[3],
|
|
||||||
const b3Vec3& A, const b3Vec3& B, const b3Vec3& C,
|
|
||||||
const b3Vec3& Q)
|
|
||||||
{
|
|
||||||
// Test vertex regions
|
|
||||||
float32 wAB[3], wBC[3], wCA[3];
|
|
||||||
b3BarycentricCoordinates(wAB, A, B, Q);
|
|
||||||
b3BarycentricCoordinates(wBC, B, C, Q);
|
|
||||||
b3BarycentricCoordinates(wCA, C, A, Q);
|
|
||||||
|
|
||||||
// R A
|
|
||||||
if (wAB[1] <= 0.0f && wCA[0] <= 0.0f)
|
|
||||||
{
|
|
||||||
out[0] = 1.0f;
|
|
||||||
out[1] = 0.0f;
|
|
||||||
out[2] = 0.0f;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// R B
|
|
||||||
if (wAB[0] <= 0.0f && wBC[1] <= 0.0f)
|
|
||||||
{
|
|
||||||
out[0] = 0.0f;
|
|
||||||
out[1] = 1.0f;
|
|
||||||
out[2] = 0.0f;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// R C
|
|
||||||
if (wBC[0] <= 0.0f && wCA[1] <= 0.0f)
|
|
||||||
{
|
|
||||||
out[0] = 0.0f;
|
|
||||||
out[1] = 0.0f;
|
|
||||||
out[2] = 1.0f;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test edge regions
|
|
||||||
float32 wABC[4];
|
|
||||||
b3BarycentricCoordinates(wABC, A, B, C, Q);
|
|
||||||
|
|
||||||
// R AB
|
|
||||||
if (wAB[0] > 0.0f && wAB[1] > 0.0f && wABC[3] * wABC[2] <= 0.0f)
|
|
||||||
{
|
|
||||||
float32 divisor = wAB[2];
|
|
||||||
B3_ASSERT(divisor > 0.0f);
|
|
||||||
float32 s = 1.0f / divisor;
|
|
||||||
out[0] = s * wAB[0];
|
|
||||||
out[1] = s * wAB[1];
|
|
||||||
out[2] = 0.0f;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// R BC
|
|
||||||
if (wBC[0] > 0.0f && wBC[1] > 0.0f && wABC[3] * wABC[0] <= 0.0f)
|
|
||||||
{
|
|
||||||
float32 divisor = wBC[2];
|
|
||||||
B3_ASSERT(divisor > 0.0f);
|
|
||||||
float32 s = 1.0f / divisor;
|
|
||||||
out[0] = 0.0f;
|
|
||||||
out[1] = s * wBC[0];
|
|
||||||
out[2] = s * wBC[1];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// R CA
|
|
||||||
if (wCA[0] > 0.0f && wCA[1] > 0.0f && wABC[3] * wABC[1] <= 0.0f)
|
|
||||||
{
|
|
||||||
float32 divisor = wCA[2];
|
|
||||||
B3_ASSERT(divisor > 0.0f);
|
|
||||||
float32 s = 1.0f / divisor;
|
|
||||||
out[0] = s * wCA[1];
|
|
||||||
out[1] = 0.0f;
|
|
||||||
out[2] = s * wCA[0];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// R ABC/ACB
|
|
||||||
float32 divisor = wABC[3];
|
|
||||||
if (divisor == 0.0f)
|
|
||||||
{
|
|
||||||
float32 s = 1.0f / 3.0f;
|
|
||||||
out[0] = s;
|
|
||||||
out[1] = s;
|
|
||||||
out[2] = s;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
B3_ASSERT(divisor > 0.0f);
|
|
||||||
float32 s = 1.0f / divisor;
|
|
||||||
out[0] = s * wABC[0];
|
|
||||||
out[1] = s * wABC[1];
|
|
||||||
out[2] = s * wABC[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
void b3ClothContactManager::Update(b3ParticleTriangleContact* c)
|
|
||||||
{
|
|
||||||
b3Particle* p1 = c->m_p1;
|
|
||||||
|
|
||||||
b3Particle* p2 = c->m_p2;
|
|
||||||
b3Particle* p3 = c->m_p3;
|
|
||||||
b3Particle* p4 = c->m_p4;
|
|
||||||
|
|
||||||
float32 r1 = p1->m_radius;
|
|
||||||
float32 r2 = 0.0f;
|
|
||||||
|
|
||||||
float32 totalRadius = r1 + r2;
|
|
||||||
|
|
||||||
b3Vec3 A = p2->m_position;
|
|
||||||
b3Vec3 B = p3->m_position;
|
|
||||||
b3Vec3 C = p4->m_position;
|
|
||||||
|
|
||||||
b3Vec3 n = b3Cross(B - A, C - A);
|
|
||||||
float32 len = n.Normalize();
|
|
||||||
|
|
||||||
// Is ABC degenerate?
|
|
||||||
if (len == 0.0f)
|
|
||||||
{
|
|
||||||
c->m_active = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
b3Vec3 P1 = p1->m_position;
|
|
||||||
|
|
||||||
float32 distance = b3Dot(n, P1 - A);
|
|
||||||
|
|
||||||
// Is P1 below the plane?
|
|
||||||
if (distance < -totalRadius)
|
|
||||||
{
|
|
||||||
c->m_active = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is P1 above the plane?
|
|
||||||
if (distance > totalRadius)
|
|
||||||
{
|
|
||||||
c->m_active = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closest point on ABC to P1
|
|
||||||
float32 wABC[3];
|
|
||||||
b3Solve3(wABC, A, B, C, P1);
|
|
||||||
|
|
||||||
b3Vec3 P2 = wABC[0] * A + wABC[1] * B + wABC[2] * C;
|
|
||||||
|
|
||||||
if (b3DistanceSquared(P1, P2) > totalRadius * totalRadius)
|
|
||||||
{
|
|
||||||
c->m_active = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate the contact
|
|
||||||
c->m_active = true;
|
|
||||||
|
|
||||||
// Is the the other point in front of the plane?
|
|
||||||
if (distance >= 0.0f)
|
|
||||||
{
|
|
||||||
c->m_front = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c->m_front = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void b3ClothContactManager::UpdateContacts()
|
void b3ClothContactManager::UpdateContacts()
|
||||||
{
|
{
|
||||||
B3_PROFILE("Cloth Update Contacts");
|
B3_PROFILE("Cloth Update Contacts");
|
||||||
|
|
||||||
// Update the state of all triangle contacts.
|
// Update the state of particle-triangle contacts.
|
||||||
b3ParticleTriangleContact* c = m_particleTriangleContactList.m_head;
|
b3ParticleTriangleContact* c = m_particleTriangleContactList.m_head;
|
||||||
while (c)
|
while (c)
|
||||||
{
|
{
|
||||||
@ -327,7 +158,7 @@ void b3ClothContactManager::UpdateContacts()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The contact persists.
|
// The contact persists.
|
||||||
Update(c);
|
c->Update();
|
||||||
|
|
||||||
c = c->m_next;
|
c = c->m_next;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user