kinematic cloth
This commit is contained in:
@ -22,6 +22,7 @@
|
|||||||
#include <bounce/common/math/mat33.h>
|
#include <bounce/common/math/mat33.h>
|
||||||
#include <bounce/common/template/array.h>
|
#include <bounce/common/template/array.h>
|
||||||
|
|
||||||
|
// Number of maximum shapes per cloth.
|
||||||
#define B3_CLOTH_SHAPE_CAPACITY 32
|
#define B3_CLOTH_SHAPE_CAPACITY 32
|
||||||
|
|
||||||
class b3StackAllocator;
|
class b3StackAllocator;
|
||||||
@ -63,6 +64,8 @@ struct b3SpringClothDef
|
|||||||
float32 kd;
|
float32 kd;
|
||||||
|
|
||||||
// Mass radius
|
// Mass radius
|
||||||
|
// Typically this is value is small and is intended for correcting visual artifacts when
|
||||||
|
// the cloth is colliding against a solid.
|
||||||
float32 r;
|
float32 r;
|
||||||
|
|
||||||
// Acceleration due to gravity (m/s^2)
|
// Acceleration due to gravity (m/s^2)
|
||||||
@ -97,10 +100,12 @@ struct b3Spring
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Static masses have zero mass and velocity, and therefore they can't move.
|
// Static masses have zero mass and velocity, and therefore they can't move.
|
||||||
|
// Kinematic masses are't moved by external and internal forces but can be moved by contact forces.
|
||||||
// Dynamic masses have non-zero mass and can move due to internal and external forces.
|
// Dynamic masses have non-zero mass and can move due to internal and external forces.
|
||||||
enum class b3MassType : u32
|
enum class b3MassType : u32
|
||||||
{
|
{
|
||||||
e_staticMass,
|
e_staticMass,
|
||||||
|
e_kinematicMass,
|
||||||
e_dynamicMass
|
e_dynamicMass
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -140,6 +145,9 @@ public:
|
|||||||
// Units are m/s^2.
|
// Units are m/s^2.
|
||||||
void SetGravity(const b3Vec3& gravity);
|
void SetGravity(const b3Vec3& gravity);
|
||||||
|
|
||||||
|
// Return the number of masses in this cloth.
|
||||||
|
u32 GetMassCount() const;
|
||||||
|
|
||||||
// Return the gravitational acceleration applied to this cloth.
|
// Return the gravitational acceleration applied to this cloth.
|
||||||
const b3Vec3& GetGravity() const;
|
const b3Vec3& GetGravity() const;
|
||||||
|
|
||||||
@ -152,11 +160,17 @@ public:
|
|||||||
// Set the position of a given point mass.
|
// Set the position of a given point mass.
|
||||||
// This function will have effect on the position of the point mass
|
// This function will have effect on the position of the point mass
|
||||||
// after performing a time step.
|
// after performing a time step.
|
||||||
void SetPosition(u32 i, const b3Vec3& translation);
|
void SetPosition(u32 i, const b3Vec3& position);
|
||||||
|
|
||||||
// Return the position of a given point mass.
|
// Return the position of a given point mass.
|
||||||
const b3Vec3& GetPosition(u32 i) const;
|
const b3Vec3& GetPosition(u32 i) const;
|
||||||
|
|
||||||
|
// Set the velocity of a given point mass.
|
||||||
|
void SetVelocity(u32 i, const b3Vec3& velocity);
|
||||||
|
|
||||||
|
// Return the velocity of a given point mass.
|
||||||
|
const b3Vec3& GetVelocity(u32 i) const;
|
||||||
|
|
||||||
// Apply a force to a given point mass.
|
// Apply a force to a given point mass.
|
||||||
void ApplyForce(u32 i, const b3Vec3& force);
|
void ApplyForce(u32 i, const b3Vec3& force);
|
||||||
|
|
||||||
@ -237,6 +251,11 @@ inline void b3SpringCloth::SetGravity(const b3Vec3& gravity)
|
|||||||
m_gravity = gravity;
|
m_gravity = gravity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline u32 b3SpringCloth::GetMassCount() const
|
||||||
|
{
|
||||||
|
return m_massCount;
|
||||||
|
}
|
||||||
|
|
||||||
inline b3MassType b3SpringCloth::GetType(u32 i) const
|
inline b3MassType b3SpringCloth::GetType(u32 i) const
|
||||||
{
|
{
|
||||||
B3_ASSERT(i < m_massCount);
|
B3_ASSERT(i < m_massCount);
|
||||||
@ -246,6 +265,7 @@ inline b3MassType b3SpringCloth::GetType(u32 i) const
|
|||||||
inline void b3SpringCloth::SetType(u32 i, b3MassType type)
|
inline void b3SpringCloth::SetType(u32 i, b3MassType type)
|
||||||
{
|
{
|
||||||
B3_ASSERT(i < m_massCount);
|
B3_ASSERT(i < m_massCount);
|
||||||
|
|
||||||
if (m_types[i] == type)
|
if (m_types[i] == type)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -276,6 +296,24 @@ inline const b3Vec3& b3SpringCloth::GetPosition(u32 i) const
|
|||||||
return m_x[i];
|
return m_x[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void b3SpringCloth::SetVelocity(u32 i, const b3Vec3& velocity)
|
||||||
|
{
|
||||||
|
B3_ASSERT(i < m_massCount);
|
||||||
|
|
||||||
|
if (m_types[i] == b3MassType::e_staticMass)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_v[i] = velocity;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const b3Vec3& b3SpringCloth::GetVelocity(u32 i) const
|
||||||
|
{
|
||||||
|
B3_ASSERT(i < m_massCount);
|
||||||
|
return m_v[i];
|
||||||
|
}
|
||||||
|
|
||||||
inline void b3SpringCloth::ApplyForce(u32 i, const b3Vec3& force)
|
inline void b3SpringCloth::ApplyForce(u32 i, const b3Vec3& force)
|
||||||
{
|
{
|
||||||
B3_ASSERT(i < m_massCount);
|
B3_ASSERT(i < m_massCount);
|
||||||
|
@ -400,7 +400,7 @@ void b3SpringCloth::GetTension(b3Array<b3Vec3>& T) const
|
|||||||
|
|
||||||
for (u32 i = 0; i < T.Count(); ++i)
|
for (u32 i = 0; i < T.Count(); ++i)
|
||||||
{
|
{
|
||||||
if (m_types[i] == b3MassType::e_staticMass)
|
if (m_types[i] != b3MassType::e_dynamicMass)
|
||||||
{
|
{
|
||||||
T[i].SetZero();
|
T[i].SetZero();
|
||||||
}
|
}
|
||||||
@ -677,11 +677,26 @@ void b3SpringCloth::Draw() const
|
|||||||
|
|
||||||
for (u32 i = 0; i < m->vertexCount; ++i)
|
for (u32 i = 0; i < m->vertexCount; ++i)
|
||||||
{
|
{
|
||||||
|
if (m_types[i] == b3MassType::e_staticMass)
|
||||||
|
{
|
||||||
|
b3Draw_draw->DrawPoint(m_x[i], 4.0f, b3Color_white);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_types[i] == b3MassType::e_kinematicMass)
|
||||||
|
{
|
||||||
|
b3Draw_draw->DrawPoint(m_x[i], 4.0f, b3Color_blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_types[i] == b3MassType::e_dynamicMass)
|
||||||
|
{
|
||||||
|
b3Draw_draw->DrawPoint(m_x[i], 4.0f, b3Color_green);
|
||||||
|
}
|
||||||
|
|
||||||
b3MassContact* c = m_contacts + i;
|
b3MassContact* c = m_contacts + i;
|
||||||
|
|
||||||
if (c->lockN)
|
if (c->lockN)
|
||||||
{
|
{
|
||||||
b3Draw_draw->DrawPoint(m_x[i], 6.0f, b3Color_green);
|
b3Draw_draw->DrawPoint(m_x[i], 6.0f, b3Color_yellow);
|
||||||
|
|
||||||
b3Draw_draw->DrawSegment(m_x[i], m_x[i] + c->n, b3Color_yellow);
|
b3Draw_draw->DrawSegment(m_x[i], m_x[i] + c->n, b3Color_yellow);
|
||||||
|
|
||||||
|
@ -104,7 +104,10 @@ void b3SpringSolver::Solve(b3DenseVec3& f)
|
|||||||
// Update state
|
// Update state
|
||||||
for (u32 i = 0; i < m_massCount; ++i)
|
for (u32 i = 0; i < m_massCount; ++i)
|
||||||
{
|
{
|
||||||
m_v[i] += x[i];
|
if (m_types[i] == b3MassType::e_dynamicMass)
|
||||||
|
{
|
||||||
|
m_v[i] += x[i];
|
||||||
|
}
|
||||||
|
|
||||||
// dx = h * (v0 + dv) + y = h * v1 + y
|
// dx = h * (v0 + dv) + y = h * v1 + y
|
||||||
m_x[i] += m_h * m_v[i] + m_y[i];
|
m_x[i] += m_h * m_v[i] + m_y[i];
|
||||||
@ -365,54 +368,44 @@ void b3SpringSolver::Compute_S(b3Mat33* out)
|
|||||||
{
|
{
|
||||||
for (u32 i = 0; i < m_massCount; ++i)
|
for (u32 i = 0; i < m_massCount; ++i)
|
||||||
{
|
{
|
||||||
switch (m_types[i])
|
out[i].SetIdentity();
|
||||||
{
|
|
||||||
case b3MassType::e_staticMass:
|
if (m_types[i] == b3MassType::e_staticMass)
|
||||||
{
|
{
|
||||||
out[i].SetZero();
|
out[i].SetZero();
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
case b3MassType::e_dynamicMass:
|
|
||||||
|
b3MassContact* c = m_contacts + i;
|
||||||
|
|
||||||
|
if (c->lockN == true)
|
||||||
{
|
{
|
||||||
if (m_contacts[i].lockN == true)
|
b3Vec3 n = c->n;
|
||||||
|
|
||||||
|
b3Mat33 S = b3Mat33_identity - b3Outer(n, n);
|
||||||
|
|
||||||
|
if (c->lockT1 == true && c->lockT2 == true)
|
||||||
{
|
{
|
||||||
b3Vec3 n = m_contacts[i].n;
|
S.SetZero();
|
||||||
|
}
|
||||||
b3Mat33 S = b3Mat33_identity - b3Outer(n, n);
|
else
|
||||||
|
{
|
||||||
if (m_contacts[i].lockT1 == true && m_contacts[i].lockT2 == true)
|
if (c->lockT1 == true)
|
||||||
{
|
{
|
||||||
S.SetZero();
|
b3Vec3 t1 = c->t1;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_contacts[i].lockT1 == true)
|
|
||||||
{
|
|
||||||
b3Vec3 t1 = m_contacts[i].t1;
|
|
||||||
|
|
||||||
S -= b3Outer(t1, t1);
|
S -= b3Outer(t1, t1);
|
||||||
}
|
|
||||||
|
|
||||||
if (m_contacts[i].lockT2 == true)
|
|
||||||
{
|
|
||||||
b3Vec3 t2 = m_contacts[i].t2;
|
|
||||||
|
|
||||||
S -= b3Outer(t2, t2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out[i] = S;
|
if (c->lockT2 == true)
|
||||||
break;
|
{
|
||||||
|
b3Vec3 t2 = c->t2;
|
||||||
|
|
||||||
|
S -= b3Outer(t2, t2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out[i].SetIdentity();
|
out[i] = S;
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
B3_ASSERT(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user