00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00026 #ifndef CYCLONE_CONTACTS_H
00027 #define CYCLONE_CONTACTS_H
00028
00029 #include "body.h"
00030
00031 namespace cyclone {
00032
00033
00034
00035
00036
00037 class ContactResolver;
00038
00040
00048
00061
00062
00063 class Contact
00064 {
00067
00068
00071
00075 friend ContactResolver;
00077
00078 public:
00083 RigidBody* body[2];
00084
00088 real friction;
00089
00093 real restitution;
00094
00096
00099 Vector3 contactPoint;
00100
00104 Vector3 contactNormal;
00105
00111 real penetration;
00113
00118 void setBodyData(RigidBody* one, RigidBody *two,
00119 real friction, real restitution);
00120
00122 protected:
00123
00129 Matrix3 contactToWorld;
00130
00135 Vector3 contactVelocity;
00136
00141 real desiredDeltaVelocity;
00142
00148 Vector3 relativeContactPosition[2];
00150
00152 protected:
00158 void calculateInternals(real duration);
00159
00166 void swapBodies();
00168
00174 void matchAwakeState();
00175
00180 void calculateDesiredDeltaVelocity(real duration);
00181
00186 Vector3 calculateLocalVelocity(unsigned bodyIndex, real duration);
00187
00193 void calculateContactBasis();
00194
00199 void applyImpulse(const Vector3 &impulse, RigidBody *body,
00200 Vector3 *velocityChange, Vector3 *rotationChange);
00201
00206 void applyVelocityChange(Vector3 velocityChange[2],
00207 Vector3 rotationChange[2]);
00208
00213 void applyPositionChange(Vector3 velocityChange[2],
00214 Vector3 rotationDirection[2],
00215 real rotationAmount[2],
00216 real penetration);
00218 };
00220
00222
00227
00271
00272 class ContactResolver
00273 {
00275 protected:
00280 unsigned velocityIterations;
00281
00286 unsigned positionIterations;
00287
00295 real velocityEpsilon;
00296
00304 real positionEpsilon;
00305
00306 public:
00311 unsigned velocityIterationsUsed;
00312
00317 unsigned positionIterationsUsed;
00318
00319 private:
00323 bool validSettings;
00324
00326 public:
00328
00332 ContactResolver(unsigned iterations,
00333 real velocityEpsilon=(real)0.01,
00334 real positionEpsilon=(real)0.01);
00335
00340 ContactResolver(unsigned velocityIterations,
00341 unsigned positionIterations,
00342 real velocityEpsilon=(real)0.01,
00343 real positionEpsilon=(real)0.01);
00344
00348 bool isValid()
00349 {
00350 return (velocityIterations > 0) &&
00351 (positionIterations > 0) &&
00352 (positionEpsilon >= 0.0f) &&
00353 (positionEpsilon >= 0.0f);
00354 }
00355
00359 void setIterations(unsigned velocityIterations,
00360 unsigned positionIterations);
00361
00365 void setIterations(unsigned iterations);
00366
00370 void setEpsilon(real velocityEpsilon,
00371 real positionEpsilon);
00372
00374
00377
00401
00402 void resolveContacts(Contact *contactArray,
00403 unsigned numContacts,
00404 real duration);
00406
00408 protected:
00411
00416 void prepareContacts(Contact *contactArray, unsigned numContacts,
00417 real duration);
00419
00424 void adjustVelocities(Contact *contactArray,
00425 unsigned numContacts,
00426 real duration);
00427
00432 void adjustPositions(Contact *contacts,
00433 unsigned numContacts,
00434 real duration);
00436 };
00438
00443 class ContactGenerator
00444 {
00445 public:
00454 virtual unsigned addContact(Contact *contact, unsigned limit) const = 0;
00455 };
00456
00457 }
00458
00459 #endif // CYCLONE_CONTACTS_H