// Chain physics
// http://www.lns.cornell.edu/spr/2001-06/msg0033480.html
// Neighboring masses connected by a spring of natural length 1 and spring constant k
D3DXVECTOR3 vForceParent = D3DXVECTOR3(0.0f,0.0f,0.0f);
D3DXVECTOR3 vForceChild = D3DXVECTOR3(0.0f,0.0f,0.0f);
D3DXVECTOR3 vForce = D3DXVECTOR3(0.0f,0.0f,0.0f);
D3DXVECTOR3 vPos;
float r, f;
// Find the force on the mass due to parent (if not top level link)
if( m_pParent && m_nLink > 1 )
{
vPos = m_pParent->GetPos();
vForceParent.x = vPos.x - m_vPos.x;
vForceParent.y = vPos.y - m_vPos.y;
vForceParent.z = vPos.z - m_vPos.z;
r = (float)sqrt( (vForceParent.x * vForceParent.x) + (vForceParent.y * vForceParent.y) + (vForceParent.z * vForceParent.z) );
f = r - 1.0f;
vForceParent.x = f * vForceParent.x / r;
vForceParent.y = f * vForceParent.y / r;
vForceParent.z = f * vForceParent.z / r;
}
// Find the force on the mass due to child (if not bottom level link with nothing attached)
//TODO: Only handle one child currently
if( m_pChildren.GetSize() > 0 && (m_nLink < s_nNumLinks || m_bPayload) )
{
vPos = m_pChildren[0]->GetPos();
vForceChild.x = vPos.x - m_vPos.x;
vForceChild.y = vPos.y - m_vPos.y;
vForceChild.z = vPos.z - m_vPos.z;
r = (float)sqrt( (vForceChild.x * vForceChild.x) + (vForceChild.y * vForceChild.y) + (vForceChild.z * vForceChild.z) );
f = r - 1.0f;
vForceChild.x = f * vForceChild.x / r;
vForceChild.y = f * vForceChild.y / r;
vForceChild.z = f * vForceChild.z / r;
}
// Find resultant force on the mass
vForce = vForceParent + vForceChild;
vForce.y += GRAVITY; // Gravity
vForce *= 0.5f * FRAMERATE_S;
// Update the position of the link
m_vPos += vForce;
Chain physics
I am trying to model a chain hanging from a movable object and would like to get some realistic motion. I found something online that had somewhat of a description but when I tried what they said to do, my chain is not visible (presumably because my calculations moved it offscreen somewhere...).
How does my code look? The URL in my comments is where I found the description.
If this is a bad way of doing it, does anyone have a suggestion for a better method?
Well, I found a better method in the book "Physics for Game Developers." My chain still doesn''t function correctly though. The only link visible is the "locked" one (doesn''t recieve any forces on it). So something is screwy.
//// ChainPhysics()// Runs the chain physics//void CraneChain::ChainPhysics( void ){ D3DXVECTOR3 dragVector; D3DXVECTOR3 f1,f2,d,v; float L; // Process gravity and drag forces if not top level link if( m_nLink > 1 ) { // Gravity m_vForces += GRAVITY_VEC * LINK_MASS; // Viscous drag dragVector = -m_vVel; D3DXVec3Normalize( &dragVector, &dragVector ); m_vForces += dragVector * Util::VecLen2( &m_vVel ) * DRAG_COEFFICIENT; // Wind D3DXVECTOR3 windVec; windVec.x = RandomFloat(0.0f,10.0f); windVec.y = 0.0f; windVec.z = RandomFloat(0.0f,1.0f); Util::Normalize( &windVec, &windVec ); m_vForces += windVec * WIND_FORCE_FACTOR; // Process spring forces if( m_pChildren.GetSize() > 0 ) { d = m_vPos - m_pChildren[0]->GetPos(); v = m_vVel - m_pChildren[0]->GetVel(); L = (CHAIN_OUTER_RADIUS + CHAIN_INNER_RADIUS) * 2.0f; // Length of spring at rest const float len = Util::VecLen( &d ); const float dot = Util::DotProd( &v, &d ); f1 = -(SPRING_TENSION * (len - L) + SPRING_DAMPENING * dot / len) * (d / len); f2 = -f1; m_vForces += f1; m_pChildren[0]->SetForces( &f2 ); } } m_vAccel = m_vForces / LINK_MASS; m_vVel += m_vAccel * FRAMERATE_S; m_vPos += m_vVel * FRAMERATE_S; //TODO: Collision detection and response}
Ok, I forgot to transform the child's position into the correct object space.
D3DXVec3TransformCoord( &d, &(m_pChildren[0]->GetPos()), &m_mAnimPoint );
d = m_vPos - d;
Still doesn't work correctly, but now I have something to work with (my links are visible). The problem is that the links aren't bound together like you would expect. What I mean is the chain keeps expanding forever, there aren't any constraints to keep it together. Where could I add this constraint?
[edited by - beoch on October 7, 2002 8:16:03 PM]
D3DXVec3TransformCoord( &d, &(m_pChildren[0]->GetPos()), &m_mAnimPoint );
d = m_vPos - d;
Still doesn't work correctly, but now I have something to work with (my links are visible). The problem is that the links aren't bound together like you would expect. What I mean is the chain keeps expanding forever, there aren't any constraints to keep it together. Where could I add this constraint?
[edited by - beoch on October 7, 2002 8:16:03 PM]
I tried to do something like that once, and your code seems very similar to mine(which I no longer have). I can''t see why your chain would expand. The lines
f1 = -(SPRING_TENSION * (len - L) + SPRING_DAMPENING * dot / len) * (d / len);
f2 = -f1;
m_vForces += f1;
m_pChildren[0]->SetForces( &f2 );
should pull the links together.
What do you have SPRING_TENSION, SPRING_DAMPENING, and L defined as?
f1 = -(SPRING_TENSION * (len - L) + SPRING_DAMPENING * dot / len) * (d / len);
f2 = -f1;
m_vForces += f1;
m_pChildren[0]->SetForces( &f2 );
should pull the links together.
What do you have SPRING_TENSION, SPRING_DAMPENING, and L defined as?
const float SPRING_TENSION = 500.0f;const float SPRING_SHEAR = 300.0f;const float SPRING_DAMPENING = 2.0f;const float CHAIN_OUTER_RADIUS = 2.0f;const float CHAIN_INNER_RADIUS = 1.0f;......L = (CHAIN_OUTER_RADIUS + CHAIN_INNER_RADIUS) * 2.0f; // Length of spring at rest
I never thought of tweaking those values. I was modifying some code for a flag sample that used springs so they might be off for what I was trying to do...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement