1 /**
2  * Copyright (c) 2006-2016 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 #include "common/Memoizer.h"
26 
27 namespace love
28 {
29 namespace physics
30 {
31 namespace box2d
32 {
33 
Contact(b2Contact * contact)34 Contact::Contact(b2Contact *contact)
35 	: contact(contact)
36 {
37 	Memoizer::add(contact, this);
38 }
39 
~Contact()40 Contact::~Contact()
41 {
42 	invalidate();
43 }
44 
invalidate()45 void Contact::invalidate()
46 {
47 	if (contact != NULL)
48 	{
49 		Memoizer::remove(contact);
50 		contact = NULL;
51 	}
52 }
53 
isValid()54 bool Contact::isValid()
55 {
56 	return contact != NULL ? true : false;
57 }
58 
getPositions(lua_State * L)59 int Contact::getPositions(lua_State *L)
60 {
61 	love::luax_assert_argc(L, 1, 1);
62 	b2WorldManifold manifold;
63 	contact->GetWorldManifold(&manifold);
64 	int points = contact->GetManifold()->pointCount;
65 	for (int i = 0; i < points; i++)
66 	{
67 		b2Vec2 position = Physics::scaleUp(manifold.points[i]);
68 		lua_pushnumber(L, position.x);
69 		lua_pushnumber(L, position.y);
70 	}
71 	return points*2;
72 }
73 
getNormal(lua_State * L)74 int Contact::getNormal(lua_State *L)
75 {
76 	love::luax_assert_argc(L, 1, 1);
77 	b2WorldManifold manifold;
78 	contact->GetWorldManifold(&manifold);
79 	lua_pushnumber(L, manifold.normal.x);
80 	lua_pushnumber(L, manifold.normal.y);
81 	return 2;
82 }
83 
getFriction() const84 float Contact::getFriction() const
85 {
86 	return contact->GetFriction();
87 }
88 
getRestitution() const89 float Contact::getRestitution() const
90 {
91 	return contact->GetRestitution();
92 }
93 
isEnabled() const94 bool Contact::isEnabled() const
95 {
96 	return contact->IsEnabled();
97 }
98 
isTouching() const99 bool Contact::isTouching() const
100 {
101 	return contact->IsTouching();
102 }
103 
setFriction(float friction)104 void Contact::setFriction(float friction)
105 {
106 	contact->SetFriction(friction);
107 }
108 
setRestitution(float restitution)109 void Contact::setRestitution(float restitution)
110 {
111 	contact->SetRestitution(restitution);
112 }
113 
setEnabled(bool enabled)114 void Contact::setEnabled(bool enabled)
115 {
116 	contact->SetEnabled(enabled);
117 }
118 
resetFriction()119 void Contact::resetFriction()
120 {
121 	contact->ResetFriction();
122 }
123 
resetRestitution()124 void Contact::resetRestitution()
125 {
126 	contact->ResetRestitution();
127 }
128 
setTangentSpeed(float speed)129 void Contact::setTangentSpeed(float speed)
130 {
131 	contact->SetTangentSpeed(speed);
132 }
133 
getTangentSpeed() const134 float Contact::getTangentSpeed() const
135 {
136 	return contact->GetTangentSpeed();
137 }
138 
getChildren(int & childA,int & childB)139 void Contact::getChildren(int &childA, int &childB)
140 {
141 	childA = contact->GetChildIndexA();
142 	childB = contact->GetChildIndexB();
143 }
144 
getFixtures(Fixture * & fixtureA,Fixture * & fixtureB)145 void Contact::getFixtures(Fixture *&fixtureA, Fixture *&fixtureB)
146 {
147 	fixtureA = (Fixture *) Memoizer::find(contact->GetFixtureA());
148 	fixtureB = (Fixture *) Memoizer::find(contact->GetFixtureB());
149 
150 	if (!fixtureA || !fixtureB)
151 		throw love::Exception("A fixture has escaped Memoizer!");
152 }
153 
154 } // box2d
155 } // physics
156 } // love
157