consistency
This commit is contained in:
parent
f5e20589eb
commit
db54750a87
@ -35,16 +35,18 @@ void b3EndProfileScope()
|
||||
g_profiler->PopEvent();
|
||||
}
|
||||
|
||||
Test::Test() : m_bodyDragger(&m_bodyRay, &m_world)
|
||||
Test::Test() :
|
||||
m_bodyDragger(&m_ray, &m_world),
|
||||
m_clothDragger(&m_ray, &m_world)
|
||||
{
|
||||
b3Draw_draw = g_draw;
|
||||
b3_convexCache = g_testSettings->convexCache;
|
||||
|
||||
m_world.SetContactListener(this);
|
||||
|
||||
m_bodyRay.origin.SetZero();
|
||||
m_bodyRay.direction.Set(0.0f, 0.0f, -1.0f);
|
||||
m_bodyRay.fraction = g_camera->m_zFar;
|
||||
m_ray.origin.SetZero();
|
||||
m_ray.direction.Set(0.0f, 0.0f, -1.0f);
|
||||
m_ray.fraction = g_camera->m_zFar;
|
||||
|
||||
m_groundHull.Set(50.0f, 1.0f, 50.0f);
|
||||
m_groundMesh.BuildTree();
|
||||
@ -117,31 +119,51 @@ void Test::Step()
|
||||
|
||||
void Test::MouseMove(const b3Ray3& pw)
|
||||
{
|
||||
m_bodyRay = pw;
|
||||
m_ray = pw;
|
||||
|
||||
if (m_bodyDragger.IsSelected() == true)
|
||||
if (m_bodyDragger.IsDragging() == true)
|
||||
{
|
||||
m_bodyDragger.Drag();
|
||||
}
|
||||
|
||||
if (m_clothDragger.IsDragging() == true)
|
||||
{
|
||||
m_clothDragger.Drag();
|
||||
}
|
||||
}
|
||||
|
||||
void Test::MouseLeftDown(const b3Ray3& pw)
|
||||
{
|
||||
if (m_bodyDragger.IsSelected() == false)
|
||||
if (m_bodyDragger.IsDragging() == false)
|
||||
{
|
||||
if (m_bodyDragger.StartDragging() == true)
|
||||
{
|
||||
BeginDragging();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_clothDragger.IsDragging() == false)
|
||||
{
|
||||
if (m_clothDragger.StartDragging() == true)
|
||||
{
|
||||
BeginDragging();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Test::MouseLeftUp(const b3Ray3& pw)
|
||||
{
|
||||
if (m_bodyDragger.IsSelected() == true)
|
||||
if (m_bodyDragger.IsDragging() == true)
|
||||
{
|
||||
m_bodyDragger.StopDragging();
|
||||
|
||||
EndDragging();
|
||||
}
|
||||
|
||||
if (m_clothDragger.IsDragging() == true)
|
||||
{
|
||||
m_clothDragger.StopDragging();
|
||||
|
||||
EndDragging();
|
||||
}
|
||||
}
|
@ -45,7 +45,13 @@ public:
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
b3RayCastSingleOutput hit;
|
||||
float32 ReportCloth(b3Shape* shape, const b3Vec3& point, const b3Vec3& normal, float32 fraction)
|
||||
{
|
||||
B3_ASSERT(false);
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
b3ShapeRayCastSingleOutput hit;
|
||||
};
|
||||
|
||||
class Test : public b3ContactListener
|
||||
@ -73,7 +79,8 @@ public:
|
||||
|
||||
b3World m_world;
|
||||
|
||||
b3Ray3 m_bodyRay;
|
||||
b3Ray3 m_ray;
|
||||
b3ClothDragger m_clothDragger;
|
||||
b3BodyDragger m_bodyDragger;
|
||||
|
||||
b3BoxHull m_groundHull;
|
||||
|
@ -22,14 +22,9 @@
|
||||
class ClothTest : public Test
|
||||
{
|
||||
public:
|
||||
ClothTest() : m_clothDragger(&m_clothRay, m_cloth)
|
||||
ClothTest()
|
||||
{
|
||||
m_world.SetGravity(b3Vec3(0.0f, -10.0f, 0.0f));
|
||||
|
||||
m_clothRay.origin.SetZero();
|
||||
m_clothRay.direction.Set(0.0f, 0.0f, -1.0f);
|
||||
m_clothRay.fraction = g_camera->m_zFar;
|
||||
|
||||
m_cloth = nullptr;
|
||||
}
|
||||
|
||||
@ -47,41 +42,13 @@ public:
|
||||
float32 E = m_cloth->GetEnergy();
|
||||
g_draw->DrawString(b3Color_white, "E = %f", E);
|
||||
|
||||
if (m_clothDragger.IsSelected() == true)
|
||||
if (m_clothDragger.IsDragging() == true)
|
||||
{
|
||||
g_draw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white);
|
||||
}
|
||||
}
|
||||
|
||||
void MouseMove(const b3Ray3& pw)
|
||||
{
|
||||
m_clothRay = pw;
|
||||
|
||||
if (m_clothDragger.IsSelected() == true)
|
||||
{
|
||||
m_clothDragger.Drag();
|
||||
}
|
||||
}
|
||||
|
||||
void MouseLeftDown(const b3Ray3& pw)
|
||||
{
|
||||
if (m_clothDragger.IsSelected() == false)
|
||||
{
|
||||
m_clothDragger.StartDragging();
|
||||
}
|
||||
}
|
||||
|
||||
void MouseLeftUp(const b3Ray3& pw)
|
||||
{
|
||||
if (m_clothDragger.IsSelected() == true)
|
||||
{
|
||||
m_clothDragger.StopDragging();
|
||||
}
|
||||
}
|
||||
|
||||
b3Ray3 m_clothRay;
|
||||
|
||||
b3Cloth* m_cloth;
|
||||
b3ClothDragger m_clothDragger;
|
||||
};
|
||||
|
||||
#endif
|
@ -69,7 +69,7 @@ public:
|
||||
|
||||
void Step()
|
||||
{
|
||||
if (m_bodyDragger.IsSelected())
|
||||
if (m_bodyDragger.IsDragging())
|
||||
{
|
||||
if (m_bodyDragger.GetBody() != m_character)
|
||||
{
|
||||
|
@ -178,8 +178,8 @@ public:
|
||||
|
||||
void CastRay(const b3Vec3 p1, const b3Vec3 p2) const
|
||||
{
|
||||
b3RayCastSingleOutput out;
|
||||
if (m_world.RayCastSingle(&out, p1, p2))
|
||||
b3ShapeRayCastSingleOutput out;
|
||||
if (m_world.RayCastSingleShape(&out, p1, p2))
|
||||
{
|
||||
g_draw->DrawSegment(p1, out.point, b3Color_green);
|
||||
|
||||
|
@ -156,7 +156,7 @@ public:
|
||||
g_draw->DrawSolidTriangle(n2, v1, v3, v2, color);
|
||||
}
|
||||
|
||||
if (m_clothDragger.IsSelected() == true)
|
||||
if (m_clothDragger.IsDragging() == true)
|
||||
{
|
||||
g_draw->DrawSegment(m_clothDragger.GetPointA(), m_clothDragger.GetPointB(), b3Color_white);
|
||||
}
|
||||
|
@ -39,12 +39,17 @@ public:
|
||||
|
||||
}
|
||||
|
||||
bool IsDragging() const
|
||||
{
|
||||
return m_shape != nullptr;
|
||||
}
|
||||
|
||||
bool StartDragging()
|
||||
{
|
||||
B3_ASSERT(m_mouseJoint == nullptr);
|
||||
|
||||
b3RayCastSingleOutput out;
|
||||
if (m_world->RayCastSingle(&out, m_ray->A(), m_ray->B()) == false)
|
||||
b3ShapeRayCastSingleOutput out;
|
||||
if (m_world->RayCastSingleShape(&out, m_ray->A(), m_ray->B()) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -88,12 +93,6 @@ public:
|
||||
m_shape = nullptr;
|
||||
}
|
||||
|
||||
bool IsSelected() const
|
||||
{
|
||||
return m_mouseJoint != nullptr;
|
||||
}
|
||||
|
||||
|
||||
b3Ray3* GetRay() const
|
||||
{
|
||||
return m_ray;
|
||||
|
@ -21,18 +21,21 @@
|
||||
|
||||
#include <bounce/collision/collision.h>
|
||||
#include <bounce/dynamics/cloth/cloth.h>
|
||||
#include <bounce/dynamics/cloth/cloth_mesh.h>
|
||||
#include <bounce/dynamics/cloth/particle.h>
|
||||
#include <bounce/dynamics/cloth/spring_force.h>
|
||||
#include <bounce/dynamics/cloth/cloth_mesh.h>
|
||||
#include <bounce/dynamics/world.h>
|
||||
|
||||
// A cloth triangle dragger.
|
||||
class b3ClothDragger
|
||||
{
|
||||
public:
|
||||
b3ClothDragger(b3Ray3* ray, b3Cloth*& cloth) : m_ray(ray), m_cloth(cloth)
|
||||
b3ClothDragger(b3Ray3* ray, b3World* world)
|
||||
{
|
||||
m_isSelected = false;
|
||||
m_spring = false;
|
||||
m_ray = ray;
|
||||
m_world = world;
|
||||
m_cloth = nullptr;
|
||||
}
|
||||
|
||||
~b3ClothDragger()
|
||||
@ -40,57 +43,29 @@ public:
|
||||
|
||||
}
|
||||
|
||||
bool IsSelected() const
|
||||
bool IsDragging() const
|
||||
{
|
||||
return m_isSelected;
|
||||
}
|
||||
|
||||
b3Vec3 GetPointA() const
|
||||
{
|
||||
B3_ASSERT(m_isSelected);
|
||||
|
||||
b3ClothMesh* m = m_cloth->GetMesh();
|
||||
b3ClothMeshTriangle* t = m->triangles + m_selection;
|
||||
|
||||
b3Vec3 A = m->vertices[t->v1];
|
||||
b3Vec3 B = m->vertices[t->v2];
|
||||
b3Vec3 C = m->vertices[t->v3];
|
||||
|
||||
return m_u * A + m_v * B + (1.0f - m_u - m_v) * C;
|
||||
}
|
||||
|
||||
b3Vec3 GetPointB() const
|
||||
{
|
||||
B3_ASSERT(m_isSelected);
|
||||
return (1.0f - m_x) * m_ray->A() + m_x * m_ray->B();
|
||||
return m_cloth != nullptr;
|
||||
}
|
||||
|
||||
bool StartDragging()
|
||||
{
|
||||
B3_ASSERT(m_isSelected == false);
|
||||
B3_ASSERT(IsDragging() == false);
|
||||
|
||||
b3RayCastInput rayIn;
|
||||
rayIn.p1 = m_ray->A();
|
||||
rayIn.p2 = m_ray->B();
|
||||
rayIn.maxFraction = B3_MAX_FLOAT;
|
||||
|
||||
b3ClothRayCastOutput rayOut;
|
||||
if (m_cloth->RayCast(&rayOut, &rayIn) == false)
|
||||
b3ClothRayCastSingleOutput rayOut;
|
||||
if (m_world->RayCastSingleCloth(&rayOut, m_ray->A(), m_ray->B()) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isSelected = true;
|
||||
|
||||
m_selection = rayOut.triangle;
|
||||
m_cloth = rayOut.cloth;
|
||||
m_mesh = m_cloth->GetMesh();
|
||||
m_triangle = m_mesh->triangles + rayOut.triangle;
|
||||
m_x = rayOut.fraction;
|
||||
|
||||
b3ClothMesh* m = m_cloth->GetMesh();
|
||||
b3ClothMeshTriangle* t = m->triangles + m_selection;
|
||||
|
||||
b3Particle* p1 = m->particles[t->v1];
|
||||
b3Particle* p2 = m->particles[t->v2];
|
||||
b3Particle* p3 = m->particles[t->v3];
|
||||
b3Particle* p1 = m_mesh->particles[m_triangle->v1];
|
||||
b3Particle* p2 = m_mesh->particles[m_triangle->v2];
|
||||
b3Particle* p3 = m_mesh->particles[m_triangle->v3];
|
||||
|
||||
b3Vec3 v1 = p1->GetPosition();
|
||||
b3Vec3 v2 = p2->GetPosition();
|
||||
@ -163,10 +138,7 @@ public:
|
||||
|
||||
void Drag()
|
||||
{
|
||||
B3_ASSERT(m_isSelected);
|
||||
|
||||
b3ClothMesh* m = m_cloth->GetMesh();
|
||||
b3ClothMeshTriangle* t = m->triangles + m_selection;
|
||||
B3_ASSERT(IsDragging() == true);
|
||||
|
||||
b3Vec3 A = GetPointA();
|
||||
b3Vec3 B = GetPointB();
|
||||
@ -179,22 +151,22 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
b3Particle* p1 = m->particles[t->v1];
|
||||
b3Particle* p1 = m_mesh->particles[m_triangle->v1];
|
||||
p1->ApplyTranslation(dx);
|
||||
|
||||
b3Particle* p2 = m->particles[t->v2];
|
||||
b3Particle* p2 = m_mesh->particles[m_triangle->v2];
|
||||
p2->ApplyTranslation(dx);
|
||||
|
||||
b3Particle* p3 = m->particles[t->v3];
|
||||
b3Particle* p3 = m_mesh->particles[m_triangle->v3];
|
||||
p3->ApplyTranslation(dx);
|
||||
}
|
||||
}
|
||||
|
||||
void StopDragging()
|
||||
{
|
||||
B3_ASSERT(m_isSelected);
|
||||
B3_ASSERT(IsDragging() == true);
|
||||
|
||||
m_isSelected = false;
|
||||
m_cloth = nullptr;
|
||||
|
||||
if (m_spring)
|
||||
{
|
||||
@ -205,28 +177,42 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
b3ClothMesh* m = m_cloth->GetMesh();
|
||||
b3ClothMeshTriangle* t = m->triangles + m_selection;
|
||||
|
||||
b3Particle* p1 = m->particles[t->v1];
|
||||
b3Particle* p1 = m_mesh->particles[m_triangle->v1];
|
||||
p1->SetType(m_t1);
|
||||
|
||||
b3Particle* p2 = m->particles[t->v2];
|
||||
b3Particle* p2 = m_mesh->particles[m_triangle->v2];
|
||||
p2->SetType(m_t2);
|
||||
|
||||
b3Particle* p3 = m->particles[t->v3];
|
||||
b3Particle* p3 = m_mesh->particles[m_triangle->v3];
|
||||
p3->SetType(m_t3);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isSelected;
|
||||
b3Vec3 GetPointA() const
|
||||
{
|
||||
B3_ASSERT(IsDragging() == true);
|
||||
|
||||
b3Vec3 A = m_mesh->vertices[m_triangle->v1];
|
||||
b3Vec3 B = m_mesh->vertices[m_triangle->v2];
|
||||
b3Vec3 C = m_mesh->vertices[m_triangle->v3];
|
||||
|
||||
return m_u * A + m_v * B + (1.0f - m_u - m_v) * C;
|
||||
}
|
||||
|
||||
b3Vec3 GetPointB() const
|
||||
{
|
||||
B3_ASSERT(IsDragging() == true);
|
||||
|
||||
return (1.0f - m_x) * m_ray->A() + m_x * m_ray->B();
|
||||
}
|
||||
private:
|
||||
b3Ray3* m_ray;
|
||||
float32 m_x;
|
||||
|
||||
b3Cloth*& m_cloth;
|
||||
u32 m_selection;
|
||||
b3World* m_world;
|
||||
b3Cloth* m_cloth;
|
||||
b3ClothMesh* m_mesh;
|
||||
b3ClothMeshTriangle* m_triangle;
|
||||
float32 m_u, m_v;
|
||||
|
||||
bool m_spring;
|
||||
|
@ -34,15 +34,10 @@ struct b3ForceDef;
|
||||
|
||||
struct b3ClothMesh;
|
||||
|
||||
struct b3RayCastInput;
|
||||
class b3RayCastListener;
|
||||
|
||||
struct b3ClothRayCastOutput
|
||||
{
|
||||
u32 triangle; // intersected triangle
|
||||
b3Vec3 point; // intersection point on surface
|
||||
b3Vec3 normal; // surface normal of intersection
|
||||
float32 fraction; // time of intersection on segment
|
||||
};
|
||||
struct b3RayCastInput;
|
||||
struct b3ClothRayCastSingleOutput;
|
||||
|
||||
// Cloth definition
|
||||
// This requires defining a cloth mesh which is typically bound to a render mesh
|
||||
@ -94,11 +89,14 @@ public:
|
||||
// Destroy a given force.
|
||||
void DestroyForce(b3Force* force);
|
||||
|
||||
// Perform a ray cast with the cloth.
|
||||
bool RayCast(b3ClothRayCastOutput* output, const b3RayCastInput* input) const;
|
||||
|
||||
// Perform a ray cast with a given cloth mesh triangle.
|
||||
bool RayCast(b3ClothRayCastOutput* output, const b3RayCastInput* input, u32 triangleIndex) const;
|
||||
bool RayCast(b3ClothRayCastSingleOutput* output, const b3RayCastInput* input, u32 triangleIndex) const;
|
||||
|
||||
// Perform a ray cast with the cloth.
|
||||
void RayCast(b3RayCastListener* listener, const b3RayCastInput* input) const;
|
||||
|
||||
// Perform a ray cast with the cloth.
|
||||
bool RayCastSingle(b3ClothRayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const;
|
||||
|
||||
// Return the cloth mesh proxy.
|
||||
b3ClothMesh* GetMesh() const;
|
||||
|
@ -36,7 +36,7 @@ class b3RayCastListener;
|
||||
class b3ContactListener;
|
||||
class b3ContactFilter;
|
||||
|
||||
struct b3RayCastSingleOutput
|
||||
struct b3ShapeRayCastSingleOutput
|
||||
{
|
||||
b3Shape* shape; // shape
|
||||
b3Vec3 point; // intersection point on surface
|
||||
@ -44,6 +44,15 @@ struct b3RayCastSingleOutput
|
||||
float32 fraction; // time of intersection on segment
|
||||
};
|
||||
|
||||
struct b3ClothRayCastSingleOutput
|
||||
{
|
||||
b3Cloth* cloth; // cloth
|
||||
u32 triangle; // triangle
|
||||
b3Vec3 point; // intersection point on surface
|
||||
b3Vec3 normal; // surface normal of intersection
|
||||
float32 fraction; // time of intersection on segment
|
||||
};
|
||||
|
||||
// Use a physics world to create/destroy rigid bodies, execute ray cast and volume queries.
|
||||
class b3World
|
||||
{
|
||||
@ -92,13 +101,6 @@ public:
|
||||
// The function parameters are the ammount of time to simulate,
|
||||
// and the number of constraint solver iterations.
|
||||
void Step(float32 dt, u32 velocityIterations, u32 positionIterations);
|
||||
|
||||
// Perform a ray cast with the world.
|
||||
// If the ray doesn't intersect with a shape in the world then return false.
|
||||
// The ray cast output is the intercepted shape, the intersection
|
||||
// point in world space, the face normal on the shape associated with the point,
|
||||
// and the intersection fraction.
|
||||
bool RayCastSingle(b3RayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const;
|
||||
|
||||
// Perform a ray cast with the world.
|
||||
// The given ray cast listener will be notified when a ray intersects a shape
|
||||
@ -106,7 +108,29 @@ public:
|
||||
// The ray cast output is the intercepted shape, the intersection
|
||||
// point in world space, the face normal on the shape associated with the point,
|
||||
// and the intersection fraction.
|
||||
void RayCast(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const;
|
||||
void RayCastShape(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const;
|
||||
|
||||
// Perform a ray cast with the world.
|
||||
// If the ray doesn't intersect with a shape in the world then return false.
|
||||
// The ray cast output is the intercepted shape, the intersection
|
||||
// point in world space, the face normal on the shape associated with the point,
|
||||
// and the intersection fraction.
|
||||
bool RayCastSingleShape(b3ShapeRayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const;
|
||||
|
||||
// Perform a ray cast with the world.
|
||||
// The given ray cast listener will be notified when a ray intersects a shape
|
||||
// in the world.
|
||||
// The ray cast output is the intercepted cloth, the intersection
|
||||
// point in world space, the face normal on the cloth associated with the point,
|
||||
// and the intersection fraction.
|
||||
void RayCastCloth(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const;
|
||||
|
||||
// Perform a ray cast with the world.
|
||||
// If the ray doesn't intersect with a cloth in the world then return false.
|
||||
// The ray cast output is the intercepted cloth, the intersection
|
||||
// point in world space, the face normal on the cloth associated with the point,
|
||||
// and the intersection fraction.
|
||||
bool RayCastSingleCloth(b3ClothRayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const;
|
||||
|
||||
// Perform a AABB query with the world.
|
||||
// The query listener will be notified when two shape AABBs are overlapping.
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <bounce/common/math/math.h>
|
||||
|
||||
class b3Shape;
|
||||
class b3Cloth;
|
||||
class b3Contact;
|
||||
|
||||
class b3QueryListener
|
||||
@ -46,6 +47,12 @@ public:
|
||||
// the intersection point on the shape, the surface normal associated with the point, and the
|
||||
// intersection fraction for the ray.
|
||||
virtual float32 ReportShape(b3Shape* shape, const b3Vec3& point, const b3Vec3& normal, float32 fraction) = 0;
|
||||
|
||||
// Report that a cloth was hit by the ray to this contact listener.
|
||||
// The reported information are the shape hit by the ray,
|
||||
// the intersection point on the cloth, the surface normal associated with the point, the
|
||||
// intersection fraction for the ray, and the triangle.
|
||||
virtual float32 ReportCloth(b3Cloth* cloth, const b3Vec3& point, const b3Vec3& normal, float32 fraction, u32 triangle) = 0;
|
||||
};
|
||||
|
||||
class b3ContactListener
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <bounce/dynamics/cloth/spring_force.h>
|
||||
#include <bounce/dynamics/cloth/cloth_solver.h>
|
||||
#include <bounce/dynamics/world.h>
|
||||
#include <bounce/dynamics/world_listeners.h>
|
||||
#include <bounce/dynamics/body.h>
|
||||
#include <bounce/dynamics/shapes/shape.h>
|
||||
#include <bounce/collision/collision.h>
|
||||
@ -347,15 +348,38 @@ void b3Cloth::ComputeMass()
|
||||
}
|
||||
}
|
||||
|
||||
bool b3Cloth::RayCast(b3ClothRayCastOutput* output, const b3RayCastInput* input) const
|
||||
void b3Cloth::RayCast(b3RayCastListener* listener, const b3RayCastInput* input) const
|
||||
{
|
||||
for (u32 i = 0; i < m_mesh->triangleCount; ++i)
|
||||
{
|
||||
b3ClothRayCastSingleOutput subOutput;
|
||||
if (RayCast(&subOutput, input, i))
|
||||
{
|
||||
float32 newFraction = listener->ReportCloth(subOutput.cloth, subOutput.point, subOutput.normal, subOutput.fraction, subOutput.triangle);
|
||||
|
||||
if (newFraction == 0.0f)
|
||||
{
|
||||
// The client has stopped the query.
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool b3Cloth::RayCastSingle(b3ClothRayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const
|
||||
{
|
||||
b3RayCastInput input;
|
||||
input.p1 = p1;
|
||||
input.p2 = p2;
|
||||
input.maxFraction = 1.0f;
|
||||
|
||||
output->triangle = ~0;
|
||||
output->fraction = input->maxFraction;
|
||||
output->fraction = B3_MAX_FLOAT;
|
||||
|
||||
for (u32 i = 0; i < m_mesh->triangleCount; ++i)
|
||||
{
|
||||
b3ClothRayCastOutput subOutput;
|
||||
if (RayCast(&subOutput, input, i))
|
||||
b3ClothRayCastSingleOutput subOutput;
|
||||
if (RayCast(&subOutput, &input, i))
|
||||
{
|
||||
if (subOutput.fraction < output->fraction)
|
||||
{
|
||||
@ -372,7 +396,7 @@ bool b3Cloth::RayCast(b3ClothRayCastOutput* output, const b3RayCastInput* input)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool b3Cloth::RayCast(b3ClothRayCastOutput* output, const b3RayCastInput* input, u32 triangleIndex) const
|
||||
bool b3Cloth::RayCast(b3ClothRayCastSingleOutput* output, const b3RayCastInput* input, u32 triangleIndex) const
|
||||
{
|
||||
B3_ASSERT(triangleIndex < m_mesh->triangleCount);
|
||||
b3ClothMeshTriangle* triangle = m_mesh->triangles + triangleIndex;
|
||||
|
@ -24,22 +24,7 @@
|
||||
|
||||
void b3FrictionForce::Apply(const b3ClothSolverData* data)
|
||||
{
|
||||
b3DenseVec3& v = *data->v;
|
||||
b3DenseVec3& f = *data->f;
|
||||
b3SparseSymMat33& dfdv = *data->dfdv;
|
||||
|
||||
u32 i = m_p->m_solverId;
|
||||
|
||||
if (m_kd > 0.0f)
|
||||
{
|
||||
f[i] += -m_kd * v[i];
|
||||
|
||||
b3Mat33 I; I.SetIdentity();
|
||||
|
||||
b3Mat33 Jv = -m_kd * I;
|
||||
|
||||
dfdv(i, i) += Jv;
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
b3Particle::b3Particle(const b3ParticleDef& def, b3Cloth* cloth)
|
||||
|
@ -378,7 +378,7 @@ void b3World::StepCloth(float32 dt)
|
||||
}
|
||||
}
|
||||
|
||||
struct b3RayCastCallback
|
||||
struct b3ShapeRayCastCallback
|
||||
{
|
||||
float32 Report(const b3RayCastInput& input, u32 proxyId)
|
||||
{
|
||||
@ -413,20 +413,20 @@ struct b3RayCastCallback
|
||||
const b3BroadPhase* broadPhase;
|
||||
};
|
||||
|
||||
void b3World::RayCast(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const
|
||||
void b3World::RayCastShape(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const
|
||||
{
|
||||
b3RayCastInput input;
|
||||
input.p1 = p1;
|
||||
input.p2 = p2;
|
||||
input.maxFraction = 1.0f;
|
||||
|
||||
b3RayCastCallback callback;
|
||||
b3ShapeRayCastCallback callback;
|
||||
callback.listener = listener;
|
||||
callback.broadPhase = &m_contactMan.m_broadPhase;
|
||||
m_contactMan.m_broadPhase.RayCast(&callback, input);
|
||||
}
|
||||
|
||||
struct b3RayCastSingleCallback
|
||||
struct b3ShapeRayCastSingleCallback
|
||||
{
|
||||
float32 Report(const b3RayCastInput& input, u32 proxyId)
|
||||
{
|
||||
@ -458,14 +458,14 @@ struct b3RayCastSingleCallback
|
||||
const b3BroadPhase* broadPhase;
|
||||
};
|
||||
|
||||
bool b3World::RayCastSingle(b3RayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const
|
||||
bool b3World::RayCastSingleShape(b3ShapeRayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const
|
||||
{
|
||||
b3RayCastInput input;
|
||||
input.p1 = p1;
|
||||
input.p2 = p2;
|
||||
input.maxFraction = 1.0f;
|
||||
|
||||
b3RayCastSingleCallback callback;
|
||||
b3ShapeRayCastSingleCallback callback;
|
||||
callback.shape0 = NULL;
|
||||
callback.output0.fraction = B3_MAX_FLOAT;
|
||||
callback.broadPhase = &m_contactMan.m_broadPhase;
|
||||
@ -491,6 +491,46 @@ bool b3World::RayCastSingle(b3RayCastSingleOutput* output, const b3Vec3& p1, con
|
||||
return false;
|
||||
}
|
||||
|
||||
void b3World::RayCastCloth(b3RayCastListener* listener, const b3Vec3& p1, const b3Vec3& p2) const
|
||||
{
|
||||
b3RayCastInput input;
|
||||
input.p1 = p1;
|
||||
input.p2 = p2;
|
||||
input.maxFraction = B3_MAX_FLOAT;
|
||||
|
||||
for (b3Cloth* c = m_clothList.m_head; c; c = c->m_next)
|
||||
{
|
||||
c->RayCast(listener, &input);
|
||||
}
|
||||
}
|
||||
|
||||
bool b3World::RayCastSingleCloth(b3ClothRayCastSingleOutput* output, const b3Vec3& p1, const b3Vec3& p2) const
|
||||
{
|
||||
output->cloth = NULL;
|
||||
output->triangle = ~0;
|
||||
output->fraction = B3_MAX_FLOAT;
|
||||
|
||||
for (b3Cloth* c = m_clothList.m_head; c; c = c->m_next)
|
||||
{
|
||||
b3ClothRayCastSingleOutput subOutput;
|
||||
if (c->RayCastSingle(&subOutput, p1, p2))
|
||||
{
|
||||
if (subOutput.fraction < output->fraction)
|
||||
{
|
||||
subOutput.cloth = c;
|
||||
*output = subOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output->cloth != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct b3QueryAABBCallback
|
||||
{
|
||||
bool Report(u32 proxyID)
|
||||
|
Loading…
x
Reference in New Issue
Block a user