30 void PointColDetector::UpdateIntraPoint(
bool contactables)
32 int contacters_size = contactables ? m_actor->ar_num_contactable_nodes : m_actor->ar_num_contacters;
34 if (contacters_size != m_object_list_size)
36 m_collision_partners.clear();
37 m_collision_partners.push_back(m_actor->ar_instance_id);
38 m_object_list_size = contacters_size;
39 update_structures_for_contacters(contactables);
43 refresh_node_positions();
47 m_kdtree[0].begin = 0;
48 m_kdtree[0].end = -m_object_list_size;
51 void PointColDetector::UpdateInterPoint(
bool ignorestate)
53 int contacters_size = 0;
54 std::vector<ActorInstanceID_t> collision_partners;
57 if (actor != m_actor && (ignorestate || actor->ar_update_physics) &&
58 m_actor->ar_bounding_box.intersects(actor->ar_bounding_box))
60 collision_partners.push_back(actor->ar_instance_id);
61 bool is_linked = std::find(m_actor->ar_linked_actors.begin(), m_actor->ar_linked_actors.end(), actor) != m_actor->ar_linked_actors.end();
62 contacters_size += is_linked ? actor->ar_num_contacters : actor->ar_num_contactable_nodes;
63 if (m_actor->ar_nodes[0].Velocity.squaredDistance(actor->ar_nodes[0].Velocity) > 16)
65 for (
int i = 0; i < m_actor->ar_num_collcabs; i++)
67 m_actor->ar_intra_collcabrate[i].rate = 0;
68 m_actor->ar_inter_collcabrate[i].rate = 0;
70 for (
int i = 0; i < actor->ar_num_collcabs; i++)
72 actor->ar_intra_collcabrate[i].rate = 0;
73 actor->ar_inter_collcabrate[i].rate = 0;
79 m_actor->ar_collision_relevant = (contacters_size > 0);
81 if (collision_partners != m_collision_partners || contacters_size != m_object_list_size)
83 m_collision_partners = collision_partners;
84 m_object_list_size = contacters_size;
85 update_structures_for_contacters(
false);
89 refresh_node_positions();
93 m_kdtree[0].begin = 0;
94 m_kdtree[0].end = -m_object_list_size;
97 void PointColDetector::update_structures_for_contacters(
bool ignoreinternal)
99 m_ref_list.resize(m_object_list_size);
100 hit_pointid_list.resize(m_object_list_size);
108 bool is_linked = std::find(m_actor->ar_linked_actors.begin(), m_actor->ar_linked_actors.end(), actor) != m_actor->
ar_linked_actors.end();
109 bool internal_collision = !ignoreinternal && ((actorid == m_actor->ar_instance_id) || is_linked);
115 hit_pointid_list[refi].nodenum =
static_cast<NodeNum_t>(i);
116 m_ref_list[refi].pidrefid = refi;
123 m_kdtree.resize(std::max(1.0, std::pow(2, std::ceil(std::log2(m_object_list_size)) + 1)));
126 void PointColDetector::query(
const Vector3 &vec1,
const Vector3 &vec2,
const Vector3 &vec3,
float enlargeBB)
130 m_bbmin.x = std::min(vec2.x, m_bbmin.x);
131 m_bbmin.x = std::min(vec3.x, m_bbmin.x);
133 m_bbmin.y = std::min(vec2.y, m_bbmin.y);
134 m_bbmin.y = std::min(vec3.y, m_bbmin.y);
136 m_bbmin.z = std::min(vec2.z, m_bbmin.z);
137 m_bbmin.z = std::min(vec3.z, m_bbmin.z);
139 m_bbmin -= enlargeBB;
143 m_bbmax.x = std::max(m_bbmax.x, vec2.x);
144 m_bbmax.x = std::max(m_bbmax.x, vec3.x);
146 m_bbmax.y = std::max(m_bbmax.y, vec2.y);
147 m_bbmax.y = std::max(m_bbmax.y, vec3.y);
149 m_bbmax.z = std::max(m_bbmax.z, vec2.z);
150 m_bbmax.z = std::max(m_bbmax.z, vec3.z);
152 m_bbmax += enlargeBB;
155 hit_list_actorset.clear();
159 void PointColDetector::queryrec(
int kdindex,
int axis)
163 if (m_kdtree[kdindex].end < 0)
165 build_kdtree_incr(axis, kdindex);
170 const std::array<float, 3> point = m_ref_list[m_kdtree[kdindex].refid].point;
171 if (point[0] >= m_bbmin.x && point[0] <= m_bbmax.x &&
172 point[1] >= m_bbmin.y && point[1] <= m_bbmax.y &&
173 point[2] >= m_bbmin.z && point[2] <= m_bbmax.z)
175 hit_list.push_back(m_ref_list[m_kdtree[kdindex].refid].pidrefid);
176 hit_list_actorset.insert(hit_pointid_list[m_ref_list[m_kdtree[kdindex].refid].pidrefid].actorid);
181 if (m_bbmax[axis] >= m_kdtree[kdindex].middle)
183 if (m_bbmin[axis] > m_kdtree[kdindex].max)
188 int newaxis = axis + 1;
195 int newindex = kdindex + kdindex + 1;
197 if (m_bbmin[axis] <= m_kdtree[kdindex].middle)
199 queryrec(newindex, newaxis);
202 kdindex = newindex + 1;
207 if (m_bbmax[axis] < m_kdtree[kdindex].min)
212 kdindex = 2 * kdindex + 1;
223 void PointColDetector::build_kdtree_incr(
int axis,
int index)
225 int end = -m_kdtree[index].end;
226 m_kdtree[index].end = end;
229 int slice_size = end - begin;
232 int newindex=index+index+1;
236 if (m_ref_list[begin].point[axis] > m_ref_list[median].point[axis])
238 std::swap(m_ref_list[begin], m_ref_list[median]);
241 m_kdtree[index].min = m_ref_list[begin].point[axis];
242 m_kdtree[index].max = m_ref_list[median].point[axis];
243 m_kdtree[index].middle = m_kdtree[index].max;
252 m_kdtree[newindex].refid = begin;
253 m_kdtree[newindex].middle = m_ref_list[m_kdtree[newindex].refid].point[axis];
254 m_kdtree[newindex].min = m_kdtree[newindex].middle;
255 m_kdtree[newindex].max = m_kdtree[newindex].middle;
256 m_kdtree[newindex].end = median;
259 m_kdtree[newindex].refid = median;
260 m_kdtree[newindex].middle = m_ref_list[m_kdtree[newindex].refid].point[axis];
261 m_kdtree[newindex].min = m_kdtree[newindex].middle;
262 m_kdtree[newindex].max = m_kdtree[newindex].middle;
263 m_kdtree[newindex].end = end;
268 median = begin + (slice_size / 2);
269 partintwo(begin, median, end, axis, m_kdtree[index].min, m_kdtree[index].max);
272 m_kdtree[index].middle = m_ref_list[median].point[axis];
275 m_kdtree[newindex].begin = begin;
276 m_kdtree[newindex].end = -median;
279 m_kdtree[newindex].begin = median;
280 m_kdtree[newindex].end = -end;
285 m_kdtree[index].refid = begin;
286 m_kdtree[index].middle = m_ref_list[m_kdtree[index].refid].point[axis];
287 m_kdtree[index].min = m_kdtree[index].middle;
288 m_kdtree[index].max = m_kdtree[index].middle;
292 void PointColDetector::partintwo(
const int start,
const int median,
const int end,
const int axis,
float &minex,
float &maxex)
299 float x = m_ref_list[k].point[axis];
304 while (!(j < k || k < i))
306 while (m_ref_list[i].point[axis] <
x)
310 while (
x < m_ref_list[j].point[axis])
315 std::swap(m_ref_list[i], m_ref_list[j]);
327 x = m_ref_list[k].point[axis];
332 for (
int i = start; i < median; ++i)
334 minex = std::min(m_ref_list[i].point[axis], minex);
336 for (
int i = median+1; i < end; ++i)
338 maxex = std::max(maxex, m_ref_list[i].point[axis]);
342 void PointColDetector::refresh_node_positions()
352 if (hit_pointid_list[refelem.pidrefid].actorid == actor->ar_instance_id)
354 refelem.setPoint(actor->ar_nodes[hit_pointid_list[refelem.pidrefid].nodenum].AbsPosition);