#include <actions.h>
Public Member Functions | |
~PABounce () | |
void | Exec (const PDTriangle &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend) |
void | Exec (const PDRectangle &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend) |
void | Exec (const PDPlane &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend) |
void | Exec (const PDSphere &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend) |
void | Exec (const PDDisc &dom, ParticleGroup &group, ParticleList::iterator ibegin, ParticleList::iterator iend) |
Public Attributes | |
pDomain * | position |
float | oneMinusFriction |
float | resilience |
float | cutoffSqr |
EXEC_METHOD |
Definition at line 63 of file actions.h.
PABounce::~PABounce | ( | ) | [inline] |
void PABounce::Exec | ( | const PDTriangle & | dom, | |
ParticleGroup & | group, | |||
ParticleList::iterator | ibegin, | |||
ParticleList::iterator | iend | |||
) |
Definition at line 313 of file actions.cpp.
References cutoffSqr, PDTriangle::D, PActionBase::dt, pVec::length2(), NewBasis(), PDTriangle::nrm, oneMinusFriction, PDTriangle::p, Particle::pos, pSameSign(), resilience, PDTriangle::u, PDTriangle::v, and Particle::vel.
00314 { 00315 pVec s1, s2; 00316 NewBasis(dom.u, dom.v, s1, s2); 00317 00318 for (ParticleList::iterator it = ibegin; it != iend; it++) { 00319 Particle &m = (*it); 00320 00321 // See if particle's current and look_ahead positions cross plane. 00322 // If not, couldn't hit, so keep going. 00323 pVec pnext = m.pos + m.vel * dt; 00324 00325 // nrm stores the plane normal (the a,b,c of the plane eqn). 00326 // Old and new distances: dist(p,plane) = n * p + d 00327 float distold = m.pos * dom.nrm + dom.D; 00328 float distnew = pnext * dom.nrm + dom.D; 00329 00330 if(pSameSign(distold, distnew)) 00331 continue; 00332 00333 float nv = dom.nrm * m.vel; 00334 float t = -distold / nv; // Time steps before hit 00335 00336 pVec phit = m.pos + m.vel * t; // Actual intersection point 00337 pVec offset = phit - dom.p; // Offset from origin in plane 00338 00339 // Dot product with basis vectors of old frame 00340 // in terms of new frame gives position in uv frame. 00341 float upos = offset * s1; 00342 float vpos = offset * s2; 00343 00344 // Did it cross plane outside triangle? 00345 if(upos < 0 || vpos < 0 || (upos + vpos) > 1) 00346 continue; 00347 00348 // A hit! A most palpable hit! 00349 // Compute tangential and normal components of velocity 00350 pVec vn = dom.nrm * nv; // Normal Vn = (V.N)N 00351 pVec vt = m.vel - vn; // Tangent Vt = V - Vn 00352 00353 // Compute new velocity heading out: 00354 // Don't apply friction if tangential velocity < cutoff 00355 if(vt.length2() <= cutoffSqr) 00356 m.vel = vt - vn * resilience; 00357 else 00358 m.vel = vt * oneMinusFriction - vn * resilience; 00359 } 00360 }
void PABounce::Exec | ( | const PDRectangle & | dom, | |
ParticleGroup & | group, | |||
ParticleList::iterator | ibegin, | |||
ParticleList::iterator | iend | |||
) |
Definition at line 362 of file actions.cpp.
References cutoffSqr, PDRectangle::D, PActionBase::dt, pVec::length2(), NewBasis(), PDRectangle::nrm, oneMinusFriction, PDRectangle::p, Particle::pos, pSameSign(), resilience, PDRectangle::u, PDRectangle::v, and Particle::vel.
00363 { 00364 pVec s1, s2; 00365 NewBasis(dom.u, dom.v, s1, s2); 00366 00367 for (ParticleList::iterator it = ibegin; it != iend; it++) { 00368 Particle &m = (*it); 00369 00370 // See if particle's current and pnext positions cross plane. 00371 // If not, couldn't hit, so keep going. 00372 pVec pnext = m.pos + m.vel * dt; 00373 00374 // nrm stores the plane normal (the a,b,c of the plane eqn). 00375 // Old and new distances: dist(p,plane) = n * p + d 00376 float distold = m.pos * dom.nrm + dom.D; 00377 float distnew = pnext * dom.nrm + dom.D; 00378 00379 if(pSameSign(distold, distnew)) 00380 continue; 00381 00382 float nv = dom.nrm * m.vel; 00383 float t = -distold / nv; // Time steps before hit 00384 00385 pVec phit = m.pos + m.vel * t; // Actual intersection point 00386 pVec offset = phit - dom.p; // Offset from origin in plane 00387 00388 // Dot product with basis vectors of old frame 00389 // in terms of new frame gives position in uv frame. 00390 float upos = offset * s1; 00391 float vpos = offset * s2; 00392 00393 // Did it cross plane outside rectangle? 00394 if(upos < 0 || upos > 1 || vpos < 0 || vpos > 1) 00395 continue; 00396 00397 // A hit! A most palpable hit! 00398 // Compute tangential and normal components of velocity 00399 pVec vn = dom.nrm * nv; // Normal Vn = (V.N)N 00400 pVec vt = m.vel - vn; // Tangent Vt = V - Vn 00401 00402 // Compute new velocity heading out: 00403 // Don't apply friction if tangential velocity < cutoff 00404 if(vt.length2() <= cutoffSqr) 00405 m.vel = vt - vn * resilience; 00406 else 00407 m.vel = vt * oneMinusFriction - vn * resilience; 00408 } 00409 }
void PABounce::Exec | ( | const PDPlane & | dom, | |
ParticleGroup & | group, | |||
ParticleList::iterator | ibegin, | |||
ParticleList::iterator | iend | |||
) |
Definition at line 411 of file actions.cpp.
References cutoffSqr, PDPlane::D, PActionBase::dt, pVec::length2(), PDPlane::nrm, oneMinusFriction, Particle::pos, pSameSign(), resilience, and Particle::vel.
00412 { 00413 for (ParticleList::iterator it = ibegin; it != iend; it++) { 00414 Particle &m = (*it); 00415 00416 // See if particle's current and look_ahead positions cross plane. 00417 // If not, couldn't hit, so keep going. 00418 pVec pnext = m.pos + m.vel * dt; 00419 00420 // nrm stores the plane normal (the a,b,c of the plane eqn). 00421 // Old and new distances: dist(p,plane) = n * p + d 00422 float distold = m.pos * dom.nrm + dom.D; 00423 float distnew = pnext * dom.nrm + dom.D; 00424 00425 if(pSameSign(distold, distnew)) 00426 continue; 00427 00428 float nv = dom.nrm * m.vel; 00429 // float t = -distold / nv; // Time steps before hit 00430 00431 // A hit! A most palpable hit! 00432 // Compute tangential and normal components of velocity 00433 pVec vn = dom.nrm * nv; // Normal Vn = (V.N)N 00434 pVec vt = m.vel - vn; // Tangent Vt = V - Vn 00435 00436 // Compute new velocity heading out: 00437 // Don't apply friction if tangential velocity < cutoff 00438 if(vt.length2() <= cutoffSqr) 00439 m.vel = vt - vn * resilience; 00440 else 00441 m.vel = vt * oneMinusFriction - vn * resilience; 00442 } 00443 }
void PABounce::Exec | ( | const PDSphere & | dom, | |
ParticleGroup & | group, | |||
ParticleList::iterator | ibegin, | |||
ParticleList::iterator | iend | |||
) |
Definition at line 445 of file actions.cpp.
References PDSphere::ctr, cutoffSqr, PActionBase::dt, pVec::length(), pVec::length2(), pVec::normalize(), oneMinusFriction, PASSERT, Particle::pos, PDSphere::radIn, PDSphere::radOut, resilience, Particle::vel, and PDSphere::Within().
00446 { 00447 PASSERT(dom.radIn == 0.0f, "Bouncing doesn't work on thick shells. radIn must be 0."); 00448 00449 float dtinv = 1.0f / dt; 00450 00451 // Bounce particles off the inside or outside of the sphere 00452 for (ParticleList::iterator it = ibegin; it != iend; it++) { 00453 Particle &m = (*it); 00454 00455 // See if particle's next position is on the opposite side of the domain. If so, bounce it. 00456 pVec pnext = m.pos + m.vel * dt; 00457 00458 if(dom.Within(m.pos)) { 00459 // We are bouncing off the inside of the sphere. 00460 if(dom.Within(pnext)) 00461 // Still inside. Do nothing. 00462 continue; 00463 00464 // Trying to go outside. Bounce back in. 00465 00466 // Inward-pointing normal to surface. This isn't computed quite right; 00467 // should extrapolate particle position to surface. 00468 pVec n(dom.ctr - m.pos); 00469 n.normalize(); 00470 00471 // Compute tangential and normal components of velocity 00472 float nmag = m.vel * n; 00473 00474 pVec vn = n * nmag; // Velocity in Normal dir Vn = (V.N)N 00475 pVec vt = m.vel - vn; // Velocity in Tangent dir Vt = V - Vn 00476 00477 // Reverse normal component of velocity 00478 if(nmag < 0) vn = -vn; // Don't reverse if it's already heading inward 00479 00480 // Compute new velocity heading out: 00481 // Don't apply friction if tangential velocity < cutoff 00482 float tanscale = (vt.length2() <= cutoffSqr) ? 1.0f : oneMinusFriction; 00483 m.vel = vt * tanscale + vn * resilience; 00484 00485 // Now see where the point will end up. Make sure we fixed it to stay inside. 00486 pVec pthree = m.pos + m.vel * dt; 00487 if(dom.Within(pthree)) { 00488 // Still inside. We're good. 00489 continue; 00490 } else { 00491 // Since the tangent plane is outside the sphere, reflecting the velocity vector about it won't necessarily bring it inside the sphere. 00492 pVec toctr = dom.ctr - pthree; 00493 float dist = toctr.length(); 00494 pVec pwish = dom.ctr - toctr * (0.999f * dom.radOut / dist); // pwish is a point just inside the sphere 00495 m.vel = (pwish - m.pos) * dtinv; // Compute a velocity to get us to pwish. 00496 } 00497 } else { 00498 // We are bouncing off the outside of the sphere. 00499 if(!dom.Within(pnext)) 00500 continue; 00501 00502 // Trying to go inside. Bounce back out. 00503 00504 // Outward-pointing normal to surface. This isn't computed quite right; 00505 // should extrapolate particle position to surface. 00506 pVec n = m.pos - dom.ctr; 00507 n.normalize(); 00508 00509 // Compute tangential and normal components of velocity 00510 float nmag = m.vel * n; 00511 00512 pVec vn = n * nmag; // Velocity in Normal dir Vn = (V.N)N 00513 pVec vt = m.vel - vn; // Velocity in Tangent dir Vt = V - Vn 00514 00515 // Reverse normal component of velocity if it points in 00516 if(nmag < 0) 00517 vn = -vn; 00518 00519 // Compute new velocity heading out: 00520 // Don't apply friction if tangential velocity < cutoff 00521 float tanscale = (vt.length2() <= cutoffSqr) ? 1.0f : oneMinusFriction; 00522 m.vel = vt * tanscale + vn * resilience; 00523 } 00524 } 00525 }
void PABounce::Exec | ( | const PDDisc & | dom, | |
ParticleGroup & | group, | |||
ParticleList::iterator | ibegin, | |||
ParticleList::iterator | iend | |||
) |
Definition at line 527 of file actions.cpp.
References cutoffSqr, PDDisc::D, PActionBase::dt, pVec::length2(), PDDisc::nrm, oneMinusFriction, PDDisc::p, Particle::pos, pSameSign(), PDDisc::radOutSqr, resilience, and Particle::vel.
00528 { 00529 for (ParticleList::iterator it = ibegin; it != iend; it++) { 00530 Particle &m = (*it); 00531 00532 // See if particle's current and look_ahead positions cross plane. 00533 // If not, couldn't hit, so keep going. 00534 pVec pnext = m.pos + m.vel * dt; 00535 00536 // nrm stores the plane normal (the a,b,c of the plane eqn). 00537 // Old and new distances: dist(p,plane) = n * p + d 00538 float distold = m.pos * dom.nrm + dom.D; 00539 float distnew = pnext * dom.nrm + dom.D; 00540 00541 if(pSameSign(distold, distnew)) 00542 continue; 00543 00544 float nv = dom.nrm * m.vel; 00545 float t = -distold / nv; // Time steps before hit 00546 00547 pVec phit = m.pos + m.vel * t; // Actual intersection point 00548 pVec offset = phit - dom.p; // Offset from origin in plane 00549 00550 float radSqr = offset.length2(); 00551 00552 // Are we going to hit the disc ring? If so, always turn to the OUTSIDE of the ring. 00553 if(radSqr < dom.radInSqr || radSqr > dom.radOutSqr) 00554 continue; 00555 00556 // A hit! A most palpable hit! 00557 // Compute tangential and normal components of velocity 00558 pVec vn = dom.nrm * nv; // Normal Vn = (V.N)N 00559 pVec vt = m.vel - vn; // Tangent Vt = V - Vn 00560 00561 // Compute new velocity heading out: 00562 // Don't apply friction if tangential velocity < cutoff 00563 if(vt.length2() <= cutoffSqr) 00564 m.vel = vt - vn * resilience; 00565 else 00566 m.vel = vt * oneMinusFriction - vn * resilience; 00567 } 00568 }
float PABounce::resilience |
float PABounce::cutoffSqr |