Overall goal:
We would like to give a feeling of real physics law on a virtual environment. We would like to have "real-time" responses, therefore we are trying to use a simple, efficient and "nice behaving" physical model. We are taking Brian Mirtich's approach (UC Berkeley): impulse-base modeling. But we did not use any of his work due more to lack of time than interest. Brian's approach may be also too complicated for a real-time environment.
We have made the following assumptions:
We are dealing with "Physics of particules" rather than "Physics of solids". The physical objects we have are:
- poolballs as spheres with mass, center, the vector position of the center of the poolball, vCenter, the velocity of the center and aCenter, the acceleration.
- cue, modeled as an independent sphere, at the tip of the virtual cue. Only this sphere is interacting with the rest of the poolball.
- bumpers, modeled as a rectangle, with minX, maxX, minY, maxY. We are actually using the felt, a rectangle instead of using each bumper (total is 8). This is just due to lack of time and for simplicity. Ideally we would like to have the ball to collide with each bumper rather than just to the bundaries of the pooltable. Practically we the current assumption is sufficient and looks sufficient. For now on we are going to use bumper and felt for the same element
- holes, just modeled as a sphere and displayed as a disk on the top of the felt. We are working in 2D but are displaying in 3D. It is possible and not more difficult to change the 2D modeling to 3D modeling of the physics: all distances are already 3D distances: we need to add 2 more walls (or bumper), the bottom and the top, change friction of rolling to friction of air (more difficult but I worked out the math because I first used air friction before rolling friction).
- one table with moving object to moving object distance
- one table with staying object to moving object distance
The moving objects are the poolballs and the cue, the staying objects are the bumpers-felt, the holes and other elements only used for the graphics but not stored in the table.
If the distance change for positive to negative, then we have detected a collision and we take an action. We have several actions to take depending on the objects:
- Collision cue-poolball,
- Collision poolball-poolball,
- Collision poolball-bumpers-felt.
- Collision poolball-hole
If the distance change from negative to positive we don't take only actions but update our "collision state machine": we are just using flags that keep track of the state of the balls: "in collision" or "not in collision". This is important because it's possible that : at time t1 you detect no collision (distance > 0) at time t2 you detect collision (distance < 0) and take an action and at t3 you are still in collision so if you don't put any state information you may take an other action that cancel the previous one and you won't have any "physical collision".
All positions of the poolball are computed based on the previous postion and based on the previous velocity and acceleration as shown here.
We bound the velocity to avoid "infinite" velocity that we had at the beginning. Just: if |velocity| > |maxVelocity| then velocity is normalized and velocity = velocity * |maxVelocity|.
The Friction we are using is "Coulomb" friction which is a constant factor in the acceleration. We first started with a more complicated model and also less adequate: air friction, where the acceleration is not a constant any more but is a linear function of the velocity.
a = c*v (c is a constant).
In that model, v(t) = K * exp(-c*t), where K embeds the initial velocity. K = v(t0)/ exp(-c*t0).
It is important in our case that we have more than a distance between two objects: usually a distance is positive or null only but not negative. Here we extend the distance to be negative as well. For instance if we compute the distance between a sphere and a plane for the poolball/felt-bumper computation: what we really want to do is the compute the distance between the sphere and a half-space.
distance between two poolballs and distance between one poolball and the felt-bumper
For the distance between the poolball and the felt-bumper we started to use the general formula of distance from a point to a plane as follows:
d = |ax+by+cz+K|/(sqrt(x^2+y^2+z^2))
where the plane's normal n ~= (a,b,c), the point P ~=(x,y,z)
and K is computed as follows: P1 ~=(x1,y1,z1) belongs to the plane therefore verifies:
ax1+by1+cz1 + K = 0, which determines K.
The geometry of the bumpers as well as its definition changed quite a bit in the project therefore we decided to stick on a simple version of the bumper and used the felt. But it should not be more difficult to include "real" bumper-ball distance computation now that the table's definition is stable.
There is still a problem of multiple collisions that can occure when the user is pushing the ball and that the direction of the poolball is more difficult to control.
We thought also of using an average velocity and acceleration over 0.5 seconds or so.
Only the normal component of the linear momentum of the spheres are changed and the tangential component remains the same before and after the shock. The shock is said to be impulsive: the forces of the two balls colliding is much greater than any other exterior forces and the shock is very short in time.
So we have to decouple the velocity into a normal component and a tangential component: the normal is along the vector difference of the two centers and the tangential is perpendicular to it. It is possible to change the coeficient of restitution so that the shock is not elastic at all.
Poolball-pooball collision and elastic shock I
Poolball-pooball collision and elastic shock II
We could eventually change the coeficient of restitution, but we didn't offer that option, it would be hard though.
Poolball-felt collision adn elastic shock
Limits of the physical model "There Is No Alternative" ("Tina", Margaret Thatcher). Actually, there are many alternatives...
At the beginning we thought that we would first compute the entire game (at least for each cue intervention) and then display it and iterate. We could have used what other have done the robotics laboratory when they mixed the configuration (position and orientation of the objects) and time to solve the problem in a 7-d space, for instance as done by Tsai-Yen Li in his thesis.
The minor problem was the dimension of the problem: 7-d for each ball, total space is 7*15=105-d, which would have been reduced easily to 3-d per ball (x,y,t), so 3*15=45-d.
We wanted to try Brian's approach instead.
The advantages of the current implementation is that it's conceptually simple and practically simple. Configuration space is nice but is not too intuitive and prediction may take more than real-time and therefore the user would have to wait some time after he/she would have played which is not the spirit of real-virtuality.
Configuration space approach would have been nice because we would have been able to predict when balls collide and therefore help synchronize the network and the sound. It turned out the lag of the network was not the a problem.
Unstable by nature...
- go from 2-d to 3-d using a rectangoloid as for the bumpers, and add gravity,
- have the felt being non planar but 3-d surface and evolve toward "mini-golf",
- record the play for each new interaction of the cue with the balls and allow a "undo" button,
- replace the ball with animated figure, but the collision detection would still be sphere-like,
- have correct "rolling" with a 3d angle,
- have a more "secure" state-machine collision-reaction data structure,
- change the model from "dynamics of particules" to "dynamics of solid rigid bodies": allow spinning probably using Brian's approach.
- use Tsai-Yen's approach as well for prediction,
- add the air friction or fogg friction and variation of the friction coeficient.
- have the ball correctly enter the hole,
- implement tactile/force feedback (?): you could hold the ball and replace them,
- model more physics,
- start-up a company in virtual-reality !!!