gosling 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/gosling/actor.rb +31 -8
- data/lib/gosling/circle.rb +9 -14
- data/lib/gosling/collision.rb +334 -51
- data/lib/gosling/image_library.rb +1 -1
- data/lib/gosling/matrix_cache.rb +21 -0
- data/lib/gosling/object_cache.rb +48 -0
- data/lib/gosling/polygon.rb +43 -19
- data/lib/gosling/rect.rb +1 -7
- data/lib/gosling/sprite.rb +2 -1
- data/lib/gosling/transformable.rb +105 -75
- data/lib/gosling/vector_cache.rb +21 -0
- data/lib/gosling/version.rb +1 -1
- data/spec/collision_spec.rb +375 -77
- data/spec/matrix_cache_spec.rb +25 -0
- data/spec/object_cache_spec.rb +22 -0
- data/spec/polygon_spec.rb +27 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/transformable_spec.rb +122 -15
- data/spec/vector_cache_spec.rb +80 -0
- metadata +12 -4
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            require_relative 'object_cache.rb'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class VectorCache
         | 
| 4 | 
            +
              include Singleton
         | 
| 5 | 
            +
              include ObjectCache
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def initialize
         | 
| 8 | 
            +
                @cache = {}
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              protected
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              def create
         | 
| 14 | 
            +
                Snow::Vec3.new
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def reset(vector)
         | 
| 18 | 
            +
                type_check(vector, Snow::Vec3)
         | 
| 19 | 
            +
                vector.set(0, 0, 0)
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
    
        data/lib/gosling/version.rb
    CHANGED
    
    
    
        data/spec/collision_spec.rb
    CHANGED
    
    | @@ -1,5 +1,27 @@ | |
| 1 1 | 
             
            require 'set'
         | 
| 2 2 |  | 
| 3 | 
            +
            module Gosling
         | 
| 4 | 
            +
              class Collision
         | 
| 5 | 
            +
                def self.collision_buffer
         | 
| 6 | 
            +
                  @@collision_buffer
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def self.global_vertices_cache
         | 
| 10 | 
            +
                  @@global_vertices_cache
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def self.global_position_cache
         | 
| 14 | 
            +
                  @@global_position_cache
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                def self.global_transform_cache
         | 
| 18 | 
            +
                  @@global_transform_cache
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                public_class_method :reset_separation_axes, :separation_axes
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| 24 | 
            +
             | 
| 3 25 | 
             
            def angle_to_vector(angle)
         | 
| 4 26 | 
             
              Snow::Vec3[Math.sin(angle).round(12), Math.cos(angle).round(12), 0]
         | 
| 5 27 | 
             
            end
         | 
| @@ -117,11 +139,17 @@ describe Gosling::Collision do | |
| 117 139 | 
             
                @angles = (0...ANGLE_COUNT).map { |i| Math::PI * 2 * i / ANGLE_COUNT }
         | 
| 118 140 | 
             
              end
         | 
| 119 141 |  | 
| 142 | 
            +
              before do
         | 
| 143 | 
            +
                Gosling::Collision.reset_separation_axes
         | 
| 144 | 
            +
              end
         | 
| 145 | 
            +
             | 
| 120 146 | 
             
              context 'any actor vs. itself' do
         | 
| 121 147 | 
             
                it 'never collides' do
         | 
| 122 148 | 
             
                  [@actor1, @circle1, @polygon1, @rect1, @sprite1].each do |actor|
         | 
| 123 149 | 
             
                    expect(Gosling::Collision.test(actor, actor)).to be false
         | 
| 124 150 | 
             
                    result = Gosling::Collision.get_collision_info(actor, actor)
         | 
| 151 | 
            +
                    expect(result[:actors]).to include(actor)
         | 
| 152 | 
            +
                    expect(result[:actors].length).to eq(2)
         | 
| 125 153 | 
             
                    expect(result[:colliding]).to be false
         | 
| 126 154 | 
             
                    expect(result[:overlap]).to be nil
         | 
| 127 155 | 
             
                    expect(result[:penetration]).to be nil
         | 
| @@ -141,6 +169,7 @@ describe Gosling::Collision do | |
| 141 169 | 
             
                  pairs.each do |pair|
         | 
| 142 170 | 
             
                    expect(Gosling::Collision.test(*pair)).to be false
         | 
| 143 171 | 
             
                    result = Gosling::Collision.get_collision_info(*pair)
         | 
| 172 | 
            +
                    expect(result[:actors]).to include(*pair)
         | 
| 144 173 | 
             
                    expect(result[:colliding]).to be false
         | 
| 145 174 | 
             
                    expect(result[:overlap]).to be nil
         | 
| 146 175 | 
             
                    expect(result[:penetration]).to be nil
         | 
| @@ -162,6 +191,7 @@ describe Gosling::Collision do | |
| 162 191 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 163 192 | 
             
                  expect(Gosling::Collision.test(@circle1, @circle2)).to be true
         | 
| 164 193 | 
             
                  result = Gosling::Collision.get_collision_info(@circle1, @circle2)
         | 
| 194 | 
            +
                  expect(result[:actors]).to include(@circle1, @circle2)
         | 
| 165 195 | 
             
                  expect(result[:colliding]).to be true
         | 
| 166 196 | 
             
                  expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(10 - Math.sqrt(50))
         | 
| 167 197 | 
             
                  expect(result[:penetration]).to eq(Snow::Vec3[1, 1, 0].normalize * result[:overlap])
         | 
| @@ -192,6 +222,7 @@ describe Gosling::Collision do | |
| 192 222 | 
             
                  expect(Gosling::Collision.test(@circle1, @circle2)).to be false
         | 
| 193 223 |  | 
| 194 224 | 
             
                  result = Gosling::Collision.get_collision_info(@circle1, @circle2)
         | 
| 225 | 
            +
                  expect(result[:actors]).to include(@circle1, @circle2)
         | 
| 195 226 | 
             
                  expect(result[:colliding]).to be false
         | 
| 196 227 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 197 228 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -212,6 +243,7 @@ describe Gosling::Collision do | |
| 212 243 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 213 244 | 
             
                  expect(Gosling::Collision.test(@circle1, @polygon1)).to be true
         | 
| 214 245 | 
             
                  result = Gosling::Collision.get_collision_info(@circle1, @polygon1)
         | 
| 246 | 
            +
                  expect(result[:actors]).to include(@circle1, @polygon1)
         | 
| 215 247 | 
             
                  expect(result[:colliding]).to be true
         | 
| 216 248 | 
             
                  expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
         | 
| 217 249 | 
             
                  expect(result[:penetration]).to eq(Snow::Vec3[1, 1, 0].normalize * result[:overlap])
         | 
| @@ -229,6 +261,7 @@ describe Gosling::Collision do | |
| 229 261 |  | 
| 230 262 | 
             
                  expect(Gosling::Collision.test(@circle1, @polygon1)).to be false
         | 
| 231 263 | 
             
                  result = Gosling::Collision.get_collision_info(@circle1, @polygon1)
         | 
| 264 | 
            +
                  expect(result[:actors]).to include(@circle1, @polygon1)
         | 
| 232 265 | 
             
                  expect(result[:colliding]).to be false
         | 
| 233 266 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 234 267 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -249,6 +282,7 @@ describe Gosling::Collision do | |
| 249 282 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 250 283 | 
             
                  expect(Gosling::Collision.test(@circle1, @rect1)).to be true
         | 
| 251 284 | 
             
                  result = Gosling::Collision.get_collision_info(@circle1, @rect1)
         | 
| 285 | 
            +
                  expect(result[:actors]).to include(@circle1, @rect1)
         | 
| 252 286 | 
             
                  expect(result[:colliding]).to be true
         | 
| 253 287 | 
             
                  expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
         | 
| 254 288 | 
             
                  expect(result[:penetration]).to eq(Snow::Vec3[1, 1, 0].normalize * result[:overlap])
         | 
| @@ -266,6 +300,7 @@ describe Gosling::Collision do | |
| 266 300 |  | 
| 267 301 | 
             
                  expect(Gosling::Collision.test(@circle1, @rect1)).to be false
         | 
| 268 302 | 
             
                  result = Gosling::Collision.get_collision_info(@circle1, @rect1)
         | 
| 303 | 
            +
                  expect(result[:actors]).to include(@circle1, @rect1)
         | 
| 269 304 | 
             
                  expect(result[:colliding]).to be false
         | 
| 270 305 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 271 306 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -286,6 +321,7 @@ describe Gosling::Collision do | |
| 286 321 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 287 322 | 
             
                  expect(Gosling::Collision.test(@circle1, @sprite1)).to be true
         | 
| 288 323 | 
             
                  result = Gosling::Collision.get_collision_info(@circle1, @sprite1)
         | 
| 324 | 
            +
                  expect(result[:actors]).to include(@circle1, @sprite1)
         | 
| 289 325 | 
             
                  expect(result[:colliding]).to be true
         | 
| 290 326 | 
             
                  expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
         | 
| 291 327 | 
             
                  expect(result[:penetration]).to eq(Snow::Vec3[1, 1, 0].normalize * result[:overlap])
         | 
| @@ -303,6 +339,7 @@ describe Gosling::Collision do | |
| 303 339 |  | 
| 304 340 | 
             
                  expect(Gosling::Collision.test(@circle1, @sprite1)).to be false
         | 
| 305 341 | 
             
                  result = Gosling::Collision.get_collision_info(@circle1, @sprite1)
         | 
| 342 | 
            +
                  expect(result[:actors]).to include(@circle1, @sprite1)
         | 
| 306 343 | 
             
                  expect(result[:colliding]).to be false
         | 
| 307 344 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 308 345 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -323,12 +360,13 @@ describe Gosling::Collision do | |
| 323 360 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 324 361 | 
             
                  expect(Gosling::Collision.test(@polygon1, @polygon2)).to be true
         | 
| 325 362 | 
             
                  result = Gosling::Collision.get_collision_info(@polygon1, @polygon2)
         | 
| 363 | 
            +
                  expect(result[:actors]).to include(@polygon1, @polygon2)
         | 
| 326 364 | 
             
                  expect(result[:colliding]).to be true
         | 
| 327 365 | 
             
                  axis = Snow::Vec2[-10, -5].normalize
         | 
| 328 366 | 
             
                  a = Snow::Vec2[0, 0].dot_product(axis)
         | 
| 329 367 | 
             
                  b = Snow::Vec2[0, 5].dot_product(axis)
         | 
| 330 368 | 
             
                  expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(a - b)
         | 
| 331 | 
            -
                  expect(result[:penetration]).to eq(Snow::Vec3[2, 1, 0].normalize * result[:overlap])
         | 
| 369 | 
            +
                  expect(result[:penetration]).to eq(Snow::Vec3[-2, 1, 0].normalize * result[:overlap])
         | 
| 332 370 | 
             
                end
         | 
| 333 371 |  | 
| 334 372 | 
             
                it 'returns a vector that separates the shapes' do
         | 
| @@ -365,6 +403,7 @@ describe Gosling::Collision do | |
| 365 403 |  | 
| 366 404 | 
             
                  expect(Gosling::Collision.test(@polygon1, @polygon2)).to be false
         | 
| 367 405 | 
             
                  result = Gosling::Collision.get_collision_info(@polygon1, @polygon2)
         | 
| 406 | 
            +
                  expect(result[:actors]).to include(@polygon1, @polygon2)
         | 
| 368 407 | 
             
                  expect(result[:colliding]).to be false
         | 
| 369 408 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 370 409 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -385,6 +424,7 @@ describe Gosling::Collision do | |
| 385 424 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 386 425 | 
             
                  expect(Gosling::Collision.test(@polygon1, @rect1)).to be true
         | 
| 387 426 | 
             
                  result = Gosling::Collision.get_collision_info(@polygon1, @rect1)
         | 
| 427 | 
            +
                  expect(result[:actors]).to include(@polygon1, @rect1)
         | 
| 388 428 | 
             
                  expect(result[:colliding]).to be true
         | 
| 389 429 | 
             
                  axis = Snow::Vec2[-10, -5].normalize
         | 
| 390 430 | 
             
                  a = Snow::Vec2[0, 0].dot_product(axis)
         | 
| @@ -404,6 +444,7 @@ describe Gosling::Collision do | |
| 404 444 |  | 
| 405 445 | 
             
                  expect(Gosling::Collision.test(@polygon1, @rect1)).to be false
         | 
| 406 446 | 
             
                  result = Gosling::Collision.get_collision_info(@polygon1, @rect1)
         | 
| 447 | 
            +
                  expect(result[:actors]).to include(@polygon1, @rect1)
         | 
| 407 448 | 
             
                  expect(result[:colliding]).to be false
         | 
| 408 449 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 409 450 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -424,6 +465,7 @@ describe Gosling::Collision do | |
| 424 465 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 425 466 | 
             
                  expect(Gosling::Collision.test(@polygon1, @sprite1)).to be true
         | 
| 426 467 | 
             
                  result = Gosling::Collision.get_collision_info(@polygon1, @sprite1)
         | 
| 468 | 
            +
                  expect(result[:actors]).to include(@polygon1, @sprite1)
         | 
| 427 469 | 
             
                  expect(result[:colliding]).to be true
         | 
| 428 470 | 
             
                  axis = Snow::Vec2[-10, -5].normalize
         | 
| 429 471 | 
             
                  a = Snow::Vec2[0, 0].dot_product(axis)
         | 
| @@ -443,6 +485,7 @@ describe Gosling::Collision do | |
| 443 485 |  | 
| 444 486 | 
             
                  expect(Gosling::Collision.test(@polygon1, @sprite1)).to be false
         | 
| 445 487 | 
             
                  result = Gosling::Collision.get_collision_info(@polygon1, @sprite1)
         | 
| 488 | 
            +
                  expect(result[:actors]).to include(@polygon1, @sprite1)
         | 
| 446 489 | 
             
                  expect(result[:colliding]).to be false
         | 
| 447 490 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 448 491 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -463,6 +506,7 @@ describe Gosling::Collision do | |
| 463 506 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 464 507 | 
             
                  expect(Gosling::Collision.test(@rect1, @rect2)).to be true
         | 
| 465 508 | 
             
                  result = Gosling::Collision.get_collision_info(@rect1, @rect2)
         | 
| 509 | 
            +
                  expect(result[:actors]).to include(@rect1, @rect2)
         | 
| 466 510 | 
             
                  expect(result[:colliding]).to be true
         | 
| 467 511 | 
             
                  expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
         | 
| 468 512 | 
             
                  if result[:penetration].x == 0
         | 
| @@ -483,6 +527,7 @@ describe Gosling::Collision do | |
| 483 527 |  | 
| 484 528 | 
             
                  expect(Gosling::Collision.test(@rect1, @rect2)).to be false
         | 
| 485 529 | 
             
                  result = Gosling::Collision.get_collision_info(@rect1, @rect2)
         | 
| 530 | 
            +
                  expect(result[:actors]).to include(@rect1, @rect2)
         | 
| 486 531 | 
             
                  expect(result[:colliding]).to be false
         | 
| 487 532 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 488 533 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -503,6 +548,7 @@ describe Gosling::Collision do | |
| 503 548 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 504 549 | 
             
                  expect(Gosling::Collision.test(@rect1, @sprite1)).to be true
         | 
| 505 550 | 
             
                  result = Gosling::Collision.get_collision_info(@rect1, @sprite1)
         | 
| 551 | 
            +
                  expect(result[:actors]).to include(@rect1, @sprite1)
         | 
| 506 552 | 
             
                  expect(result[:colliding]).to be true
         | 
| 507 553 | 
             
                  expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(5)
         | 
| 508 554 | 
             
                  if result[:penetration].x == 0
         | 
| @@ -523,6 +569,7 @@ describe Gosling::Collision do | |
| 523 569 |  | 
| 524 570 | 
             
                  expect(Gosling::Collision.test(@rect1, @sprite1)).to be false
         | 
| 525 571 | 
             
                  result = Gosling::Collision.get_collision_info(@rect1, @sprite1)
         | 
| 572 | 
            +
                  expect(result[:actors]).to include(@rect1, @sprite1)
         | 
| 526 573 | 
             
                  expect(result[:colliding]).to be false
         | 
| 527 574 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 528 575 | 
             
                  expect(result[:penetration]).to be nil
         | 
| @@ -543,6 +590,7 @@ describe Gosling::Collision do | |
| 543 590 | 
             
                it 'collides if the shapes are close enough' do
         | 
| 544 591 | 
             
                  expect(Gosling::Collision.test(@sprite1, @sprite2)).to be true
         | 
| 545 592 | 
             
                  result = Gosling::Collision.get_collision_info(@sprite1, @sprite2)
         | 
| 593 | 
            +
                  expect(result[:actors]).to include(@sprite1, @sprite2)
         | 
| 546 594 | 
             
                  expect(result[:colliding]).to be true
         | 
| 547 595 | 
             
                  expect(result[:overlap]).to be_within(FLOAT_TOLERANCE).of(8)
         | 
| 548 596 | 
             
                  if result[:penetration].x == 0
         | 
| @@ -563,13 +611,14 @@ describe Gosling::Collision do | |
| 563 611 |  | 
| 564 612 | 
             
                  expect(Gosling::Collision.test(@sprite1, @sprite2)).to be false
         | 
| 565 613 | 
             
                  result = Gosling::Collision.get_collision_info(@sprite1, @sprite2)
         | 
| 614 | 
            +
                  expect(result[:actors]).to include(@sprite1, @sprite2)
         | 
| 566 615 | 
             
                  expect(result[:colliding]).to be false
         | 
| 567 616 | 
             
                  expect(result[:overlap]).to be nil
         | 
| 568 617 | 
             
                  expect(result[:penetration]).to be nil
         | 
| 569 618 | 
             
                end
         | 
| 570 619 | 
             
              end
         | 
| 571 620 |  | 
| 572 | 
            -
              describe ' | 
| 621 | 
            +
              describe '.is_point_in_shape?' do
         | 
| 573 622 | 
             
                it 'expects a point and an actor' do
         | 
| 574 623 | 
             
                  expect { Gosling::Collision.is_point_in_shape?(Snow::Vec3[0, 0, 0], @actor1) }.not_to raise_error
         | 
| 575 624 |  | 
| @@ -756,13 +805,13 @@ describe Gosling::Collision do | |
| 756 805 | 
             
                end
         | 
| 757 806 | 
             
              end
         | 
| 758 807 |  | 
| 759 | 
            -
              describe ' | 
| 808 | 
            +
              describe '.get_normal' do
         | 
| 760 809 | 
             
                it 'expects a 3d vector' do
         | 
| 761 810 | 
             
                  expect { Gosling::Collision.get_normal(Snow::Vec3[1, 0, 0]) }.not_to raise_error
         | 
| 762 811 | 
             
                  expect { Gosling::Collision.get_normal(Snow::Vec3[1, 0, 1, 0]) }.to raise_error(ArgumentError)
         | 
| 763 812 | 
             
                  expect { Gosling::Collision.get_normal(Snow::Vec3[1, 0]) }.to raise_error(ArgumentError)
         | 
| 764 | 
            -
                  expect { Gosling::Collision.get_normal(:foo) }.to raise_error | 
| 765 | 
            -
                  expect { Gosling::Collision.get_normal(nil) }.to raise_error | 
| 813 | 
            +
                  expect { Gosling::Collision.get_normal(:foo) }.to raise_error
         | 
| 814 | 
            +
                  expect { Gosling::Collision.get_normal(nil) }.to raise_error
         | 
| 766 815 | 
             
                end
         | 
| 767 816 |  | 
| 768 817 | 
             
                it 'returns a 3d vector' do
         | 
| @@ -815,7 +864,7 @@ describe Gosling::Collision do | |
| 815 864 | 
             
                end
         | 
| 816 865 | 
             
              end
         | 
| 817 866 |  | 
| 818 | 
            -
              describe ' | 
| 867 | 
            +
              describe '.get_polygon_separation_axes' do
         | 
| 819 868 | 
             
                it 'expects an array of length 3 vectors' do
         | 
| 820 869 | 
             
                  good_vector_array = [
         | 
| 821 870 | 
             
                    Snow::Vec3[3, 1, 0],
         | 
| @@ -833,10 +882,10 @@ describe Gosling::Collision do | |
| 833 882 | 
             
                  ]
         | 
| 834 883 | 
             
                  p = Gosling::Polygon.new(@window)
         | 
| 835 884 | 
             
                  expect { Gosling::Collision.get_polygon_separation_axes(good_vector_array) }.not_to raise_error
         | 
| 836 | 
            -
                  expect { Gosling::Collision.get_polygon_separation_axes(bad_vector_array) }.to raise_error | 
| 885 | 
            +
                  expect { Gosling::Collision.get_polygon_separation_axes(bad_vector_array) }.to raise_error
         | 
| 837 886 | 
             
                  expect { Gosling::Collision.get_polygon_separation_axes(p.get_vertices) }.not_to raise_error
         | 
| 838 | 
            -
                  expect { Gosling::Collision.get_polygon_separation_axes(p) }.to raise_error | 
| 839 | 
            -
                  expect { Gosling::Collision.get_polygon_separation_axes(:foo) }.to raise_error | 
| 887 | 
            +
                  expect { Gosling::Collision.get_polygon_separation_axes(p) }.to raise_error
         | 
| 888 | 
            +
                  expect { Gosling::Collision.get_polygon_separation_axes(:foo) }.to raise_error
         | 
| 840 889 | 
             
                end
         | 
| 841 890 |  | 
| 842 891 | 
             
                it 'returns an array of 3d vectors' do
         | 
| @@ -847,7 +896,8 @@ describe Gosling::Collision do | |
| 847 896 | 
             
                    Snow::Vec3[1, 4, 0],
         | 
| 848 897 | 
             
                    Snow::Vec3[2, 5, 0]
         | 
| 849 898 | 
             
                  ]
         | 
| 850 | 
            -
                   | 
| 899 | 
            +
                  Gosling::Collision.get_polygon_separation_axes(vertices)
         | 
| 900 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 851 901 | 
             
                  expect(result).to be_instance_of(Array)
         | 
| 852 902 | 
             
                  expect(result.reject { |v| v.is_a?(Snow::Vec3) }).to be_empty
         | 
| 853 903 | 
             
                end
         | 
| @@ -860,7 +910,8 @@ describe Gosling::Collision do | |
| 860 910 | 
             
                    Snow::Vec3[2, 2, 0],
         | 
| 861 911 | 
             
                    Snow::Vec3[2, 2, 0]
         | 
| 862 912 | 
             
                  ]
         | 
| 863 | 
            -
                   | 
| 913 | 
            +
                  Gosling::Collision.get_polygon_separation_axes(vertices)
         | 
| 914 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 864 915 | 
             
                  expect(result.length).to be == 3
         | 
| 865 916 | 
             
                end
         | 
| 866 917 |  | 
| @@ -872,17 +923,19 @@ describe Gosling::Collision do | |
| 872 923 | 
             
                    Snow::Vec3[-1, -1, 0],
         | 
| 873 924 | 
             
                    Snow::Vec3[-1,  2, 0]
         | 
| 874 925 | 
             
                  ]
         | 
| 875 | 
            -
                   | 
| 876 | 
            -
                   | 
| 877 | 
            -
                  expect(result | 
| 878 | 
            -
             | 
| 879 | 
            -
             | 
| 880 | 
            -
             | 
| 881 | 
            -
             | 
| 926 | 
            +
                  Gosling::Collision.get_polygon_separation_axes(vertices)
         | 
| 927 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 928 | 
            +
                  expect(result).to match_array([
         | 
| 929 | 
            +
                                      Snow::Vec3[ 1,  3, 0].normalize,
         | 
| 930 | 
            +
                                      Snow::Vec3[ 2, -1, 0].normalize,
         | 
| 931 | 
            +
                                      Snow::Vec3[ 1, -1, 0].normalize,
         | 
| 932 | 
            +
                                      Snow::Vec3[-1, -1, 0].normalize,
         | 
| 933 | 
            +
                                      Snow::Vec3[-3,  0, 0].normalize
         | 
| 934 | 
            +
                                    ])
         | 
| 882 935 | 
             
                end
         | 
| 883 936 | 
             
              end
         | 
| 884 937 |  | 
| 885 | 
            -
              describe ' | 
| 938 | 
            +
              describe '.get_circle_separation_axis' do
         | 
| 886 939 | 
             
                before do
         | 
| 887 940 | 
             
                  clean_shape(@circle1)
         | 
| 888 941 | 
             
                  clean_shape(@circle2)
         | 
| @@ -893,8 +946,8 @@ describe Gosling::Collision do | |
| 893 946 | 
             
                  expect { Gosling::Collision.get_circle_separation_axis(@circle1, @polygon1) }.not_to raise_error
         | 
| 894 947 | 
             
                  expect { Gosling::Collision.get_circle_separation_axis(@rect1, @circle2) }.not_to raise_error
         | 
| 895 948 |  | 
| 896 | 
            -
                  expect { Gosling::Collision.get_circle_separation_axis( | 
| 897 | 
            -
                  expect { Gosling::Collision.get_circle_separation_axis( | 
| 949 | 
            +
                  expect { Gosling::Collision.get_circle_separation_axis(@circle1, @circle2, Snow::Vec3.new) }.to raise_error(ArgumentError)
         | 
| 950 | 
            +
                  expect { Gosling::Collision.get_circle_separation_axis(:foo, @circle2) }.to raise_error
         | 
| 898 951 | 
             
                  expect { Gosling::Collision.get_circle_separation_axis(@circle1) }.to raise_error(ArgumentError)
         | 
| 899 952 | 
             
                  expect { Gosling::Collision.get_circle_separation_axis() }.to raise_error(ArgumentError)
         | 
| 900 953 | 
             
                  expect { Gosling::Collision.get_circle_separation_axis(:foo) }.to raise_error(ArgumentError)
         | 
| @@ -907,8 +960,10 @@ describe Gosling::Collision do | |
| 907 960 | 
             
                  @circle2.x = 10
         | 
| 908 961 | 
             
                  @circle2.y = -5
         | 
| 909 962 |  | 
| 910 | 
            -
                   | 
| 911 | 
            -
                   | 
| 963 | 
            +
                  Gosling::Collision.get_circle_separation_axis(@circle1, @circle2)
         | 
| 964 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 965 | 
            +
                  expect(result.length).to eq(1)
         | 
| 966 | 
            +
                  expect(result.first).to be_instance_of(Snow::Vec3)
         | 
| 912 967 | 
             
                end
         | 
| 913 968 |  | 
| 914 969 | 
             
                it "returns nil if distance beween shape centers is 0" do
         | 
| @@ -929,12 +984,14 @@ describe Gosling::Collision do | |
| 929 984 | 
             
                  @circle2.x = 10
         | 
| 930 985 | 
             
                  @circle2.y = -5
         | 
| 931 986 |  | 
| 932 | 
            -
                   | 
| 933 | 
            -
                   | 
| 987 | 
            +
                  Gosling::Collision.get_circle_separation_axis(@circle1, @circle2)
         | 
| 988 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 989 | 
            +
                  expect(result.length).to eq(1)
         | 
| 990 | 
            +
                  expect(result.first).to be == Snow::Vec3[1, 1, 0].normalize
         | 
| 934 991 | 
             
                end
         | 
| 935 992 | 
             
              end
         | 
| 936 993 |  | 
| 937 | 
            -
              describe ' | 
| 994 | 
            +
              describe '.get_separation_axes' do
         | 
| 938 995 | 
             
                it 'expects two shapes' do
         | 
| 939 996 | 
             
                  expect { Gosling::Collision.get_separation_axes(@circle1, @circle2) }.not_to raise_error
         | 
| 940 997 | 
             
                  expect { Gosling::Collision.get_separation_axes(@circle1, @polygon2) }.not_to raise_error
         | 
| @@ -943,7 +1000,7 @@ describe Gosling::Collision do | |
| 943 1000 | 
             
                  expect { Gosling::Collision.get_separation_axes(@sprite1, @polygon2) }.not_to raise_error
         | 
| 944 1001 |  | 
| 945 1002 | 
             
                  expect { Gosling::Collision.get_separation_axes(@actor1, @circle2) }.to raise_error(ArgumentError)
         | 
| 946 | 
            -
                  expect { Gosling::Collision.get_separation_axes(@circle1, @circle2, @polygon2) }.to raise_error | 
| 1003 | 
            +
                  expect { Gosling::Collision.get_separation_axes(@circle1, @circle2, @polygon2) }.to raise_error
         | 
| 947 1004 | 
             
                  expect { Gosling::Collision.get_separation_axes(@circle1, 1) }.to raise_error(ArgumentError)
         | 
| 948 1005 | 
             
                  expect { Gosling::Collision.get_separation_axes(@polygon1, :foo) }.to raise_error(ArgumentError)
         | 
| 949 1006 | 
             
                  expect { Gosling::Collision.get_separation_axes(:foo) }.to raise_error(ArgumentError)
         | 
| @@ -951,13 +1008,15 @@ describe Gosling::Collision do | |
| 951 1008 | 
             
                end
         | 
| 952 1009 |  | 
| 953 1010 | 
             
                it 'returns an array of 3d vectors' do
         | 
| 954 | 
            -
                   | 
| 1011 | 
            +
                  Gosling::Collision.get_separation_axes(@polygon1, @polygon2)
         | 
| 1012 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 955 1013 | 
             
                  expect(result).to be_instance_of(Array)
         | 
| 956 1014 | 
             
                  expect(result.reject { |v| v.is_a?(Snow::Vec3) }).to be_empty
         | 
| 957 1015 | 
             
                end
         | 
| 958 1016 |  | 
| 959 1017 | 
             
                it 'returns only unit vectors' do
         | 
| 960 | 
            -
                   | 
| 1018 | 
            +
                  Gosling::Collision.get_separation_axes(@polygon1, @circle1)
         | 
| 1019 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 961 1020 | 
             
                  expect(result).to be_instance_of(Array)
         | 
| 962 1021 | 
             
                  result.each do |v|
         | 
| 963 1022 | 
             
                    expect(v).to be_instance_of(Snow::Vec3)
         | 
| @@ -965,22 +1024,19 @@ describe Gosling::Collision do | |
| 965 1024 | 
             
                  end
         | 
| 966 1025 | 
             
                end
         | 
| 967 1026 |  | 
| 968 | 
            -
                it 'returns only right-facing (positive x direction) vectors' do
         | 
| 969 | 
            -
                  result = Gosling::Collision.get_separation_axes(@rect2, @polygon1)
         | 
| 970 | 
            -
                  expect(result).to be_instance_of(Array)
         | 
| 971 | 
            -
                  expect(result.reject { |v| v.is_a?(Snow::Vec3) && v[0] >= 0 }).to be_empty
         | 
| 972 | 
            -
                end
         | 
| 973 | 
            -
             | 
| 974 1027 | 
             
                it 'returns only unique vectors' do
         | 
| 975 | 
            -
                   | 
| 1028 | 
            +
                  Gosling::Collision.get_separation_axes(@rect2, @polygon2)
         | 
| 1029 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 976 1030 | 
             
                  expect(result).to be_instance_of(Array)
         | 
| 977 1031 | 
             
                  expect(result.uniq.length).to be == result.length
         | 
| 978 1032 | 
             
                end
         | 
| 979 1033 |  | 
| 980 1034 | 
             
                it 'is commutative' do
         | 
| 981 | 
            -
                   | 
| 982 | 
            -
                   | 
| 983 | 
            -
                   | 
| 1035 | 
            +
                  Gosling::Collision.get_separation_axes(@rect2, @polygon2)
         | 
| 1036 | 
            +
                  result1 = Gosling::Collision.separation_axes.dup
         | 
| 1037 | 
            +
                  Gosling::Collision.get_separation_axes(@polygon2, @rect2)
         | 
| 1038 | 
            +
                  result2 = Gosling::Collision.separation_axes.dup
         | 
| 1039 | 
            +
                  expect(result1.map { |v| v.to_s }).to match_array(result2.map { |v| v.to_s })
         | 
| 984 1040 | 
             
                end
         | 
| 985 1041 |  | 
| 986 1042 | 
             
                it 'respects centering' do
         | 
| @@ -990,12 +1046,13 @@ describe Gosling::Collision do | |
| 990 1046 |  | 
| 991 1047 | 
             
                  clean_shape(@circle1)
         | 
| 992 1048 |  | 
| 993 | 
            -
                   | 
| 994 | 
            -
                   | 
| 995 | 
            -
             | 
| 996 | 
            -
             | 
| 997 | 
            -
             | 
| 998 | 
            -
             | 
| 1049 | 
            +
                  Gosling::Collision.get_separation_axes(@polygon1, @circle1)
         | 
| 1050 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 1051 | 
            +
                  expect(result).to match_array([
         | 
| 1052 | 
            +
                                      Snow::Vec3[10, 5, 0].normalize,
         | 
| 1053 | 
            +
                                      Snow::Vec3[0, -10, 0].normalize,
         | 
| 1054 | 
            +
                                      Snow::Vec3[-10, 5, 0].normalize
         | 
| 1055 | 
            +
                                    ])
         | 
| 999 1056 | 
             
                end
         | 
| 1000 1057 |  | 
| 1001 1058 | 
             
                it 'respects scaling' do
         | 
| @@ -1005,26 +1062,28 @@ describe Gosling::Collision do | |
| 1005 1062 |  | 
| 1006 1063 | 
             
                  clean_shape(@circle1)
         | 
| 1007 1064 |  | 
| 1008 | 
            -
                   | 
| 1009 | 
            -
                   | 
| 1010 | 
            -
             | 
| 1011 | 
            -
             | 
| 1012 | 
            -
             | 
| 1013 | 
            -
             | 
| 1065 | 
            +
                  Gosling::Collision.get_separation_axes(@polygon1, @circle1)
         | 
| 1066 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 1067 | 
            +
                  expect(result).to match_array([
         | 
| 1068 | 
            +
                                      Snow::Vec3[20, 15, 0].normalize,
         | 
| 1069 | 
            +
                                      Snow::Vec3[0, -30, 0].normalize,
         | 
| 1070 | 
            +
                                      Snow::Vec3[-20, 15, 0].normalize
         | 
| 1071 | 
            +
                                    ])
         | 
| 1014 1072 | 
             
                end
         | 
| 1015 1073 |  | 
| 1016 1074 | 
             
                it 'respects rotation' do
         | 
| 1017 1075 | 
             
                  clean_shape(@polygon1)
         | 
| 1018 1076 | 
             
                  @polygon1.rotation = Math::PI / 2
         | 
| 1019 | 
            -
                   | 
| 1077 | 
            +
                  Gosling::Collision.get_separation_axes(@polygon1, @circle1)
         | 
| 1078 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 1020 1079 |  | 
| 1021 1080 | 
             
                  clean_shape(@circle1)
         | 
| 1022 1081 |  | 
| 1023 | 
            -
                  expect(result).to  | 
| 1024 | 
            -
             | 
| 1025 | 
            -
             | 
| 1026 | 
            -
             | 
| 1027 | 
            -
             | 
| 1082 | 
            +
                  expect(result).to match_array([
         | 
| 1083 | 
            +
                                      Snow::Vec3[5, -10, 0].normalize,
         | 
| 1084 | 
            +
                                      Snow::Vec3[-10, 0, 0].normalize,
         | 
| 1085 | 
            +
                                      Snow::Vec3[5, 10, 0].normalize
         | 
| 1086 | 
            +
                                    ])
         | 
| 1028 1087 | 
             
                end
         | 
| 1029 1088 |  | 
| 1030 1089 | 
             
                it 'respects translation' do
         | 
| @@ -1034,13 +1093,14 @@ describe Gosling::Collision do | |
| 1034 1093 |  | 
| 1035 1094 | 
             
                  clean_shape(@circle1)
         | 
| 1036 1095 |  | 
| 1037 | 
            -
                   | 
| 1038 | 
            -
                   | 
| 1039 | 
            -
             | 
| 1040 | 
            -
             | 
| 1041 | 
            -
             | 
| 1042 | 
            -
             | 
| 1043 | 
            -
             | 
| 1096 | 
            +
                  Gosling::Collision.get_separation_axes(@polygon1, @circle1)
         | 
| 1097 | 
            +
                  result = Gosling::Collision.separation_axes
         | 
| 1098 | 
            +
                  expect(result).to match_array([
         | 
| 1099 | 
            +
                                      Snow::Vec3[10, 5, 0].normalize,
         | 
| 1100 | 
            +
                                      Snow::Vec3[0, -10, 0].normalize,
         | 
| 1101 | 
            +
                                      Snow::Vec3[-10, 5, 0].normalize,
         | 
| 1102 | 
            +
                                      Snow::Vec3[50, -10, 0].normalize
         | 
| 1103 | 
            +
                                    ])
         | 
| 1044 1104 | 
             
                end
         | 
| 1045 1105 |  | 
| 1046 1106 | 
             
                context 'with two polygons' do
         | 
| @@ -1062,7 +1122,8 @@ describe Gosling::Collision do | |
| 1062 1122 | 
             
                      [@rect2, @sprite2],
         | 
| 1063 1123 | 
             
                      [@sprite1, @sprite2]
         | 
| 1064 1124 | 
             
                    ].each do |shapes|
         | 
| 1065 | 
            -
                       | 
| 1125 | 
            +
                      Gosling::Collision.get_separation_axes(*shapes)
         | 
| 1126 | 
            +
                      result = Gosling::Collision.separation_axes
         | 
| 1066 1127 | 
             
                      vertex_count = 0
         | 
| 1067 1128 | 
             
                      shapes.each { |s| vertex_count += s.get_vertices.length }
         | 
| 1068 1129 | 
             
                      expect(result.length).to be_between(2, vertex_count).inclusive
         | 
| @@ -1077,7 +1138,8 @@ describe Gosling::Collision do | |
| 1077 1138 | 
             
                      @circle1.y = 0
         | 
| 1078 1139 | 
             
                      @circle2.x = 0
         | 
| 1079 1140 | 
             
                      @circle2.y = 0
         | 
| 1080 | 
            -
                       | 
| 1141 | 
            +
                      Gosling::Collision.get_separation_axes(@circle1, @circle2)
         | 
| 1142 | 
            +
                      result = Gosling::Collision.separation_axes
         | 
| 1081 1143 | 
             
                      expect(result).to be_instance_of(Array)
         | 
| 1082 1144 | 
             
                      expect(result).to be_empty
         | 
| 1083 1145 | 
             
                    end
         | 
| @@ -1088,7 +1150,8 @@ describe Gosling::Collision do | |
| 1088 1150 | 
             
                    @circle1.y = 0
         | 
| 1089 1151 | 
             
                    @circle2.x = 17
         | 
| 1090 1152 | 
             
                    @circle2.y = -5
         | 
| 1091 | 
            -
                     | 
| 1153 | 
            +
                    Gosling::Collision.get_separation_axes(@circle1, @circle2)
         | 
| 1154 | 
            +
                    result = Gosling::Collision.separation_axes
         | 
| 1092 1155 | 
             
                    expect(result).to be_instance_of(Array)
         | 
| 1093 1156 | 
             
                    expect(result.length).to be == 1
         | 
| 1094 1157 | 
             
                  end
         | 
| @@ -1104,7 +1167,8 @@ describe Gosling::Collision do | |
| 1104 1167 | 
             
                      [@circle1, @sprite1],
         | 
| 1105 1168 | 
             
                      [@circle2, @sprite2]
         | 
| 1106 1169 | 
             
                    ].each do |shapes|
         | 
| 1107 | 
            -
                       | 
| 1170 | 
            +
                      Gosling::Collision.get_separation_axes(*shapes)
         | 
| 1171 | 
            +
                      result = Gosling::Collision.separation_axes
         | 
| 1108 1172 | 
             
                      vertex_count = shapes[1].get_vertices.length
         | 
| 1109 1173 | 
             
                      expect(result.length).to be_between(2, vertex_count + 1).inclusive
         | 
| 1110 1174 | 
             
                    end
         | 
| @@ -1112,8 +1176,8 @@ describe Gosling::Collision do | |
| 1112 1176 | 
             
                end
         | 
| 1113 1177 | 
             
              end
         | 
| 1114 1178 |  | 
| 1115 | 
            -
              describe ' | 
| 1116 | 
            -
                it 'expects a shape and a 3d unit vector' do
         | 
| 1179 | 
            +
              describe '.project_onto_axis' do
         | 
| 1180 | 
            +
                it 'expects a shape and a 3d or better unit vector' do
         | 
| 1117 1181 | 
             
                  axis = Snow::Vec3[1, 1, 0]
         | 
| 1118 1182 |  | 
| 1119 1183 | 
             
                  expect { Gosling::Collision.project_onto_axis(@sprite1, axis) }.not_to raise_error
         | 
| @@ -1121,11 +1185,11 @@ describe Gosling::Collision do | |
| 1121 1185 | 
             
                  expect { Gosling::Collision.project_onto_axis(@circle1, axis) }.not_to raise_error
         | 
| 1122 1186 | 
             
                  expect { Gosling::Collision.project_onto_axis(@polygon1, axis) }.not_to raise_error
         | 
| 1123 1187 |  | 
| 1124 | 
            -
                  expect { Gosling::Collision.project_onto_axis(:foo, axis) }.to raise_error | 
| 1125 | 
            -
                  expect { Gosling::Collision.project_onto_axis(@sprite1, Snow::Vec4[1, 1, 0, 2]) }. | 
| 1188 | 
            +
                  expect { Gosling::Collision.project_onto_axis(:foo, axis) }.to raise_error
         | 
| 1189 | 
            +
                  expect { Gosling::Collision.project_onto_axis(@sprite1, Snow::Vec4[1, 1, 0, 2]) }.not_to raise_error
         | 
| 1126 1190 | 
             
                  expect { Gosling::Collision.project_onto_axis(@rect1, Snow::Vec2[1, 1]) }.to raise_error(ArgumentError)
         | 
| 1127 1191 | 
             
                  expect { Gosling::Collision.project_onto_axis(@polygon1, :foo) }.to raise_error(ArgumentError)
         | 
| 1128 | 
            -
                  expect { Gosling::Collision.project_onto_axis(@circle1, @circle1, axis) }.to raise_error | 
| 1192 | 
            +
                  expect { Gosling::Collision.project_onto_axis(@circle1, @circle1, axis) }.to raise_error
         | 
| 1129 1193 | 
             
                  expect { Gosling::Collision.project_onto_axis() }.to raise_error(ArgumentError)
         | 
| 1130 1194 | 
             
                end
         | 
| 1131 1195 |  | 
| @@ -1137,6 +1201,22 @@ describe Gosling::Collision do | |
| 1137 1201 | 
             
                  expect(result.reject { |x| x.is_a?(Numeric) }).to be_empty
         | 
| 1138 1202 | 
             
                end
         | 
| 1139 1203 |  | 
| 1204 | 
            +
                it 'works with four dimensional axes' do
         | 
| 1205 | 
            +
                  clean_shape(@circle1)
         | 
| 1206 | 
            +
                  @circle1.x = 1
         | 
| 1207 | 
            +
                  @circle1.y = 1
         | 
| 1208 | 
            +
                  @circle1.radius = 5
         | 
| 1209 | 
            +
             | 
| 1210 | 
            +
                  axis = Snow::Vec4[-1, 1, 0, 0].normalize
         | 
| 1211 | 
            +
                  result = Gosling::Collision.project_onto_axis(@circle1, axis)
         | 
| 1212 | 
            +
                  expect(result).to be == [-5, 5]
         | 
| 1213 | 
            +
             | 
| 1214 | 
            +
                  axis.z = 2
         | 
| 1215 | 
            +
                  axis.w = -3
         | 
| 1216 | 
            +
                  result = Gosling::Collision.project_onto_axis(@circle1, axis)
         | 
| 1217 | 
            +
                  expect(result).to be == [-5, 5]
         | 
| 1218 | 
            +
                end
         | 
| 1219 | 
            +
             | 
| 1140 1220 | 
             
                context 'with a circle' do
         | 
| 1141 1221 | 
             
                  before do
         | 
| 1142 1222 | 
             
                    clean_shape(@circle1)
         | 
| @@ -1339,7 +1419,7 @@ describe Gosling::Collision do | |
| 1339 1419 | 
             
                end
         | 
| 1340 1420 | 
             
              end
         | 
| 1341 1421 |  | 
| 1342 | 
            -
              describe ' | 
| 1422 | 
            +
              describe '.projections_overlap?' do
         | 
| 1343 1423 | 
             
                it 'accepts two length 2 arrays with numbers' do
         | 
| 1344 1424 | 
             
                  expect { Gosling::Collision.projections_overlap?([0, 0], [0, 0]) }.not_to raise_error
         | 
| 1345 1425 | 
             
                  expect { Gosling::Collision.projections_overlap?([1, 2], [3, -4]) }.not_to raise_error
         | 
| @@ -1349,7 +1429,7 @@ describe Gosling::Collision do | |
| 1349 1429 | 
             
                  expect { Gosling::Collision.projections_overlap?([1, 2], [3, -4], [5, 6]) }.to raise_error(ArgumentError)
         | 
| 1350 1430 | 
             
                  expect { Gosling::Collision.projections_overlap?([1, 2]) }.to raise_error(ArgumentError)
         | 
| 1351 1431 | 
             
                  expect { Gosling::Collision.projections_overlap?([1, 2], :foo) }.to raise_error(ArgumentError)
         | 
| 1352 | 
            -
                  expect { Gosling::Collision.projections_overlap?(nil, [1, 2]) }.to raise_error | 
| 1432 | 
            +
                  expect { Gosling::Collision.projections_overlap?(nil, [1, 2]) }.to raise_error
         | 
| 1353 1433 | 
             
                end
         | 
| 1354 1434 |  | 
| 1355 1435 | 
             
                context 'when a and b do not overlap' do
         | 
| @@ -1397,7 +1477,7 @@ describe Gosling::Collision do | |
| 1397 1477 | 
             
                end
         | 
| 1398 1478 | 
             
              end
         | 
| 1399 1479 |  | 
| 1400 | 
            -
              describe ' | 
| 1480 | 
            +
              describe '.get_overlap' do
         | 
| 1401 1481 | 
             
                it 'accepts two length 2 arrays with numbers' do
         | 
| 1402 1482 | 
             
                  expect { Gosling::Collision.get_overlap([0, 0], [0, 0]) }.not_to raise_error
         | 
| 1403 1483 | 
             
                  expect { Gosling::Collision.get_overlap([1, 2], [3, -4]) }.not_to raise_error
         | 
| @@ -1407,7 +1487,7 @@ describe Gosling::Collision do | |
| 1407 1487 | 
             
                  expect { Gosling::Collision.get_overlap([1, 2], [3, -4], [5, 6]) }.to raise_error(ArgumentError)
         | 
| 1408 1488 | 
             
                  expect { Gosling::Collision.get_overlap([1, 2]) }.to raise_error(ArgumentError)
         | 
| 1409 1489 | 
             
                  expect { Gosling::Collision.get_overlap([1, 2], :foo) }.to raise_error(ArgumentError)
         | 
| 1410 | 
            -
                  expect { Gosling::Collision.get_overlap(nil, [1, 2]) }.to raise_error | 
| 1490 | 
            +
                  expect { Gosling::Collision.get_overlap(nil, [1, 2]) }.to raise_error
         | 
| 1411 1491 | 
             
                end
         | 
| 1412 1492 |  | 
| 1413 1493 | 
             
                context 'when a and b do not overlap' do
         | 
| @@ -1454,4 +1534,222 @@ describe Gosling::Collision do | |
| 1454 1534 | 
             
                  end
         | 
| 1455 1535 | 
             
                end
         | 
| 1456 1536 | 
             
              end
         | 
| 1537 | 
            +
             | 
| 1538 | 
            +
              describe '.buffer_shapes' do
         | 
| 1539 | 
            +
                it 'accepts an array of actors' do
         | 
| 1540 | 
            +
                  expect { Gosling::Collision.buffer_shapes([]) }.not_to raise_error
         | 
| 1541 | 
            +
                  expect { Gosling::Collision.buffer_shapes([@actor1, @circle1, @polygon1, @rect1, @sprite1]) }.not_to raise_error
         | 
| 1542 | 
            +
             | 
| 1543 | 
            +
                  expect { Gosling::Collision.buffer_shapes(@actor1) }.to raise_error(ArgumentError)
         | 
| 1544 | 
            +
                  expect { Gosling::Collision.buffer_shapes(:foo) }.to raise_error(ArgumentError)
         | 
| 1545 | 
            +
                  expect { Gosling::Collision.buffer_shapes(nil) }.to raise_error(ArgumentError)
         | 
| 1546 | 
            +
                end
         | 
| 1547 | 
            +
             | 
| 1548 | 
            +
                it 'resets the buffer iterators' do
         | 
| 1549 | 
            +
                  expect(Gosling::Collision).to receive(:reset_buffer_iterators)
         | 
| 1550 | 
            +
                  Gosling::Collision.buffer_shapes([@actor1])
         | 
| 1551 | 
            +
                end
         | 
| 1552 | 
            +
             | 
| 1553 | 
            +
                context 'when actors are initially buffered' do
         | 
| 1554 | 
            +
                  before(:all) do
         | 
| 1555 | 
            +
                    Gosling::Collision.clear_buffer
         | 
| 1556 | 
            +
                    [@actor1, @circle1, @polygon1, @rect1, @sprite1].each { |a|
         | 
| 1557 | 
            +
                      @scale_actor.add_child(a)
         | 
| 1558 | 
            +
                      a.x = 0
         | 
| 1559 | 
            +
                      a.y = 0
         | 
| 1560 | 
            +
                    }
         | 
| 1561 | 
            +
                    Gosling::Collision.buffer_shapes([@actor1, @circle1, @polygon1, @rect1, @sprite1])
         | 
| 1562 | 
            +
                  end
         | 
| 1563 | 
            +
             | 
| 1564 | 
            +
                  it 'adds those actors to the collision test set' do
         | 
| 1565 | 
            +
                    [@circle1, @polygon1, @rect1, @sprite1].each do |actor|
         | 
| 1566 | 
            +
                      expect(Gosling::Collision.collision_buffer).to include(actor)
         | 
| 1567 | 
            +
                    end
         | 
| 1568 | 
            +
                  end
         | 
| 1569 | 
            +
             | 
| 1570 | 
            +
                  it 'caches computationally expensive information about each actor' do
         | 
| 1571 | 
            +
                    expect(Gosling::Collision.global_vertices_cache.length).to eq(3)
         | 
| 1572 | 
            +
                    expect(Gosling::Collision.global_position_cache.length).to eq(4)
         | 
| 1573 | 
            +
                    expect(Gosling::Collision.global_transform_cache.length).to eq(4)
         | 
| 1574 | 
            +
             | 
| 1575 | 
            +
                    [@actor1, @circle1, @polygon1, @rect1, @sprite1].each do |actor|
         | 
| 1576 | 
            +
                      expect(actor).not_to receive(:get_global_vertices)
         | 
| 1577 | 
            +
                      expect(actor).not_to receive(:get_global_position)
         | 
| 1578 | 
            +
                      expect(actor).not_to receive(:get_global_transform)
         | 
| 1579 | 
            +
                    end
         | 
| 1580 | 
            +
             | 
| 1581 | 
            +
                    collisions = []
         | 
| 1582 | 
            +
                    while true
         | 
| 1583 | 
            +
                      info = Gosling::Collision.next_collision_info
         | 
| 1584 | 
            +
                      break unless info
         | 
| 1585 | 
            +
                      collisions << info
         | 
| 1586 | 
            +
                    end
         | 
| 1587 | 
            +
                    expect(collisions.length).to eq(6)
         | 
| 1588 | 
            +
                  end
         | 
| 1589 | 
            +
             | 
| 1590 | 
            +
                  it 'only caches info for children of the Actor class' do
         | 
| 1591 | 
            +
                    [@actor1].each do |actor|
         | 
| 1592 | 
            +
                      expect(Gosling::Collision.collision_buffer).not_to include(actor)
         | 
| 1593 | 
            +
                    end
         | 
| 1594 | 
            +
                  end
         | 
| 1595 | 
            +
             | 
| 1596 | 
            +
                  context 'and then re-buffered' do
         | 
| 1597 | 
            +
                    it 'updates info for already buffered actors' do
         | 
| 1598 | 
            +
                      [@circle1, @circle2].each do |actor|
         | 
| 1599 | 
            +
                        expect(actor).to receive(:get_global_position).once.and_call_original
         | 
| 1600 | 
            +
                        expect(actor).to receive(:get_global_transform).twice.and_call_original
         | 
| 1601 | 
            +
                      end
         | 
| 1602 | 
            +
                      [@rect1].each do |actor|
         | 
| 1603 | 
            +
                        expect(actor).to receive(:get_global_vertices).once.and_call_original
         | 
| 1604 | 
            +
                        expect(actor).to receive(:get_global_transform).exactly(3).times.and_call_original
         | 
| 1605 | 
            +
                      end
         | 
| 1606 | 
            +
             | 
| 1607 | 
            +
                      Gosling::Collision.buffer_shapes([@circle1, @circle2, @rect1])
         | 
| 1608 | 
            +
             | 
| 1609 | 
            +
                      [@circle1, @circle2, @rect1].each do |actor|
         | 
| 1610 | 
            +
                        expect(Gosling::Collision.collision_buffer.select { |a| a == actor }.length).to eq(1)
         | 
| 1611 | 
            +
                      end
         | 
| 1612 | 
            +
                      expect(Gosling::Collision.global_vertices_cache.length).to eq(3)
         | 
| 1613 | 
            +
                      expect(Gosling::Collision.global_position_cache.length).to eq(5)
         | 
| 1614 | 
            +
                      expect(Gosling::Collision.global_transform_cache.length).to eq(5)
         | 
| 1615 | 
            +
                    end
         | 
| 1616 | 
            +
                  end
         | 
| 1617 | 
            +
             | 
| 1618 | 
            +
                  after(:all) do
         | 
| 1619 | 
            +
                    Gosling::Collision.clear_buffer
         | 
| 1620 | 
            +
                    [@actor1, @circle1, @polygon1, @rect1, @sprite1].each { |a| @scale_actor.remove_child(a) }
         | 
| 1621 | 
            +
                  end
         | 
| 1622 | 
            +
                end
         | 
| 1623 | 
            +
              end
         | 
| 1624 | 
            +
             | 
| 1625 | 
            +
              describe '.next_collision_info' do
         | 
| 1626 | 
            +
                before(:all) do
         | 
| 1627 | 
            +
                  Gosling::Collision.clear_buffer
         | 
| 1628 | 
            +
                  [@circle1, @polygon1, @rect1, @sprite1].each { |a| a.x = 0; a.y = 0 }
         | 
| 1629 | 
            +
                  Gosling::Collision.buffer_shapes([@circle1, @polygon1, @rect1, @sprite1])
         | 
| 1630 | 
            +
                end
         | 
| 1631 | 
            +
             | 
| 1632 | 
            +
                it 'returns collision information for the next pair of colliding actors, then nil when done' do
         | 
| 1633 | 
            +
                  info = Gosling::Collision.next_collision_info
         | 
| 1634 | 
            +
                  expect(info[:actors]).to include(@polygon1, @circle1)
         | 
| 1635 | 
            +
                  expect(info[:colliding]).to be true
         | 
| 1636 | 
            +
             | 
| 1637 | 
            +
                  info = Gosling::Collision.next_collision_info
         | 
| 1638 | 
            +
                  expect(info[:actors]).to include(@rect1, @circle1)
         | 
| 1639 | 
            +
                  expect(info[:colliding]).to be true
         | 
| 1640 | 
            +
             | 
| 1641 | 
            +
                  info = Gosling::Collision.next_collision_info
         | 
| 1642 | 
            +
                  expect(info[:actors]).to include(@rect1, @polygon1)
         | 
| 1643 | 
            +
                  expect(info[:colliding]).to be true
         | 
| 1644 | 
            +
             | 
| 1645 | 
            +
                  info = Gosling::Collision.next_collision_info
         | 
| 1646 | 
            +
                  expect(info[:actors]).to include(@sprite1, @circle1)
         | 
| 1647 | 
            +
                  expect(info[:colliding]).to be true
         | 
| 1648 | 
            +
             | 
| 1649 | 
            +
                  info = Gosling::Collision.next_collision_info
         | 
| 1650 | 
            +
                  expect(info[:actors]).to include(@sprite1, @polygon1)
         | 
| 1651 | 
            +
                  expect(info[:colliding]).to be true
         | 
| 1652 | 
            +
             | 
| 1653 | 
            +
                  info = Gosling::Collision.next_collision_info
         | 
| 1654 | 
            +
                  expect(info[:actors]).to include(@sprite1, @rect1)
         | 
| 1655 | 
            +
                  expect(info[:colliding]).to be true
         | 
| 1656 | 
            +
             | 
| 1657 | 
            +
                  expect(Gosling::Collision.next_collision_info).to be_nil
         | 
| 1658 | 
            +
                end
         | 
| 1659 | 
            +
             | 
| 1660 | 
            +
                after(:all) do
         | 
| 1661 | 
            +
                  Gosling::Collision.clear_buffer
         | 
| 1662 | 
            +
                end
         | 
| 1663 | 
            +
              end
         | 
| 1664 | 
            +
             | 
| 1665 | 
            +
              describe '.peek_at_next_collision' do
         | 
| 1666 | 
            +
                before(:all) do
         | 
| 1667 | 
            +
                  Gosling::Collision.clear_buffer
         | 
| 1668 | 
            +
                  [@circle1, @polygon1, @rect1, @sprite1].each { |a| a.x = 0; a.y = 0 }
         | 
| 1669 | 
            +
                  Gosling::Collision.buffer_shapes([@circle1, @polygon1, @rect1, @sprite1])
         | 
| 1670 | 
            +
                end
         | 
| 1671 | 
            +
             | 
| 1672 | 
            +
                it 'returns references to the next two buffered actors to be collision tested, if any' do
         | 
| 1673 | 
            +
                  expect(Gosling::Collision.peek_at_next_collision).to eq([@polygon1, @circle1])
         | 
| 1674 | 
            +
                  2.times { Gosling::Collision.skip_next_collision }
         | 
| 1675 | 
            +
                  expect(Gosling::Collision.peek_at_next_collision).to eq([@rect1, @polygon1])
         | 
| 1676 | 
            +
                  2.times { Gosling::Collision.skip_next_collision }
         | 
| 1677 | 
            +
                  info = Gosling::Collision.next_collision_info
         | 
| 1678 | 
            +
                  expect(info[:actors]).to include(@sprite1, @polygon1)
         | 
| 1679 | 
            +
                  2.times { Gosling::Collision.skip_next_collision }
         | 
| 1680 | 
            +
                  expect(Gosling::Collision.peek_at_next_collision).to be_nil
         | 
| 1681 | 
            +
                end
         | 
| 1682 | 
            +
             | 
| 1683 | 
            +
                after(:all) do
         | 
| 1684 | 
            +
                  Gosling::Collision.clear_buffer
         | 
| 1685 | 
            +
                end
         | 
| 1686 | 
            +
              end
         | 
| 1687 | 
            +
             | 
| 1688 | 
            +
              describe '.skip_next_collision' do
         | 
| 1689 | 
            +
                before(:all) do
         | 
| 1690 | 
            +
                  Gosling::Collision.clear_buffer
         | 
| 1691 | 
            +
                  [@circle1, @polygon1, @rect1, @sprite1].each { |a| a.x = 0; a.y = 0 }
         | 
| 1692 | 
            +
                  Gosling::Collision.buffer_shapes([@circle1, @polygon1, @rect1])
         | 
| 1693 | 
            +
                end
         | 
| 1694 | 
            +
             | 
| 1695 | 
            +
                it 'moves the collision iterators forward without performing any collision testing' do
         | 
| 1696 | 
            +
                  expect(Gosling::Collision.peek_at_next_collision).to eq([@polygon1, @circle1])
         | 
| 1697 | 
            +
                  Gosling::Collision.skip_next_collision
         | 
| 1698 | 
            +
                  expect(Gosling::Collision.peek_at_next_collision).to eq([@rect1, @circle1])
         | 
| 1699 | 
            +
                  Gosling::Collision.skip_next_collision
         | 
| 1700 | 
            +
                  info = Gosling::Collision.next_collision_info
         | 
| 1701 | 
            +
                  expect(info[:actors]).to include(@rect1, @polygon1)
         | 
| 1702 | 
            +
                  Gosling::Collision.skip_next_collision
         | 
| 1703 | 
            +
                  expect(Gosling::Collision.peek_at_next_collision).to be_nil
         | 
| 1704 | 
            +
                end
         | 
| 1705 | 
            +
             | 
| 1706 | 
            +
                after(:all) do
         | 
| 1707 | 
            +
                  Gosling::Collision.clear_buffer
         | 
| 1708 | 
            +
                end
         | 
| 1709 | 
            +
              end
         | 
| 1710 | 
            +
             | 
| 1711 | 
            +
              describe '.unbuffer_shapes' do
         | 
| 1712 | 
            +
                it 'accepts an array of actors' do
         | 
| 1713 | 
            +
                  expect { Gosling::Collision.unbuffer_shapes([]) }.not_to raise_error
         | 
| 1714 | 
            +
                  expect { Gosling::Collision.unbuffer_shapes([@actor1, @circle1, @polygon1, @rect1, @sprite1]) }.not_to raise_error
         | 
| 1715 | 
            +
             | 
| 1716 | 
            +
                  expect { Gosling::Collision.unbuffer_shapes(@actor1) }.to raise_error(ArgumentError)
         | 
| 1717 | 
            +
                  expect { Gosling::Collision.unbuffer_shapes(:foo) }.to raise_error(ArgumentError)
         | 
| 1718 | 
            +
                  expect { Gosling::Collision.unbuffer_shapes(nil) }.to raise_error(ArgumentError)
         | 
| 1719 | 
            +
                end
         | 
| 1720 | 
            +
             | 
| 1721 | 
            +
                it 'resets the buffer iterators' do
         | 
| 1722 | 
            +
                  expect(Gosling::Collision).to receive(:reset_buffer_iterators)
         | 
| 1723 | 
            +
                  Gosling::Collision.unbuffer_shapes([@actor1])
         | 
| 1724 | 
            +
                end
         | 
| 1725 | 
            +
             | 
| 1726 | 
            +
                it 'removes those actors from the collision test list and related info from the caches' do
         | 
| 1727 | 
            +
                  Gosling::Collision.buffer_shapes([@actor1, @circle1, @polygon1, @rect1, @sprite1])
         | 
| 1728 | 
            +
                  Gosling::Collision.unbuffer_shapes([@actor1, @polygon1, @sprite1])
         | 
| 1729 | 
            +
                  [@actor1, @polygon1, @sprite1].each do |actor|
         | 
| 1730 | 
            +
                    expect(Gosling::Collision.collision_buffer).not_to include(actor)
         | 
| 1731 | 
            +
                  end
         | 
| 1732 | 
            +
                  expect(Gosling::Collision.global_vertices_cache.length).to eq(1)
         | 
| 1733 | 
            +
                  expect(Gosling::Collision.global_position_cache.length).to eq(2)
         | 
| 1734 | 
            +
                  expect(Gosling::Collision.global_transform_cache.length).to eq(2)
         | 
| 1735 | 
            +
                end
         | 
| 1736 | 
            +
              end
         | 
| 1737 | 
            +
             | 
| 1738 | 
            +
              describe '.clear_buffer' do
         | 
| 1739 | 
            +
                it 'removes all actors from the collision test list and related info from the caches' do
         | 
| 1740 | 
            +
                  Gosling::Collision.buffer_shapes([@actor1, @circle1, @polygon1, @rect1, @sprite1])
         | 
| 1741 | 
            +
                  Gosling::Collision.clear_buffer
         | 
| 1742 | 
            +
                  [@actor1, @circle1, @polygon1, @rect1, @sprite1].each do |actor|
         | 
| 1743 | 
            +
                    expect(Gosling::Collision.collision_buffer).not_to include(actor)
         | 
| 1744 | 
            +
                  end
         | 
| 1745 | 
            +
                  expect(Gosling::Collision.global_vertices_cache.length).to eq(0)
         | 
| 1746 | 
            +
                  expect(Gosling::Collision.global_position_cache.length).to eq(0)
         | 
| 1747 | 
            +
                  expect(Gosling::Collision.global_transform_cache.length).to eq(0)
         | 
| 1748 | 
            +
                end
         | 
| 1749 | 
            +
             | 
| 1750 | 
            +
                it 'resets the buffer iterators' do
         | 
| 1751 | 
            +
                  expect(Gosling::Collision).to receive(:reset_buffer_iterators)
         | 
| 1752 | 
            +
                  Gosling::Collision.clear_buffer
         | 
| 1753 | 
            +
                end
         | 
| 1754 | 
            +
              end
         | 
| 1457 1755 | 
             
            end
         |