World: Extracted the collision reaction code into its own class. Made the collision...
[scd.git] / test / net / habraun / sd / ImpulseSolverTest.scala
blob08ecb44a3a68cdacb0941c1b46d20e091bd25c0c
1 /*
2 Copyright (c) 2009 Hanno Braun <hanno@habraun.net>
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
19 package net.habraun.sd
23 import collision._
24 import math._
26 import org.junit._
27 import org.junit.Assert._
31 class ImpulseSolverTest {
33 val t = 2.0
35 var solve: ConstraintSolver = null
39 @Before
40 def setup {
41 solve = new ImpulseSolver
46 @Test
47 def verifyCollisionEffects {
48 val b1 = new Body
49 b1.position = Vec2D(-20, -21)
50 b1.mass = 4
51 b1.velocity = Vec2D(-10, -10)
52 val b2 = new Body
53 b2.position = Vec2D(10, 9)
54 b2.mass = 8
55 b2.velocity = Vec2D(5, 5)
56 val collision = Collision(1.0, Contact(b1, Vec2D(0, 0), Vec2D(0, -1), b2),
57 Contact(b2, Vec2D(0, 0), Vec2D(0, 1), b1))
59 solve(t, collision)
61 assertEquals(Vec2D(0, 80), b1.appliedImpulse)
62 assertEquals(Vec2D(0, -80), b2.appliedImpulse)
67 @Test
68 def verifyCollisionEffectsWithBody1Static {
69 val b1 = new Body
70 b1.mass = Double.PositiveInfinity
71 val b2 = new Body
72 b2.mass = 5
73 b2.position = Vec2D(2, 2)
74 b2.velocity = Vec2D(1, 1)
75 val collision = Collision(1.0, Contact(b1, Vec2D(0, 0), Vec2D(0, -1), b2),
76 Contact(b2, Vec2D(0, 0), Vec2D(0, 1), b1))
78 solve(t, collision)
80 assertEquals(Vec2D(0, 0), b1.appliedImpulse)
81 assertEquals(Vec2D(0, -10), b2.appliedImpulse)
86 @Test
87 def verifyCollisionEffectsWithBody2Static {
88 val b1 = new Body
89 b1.mass= 5
90 b1.position = Vec2D(2, 2)
91 b1.velocity = Vec2D(1, 1)
92 val b2 = new Body
93 b2.mass = Double.PositiveInfinity
94 val collision = Collision(1.0, Contact(b1, Vec2D(0, 0), Vec2D(0, 1), b2),
95 Contact(b2, Vec2D(0, 0), Vec2D(0, -1), b1))
97 solve(t, collision)
99 assertEquals(Vec2D(0, -10), b1.appliedImpulse)
100 assertEquals(Vec2D(0, 0), b2.appliedImpulse)
105 @Test
106 def addBodiesThatWouldIntersectAfterMovementVerifyTheyDont {
107 val b1 = new Body
108 b1.shape = Circle(2)
109 b1.position = Vec2D(2, 0)
110 b1.velocity = Vec2D(1, 0)
111 val b2 = new Body
112 b2.shape = Circle(2)
113 b2.position = Vec2D(5, 0)
114 b2.velocity = Vec2D(0, 0)
115 val collision = Collision(0.5, Contact(b1, Vec2D(3, 0), Vec2D(1, 0), b2),
116 Contact(b2, Vec2D(3, 0), Vec2D(-1, 0), b1))
118 solve(t, collision)
120 val expectedPosition = Vec2D(1, 0)
122 assertEquals(expectedPosition.x, b1.position.x, 0.01)
123 assertEquals(expectedPosition.y, b1.position.y, 0.01)
128 @Test
129 def testForIntersectionAtHighPositionValues {
130 // This is a real-world example that led to a bug. That's where all the odd numbers come from.
131 val b1 = new Body
132 b1.shape = Circle(5)
133 b1.position = Vec2D(-806.75411, 387.8899501)
134 b1.velocity = Vec2D(-445.3620529718986, -50.442888201040574)
135 val b2 = new Body
136 b2.shape = Circle(30)
137 b2.position = Vec2D(50.0, 469.8163204364546)
138 b2.velocity = Vec2D(0.0, 0.0)
139 val collision = Collision(0.4766389925763854,
140 Contact(b1, Vec2D(3, 0), Vec2D(-0.8732041733361332, -0.4873545646327327), b2),
141 Contact(b2, Vec2D(3, 0), Vec2D(0.8732041733361332, 0.4873545646327327), b1))
143 solve(t, collision)
145 assertTrue((b2.position - b1.position).squaredLength >= 35.0 * 35.0)