00001
00002
00003
00004
00005
00006
00007
00008 #ifndef WORLD_H_
00009 #define WORLD_H_
00010
00011
00012 #include "../Common/Timer.h"
00013 #include "RigidBody.h"
00014 #include "Contact.h"
00015 #include "ContactGenerator.h"
00016 #include "ContactResolver.h"
00017 #include "../Engine/INotifiable.h"
00018 #include "../Engine/GameState.h"
00019 #include <vector>
00020 #include <algorithm>
00021 #include <functional>
00022 #include <iostream>
00023
00024 using namespace std;
00025
00026 struct RegisteredBody {
00027 RigidBody * body;
00028 RegisteredBody * next;
00029 };
00030
00031 struct RegisteredContactGen {
00032 ContactGenerator * gen;
00033 RegisteredContactGen * next;
00034 };
00035
00036 struct RegisteredContactRes {
00037 ContactResolver * res;
00038 RegisteredContactRes * next;
00039 };
00040
00041 class Physics: public INotifiable {
00042
00043 ContactResolver * resolver;
00044 ContactGenerator * generator;
00045
00046 std::vector<RigidBody *> bodies;
00047 std::vector<Contact> contacts;
00048 std::vector<Vector> pockets;
00049 real pocketSize;
00050 RigidBody * white;
00051 GameState *state;
00052
00053 real power;
00054
00055 void findBallsInPocket();
00056 bool isInPocket(const Vector& pos) {
00057 for(std::vector<Vector>::iterator it = pockets.begin(); it!=pockets.end();it++) {
00058 if((pos-(*it)).magnitude()<pocketSize) {
00059 return true;
00060 }
00061 }
00062 return false;
00063 }
00064 public:
00065 Physics() {
00066 state=GameState::getInstance(); power = 1.0;
00067 pocketSize = POCKETSIZE;
00068 pockets.push_back(Vector(TABLEWIDTH/2.0,0.0,TABLELENGTH/2.0));
00069 pockets.push_back(Vector(TABLEWIDTH/2.0,0.0,-TABLELENGTH/2.0));
00070 pockets.push_back(Vector(-TABLEWIDTH/2.0,0.0,TABLELENGTH/2.0));
00071 pockets.push_back(Vector(-TABLEWIDTH/2.0,0.0,-TABLELENGTH/2.0));
00072 pockets.push_back(Vector(TABLEWIDTH/2.0,0.0, 0.0));
00073 pockets.push_back(Vector(-TABLEWIDTH/2.0,0.0, 0.0));
00074 };
00075 void startFrame();
00076 void integrate(real duration);
00077 unsigned generateContacts();
00078 void physicsUpdate(real durationInMicroSec);
00079
00080 void add(RigidBody * b);
00081
00082 void hitCueBall(const Vector& normal, real _power, const Vector& stick);
00083 RigidBody * getCueBall();
00084 void setCueBall(RigidBody * b) { white = b ;}
00085 void debug() {
00086 for(std::vector<RigidBody*>::iterator it = bodies.begin();it!=bodies.end();it++)
00087 std::cout << (*it)->getPosition();
00088
00089 }
00090 void increasePower() {
00091 power*=1.1;
00092 }
00093 void decreasePower() {
00094 power *= 0.9;
00095 }
00096
00097 void processNotification(ISubject *subject);
00098 void reset() {
00099 bodies.clear();
00100 state=GameState::getInstance(); power = 1.0;
00101 pocketSize = POCKETSIZE;
00102 pockets.push_back(Vector(TABLEWIDTH/2.0,0.0,TABLELENGTH/2.0));
00103 pockets.push_back(Vector(TABLEWIDTH/2.0,0.0,-TABLELENGTH/2.0));
00104 pockets.push_back(Vector(-TABLEWIDTH/2.0,0.0,TABLELENGTH/2.0));
00105 pockets.push_back(Vector(-TABLEWIDTH/2.0,0.0,-TABLELENGTH/2.0));
00106 pockets.push_back(Vector(TABLEWIDTH/2.0,0.0, 0.0));
00107 pockets.push_back(Vector(-TABLEWIDTH/2.0,0.0, 0.0));
00108 }
00109
00110 bool isAnimationFinished() {
00111 for(std::vector<RigidBody *>::iterator it = bodies.begin(); it!= bodies.end(); ++it) {
00112 if((*it)->isAwake()) {
00113
00114 return false;
00115 }
00116 }
00117 return true;
00118 }
00119
00120 };
00121
00122
00123 #endif