-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPhysics.cpp
More file actions
93 lines (85 loc) · 3.3 KB
/
Physics.cpp
File metadata and controls
93 lines (85 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "Physics.hpp"
namespace Physics{
Ogre::Vector3 projectTo(Ogre::Vector3 src,Ogre::Vector3 dest)
{
return src.dotProduct(dest)*dest/dest.squaredLength();
}
void preciseMove(PoolBall *poolBall,Ogre::Real interval)
{
Ogre::SceneNode *sceneNode=poolBall->getEntity()->getParentSceneNode();
Ogre::Vector3 oldVelocity=poolBall->getVelocity();
Ogre::Vector3 frictionDirection=oldVelocity;
frictionDirection.normalise();
Ogre::Vector3 newVelocity=oldVelocity-frictionDirection*poolBall->getFricCoef()*interval*GRAVITY_ACCELERATION;
Ogre::Vector3 transVec=(oldVelocity+newVelocity)*interval/2;
sceneNode->translate(transVec);
sceneNode->pitch(Ogre::Radian(transVec.y/poolBall->getRadius()));
sceneNode->yaw(Ogre::Radian(transVec.x/poolBall->getRadius()));
poolBall->setVelocity(newVelocity);
//#ifdef _DEBUG
// if((abs(sceneNode->getPosition().x)>1000)||(abs(sceneNode->getPosition().y)>2000))
// {
// setStop(poolBall);
// }
//#endif // _DEBUG
}
void fuzzyMove(PoolBall* poolBall,Ogre::Real interval)
{
Ogre::SceneNode *sceneNode=poolBall->getEntity()->getParentSceneNode();
sceneNode->setPosition(sceneNode->getPosition()+poolBall->getVelocity()*interval);
}
void setStop(PoolBall *poolBall)
{
poolBall->setVelocity(Ogre::Vector3(0,0,0));
}
bool isStop(PoolBall *poolBall)
{
return poolBall->getVelocity().squaredLength()<=VELOCITY_THRESHOLD*VELOCITY_THRESHOLD;
}
bool isCollide(PoolBall * lhs,PoolBall* rhs,Ogre::Real interval)
{
Ogre::Real distance=
(lhs->getPosition()+lhs->getVelocity()*interval).distance(
(rhs->getPosition()+rhs->getVelocity()*interval));
if (!((isStop(lhs))&&isStop(rhs)))
if (distance<=(lhs->getRadius()+rhs->getRadius()))
return true;
return false;
}
void collideTwinBall(PoolBall *lhs,PoolBall*rhs,Ogre::Real restCoef)
{
Ogre::Vector3 deltaVelo=lhs->getVelocity()-rhs->getVelocity();
Ogre::Vector3 deltaPos=lhs->getPosition()-rhs->getPosition();
Ogre::Real l_m=lhs->getMass();
Ogre::Real r_m=rhs->getMass();
lhs->changeVelocity(-projectTo(deltaVelo,deltaPos));
rhs->changeVelocity(l_m*projectTo(deltaVelo,deltaPos)/r_m);
}
bool collideBoundary(PoolBall *poolBall,int collideWallTag){
if (collideWallTag==1)
{
poolBall->setVelocity(poolBall->getVelocity().reflect(Ogre::Vector3(1,0,0)));
return true;
}else if(collideWallTag==2){
poolBall->setVelocity(poolBall->getVelocity().reflect(Ogre::Vector3(0,1,0)));
return true;
}else if(collideWallTag==3){
poolBall->setVelocity(poolBall->getVelocity().reflect(Ogre::Vector3(1,0,0)));
poolBall->setVelocity(poolBall->getVelocity().reflect(Ogre::Vector3(0,1,0)));
return true;
}
return false;
}
Ogre::Real timeBeforeCollide(PoolBall *lhs,PoolBall *rhs)
{
Ogre::Vector3 deltaPos=lhs->getPosition()-rhs->getPosition();
Ogre::Vector3 deltaVelo=lhs->getVelocity()-rhs->getVelocity();
Ogre::Real lresult=(-deltaPos.dotProduct(deltaVelo)
-Ogre::Math::Sqrt(deltaVelo.squaredLength()*Ogre::Math::Sqr(lhs->getRadius()+rhs->getRadius())
-deltaPos.crossProduct(deltaVelo).squaredLength()))/deltaVelo.squaredLength();
Ogre::Real rresult=(-deltaPos.dotProduct(deltaVelo)
+Ogre::Math::Sqrt(deltaVelo.squaredLength()*Ogre::Math::Sqr(lhs->getRadius()+rhs->getRadius())
-deltaPos.crossProduct(deltaVelo).squaredLength()))/deltaVelo.squaredLength();
return lresult;
}
}