Commit 8e18b3d5682b4973450d7d64df6643f97e374036

Authored by Bjørn-Richard Pedersen
1 parent 1a3cf963

Start of second week

CMakeLists.txt
... ... @@ -2,7 +2,7 @@
2 2 cmake_minimum_required(VERSION 3.4)
3 3  
4 4 # Nice name for the IDEs
5   -project(collision_library_stub VERSION 0.1 LANGUAGES CXX)
  5 +project(collision_library VERSION 0.1 LANGUAGES CXX)
6 6  
7 7 # Specify compiler features
8 8 set(CMAKE_CXX_STANDARD 14)
... ...
include/collision_library.cpp
1 1 #include "collision_library.h"
2 2  
  3 +#include <chrono>
  4 +using namespace std::chrono_literals;
3 5  
4 6  
5 7 namespace collision
... ... @@ -23,7 +25,9 @@ namespace collision
23 25 const auto radius_sum = S0_radius + S1_radius;
24 26  
25 27 const auto Q = (S1_position - S0_position);
26   - const auto R = (S1.computeTrajectory(new_dt) - S0.computeTrajectory(new_dt));
  28 + const auto r1 = S1.computeTrajectory(new_dt);
  29 + const auto r2 = S0.computeTrajectory(new_dt);
  30 + const auto R = r1 - r2;
27 31  
28 32 const auto _QR = Q * R;
29 33 const auto _QRQR = std::pow( _QR, 2);
... ... @@ -56,6 +60,39 @@ namespace collision
56 60  
57 61 }
58 62  
  63 + void
  64 + computeImpactResponse (DynamicPhysObject<GMlib::PSphere<float>>& S0,
  65 + DynamicPhysObject<GMlib::PSphere<float>>& S1,
  66 + seconds_type dt)
  67 + {
  68 + const auto S0_old_vel = S0.velocity; // 2.1
  69 + const auto S1_old_vel = S1.velocity; // -2.1
  70 +
  71 + const auto S0_pos = S0.getPos().toType<double>();
  72 + const auto S1_pos = S1.getPos().toType<double>();
  73 +
  74 + const auto S0_mass = S0.mass;
  75 + const auto S1_mass = S1.mass;
  76 +
  77 + const auto distance_vector_d = GMlib::Vector<double,3>(S1_pos - S0_pos);
  78 + const auto normal_d = distance_vector_d.getNormalized();
  79 + const auto n = (GMlib::Vector<double,3>(distance_vector_d).getLinIndVec()).getNormalized();
  80 +
  81 + const auto v0_d = (S0_old_vel * normal_d);
  82 + const auto v1_d = (S1_old_vel * normal_d);
  83 + const auto v0_n = (S0_old_vel * n);
  84 + const auto v1_n = (S1_old_vel * n);
  85 +
  86 + const auto new_v0_d = (((S0_mass - S1_mass) / (S0_mass + S1_mass) ) * v0_d ) + (((2 * S1_mass) / (S0_mass + S1_mass) ) * v1_d );
  87 + const auto new_v1_d = (((S1_mass - S0_mass) / (S0_mass + S1_mass) ) * v1_d ) + (((2 * S0_mass) / (S0_mass + S1_mass) ) * v0_d );
  88 +
  89 + const auto S0_new_vel = (v0_n * n) + (new_v0_d * normal_d); // -2.1
  90 + const auto S1_new_vel = v1_n * n + new_v1_d * normal_d; // 2.1
  91 +
  92 + S0.velocity = S0_new_vel;
  93 + S1.velocity = S1_new_vel;
  94 + }
  95 +
59 96 CollisionState
60 97 detectCollision (const DynamicPhysObject<GMlib::PSphere<float>>& S,
61 98 const StaticPhysObject<GMlib::PPlane<float>>& P,
... ... @@ -101,36 +138,22 @@ namespace collision
101 138 }
102 139  
103 140 void
104   - computeImpactResponse (DynamicPhysObject<GMlib::PSphere<float>>& S0,
105   - DynamicPhysObject<GMlib::PSphere<float>>& S1,
106   - seconds_type dt)
107   - {
108   - const auto S0_old_vel = S0.velocity; // 2.1
109   - const auto S1_old_vel = S1.velocity; // -2.1
110   -
111   - const auto S0_pos = S0.getPos();
112   - const auto S1_pos = S1.getPos();
113   -
114   - const auto S0_mass = S0.mass;
115   - const auto S1_mass = S1.mass;
  141 + computeImpactResponse (DynamicPhysObject<GMlib::PSphere<float>>& S,
  142 + const StaticPhysObject<GMlib::PPlane<float>>& P,
  143 + seconds_type dt) {
116 144  
117   - const auto distance_vector_d = GMlib::Vector<float,3>(S1_pos - S0_pos);
118   - const auto normal_d = distance_vector_d.getNormalized();
119   - const auto n = (GMlib::Vector<float,3>(distance_vector_d).getLinIndVec()).getNormalized();
  145 + auto &plane = const_cast<StaticPhysObject<GMlib::PPlane<float>>&>(P);
  146 + const auto p = plane.evaluateParent(0.5f, 0.5f, 1, 1);
  147 + const auto u = p(1)(0);
  148 + const auto v = p(0)(1);
120 149  
121   - const auto v0_d = (S0_old_vel * normal_d);
122   - const auto v1_d = (S1_old_vel * normal_d);
123   - const auto v0_n = (S0_old_vel * n);
124   - const auto v1_n = (S1_old_vel * n);
  150 + const auto n = u ^ v;
  151 + const auto n_normal = GMlib::Vector<float,3>(n).getNormalized();
125 152  
126   - const auto new_v0_d = (((S0_mass - S1_mass) / (S0_mass + S1_mass) ) * v0_d ) + (((2 * S1_mass) / (S0_mass + S1_mass) ) * v1_d );
127   - const auto new_v1_d = (((S1_mass - S0_mass) / (S0_mass + S1_mass) ) * v1_d ) + (((2 * S0_mass) / (S0_mass + S1_mass) ) * v0_d );
  153 + const auto new_vel = S.velocity - (2*(S.velocity * n_normal) * n_normal);
128 154  
129   - const auto S0_new_vel = (v0_n * n) + (new_v0_d * normal_d); // -2.1
130   - const auto S1_new_vel = v1_n * n + new_v1_d * normal_d; // 2.1
  155 + S.velocity = new_vel;
131 156  
132   - S0.velocity = S0_new_vel;
133   - S1.velocity = S1_new_vel;
134 157 }
135 158  
136 159 CollisionState detectCollision (const DynamicPSphere& S,
... ... @@ -195,38 +218,67 @@ namespace collision
195 218  
196 219 }
197 220  
198   - void computeImpactResponse (DynamicPSphere& S, const StaticPBezierSurf& B,
  221 + void
  222 + computeImpactResponse (DynamicPSphere& S, const StaticPBezierSurf& B,
199 223 seconds_type dt) {
200 224  
201 225 }
202 226  
  227 + CollisionState detectCollision (const DynamicPSphere& S0,
  228 + const StaticPSphere& S1, seconds_type dt) {
  229 +
  230 + }
  231 +
203 232 void
204   - computeImpactResponse (DynamicPhysObject<GMlib::PSphere<float>>& S,
205   - const StaticPhysObject<GMlib::PCylinder<float>>& C,
206   - seconds_type dt) {
  233 + computeImpactResponse (DynamicPSphere& S0, const StaticPSphere& S1,
  234 + seconds_type dt) {
207 235  
  236 + }
  237 +
  238 + CollisionState
  239 + detectCollision(const DynamicPSphere &S, const DynamicPCylinder &C, seconds_type dt) {
208 240  
209 241 }
210 242  
211 243 void
212   - computeImpactResponse (DynamicPhysObject<GMlib::PSphere<float>>& S,
213   - const StaticPhysObject<GMlib::PPlane<float>>& P,
214   - seconds_type dt) {
  244 + computeImpactResponse (DynamicPSphere& S, DynamicPCylinder& C,
  245 + seconds_type dt) {
215 246  
216   - auto &plane = const_cast<StaticPhysObject<GMlib::PPlane<float>>&>(P);
217   - const auto p = plane.evaluateParent(0.5f, 0.5f, 1, 1);
218   - const auto u = p(1)(0);
219   - const auto v = p(0)(1);
  247 + }
220 248  
221   - const auto n = u ^ v;
222   - const auto n_normal = GMlib::Vector<float,3>(n).getNormalized();
  249 + CollisionState
  250 + detectCollision (const DynamicPSphere& S, const StaticPCylinder& C, seconds_type dt) {
223 251  
224   - const auto new_vel = S.velocity - (2*(S.velocity * n_normal) * n_normal);
  252 + }
225 253  
226   - S.velocity = new_vel;
  254 + void
  255 + computeImpactResponse (DynamicPSphere& S, const StaticPCylinder& C,
  256 + seconds_type dt);
  257 +
  258 + CollisionState
  259 + detectCollision (const DynamicPCylinder& C0, const DynamicPCylinder& C, seconds_type dt);
  260 +
  261 + void computeImpactResponse (DynamicPCylinder& C0, DynamicPCylinder& C1,
  262 + seconds_type dt) {
227 263  
228 264 }
229 265  
  266 + void computeImpactResponse (DynamicPCylinder& C, const StaticPSphere& S,
  267 + seconds_type dt){
  268 +
  269 + }
  270 +
  271 + void computeImpactResponse (DynamicPCylinder& C, const StaticPBezierSurf& B,
  272 + seconds_type dt){
  273 +
  274 + }
  275 +
  276 + void computeImpactResponse (DynamicPCylinder& C, const StaticPPlane& P,
  277 + seconds_type dt){
  278 +
  279 + }
  280 +
  281 +
230 282 std::unique_ptr<Controller>
231 283 unittestCollisionControllerFactory() {
232 284  
... ... @@ -236,15 +288,38 @@ namespace collision
236 288 void
237 289 DynamicPhysObject<GMlib::PSphere<float> >::simulateToTInDt(seconds_type t){
238 290  
  291 + auto dt = t - this->curr_t_in_dt;
  292 + auto MI = this->getMatrixToSceneInverse();
  293 + auto ds = this->computeTrajectory(dt);
  294 +
  295 + // Move
  296 + this->translateParent( MI * ds);
  297 + this->curr_t_in_dt = t;
  298 +
  299 + // Update physics
  300 + auto F = this->externalForces();
  301 + auto a = 0.5 * F * (this->mass) * std::pow(dt.count(), 2);
  302 +
  303 + this->velocity += a;
239 304 }
240 305  
241   - GMlib::Vector<float,3>
  306 +
  307 +
  308 + GMlib::Vector<double,3>
242 309 DynamicPhysObject<GMlib::PSphere<float> >::computeTrajectory(seconds_type dt) const {
243 310  
244   - return this->velocity * dt.count() + ( 0.5 * this->externalForces() * std::pow(dt.count(),2) );
  311 + auto vel = this->velocity;
  312 + auto dtCount = dt.count(); // 0
  313 + auto xF = this->externalForces();
  314 + auto mas = this->mass;
  315 +
  316 + return vel * dtCount + 0.5 * xF * mas * std::pow(dtCount,2);
  317 +
  318 +// return this->velocity * dt.count() + ( 0.5 * this->externalForces() * (this->mass) * std::pow(dt.count(),2) );
  319 +
245 320 }
246 321  
247   - GMlib::Vector<float,3>
  322 + GMlib::Vector<double,3>
248 323 DynamicPhysObject<GMlib::PSphere<float> >::externalForces() const {
249 324  
250 325 assert(environment != nullptr);
... ... @@ -255,13 +330,152 @@ namespace collision
255 330 void
256 331 MyController::localSimulate(double dt) {
257 332  
  333 + // Reset time variable for all objects
  334 + for( auto sphere : _dynamic_spheres) {
  335 +
  336 + sphere->curr_t_in_dt = seconds_type{0.0};
  337 + }
  338 +
  339 + // Collision detection algorithm
  340 + _collisions.clear(); // Initialize
  341 +
  342 +
  343 + //Check for collisions between Spheres
  344 + for( auto& sphere : _dynamic_spheres) {
  345 +
  346 + // Sending in sphere twice in the initial call because the function will require a second object in future calls
  347 + // Må da være en bedre måte å gjøre det på
  348 +
  349 + sphereDynamicCollision(sphere, sphere, seconds_type(dt));
  350 + sphereStaticCollision(sphere, sphere, seconds_type(dt));
  351 + }
  352 +
  353 + // Make Collision unique
  354 + sortAndMakeUnique(_collisions);
  355 + std::reverse(_collisions.begin(), _collisions.end());
  356 +
  357 + // Impact response
  358 + while( !_collisions.empty() ) {
  359 +
  360 + auto c = _collisions.back();
  361 + _collisions.pop_back();
  362 +
  363 + c.obj1->simulateToTInDt(c.t_in_dt);
  364 + c.obj2->simulateToTInDt(c.t_in_dt);
  365 +
  366 + // Add more objects here if you end up using more
  367 + auto d_sphere_1 = dynamic_cast<DynamicPSphere*>(c.obj1);
  368 + auto d_sphere_2 = dynamic_cast<DynamicPSphere*>(c.obj2);
  369 + auto s_sphere_2 = dynamic_cast<StaticPSphere*>(c.obj2);
  370 + auto d_cylinder_1 = dynamic_cast<DynamicPCylinder*>(c.obj1);
  371 + auto d_cylinder_2 = dynamic_cast<DynamicPCylinder*>(c.obj2);
  372 + auto s_cylinder_2 = dynamic_cast<StaticPCylinder*>(c.obj2);
  373 + auto s_plane_2 = dynamic_cast<StaticPPlane*>(c.obj2);
  374 + auto s_bezier_2 = dynamic_cast<StaticPBezierSurf*>(c.obj2);
  375 +
  376 +
  377 +
  378 + // First object is sphere
  379 + if(d_sphere_1) {
  380 +
  381 + if (d_sphere_2)
  382 + computeImpactResponse( *d_sphere_1, *d_sphere_2, c.t_in_dt); // D_Sphere vs. D_Sphere
  383 + else if (d_sphere_1 && s_sphere_2)
  384 + computeImpactResponse( *d_sphere_1, *s_sphere_2, c.t_in_dt); // D_Sphere vs. S_Sphere
  385 + else if (d_sphere_1 && d_cylinder_2)
  386 + computeImpactResponse( *d_sphere_1, *d_cylinder_2, c.t_in_dt); // D_Sphere vs. D_Cylinder
  387 + else if (d_sphere_1 && s_cylinder_2)
  388 + computeImpactResponse( *d_sphere_1, *d_cylinder_2, c.t_in_dt); // D_Sphere vs. S_Cylinder
  389 + else if (d_sphere_1 && s_plane_2)
  390 + computeImpactResponse( *d_sphere_1, *s_plane_2, c.t_in_dt); // D_Sphere vs. S_Plane
  391 + else if (d_sphere_1 && s_bezier_2)
  392 + computeImpactResponse( *d_sphere_1, *s_bezier_2, c.t_in_dt); // D_Sphere vs. S_Bezier
  393 +
  394 + }
  395 +
  396 + // First object is cylinder
  397 + if(d_cylinder_1) {
  398 +
  399 + if (d_cylinder_2)
  400 + computeImpactResponse( *d_cylinder_1, *d_cylinder_2, c.t_in_dt); // D_Cylinder vs. D_Cylinder
  401 + else if (d_cylinder_1 && s_cylinder_2)
  402 + computeImpactResponse( *d_sphere_1, *d_cylinder_2, c.t_in_dt); // D_Cylinder vs. S_Cylinder
  403 + else if (d_cylinder_1 && d_sphere_2)
  404 + computeImpactResponse( *d_sphere_2, *d_cylinder_1, c.t_in_dt); // D_Cylinder vs. D_Sphere
  405 + else if (d_cylinder_1 && s_sphere_2)
  406 + computeImpactResponse( *d_cylinder_1, *s_sphere_2, c.t_in_dt); // D_Cylinder vs. S_Sphere
  407 + else if (d_cylinder_1 && s_bezier_2)
  408 + computeImpactResponse( *d_cylinder_1, *s_bezier_2, c.t_in_dt); // D_Cylinder vs. S_Bezier
  409 + else if (d_cylinder_1 && s_plane_2)
  410 + computeImpactResponse( *d_cylinder_1, *s_plane_2, c.t_in_dt); // D_Cylinder vs. S_Plane
  411 +
  412 + }
  413 +
  414 + // Additional collisions for the dynamic objects in the collision_object
  415 + // Not allowed: Same collision twice, cannot collide with itself
  416 +
  417 + // If the dynamic object (obj1) is a sphere
  418 + if( d_sphere_1) {
  419 +
  420 +
  421 +
  422 + sphereDynamicCollision(d_sphere_1, c.obj2, seconds_type(dt)); // Does it collide with any dynamic objects? Can't with same obj as last time
  423 + sphereStaticCollision(d_sphere_1, c.obj2, seconds_type(dt)); // Does it collide with any static objects? Can't with same obj as last time
  424 +
  425 + // If sphere 1 collided with a dynamic sphere, check for that sphere's future collisions
  426 + if(d_sphere_2) {
  427 +
  428 + sphereDynamicCollision(d_sphere_2, d_sphere_1, seconds_type(dt)); // Does it collide with any dynamic objects? Can't with sphere 1
  429 + sphereStaticCollision(d_sphere_2, c.obj2, seconds_type(dt)); // Does it collide with any static objects? Placeholder variable for "Last object"
  430 + }
  431 +
  432 + // Same if object 2 is a dynamic cylinder
  433 + if(d_cylinder_2) {
  434 +
  435 + //cylinderDynamicCollision(d_cylinder_2, d_sphere_1, seconds_type(dt));
  436 + //cylinderStaticCollision(d_cylinder_2, c.obj2, seconds_type(dt));
  437 + }
  438 + }
  439 +
  440 + // If the dynamic object (obj1) is a cylinder
  441 + if(d_cylinder_1) {
  442 +
  443 + //cylinderDynamicCollision(d_cylinder_1, c.obj2, seconds_type(dt));
  444 + //cylinderStaticCollision(d_cylinder_1, c.obj2, seconds_type(dt));
  445 +
  446 + if(d_cylinder_2) {
  447 +
  448 + //cylinderDynamicCollision(d_cylinder_2, d_cylinder_1, seconds_type(dt));
  449 + //cylinderStaticCollision(d_cylinder_2, c.obj2, seconds_type(dt));
  450 + }
  451 +
  452 + if(d_sphere_2) {
  453 +
  454 + sphereDynamicCollision(d_sphere_2, d_sphere_1, seconds_type(dt));
  455 + sphereStaticCollision(d_sphere_2, c.obj2, seconds_type(dt));
  456 + }
  457 + }
  458 +
  459 + }
  460 +
  461 +// Start simulation for all objects
  462 + for( auto sphere : _dynamic_spheres) {
  463 +
  464 + sphere->simulateToTInDt(seconds_type(dt));
  465 +
  466 +
  467 +
  468 + }
  469 +
258 470 }
259 471  
260 472 // Adding objects to vector
261 473 void
262 474 MyController::add(DynamicPSphere * const sphere) {
263 475  
  476 + sphere->environment = &_env;
264 477 _dynamic_spheres.push_back(sphere);
  478 +
265 479 }
266 480 void
267 481 MyController::add(StaticPSphere * const sphere) {
... ... @@ -286,3 +500,4 @@ namespace collision
286 500  
287 501 } // END namespace collision
288 502  
  503 +
... ...
include/collision_library.h
... ... @@ -4,6 +4,7 @@
4 4 // collision library interface
5 5 #include <collision_interface.h>
6 6  
  7 +#include <typeinfo>
7 8  
8 9  
9 10 namespace collision
... ... @@ -21,16 +22,29 @@ public:
21 22 void add (StaticPCylinder* const cylinder);
22 23 void add (StaticPBezierSurf* const surf);
23 24  
  25 +
  26 +private:
  27 +
  28 + template <typename T_s, typename T_o>
  29 + void sphereStaticCollision(T_s* sphere, T_o* object, seconds_type dt);
  30 +
  31 + template <typename T_s, typename T_o>
  32 + void sphereDynamicCollision(T_s* sphere, T_o* object, seconds_type dt);
  33 +
24 34 protected:
25 35 void localSimulate (double dt) override;
26 36  
27   - std::vector<DynamicPSphere*> _dynamic_spheres;
28   - std::vector<StaticPSphere*> _static_spheres;
29   - std::vector<StaticPPlane*> _static_planes;
30   - std::vector<StaticPCylinder*> _static_cylinders;
31   - std::vector<StaticPBezierSurf*> _static_bezier_surf;
  37 + std::vector<DynamicPSphere*> _dynamic_spheres;
  38 + std::vector<DynamicPCylinder*> _dynamic_cylinders;
  39 + std::vector<StaticPSphere*> _static_spheres;
  40 + std::vector<StaticPPlane*> _static_planes;
  41 + std::vector<StaticPCylinder*> _static_cylinders;
  42 + std::vector<StaticPBezierSurf*> _static_bezier_surf;
  43 + std::vector<collision::CollisionObject> _collisions;
32 44  
33   - std::vector<collision::CollisionObject> _collisions;
  45 +
  46 +
  47 + Environment _env;
34 48  
35 49  
36 50 };
... ... @@ -42,10 +56,10 @@ public:
42 56  
43 57 void simulateToTInDt( seconds_type t ) override;
44 58  
45   - GMlib::Vector<float, 3>
  59 + GMlib::Vector<double, 3>
46 60 computeTrajectory (seconds_type dt) const override; // [m]
47 61  
48   - GMlib::Vector<float, 3> externalForces () const override; // [m / s^2]
  62 + GMlib::Vector<double, 3> externalForces () const override; // [m / s^2]
49 63 };
50 64  
51 65 template <class PSurf_T, typename... Arguments>
... ... @@ -65,11 +79,155 @@ std::unique_ptr&lt;StaticPhysObject&lt;PSurf_T&gt;&gt; unittestStaticPhysObjectFactory(Argum
65 79 template <class Container_T >
66 80 void sortAndMakeUnique( Container_T& container) {
67 81  
  82 + // Sort
  83 +
  84 + std::sort( std::begin(container), std::end(container), [](const auto& a, const auto& b) {
  85 + return a.t_in_dt < b.t_in_dt;
  86 + });
  87 +
  88 + // Make unique
  89 +
  90 + auto pred = [](const auto &a, const auto &b) {
  91 +
  92 + auto is_d_pred = []( const auto* obj ) {
  93 + if(dynamic_cast<const DynamicPSphere*>(obj)) return true;
  94 +
  95 +
  96 +
  97 + return false;
  98 + };
  99 +
  100 + if( a.obj1 == b.obj1 ) return true;
  101 + if( a.obj1 == b.obj2 ) return true;
  102 + if( a.obj2 == b.obj1 ) return true;
  103 + if( ( is_d_pred(a.obj2) or is_d_pred(b.obj2) )
  104 + and a.obj2 == b.obj2 ) return true;
  105 +
  106 + return false;
  107 + };
  108 +
  109 + typename Container_T::iterator NE = std::end(container);
  110 + for( auto first_iter = std::begin(container); first_iter != NE; ++first_iter) {
  111 +
  112 + for( auto r_iterator = NE - 1; r_iterator != first_iter; --r_iterator) {
  113 +
  114 + if( (pred(*first_iter, *r_iterator))) {
  115 + std::swap( *r_iterator, *(NE-1) );
  116 + NE--;
  117 +
  118 + }
  119 + }
  120 + }
  121 +
  122 + container.erase( NE, std::end( container ) );
  123 +
  124 + } // EOF
  125 +
  126 +
  127 +template <typename T_s, typename T_o>
  128 +inline
  129 +void MyController::sphereDynamicCollision(T_s* sphere, T_o* object, seconds_type dt) {
  130 +
  131 + auto cylinder = dynamic_cast<DynamicPCylinder*>(object);
  132 +// auto plane = dynamic_cast<DynamicPPlane*>(object);
  133 +
  134 + if( cylinder ) {
  135 +
  136 + // Sphere vs. Dynamic Cylinder
  137 + }
  138 +// else if( plane ) {
  139 +
  140 + // Sphere vs. Dynamic Plane
  141 +// }
  142 + else {
  143 +
  144 + // Sphere vs. Dynamic Sphere
  145 + for( auto iter = std::begin(_dynamic_spheres); iter != std::end(_dynamic_spheres); ++iter) {
  146 +
  147 + if( (*iter == sphere) or (*iter == object) ) {
  148 + break;
  149 + }
  150 + else {
  151 +
  152 + // Check only for collisions for the first dynamic sphere
  153 + auto col = detectCollision(*sphere, **iter, dt);
  154 +
  155 + // The check for if the second object is a dynamic sphere is done in the main algorithm
  156 + // and the method is called again only with the 1'st and 2'nd sphere swapped
  157 +
  158 + if( col.CollisionState::flag == CollisionStateFlag::Collision ) {
  159 +
  160 + auto& first_sphere = sphere;
  161 + auto& second_sphere = *iter;
  162 +
  163 + auto new_t = std::max(first_sphere->curr_t_in_dt, second_sphere->curr_t_in_dt);
  164 +
  165 + if( col.time > seconds_type(new_t) and col.time < dt) {
  166 + auto col_obj = CollisionObject(first_sphere, second_sphere, col.time);
  167 + _collisions.push_back(col_obj);
  168 + }
  169 + }
  170 + }
  171 + }
  172 + }
  173 +
68 174  
69 175 }
70 176  
  177 +template <typename T_s, typename T_o>
  178 +inline
  179 +void MyController::sphereStaticCollision(T_s* sphere, T_o* object, seconds_type dt)
  180 +{
  181 +
  182 + // The game will mainly have two types of static objects that can be collided with, planes and bezier surfaces
  183 + // Checks to see which one the sphere has collided with
  184 + auto plane = dynamic_cast<const StaticPPlane*>(object);
  185 + auto bezier_s = dynamic_cast<const StaticPBezierSurf*>(object);
  186 +
  187 +
  188 + // Sphere vs. Static Plane
  189 + if( plane ) {
  190 +
  191 + for( auto iter = std::begin(_static_planes); iter != std::end(_static_planes); ++iter) {
  192 +
  193 + // The sphere cannot collide with the same plane it just collided with
  194 + if( *iter == plane ) {
  195 + break;
  196 + }
  197 +
  198 + auto col = detectCollision(*sphere, **iter, dt);
  199 +
  200 + if( col.CollisionState::flag == CollisionStateFlag::Collision ) {
  201 +
  202 + auto& static_object = *iter;
  203 +
  204 + auto new_t = sphere->curr_t_in_dt;
  205 +
  206 + if( col.time > seconds_type(new_t) and col.time < dt)
  207 + {
  208 + auto col_obj = CollisionObject(sphere, static_object, col.time);
  209 + _collisions.push_back(col_obj);
  210 + }
  211 + }
  212 + }
  213 + }
  214 +
  215 + // Same as above, only for bezier surfaces
  216 + else if( bezier_s) {
  217 +
  218 + }
  219 +
  220 +
  221 +}
  222 +
  223 +
71 224 } // END namespace collision
72 225  
73 226  
74 227  
75   -#endif //COLLISION_LIBRARY_H
  228 +#endif
  229 +
  230 +
  231 +
  232 +
  233 +
... ...
unittests/hello_world.cc
... ... @@ -25,3 +25,39 @@ TEST(MyUniqueTestCategory, MyCategory_UniqueTestName_WhichFails) {
25 25  
26 26 EXPECT_FALSE(true);
27 27 }
  28 +
  29 +TEST(UniqueTest, DevelopmentTest) {
  30 +
  31 + Environment env;
  32 +
  33 + auto sphere1 = unittestDynamicPhysObjectFactory<GMlib::PSphere<float>>();
  34 + sphere1->environment = &env;
  35 + sphere1->translate(Vector<float,3>{1.0f,-3.0f,0.0f});
  36 + sphere1->velocity = Vector<double, 3>{0.0, 2.1, 0.0};
  37 + sphere1->curr_t_in_dt = seconds_type{0};
  38 +
  39 + auto sphere2 = unittestDynamicPhysObjectFactory<GMlib::PSphere<float>>();
  40 + sphere2->environment = &env;
  41 + sphere2->translate(Vector<float,3>{1.0f,3.0f,0.0f});
  42 + sphere2->velocity = Vector<double, 3>{0.0, -2.1, 0.0};
  43 + sphere2->curr_t_in_dt = seconds_type{0};
  44 +
  45 + const double dt {1.0};
  46 +
  47 +
  48 + auto controller = unittestCollisionControllerFactory();
  49 + controller->add(sphere1.get());
  50 + controller->add(sphere2.get());
  51 +
  52 + Scene scene;
  53 + scene.insert(controller.get());
  54 + scene.prepare();
  55 +
  56 + scene.enabledFixedDt();
  57 + scene.setFixedDt(dt);
  58 + scene.start();
  59 + scene.simulate();
  60 + scene.prepare();
  61 +
  62 + EXPECT_FALSE(true);
  63 +}
... ...