physics.lua 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. -- love.physics
  2. --------------------------------------------------------------------------------
  3. --------------------------------------------------------------------------------
  4. ----------------------------------OBJECTS---------------------------------------
  5. --------------------------------------------------------------------------------
  6. --------------------------------------------------------------------------------
  7. -- Body (love.physics.newBody)
  8. love.test.physics.Body = function(test)
  9. -- create body
  10. local world = love.physics.newWorld(1, 1, true)
  11. local body1 = love.physics.newBody(world, 0, 0, 'static')
  12. local body2 = love.physics.newBody(world, 30, 30, 'dynamic')
  13. love.physics.newRectangleShape(body1, 5, 5, 10, 10)
  14. love.physics.newRectangleShape(body2, 5, 5, 10, 10)
  15. test:assertObject(body1)
  16. -- check shapes
  17. test:assertEquals(1, #body1:getShapes(), 'check shapes total 1')
  18. test:assertEquals(1, #body2:getShapes(), 'check shapes total 2')
  19. test:assertNotEquals(nil, body1:getShape(), 'check shape 1')
  20. test:assertNotEquals(nil, body2:getShape(), 'check shape 2')
  21. -- check body active
  22. test:assertTrue(body1:isActive(), 'check active by def')
  23. -- check body bullet
  24. test:assertFalse(body1:isBullet(), 'check not bullet by def')
  25. body1:setBullet(true)
  26. test:assertTrue(body1:isBullet(), 'check set bullet')
  27. -- check fixed rotation
  28. test:assertFalse(body1:isFixedRotation(), 'check fix rot def')
  29. body1:setFixedRotation(true)
  30. test:assertTrue(body1:isFixedRotation(), 'check set fix rot')
  31. -- check sleeping/waking
  32. test:assertTrue(body1:isSleepingAllowed(), 'check sleep def')
  33. body1:setSleepingAllowed(false)
  34. test:assertFalse(body1:isSleepingAllowed(), 'check set sleep')
  35. body1:setSleepingAllowed(true)
  36. world:update(1)
  37. test:assertFalse(body1:isAwake(), 'check fell asleep')
  38. body1:setSleepingAllowed(false)
  39. body1:setType('dynamic')
  40. test:assertTrue(body1:isAwake(), 'check waking up')
  41. -- check touching
  42. test:assertFalse(body1:isTouching(body2))
  43. body2:setPosition(5, 5)
  44. world:update(1)
  45. test:assertTrue(body1:isTouching(body2))
  46. -- check children lists
  47. test:assertEquals(1, #body1:getContacts(), 'check contact list')
  48. test:assertEquals(0, #body1:getJoints(), 'check joints list')
  49. love.physics.newDistanceJoint(body1, body2, 5, 5, 10, 10, true)
  50. test:assertEquals(1, #body1:getJoints(), 'check joints list')
  51. -- check local points
  52. local x, y = body1:getLocalCenter()
  53. test:assertRange(x, 5, 6, 'check local center x')
  54. test:assertRange(y, 5, 6, 'check local center y')
  55. local lx, ly = body1:getLocalPoint(10, 10)
  56. test:assertRange(lx, 10, 11, 'check local point x')
  57. test:assertRange(ly, 9, 10, 'check local point y')
  58. local lx1, ly1, lx2, ly2 = body1:getLocalPoints(0, 5, 5, 10)
  59. test:assertRange(lx1, 0, 1, 'check local points x 1')
  60. test:assertRange(ly1, 3, 4, 'check local points y 1')
  61. test:assertRange(lx2, 5, 6, 'check local points x 2')
  62. test:assertRange(ly2, 9, 10, 'check local points y 2')
  63. -- check world points
  64. local wx, wy = body1:getWorldPoint(10.4, 9)
  65. test:assertRange(wx, 10, 11, 'check world point x')
  66. test:assertRange(wy, 10, 11, 'check world point y')
  67. local wx1, wy1, wx2, wy2 = body1:getWorldPoints(0.4, 4, 5.4, 9)
  68. test:assertRange(wx1, 0, 1, 'check world points x 1')
  69. test:assertRange(wy1, 5, 6, 'check world points y 1')
  70. test:assertRange(wx2, 5, 6, 'check world points x 2')
  71. test:assertRange(wy2, 10, 11, 'check world points y 2')
  72. -- check angular damping + velocity
  73. test:assertEquals(0, body1:getAngularDamping(), 'check angular damping')
  74. test:assertEquals(0, body1:getAngularVelocity(), 'check angular velocity')
  75. -- check world props
  76. test:assertObject(body1:getWorld())
  77. test:assertEquals(2, body1:getWorld():getBodyCount(), 'check world count')
  78. local cx, cy = body1:getWorldCenter()
  79. test:assertRange(cx, 4, 5, 'check world center x')
  80. test:assertRange(cy, 6, 7, 'check world center y')
  81. local vx, vy = body1:getWorldVector(5, 10)
  82. test:assertEquals(5, vx, 'check vector x')
  83. test:assertEquals(10, vy, 'check vector y')
  84. -- check inertia
  85. test:assertRange(body1:getInertia(), 5, 6, 'check inertia')
  86. -- check angle
  87. test:assertEquals(0, body1:getAngle(), 'check def angle')
  88. body1:setAngle(90 * (math.pi/180))
  89. test:assertEquals(math.floor(math.pi/2*100), math.floor(body1:getAngle()*100), 'check set angle')
  90. -- check gravity scale
  91. test:assertEquals(1, body1:getGravityScale(), 'check def grav')
  92. body1:setGravityScale(2)
  93. test:assertEquals(2, body1:getGravityScale(), 'check change grav')
  94. -- check damping
  95. test:assertEquals(0, body1:getLinearDamping(), 'check def lin damping')
  96. body1:setLinearDamping(0.1)
  97. test:assertRange(body1:getLinearDamping(), 0, 0.2, 'check change lin damping')
  98. -- check velocity
  99. local x2, y2 = body1:getLinearVelocity()
  100. test:assertEquals(1, x2, 'check def lin velocity x')
  101. test:assertEquals(1, y2, 'check def lin velocity y')
  102. body1:setLinearVelocity(4, 5)
  103. local x3, y3 = body1:getLinearVelocity()
  104. test:assertEquals(4, x3, 'check change lin velocity x')
  105. test:assertEquals(5, y3, 'check change lin velocity y')
  106. -- check mass
  107. test:assertRange(body1:getMass(), 0.1, 0.2, 'check def mass')
  108. body1:setMass(10)
  109. test:assertEquals(10, body1:getMass(), 'check change mass')
  110. body1:setMassData(3, 5, 10, 1)
  111. local x4, y4, mass4, inertia4 = body1:getMassData()
  112. test:assertEquals(3, x4, 'check mass data change x')
  113. test:assertEquals(5, y4, 'check mass data change y')
  114. test:assertEquals(10, mass4, 'check mass data change mass')
  115. test:assertRange(inertia4, 340, 341, 'check mass data change inertia')
  116. body1:resetMassData()
  117. local x5, y5, mass5, inertia5 = body1:getMassData()
  118. test:assertRange(x5, 5, 6, 'check mass data reset x')
  119. test:assertRange(y5, 5, 6, 'check mass data reset y')
  120. test:assertRange(mass5, 0.1, 0.2, 'check mass data reset mass')
  121. test:assertRange(inertia5, 5, 6, 'check mass data reset inertia')
  122. test:assertFalse(body1:hasCustomMassData())
  123. -- check position
  124. local x6, y6 = body1:getPosition()
  125. test:assertRange(x6, -1, 0, 'check position x')
  126. test:assertRange(y6, 0, 1, 'check position y')
  127. body1:setPosition(10, 4)
  128. local x7, y7 = body1:getPosition()
  129. test:assertEquals(x7, 10, 'check set position x')
  130. test:assertEquals(y7, 4, 'check set position y')
  131. -- check type
  132. test:assertEquals('dynamic', body1:getType(), 'check type match')
  133. body1:setType('kinematic')
  134. body1:setType('static')
  135. test:assertEquals('static', body1:getType(), 'check type change')
  136. -- check userdata
  137. test:assertEquals(nil, body1:getUserData(), 'check user data')
  138. body1:setUserData({ love = 'cool' })
  139. test:assertEquals('cool', body1:getUserData().love, 'check set user data')
  140. -- check x/y direct
  141. test:assertEquals(10, math.floor(body1:getX()), 'check get x')
  142. test:assertEquals(4, math.floor(body1:getY()), 'check get y')
  143. body1:setX(0)
  144. body1:setY(0)
  145. test:assertEquals(0, body1:getX(), 'check get x')
  146. test:assertEquals(0, body1:getY(), 'check get y')
  147. -- apply angular impulse
  148. local vel = body2:getAngularVelocity()
  149. test:assertRange(vel, 0, 0, 'check velocity before')
  150. body2:applyAngularImpulse(10)
  151. local vel1 = body2:getAngularVelocity()
  152. test:assertRange(vel1, 5, 6, 'check velocity after 1')
  153. -- apply standard force
  154. local ang1 = body2:getAngle()
  155. test:assertRange(ang1, 0.1, 0.2, 'check initial angle 1')
  156. body2:applyForce(2, 3)
  157. world:update(2)
  158. local vel2 = body2:getAngularVelocity()
  159. local ang2 = body2:getAngle()
  160. test:assertRange(ang2, -0.1, 0, 'check angle after 2')
  161. test:assertRange(vel2, 1, 2, 'check velocity after 2')
  162. -- apply linear impulse
  163. body2:applyLinearImpulse(-4, -59)
  164. world:update(1)
  165. local ang3 = body2:getAngle()
  166. local vel3 = body2:getAngularVelocity()
  167. test:assertRange(ang3, -2, -1, 'check angle after 3')
  168. test:assertRange(vel3, 0, 1, 'check velocity after 3')
  169. -- apply torque
  170. body2:applyTorque(4)
  171. world:update(2)
  172. local ang4 = body2:getAngle()
  173. local vel4 = body2:getAngularVelocity()
  174. test:assertRange(ang4, -1, 0, 'check angle after 4')
  175. test:assertRange(vel4, 0, 1, 'check velocity after 4')
  176. -- check destroy
  177. test:assertFalse(body1:isDestroyed(), 'check not destroyed')
  178. body1:destroy()
  179. test:assertTrue(body1:isDestroyed(), 'check destroyed')
  180. end
  181. -- Contact (love.physics.World:getContacts)
  182. love.test.physics.Contact = function(test)
  183. -- create a setup so we can access some contact objects
  184. local world = love.physics.newWorld(1, 1, true)
  185. local body1 = love.physics.newBody(world, 0, 0, 'dynamic')
  186. local body2 = love.physics.newBody(world, 10, 10, 'dynamic')
  187. local rectangle1 = love.physics.newRectangleShape(body1, 0, 0, 10, 10)
  188. local rectangle2 = love.physics.newRectangleShape(body2, 0, 0, 10, 10)
  189. rectangle1:setUserData('rec1')
  190. rectangle2:setUserData('rec2')
  191. -- used to check for collisions + no. of collisions
  192. local collided = false
  193. local pass = 1
  194. -- set callback for contact start
  195. world:setCallbacks(
  196. function(shape_a, shape_b, contact)
  197. collided = true
  198. -- check contact object
  199. test:assertObject(contact)
  200. -- check child indices
  201. local indexA, indexB = contact:getChildren()
  202. test:assertEquals(1, indexA, 'check child indice a')
  203. test:assertEquals(1, indexB, 'check child indice b')
  204. -- check shapes match using userdata
  205. local shapeA, shapeB = contact:getShapes()
  206. test:assertEquals(shape_a:getUserData(), shapeA:getUserData(), 'check shape a matches')
  207. test:assertEquals(shape_b:getUserData(), shapeB:getUserData(), 'check shape b matches')
  208. -- check normal pos
  209. local nx, ny = contact:getNormal()
  210. test:assertEquals(1, nx, 'check normal x')
  211. test:assertEquals(0, ny, 'check normal y')
  212. -- check actual pos
  213. local px1, py1, px2, py2 = contact:getPositions()
  214. test:assertRange(px1, 5, 6, 'check collide x 1')
  215. test:assertRange(py1, 5, 6, 'check collide y 1')
  216. test:assertRange(px2, 5, 6, 'check collide x 2')
  217. test:assertRange(py2, 5, 6, 'check collide y 2')
  218. -- check touching
  219. test:assertTrue(contact:isTouching(), 'check touching')
  220. -- check enabled (we pass through twice to test on/off)
  221. test:assertEquals(pass == 1, contact:isEnabled(), 'check enabled for pass ' .. tostring(pass))
  222. -- check friction
  223. test:assertRange(contact:getFriction(), 0.2, 0.3, 'check def friction')
  224. contact:setFriction(0.1)
  225. test:assertRange(contact:getFriction(), 0.1, 0.2, 'check set friction')
  226. contact:resetFriction()
  227. test:assertRange(contact:getFriction(), 0.2, 0.3, 'check reset friction')
  228. -- check restitution
  229. test:assertEquals(0, contact:getRestitution(), 'check def restitution')
  230. contact:setRestitution(1)
  231. test:assertEquals(1, contact:getRestitution(), 'check set restitution')
  232. contact:resetRestitution()
  233. test:assertEquals(0, contact:getRestitution(), 'check reset restitution')
  234. pass = pass + 1
  235. end, function() end, function(shape_a, shape_b, contact)
  236. if pass > 2 then
  237. contact:setEnabled(false)
  238. end
  239. end, function() end
  240. )
  241. -- check bodies collided
  242. world:update(1)
  243. test:assertTrue(collided, 'check bodies collided')
  244. -- update again for enabled check
  245. world:update(1)
  246. test:assertEquals(2, pass, 'check ran twice')
  247. end
  248. -- Joint (love.physics.newDistanceJoint)
  249. love.test.physics.Joint = function(test)
  250. -- make joint
  251. local world = love.physics.newWorld(1, 1, true)
  252. local body1 = love.physics.newBody(world, 10, 10, 'dynamic')
  253. local body2 = love.physics.newBody(world, 20, 20, 'dynamic')
  254. local joint = love.physics.newDistanceJoint(body1, body2, 10, 10, 20, 20, true)
  255. test:assertObject(joint)
  256. -- check type
  257. test:assertEquals('distance', joint:getType(), 'check joint type')
  258. -- check not destroyed
  259. test:assertFalse(joint:isDestroyed(), 'check not destroyed')
  260. -- check reaction props
  261. world:update(1)
  262. local rx1, ry1 = joint:getReactionForce(1)
  263. test:assertEquals(0, rx1, 'check reaction force x')
  264. test:assertEquals(0, ry1, 'check reaction force y')
  265. local rx2, ry2 = joint:getReactionTorque(1)
  266. test:assertEquals(0, rx2, 'check reaction torque x')
  267. test:assertEquals(nil, ry2, 'check reaction torque y')
  268. -- check body pointer
  269. local b1, b2 = joint:getBodies()
  270. test:assertEquals(body1:getX(), b1:getX(), 'check body 1')
  271. test:assertEquals(body2:getX(), b2:getX(), 'check body 2')
  272. -- check joint anchors
  273. local x1, y1, x2, y2 = joint:getAnchors()
  274. test:assertRange(x1, 10, 11, 'check anchor x1')
  275. test:assertRange(y1, 10, 11, 'check anchor y1')
  276. test:assertRange(x2, 20, 21, 'check anchor x2')
  277. test:assertRange(y2, 20, 21, 'check anchor y2')
  278. test:assertTrue(joint:getCollideConnected(), 'check not colliding')
  279. -- test userdata
  280. test:assertEquals(nil, joint:getUserData(), 'check no data by def')
  281. joint:setUserData('hello')
  282. test:assertEquals('hello', joint:getUserData(), 'check set userdata')
  283. -- destroy
  284. joint:destroy()
  285. test:assertTrue(joint:isDestroyed(), 'check destroyed')
  286. end
  287. -- Shape (love.physics.newCircleShape)
  288. -- @NOTE in 12.0 fixtures have been merged into shapes
  289. love.test.physics.Shape = function(test)
  290. -- create shape
  291. local world = love.physics.newWorld(0, 0, false)
  292. local body1 = love.physics.newBody(world, 0, 0, 'dynamic')
  293. local shape1 = love.physics.newRectangleShape(body1, 5, 5, 10, 10)
  294. test:assertObject(shape1)
  295. -- check child count
  296. test:assertEquals(1, shape1:getChildCount(), 'check child count')
  297. -- check radius
  298. test:assertRange(shape1:getRadius(), 0, 0.4, 'check radius')
  299. -- check type match
  300. test:assertEquals('polygon', shape1:getType(), 'check rectangle type')
  301. -- check body pointer
  302. test:assertEquals(0, shape1:getBody():getX(), 'check body link')
  303. -- check category
  304. test:assertEquals(1, shape1:getCategory(), 'check def category')
  305. shape1:setCategory(3, 5, 6)
  306. local categories = {shape1:getCategory()}
  307. test:assertEquals(14, categories[1] + categories[2] + categories[3], 'check set category')
  308. -- check sensor prop
  309. test:assertFalse(shape1:isSensor(), 'check sensor def')
  310. shape1:setSensor(true)
  311. test:assertTrue(shape1:isSensor(), 'check set sensor')
  312. shape1:setSensor(false)
  313. -- check not destroyed
  314. test:assertFalse(shape1:isDestroyed(), 'check not destroyed')
  315. -- check user data
  316. test:assertEquals(nil, shape1:getUserData(), 'check no user data')
  317. shape1:setUserData({ test = 14 })
  318. test:assertEquals(14, shape1:getUserData().test, 'check user data set')
  319. -- check bounding box
  320. -- polygons have an additional skin radius to help with collisions
  321. -- so this wont be 0, 0, 10, 10 as you'd think but has an additional 0.3 padding
  322. local topLeftX, topLeftY, bottomRightX, bottomRightY = shape1:computeAABB(0, 0, 0, 1)
  323. local tlx, tly, brx, bry = shape1:getBoundingBox(1)
  324. test:assertEquals(topLeftX, tlx, 'check bbox methods match tlx')
  325. test:assertEquals(topLeftY, tly, 'check bbox methods match tly')
  326. test:assertEquals(bottomRightX, brx, 'check bbox methods match brx')
  327. test:assertEquals(bottomRightY, bry, 'check bbox methods match bry')
  328. test:assertEquals(topLeftX, topLeftY, 'check bbox tl 1')
  329. test:assertRange(topLeftY, -0.3, -0.2, 'check bbox tl 2')
  330. test:assertEquals(bottomRightX, bottomRightY, 'check bbox br 1')
  331. test:assertRange(bottomRightX, 10.3, 10.4, 'check bbox br 2')
  332. -- check density
  333. test:assertEquals(1, shape1:getDensity(), 'check def density')
  334. shape1:setDensity(5)
  335. test:assertEquals(5, shape1:getDensity(), 'check set density')
  336. -- check mass
  337. local x1, y1, mass1, inertia1 = shape1:getMassData()
  338. test:assertRange(x1, 5, 5.1, 'check shape mass pos x')
  339. test:assertRange(y1, 5, 5.1, 'check shape mass pos y')
  340. test:assertRange(mass1, 0.5, 0.6, 'check mass at 1 density')
  341. test:assertRange(inertia1, 0, 0.1, 'check intertia at 1 density')
  342. local x2, y2, mass2, inertia2 = shape1:computeMass(1000)
  343. test:assertRange(mass2, 111, 112, 'check mass at 1000 density')
  344. test:assertRange(inertia2, 7407, 7408, 'check intertia at 1000 density')
  345. -- check friction
  346. test:assertRange(shape1:getFriction(), 0.2, 0.3, 'check def friction')
  347. shape1:setFriction(1)
  348. test:assertEquals(1, shape1:getFriction(), 'check set friction')
  349. -- check restitution
  350. test:assertEquals(0, shape1:getRestitution(), 'check def restitution')
  351. shape1:setRestitution(0.5)
  352. test:assertRange(shape1:getRestitution(), 0.5, 0.6, 'check set restitution')
  353. -- check points
  354. local bodyp = love.physics.newBody(world, 0, 0, 'dynamic')
  355. local shape2 = love.physics.newRectangleShape(bodyp, 5, 5, 10, 10)
  356. test:assertTrue(shape2:testPoint(5, 5), 'check point 5,5')
  357. test:assertTrue(shape2:testPoint(10, 10, 0, 15, 15), 'check point 15,15 after translate 10,10')
  358. test:assertFalse(shape2:testPoint(5, 5, 90, 10, 10), 'check point 10,10 after translate 5,5,90')
  359. test:assertFalse(shape2:testPoint(10, 10, 90, 5, 5), 'check point 5,5 after translate 10,10,90')
  360. test:assertFalse(shape2:testPoint(15, 15), 'check point 15,15')
  361. -- check ray cast
  362. local xn1, yn1, fraction1 = shape2:rayCast(-20, -20, 20, 20, 100, 0, 0, 0, 1)
  363. test:assertNotEquals(nil, xn1, 'check ray 1 x')
  364. test:assertNotEquals(nil, xn1, 'check ray 1 y')
  365. local xn2, yn2, fraction2 = shape2:rayCast(10, 10, -150, -150, 100, 0, 0, 0, 1)
  366. test:assertEquals(nil, xn2, 'check ray 2 x')
  367. test:assertEquals(nil, yn2, 'check ray 2 y')
  368. -- check filtering
  369. test:assertEquals(nil, shape2:getMask(), 'check no mask')
  370. shape2:setMask(1, 2, 3)
  371. test:assertEquals(3, #{shape2:getMask()}, 'check set mask')
  372. test:assertEquals(0, shape2:getGroupIndex(), 'check no index')
  373. shape2:setGroupIndex(-1)
  374. test:assertEquals(-1, shape2:getGroupIndex(), 'check set index')
  375. local cat, mask, group = shape2:getFilterData()
  376. test:assertEquals(1, cat, 'check filter cat')
  377. test:assertEquals(65528, mask, 'check filter mask')
  378. test:assertEquals(-1, group, 'check filter group')
  379. -- check destroyed
  380. shape1:destroy()
  381. test:assertTrue(shape1:isDestroyed(), 'check destroyed')
  382. shape2:destroy()
  383. -- run some collision checks using filters, setup new shapes
  384. local body2 = love.physics.newBody(world, 5, 5, 'dynamic')
  385. local shape3 = love.physics.newRectangleShape(body1, 0, 0, 10, 10)
  386. local shape4 = love.physics.newRectangleShape(body2, 0, 0, 10, 10)
  387. local collisions = 0
  388. world:setCallbacks(
  389. function() collisions = collisions + 1 end,
  390. function() end,
  391. function() end,
  392. function() end
  393. )
  394. -- same positive group do collide
  395. shape3:setGroupIndex(1)
  396. shape4:setGroupIndex(1)
  397. world:update(1)
  398. test:assertEquals(1, collisions, 'check positive group collide')
  399. -- check negative group dont collide
  400. shape3:setGroupIndex(-1)
  401. shape4:setGroupIndex(-1)
  402. body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1)
  403. test:assertEquals(1, collisions, 'check negative group collide')
  404. -- check masks do collide
  405. shape3:setGroupIndex(0)
  406. shape4:setGroupIndex(0)
  407. shape3:setCategory(2)
  408. shape4:setMask(3)
  409. body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1)
  410. test:assertEquals(2, collisions, 'check mask collide')
  411. -- check masks not colliding
  412. shape3:setCategory(2)
  413. shape4:setMask(2, 4, 6)
  414. body2:setPosition(20, 20); world:update(1); body2:setPosition(0, 0); world:update(1)
  415. test:assertEquals(2, collisions, 'check mask not collide')
  416. end
  417. -- World (love.physics.newWorld)
  418. love.test.physics.World = function(test)
  419. -- create new world
  420. local world = love.physics.newWorld(0, 0, false)
  421. local body1 = love.physics.newBody(world, 0, 0, 'dynamic')
  422. local rectangle1 = love.physics.newRectangleShape(body1, 0, 0, 10, 10)
  423. test:assertObject(world)
  424. -- check bodies in world
  425. test:assertEquals(1, #world:getBodies(), 'check 1 body')
  426. test:assertEquals(0, world:getBodies()[1]:getX(), 'check body prop x')
  427. test:assertEquals(0, world:getBodies()[1]:getY(), 'check body prop y')
  428. world:translateOrigin(-10, -10) -- check affects bodies
  429. test:assertRange(world:getBodies()[1]:getX(), 9, 11, 'check body prop change x')
  430. test:assertRange(world:getBodies()[1]:getY(), 9, 11, 'check body prop change y')
  431. test:assertEquals(1, world:getBodyCount(), 'check 1 body count')
  432. -- check shapes in world
  433. test:assertEquals(1, #world:getShapesInArea(0, 0, 10, 10), 'check shapes in area #1')
  434. test:assertEquals(0, #world:getShapesInArea(20, 20, 30, 30), 'check shapes in area #1')
  435. -- check world status
  436. test:assertFalse(world:isLocked(), 'check not updating')
  437. test:assertFalse(world:isSleepingAllowed(), 'check no sleep (till brooklyn)')
  438. world:setSleepingAllowed(true)
  439. test:assertTrue(world:isSleepingAllowed(), 'check can sleep')
  440. -- check world objects
  441. test:assertEquals(0, #world:getJoints(), 'check no joints')
  442. test:assertEquals(0, world:getJointCount(), 'check no joints count')
  443. test:assertEquals(0, world:getGravity(), 'check def gravity')
  444. test:assertEquals(0, #world:getContacts(), 'check no contacts')
  445. test:assertEquals(0, world:getContactCount(), 'check no contact count')
  446. -- check callbacks are called
  447. local beginContact, endContact, preSolve, postSolve = world:getCallbacks()
  448. test:assertEquals(nil, beginContact, 'check no begin contact callback')
  449. test:assertEquals(nil, endContact, 'check no end contact callback')
  450. test:assertEquals(nil, preSolve, 'check no pre solve callback')
  451. test:assertEquals(nil, postSolve, 'check no post solve callback')
  452. local beginContactCheck = false
  453. local endContactCheck = false
  454. local preSolveCheck = false
  455. local postSolveCheck = false
  456. local collisions = 0
  457. world:setCallbacks(
  458. function() beginContactCheck = true; collisions = collisions + 1 end,
  459. function() endContactCheck = true end,
  460. function() preSolveCheck = true end,
  461. function() postSolveCheck = true end
  462. )
  463. -- setup so we can collide stuff to call the callbacks
  464. local body2 = love.physics.newBody(world, 10, 10, 'dynamic')
  465. local rectangle2 = love.physics.newRectangleShape(body2, 0, 0, 10, 10)
  466. test:assertFalse(beginContactCheck, 'check world didnt update after adding body')
  467. world:update(1)
  468. test:assertTrue(beginContactCheck, 'check contact start')
  469. test:assertTrue(preSolveCheck, 'check pre solve')
  470. test:assertTrue(postSolveCheck, 'check post solve')
  471. body2:setPosition(100, 100)
  472. world:update(1)
  473. test:assertTrue(endContactCheck, 'check contact end')
  474. -- check point checking
  475. local shapes = 0
  476. world:queryShapesInArea(0, 0, 10, 10, function(x)
  477. shapes = shapes + 1
  478. end)
  479. test:assertEquals(1, shapes, 'check shapes in area')
  480. -- check raycast
  481. world:rayCast(0, 0, 200, 200, function(x)
  482. shapes = shapes + 1
  483. return 1
  484. end)
  485. test:assertEquals(3, shapes, 'check shapes in raycast')
  486. test:assertEquals(world:rayCastClosest(0, 0, 200, 200), rectangle1, 'check closest raycast')
  487. test:assertNotEquals(nil, world:rayCastAny(0, 0, 200, 200), 'check any raycast')
  488. -- change collision logic
  489. test:assertEquals(nil, world:getContactFilter(), 'check def filter')
  490. world:update(1)
  491. world:setContactFilter(function(s1, s2)
  492. return false -- nothing collides
  493. end)
  494. body2:setPosition(10, 10)
  495. world:update(1)
  496. test:assertEquals(1, collisions, 'check collision logic change')
  497. -- check gravity
  498. world:setGravity(1, 1)
  499. test:assertEquals(1, world:getGravity(), 'check grav change')
  500. -- check destruction
  501. test:assertFalse(world:isDestroyed(), 'check not destroyed')
  502. world:destroy()
  503. test:assertTrue(world:isDestroyed(), 'check world destroyed')
  504. end
  505. --------------------------------------------------------------------------------
  506. --------------------------------------------------------------------------------
  507. ------------------------------------METHODS-------------------------------------
  508. --------------------------------------------------------------------------------
  509. --------------------------------------------------------------------------------
  510. -- love.physics.getDistance
  511. love.test.physics.getDistance = function(test)
  512. -- setup two fixtues to check
  513. local world = love.physics.newWorld(0, 0, false)
  514. local body = love.physics.newBody(world, 10, 10, 'static')
  515. local shape1 = love.physics.newEdgeShape(body, 0, 0, 5, 5)
  516. local shape2 = love.physics.newEdgeShape(body, 10, 10, 15, 15)
  517. -- check distance between them
  518. test:assertRange(love.physics.getDistance(shape1, shape2), 6, 7, 'check distance matches')
  519. end
  520. -- love.physics.getMeter
  521. love.test.physics.getMeter = function(test)
  522. -- check value set is returned
  523. love.physics.setMeter(30)
  524. test:assertEquals(30, love.physics.getMeter(), 'check meter matches')
  525. end
  526. -- love.physics.newBody
  527. -- @NOTE this is just basic nil checking, objs have their own test method
  528. love.test.physics.newBody = function(test)
  529. local world = love.physics.newWorld(1, 1, true)
  530. local body = love.physics.newBody(world, 10, 10, 'static')
  531. test:assertObject(body)
  532. end
  533. -- love.physics.newChainShape
  534. -- @NOTE this is just basic nil checking, objs have their own test method
  535. love.test.physics.newChainShape = function(test)
  536. local world = love.physics.newWorld(1, 1, true)
  537. local body = love.physics.newBody(world, 10, 10, 'static')
  538. test:assertObject(love.physics.newChainShape(body, true, 0, 0, 1, 0, 1, 1, 0, 1))
  539. end
  540. -- love.physics.newCircleShape
  541. -- @NOTE this is just basic nil checking, objs have their own test method
  542. love.test.physics.newCircleShape = function(test)
  543. local world = love.physics.newWorld(1, 1, true)
  544. local body = love.physics.newBody(world, 10, 10, 'static')
  545. test:assertObject(love.physics.newCircleShape(body, 10))
  546. end
  547. -- love.physics.newDistanceJoint
  548. -- @NOTE this is just basic nil checking, objs have their own test method
  549. love.test.physics.newDistanceJoint = function(test)
  550. local world = love.physics.newWorld(1, 1, true)
  551. local body1 = love.physics.newBody(world, 10, 10, 'static')
  552. local body2 = love.physics.newBody(world, 20, 20, 'static')
  553. local obj = love.physics.newDistanceJoint(body1, body2, 10, 10, 20, 20, true)
  554. test:assertObject(obj)
  555. end
  556. -- love.physics.newEdgeShape
  557. -- @NOTE this is just basic nil checking, objs have their own test method
  558. love.test.physics.newEdgeShape = function(test)
  559. local world = love.physics.newWorld(1, 1, true)
  560. local body = love.physics.newBody(world, 10, 10, 'static')
  561. local obj = love.physics.newEdgeShape(body, 0, 0, 10, 10)
  562. test:assertObject(obj)
  563. end
  564. -- love.physics.newFrictionJoint
  565. -- @NOTE this is just basic nil checking, objs have their own test method
  566. love.test.physics.newFrictionJoint = function(test)
  567. local world = love.physics.newWorld(1, 1, true)
  568. local body1 = love.physics.newBody(world, 10, 10, 'static')
  569. local body2 = love.physics.newBody(world, 20, 20, 'static')
  570. local obj = love.physics.newFrictionJoint(body1, body2, 15, 15, true)
  571. test:assertObject(obj)
  572. end
  573. -- love.physics.newGearJoint
  574. -- @NOTE this is just basic nil checking, objs have their own test method
  575. love.test.physics.newGearJoint = function(test)
  576. local world = love.physics.newWorld(1, 1, true)
  577. local body1 = love.physics.newBody(world, 10, 10, 'dynamic')
  578. local body2 = love.physics.newBody(world, 20, 20, 'dynamic')
  579. local body3 = love.physics.newBody(world, 30, 30, 'dynamic')
  580. local body4 = love.physics.newBody(world, 40, 40, 'dynamic')
  581. local joint1 = love.physics.newPrismaticJoint(body1, body2, 10, 10, 20, 20, true)
  582. local joint2 = love.physics.newPrismaticJoint(body3, body4, 30, 30, 40, 40, true)
  583. local obj = love.physics.newGearJoint(joint1, joint2, 1, true)
  584. test:assertObject(obj)
  585. end
  586. -- love.physics.newMotorJoint
  587. -- @NOTE this is just basic nil checking, objs have their own test method
  588. love.test.physics.newMotorJoint = function(test)
  589. local world = love.physics.newWorld(1, 1, true)
  590. local body1 = love.physics.newBody(world, 10, 10, 'static')
  591. local body2 = love.physics.newBody(world, 20, 20, 'static')
  592. local obj = love.physics.newMotorJoint(body1, body2, 1)
  593. test:assertObject(obj)
  594. end
  595. -- love.physics.newMouseJoint
  596. -- @NOTE this is just basic nil checking, objs have their own test method
  597. love.test.physics.newMouseJoint = function(test)
  598. local world = love.physics.newWorld(1, 1, true)
  599. local body = love.physics.newBody(world, 10, 10, 'static')
  600. local obj = love.physics.newMouseJoint(body, 10, 10)
  601. test:assertObject(obj)
  602. end
  603. -- love.physics.newPolygonShape
  604. -- @NOTE this is just basic nil checking, objs have their own test method
  605. love.test.physics.newPolygonShape = function(test)
  606. local world = love.physics.newWorld(1, 1, true)
  607. local body = love.physics.newBody(world, 10, 10, 'static')
  608. local obj = love.physics.newPolygonShape(body, {0, 0, 2, 3, 2, 1, 3, 1, 5, 1})
  609. test:assertObject(obj)
  610. end
  611. -- love.physics.newPrismaticJoint
  612. -- @NOTE this is just basic nil checking, objs have their own test method
  613. love.test.physics.newPrismaticJoint = function(test)
  614. local world = love.physics.newWorld(1, 1, true)
  615. local body1 = love.physics.newBody(world, 10, 10, 'static')
  616. local body2 = love.physics.newBody(world, 20, 20, 'static')
  617. local obj = love.physics.newPrismaticJoint(body1, body2, 10, 10, 20, 20, true)
  618. test:assertObject(obj)
  619. end
  620. -- love.physics.newPulleyJoint
  621. -- @NOTE this is just basic nil checking, objs have their own test method
  622. love.test.physics.newPulleyJoint = function(test)
  623. local world = love.physics.newWorld(1, 1, true)
  624. local body1 = love.physics.newBody(world, 10, 10, 'static')
  625. local body2 = love.physics.newBody(world, 20, 20, 'static')
  626. local obj = love.physics.newPulleyJoint(body1, body2, 10, 10, 20, 20, 15, 15, 25, 25, 1, true)
  627. test:assertObject(obj)
  628. end
  629. -- love.physics.newRectangleShape
  630. -- @NOTE this is just basic nil checking, objs have their own test method
  631. love.test.physics.newRectangleShape = function(test)
  632. local world = love.physics.newWorld(1, 1, true)
  633. local body = love.physics.newBody(world, 10, 10, 'static')
  634. local shape1 = love.physics.newRectangleShape(body, 10, 20)
  635. local shape2 = love.physics.newRectangleShape(body, 10, 10, 40, 30, 10)
  636. test:assertObject(shape1)
  637. test:assertObject(shape2)
  638. end
  639. -- love.physics.newRevoluteJoint
  640. -- @NOTE this is just basic nil checking, objs have their own test method
  641. love.test.physics.newRevoluteJoint = function(test)
  642. local world = love.physics.newWorld(1, 1, true)
  643. local body1 = love.physics.newBody(world, 10, 10, 'static')
  644. local body2 = love.physics.newBody(world, 20, 20, 'static')
  645. local obj = love.physics.newRevoluteJoint(body1, body2, 10, 10, true)
  646. test:assertObject(obj)
  647. end
  648. -- love.physics.newRopeJoint
  649. -- @NOTE this is just basic nil checking, objs have their own test method
  650. love.test.physics.newRopeJoint = function(test)
  651. local world = love.physics.newWorld(1, 1, true)
  652. local body1 = love.physics.newBody(world, 10, 10, 'static')
  653. local body2 = love.physics.newBody(world, 20, 20, 'static')
  654. local obj = love.physics.newRopeJoint(body1, body2, 10, 10, 20, 20, 50, true)
  655. test:assertObject(obj)
  656. end
  657. -- love.physics.newWeldJoint
  658. -- @NOTE this is just basic nil checking, objs have their own test method
  659. love.test.physics.newWeldJoint = function(test)
  660. local world = love.physics.newWorld(1, 1, true)
  661. local body1 = love.physics.newBody(world, 10, 10, 'static')
  662. local body2 = love.physics.newBody(world, 20, 20, 'static')
  663. local obj = love.physics.newWeldJoint(body1, body2, 10, 10, true)
  664. test:assertObject(obj)
  665. end
  666. -- love.physics.newWheelJoint
  667. -- @NOTE this is just basic nil checking, objs have their own test method
  668. love.test.physics.newWheelJoint = function(test)
  669. local world = love.physics.newWorld(1, 1, true)
  670. local body1 = love.physics.newBody(world, 10, 10, 'static')
  671. local body2 = love.physics.newBody(world, 20, 20, 'static')
  672. local obj = love.physics.newWheelJoint(body1, body2, 10, 10, 5, 5, true)
  673. test:assertObject(obj)
  674. end
  675. -- love.physics.newWorld
  676. -- @NOTE this is just basic nil checking, objs have their own test method
  677. love.test.physics.newWorld = function(test)
  678. local world = love.physics.newWorld(1, 1, true)
  679. test:assertObject(world)
  680. end
  681. -- love.physics.setMeter
  682. love.test.physics.setMeter = function(test)
  683. -- set initial meter
  684. local world = love.physics.newWorld(1, 1, true)
  685. love.physics.setMeter(30)
  686. local body = love.physics.newBody(world, 300, 300, "dynamic")
  687. -- check changing meter changes pos value relatively
  688. love.physics.setMeter(10)
  689. local x, y = body:getPosition()
  690. test:assertEquals(100, x, 'check pos x')
  691. test:assertEquals(100, y, 'check pos y')
  692. end