1 /**
2  * Copyright (c) 2006-2019 LOVE Development Team
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the authors be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  **/
20 
21 #include "Contact.h"
22 #include "World.h"
23 #include "Physics.h"
24 
25 namespace love
26 {
27 namespace physics
28 {
29 namespace box2d
30 {
31 
32 love::Type Contact::type("Contact", &Object::type);
33 
Contact(World * world,b2Contact * contact)34 Contact::Contact(World *world, b2Contact *contact)
35 	: contact(contact)
36 	, world(world)
37 {
38 	world->registerObject(contact, this);
39 }
40 
~Contact()41 Contact::~Contact()
42 {
43 	invalidate();
44 }
45 
invalidate()46 void Contact::invalidate()
47 {
48 	if (contact != NULL)
49 	{
50 		world->unregisterObject(contact);
51 		contact = NULL;
52 	}
53 }
54 
isValid()55 bool Contact::isValid()
56 {
57 	return contact != NULL;
58 }
59 
getPositions(lua_State * L)60 int Contact::getPositions(lua_State *L)
61 {
62 	love::luax_assert_argc(L, 1, 1);
63 	b2WorldManifold manifold;
64 	contact->GetWorldManifold(&manifold);
65 	int points = contact->GetManifold()->pointCount;
66 	for (int i = 0; i < points; i++)
67 	{
68 		b2Vec2 position = Physics::scaleUp(manifold.points[i]);
69 		lua_pushnumber(L, position.x);
70 		lua_pushnumber(L, position.y);
71 	}
72 	return points*2;
73 }
74 
getNormal(lua_State * L)75 int Contact::getNormal(lua_State *L)
76 {
77 	love::luax_assert_argc(L, 1, 1);
78 	b2WorldManifold manifold;
79 	contact->GetWorldManifold(&manifold);
80 	lua_pushnumber(L, manifold.normal.x);
81 	lua_pushnumber(L, manifold.normal.y);
82 	return 2;
83 }
84 
getFriction() const85 float Contact::getFriction() const
86 {
87 	return contact->GetFriction();
88 }
89 
getRestitution() const90 float Contact::getRestitution() const
91 {
92 	return contact->GetRestitution();
93 }
94 
isEnabled() const95 bool Contact::isEnabled() const
96 {
97 	return contact->IsEnabled();
98 }
99 
isTouching() const100 bool Contact::isTouching() const
101 {
102 	return contact->IsTouching();
103 }
104 
setFriction(float friction)105 void Contact::setFriction(float friction)
106 {
107 	contact->SetFriction(friction);
108 }
109 
setRestitution(float restitution)110 void Contact::setRestitution(float restitution)
111 {
112 	contact->SetRestitution(restitution);
113 }
114 
setEnabled(bool enabled)115 void Contact::setEnabled(bool enabled)
116 {
117 	contact->SetEnabled(enabled);
118 }
119 
resetFriction()120 void Contact::resetFriction()
121 {
122 	contact->ResetFriction();
123 }
124 
resetRestitution()125 void Contact::resetRestitution()
126 {
127 	contact->ResetRestitution();
128 }
129 
setTangentSpeed(float speed)130 void Contact::setTangentSpeed(float speed)
131 {
132 	contact->SetTangentSpeed(speed);
133 }
134 
getTangentSpeed() const135 float Contact::getTangentSpeed() const
136 {
137 	return contact->GetTangentSpeed();
138 }
139 
getChildren(int & childA,int & childB)140 void Contact::getChildren(int &childA, int &childB)
141 {
142 	childA = contact->GetChildIndexA();
143 	childB = contact->GetChildIndexB();
144 }
145 
getFixtures(Fixture * & fixtureA,Fixture * & fixtureB)146 void Contact::getFixtures(Fixture *&fixtureA, Fixture *&fixtureB)
147 {
148 	fixtureA = (Fixture *) world->findObject(contact->GetFixtureA());
149 	fixtureB = (Fixture *) world->findObject(contact->GetFixtureB());
150 
151 	if (!fixtureA || !fixtureB)
152 		throw love::Exception("A fixture has escaped Memoizer!");
153 }
154 
155 } // box2d
156 } // physics
157 } // love
158