1 /*************************************************************************/
2 /*  area_pair_2d_sw.cpp                                                  */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #include "area_pair_2d_sw.h"
32 #include "collision_solver_2d_sw.h"
33 
setup(real_t p_step)34 bool AreaPair2DSW::setup(real_t p_step) {
35 
36 	bool result = false;
37 
38 	if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
39 		result = false;
40 	} else if (area->test_collision_mask(body) && CollisionSolver2DSW::solve(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), Vector2(), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), Vector2(), NULL, this)) {
41 		result = true;
42 	}
43 
44 	if (result != colliding) {
45 
46 		if (result) {
47 
48 			if (area->get_space_override_mode() != Physics2DServer::AREA_SPACE_OVERRIDE_DISABLED)
49 				body->add_area(area);
50 			if (area->has_monitor_callback())
51 				area->add_body_to_query(body, body_shape, area_shape);
52 
53 		} else {
54 
55 			if (area->get_space_override_mode() != Physics2DServer::AREA_SPACE_OVERRIDE_DISABLED)
56 				body->remove_area(area);
57 			if (area->has_monitor_callback())
58 				area->remove_body_from_query(body, body_shape, area_shape);
59 		}
60 
61 		colliding = result;
62 	}
63 
64 	return false; //never do any post solving
65 }
66 
solve(real_t p_step)67 void AreaPair2DSW::solve(real_t p_step) {
68 }
69 
AreaPair2DSW(Body2DSW * p_body,int p_body_shape,Area2DSW * p_area,int p_area_shape)70 AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body, int p_body_shape, Area2DSW *p_area, int p_area_shape) {
71 
72 	body = p_body;
73 	area = p_area;
74 	body_shape = p_body_shape;
75 	area_shape = p_area_shape;
76 	colliding = false;
77 	body->add_constraint(this, 0);
78 	area->add_constraint(this);
79 	if (p_body->get_mode() == Physics2DServer::BODY_MODE_KINEMATIC) //need to be active to process pair
80 		p_body->set_active(true);
81 }
82 
~AreaPair2DSW()83 AreaPair2DSW::~AreaPair2DSW() {
84 
85 	if (colliding) {
86 
87 		if (area->get_space_override_mode() != Physics2DServer::AREA_SPACE_OVERRIDE_DISABLED)
88 			body->remove_area(area);
89 		if (area->has_monitor_callback())
90 			area->remove_body_from_query(body, body_shape, area_shape);
91 	}
92 	body->remove_constraint(this);
93 	area->remove_constraint(this);
94 }
95 
96 //////////////////////////////////
97 
setup(real_t p_step)98 bool Area2Pair2DSW::setup(real_t p_step) {
99 
100 	bool result = false;
101 	if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
102 		result = false;
103 	} else if (area_a->test_collision_mask(area_b) && CollisionSolver2DSW::solve(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), Vector2(), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), Vector2(), NULL, this)) {
104 		result = true;
105 	}
106 
107 	if (result != colliding) {
108 
109 		if (result) {
110 
111 			if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
112 				area_b->add_area_to_query(area_a, shape_a, shape_b);
113 
114 			if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
115 				area_a->add_area_to_query(area_b, shape_b, shape_a);
116 
117 		} else {
118 
119 			if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
120 				area_b->remove_area_from_query(area_a, shape_a, shape_b);
121 
122 			if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
123 				area_a->remove_area_from_query(area_b, shape_b, shape_a);
124 		}
125 
126 		colliding = result;
127 	}
128 
129 	return false; //never do any post solving
130 }
131 
solve(real_t p_step)132 void Area2Pair2DSW::solve(real_t p_step) {
133 }
134 
Area2Pair2DSW(Area2DSW * p_area_a,int p_shape_a,Area2DSW * p_area_b,int p_shape_b)135 Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area_b, int p_shape_b) {
136 
137 	area_a = p_area_a;
138 	area_b = p_area_b;
139 	shape_a = p_shape_a;
140 	shape_b = p_shape_b;
141 	colliding = false;
142 	area_a->add_constraint(this);
143 	area_b->add_constraint(this);
144 }
145 
~Area2Pair2DSW()146 Area2Pair2DSW::~Area2Pair2DSW() {
147 
148 	if (colliding) {
149 
150 		if (area_b->has_area_monitor_callback())
151 			area_b->remove_area_from_query(area_a, shape_a, shape_b);
152 
153 		if (area_a->has_area_monitor_callback())
154 			area_a->remove_area_from_query(area_b, shape_b, shape_a);
155 	}
156 
157 	area_a->remove_constraint(this);
158 	area_b->remove_constraint(this);
159 }
160