gsdx-ogl: Restart collision detection algorithm for remaining sprites

It's useless on its own, but it prepares for the next commit.
This commit is contained in:
Jonathan Li 2016-01-11 17:44:17 +00:00
parent 3c528f0fdd
commit f3b6829c74
1 changed files with 51 additions and 42 deletions

View File

@ -485,59 +485,68 @@ GSRendererOGL::PRIM_OVERLAP GSRendererOGL::PrimitiveOverlap()
// Check intersection of sprite primitive only // Check intersection of sprite primitive only
size_t count = m_vertex.next; size_t count = m_vertex.next;
GSVertex* v = &m_vertex.buff[0]; PRIM_OVERLAP overlap = PRIM_OVERLAP_NO;
GSVertex* v = m_vertex.buff;
// In order to speed up comparaison a boundind-box is accumulated. It removes a size_t i = 0;
// loop so code is much faster (check game virtua fighter). Besides it allow to check while (i < count) {
// properly the Y order. // In order to speed up comparison a bounding-box is accumulated. It removes a
GSVector4i all; // loop so code is much faster (check game virtua fighter). Besides it allow to check
//FIXME better vector operation // properly the Y order.
if (v[1].XYZ.Y < v[0].XYZ.Y) { GSVector4i all;
all.y = v[1].XYZ.Y;
all.w = v[0].XYZ.Y;
} else {
all.y = v[0].XYZ.Y;
all.w = v[1].XYZ.Y;
}
if (v[1].XYZ.X < v[0].XYZ.X) {
all.x = v[1].XYZ.X;
all.z = v[0].XYZ.X;
} else {
all.x = v[0].XYZ.X;
all.z = v[1].XYZ.X;
}
for(size_t i = 2; i < count; i += 2) {
GSVector4i sprite;
//FIXME better vector operation //FIXME better vector operation
if (v[i+1].XYZ.Y < v[i+0].XYZ.Y) { if (v[i+1].XYZ.Y < v[i+0].XYZ.Y) {
sprite.y = v[i+1].XYZ.Y; all.y = v[i+1].XYZ.Y;
sprite.w = v[i+0].XYZ.Y; all.w = v[i+0].XYZ.Y;
} else { } else {
sprite.y = v[i+0].XYZ.Y; all.y = v[i+0].XYZ.Y;
sprite.w = v[i+1].XYZ.Y; all.w = v[i+1].XYZ.Y;
} }
if (v[i+1].XYZ.X < v[i+0].XYZ.X) { if (v[i+1].XYZ.X < v[i+0].XYZ.X) {
sprite.x = v[i+1].XYZ.X; all.x = v[i+1].XYZ.X;
sprite.z = v[i+0].XYZ.X; all.z = v[i+0].XYZ.X;
} else { } else {
sprite.x = v[i+0].XYZ.X; all.x = v[i+0].XYZ.X;
sprite.z = v[i+1].XYZ.X; all.z = v[i+1].XYZ.X;
} }
// Be sure to get vertex in good order, otherwise .r* function doesn't size_t j = i + 2;
// work as expected. while (j < count) {
ASSERT(sprite.x <= sprite.z); GSVector4i sprite;
ASSERT(sprite.y <= sprite.w); //FIXME better vector operation
ASSERT(all.x <= all.z); if (v[j+1].XYZ.Y < v[j+0].XYZ.Y) {
ASSERT(all.y <= all.w); sprite.y = v[j+1].XYZ.Y;
sprite.w = v[j+0].XYZ.Y;
} else {
sprite.y = v[j+0].XYZ.Y;
sprite.w = v[j+1].XYZ.Y;
}
if (v[j+1].XYZ.X < v[j+0].XYZ.X) {
sprite.x = v[j+1].XYZ.X;
sprite.z = v[j+0].XYZ.X;
} else {
sprite.x = v[j+0].XYZ.X;
sprite.z = v[j+1].XYZ.X;
}
if (all.rintersect(sprite).rempty()) { // Be sure to get vertex in good order, otherwise .r* function doesn't
all = all.runion(sprite); // work as expected.
} else { ASSERT(sprite.x <= sprite.z);
return PRIM_OVERLAP_YES; ASSERT(sprite.y <= sprite.w);
ASSERT(all.x <= all.z);
ASSERT(all.y <= all.w);
if (all.rintersect(sprite).rempty()) {
all = all.runion(sprite);
} else {
overlap = PRIM_OVERLAP_YES;
break;
}
j += 2;
} }
i = j;
} }
#if 0 #if 0
// Old algo: less constraint but O(n^2) instead of O(n) as above // Old algo: less constraint but O(n^2) instead of O(n) as above
@ -580,7 +589,7 @@ GSRendererOGL::PRIM_OVERLAP GSRendererOGL::PrimitiveOverlap()
#endif #endif
//fprintf(stderr, "%d: Yes, code can be optimized (draw of %d vertices)\n", s_n, count); //fprintf(stderr, "%d: Yes, code can be optimized (draw of %d vertices)\n", s_n, count);
return PRIM_OVERLAP_NO; return overlap;
} }
GSVector4i GSRendererOGL::ComputeBoundingBox(const GSVector2& rtscale, const GSVector2i& rtsize) GSVector4i GSRendererOGL::ComputeBoundingBox(const GSVector2& rtscale, const GSVector2i& rtsize)