use of spacegraph.space2d.phys.collision.AABB in project narchy by automenta.
the class DefaultBroadPhaseBuffer method testOverlap.
@Override
public boolean testOverlap(int proxyIdA, int proxyIdB) {
// return AABB.testOverlap(proxyA.aabb, proxyB.aabb);
// return m_tree.overlap(proxyIdA, proxyIdB);
final AABB a = m_tree.getFatAABB(proxyIdA);
final AABB b = m_tree.getFatAABB(proxyIdB);
if (b.lowerBound.x - a.upperBound.x > 0.0f || b.lowerBound.y - a.upperBound.y > 0.0f) {
return false;
}
return !(a.lowerBound.x - b.upperBound.x > 0.0f) && !(a.lowerBound.y - b.upperBound.y > 0.0f);
}
use of spacegraph.space2d.phys.collision.AABB in project narchy by automenta.
the class DynamicTreeFlatNodes method moveProxy.
@Override
public final boolean moveProxy(int proxyId, final AABB aabb, Tuple2f displacement) {
assert (0 <= proxyId && proxyId < m_nodeCapacity);
final int node = proxyId;
assert (m_child1[node] == NULL_NODE);
final AABB nodeAABB = m_aabb[node];
// if (nodeAABB.contains(aabb)) {
if (nodeAABB.lowerBound.x <= aabb.lowerBound.x && nodeAABB.lowerBound.y <= aabb.lowerBound.y && aabb.upperBound.x <= nodeAABB.upperBound.x && aabb.upperBound.y <= nodeAABB.upperBound.y) {
return false;
}
removeLeaf(node);
// Extend AABB
final Tuple2f lowerBound = nodeAABB.lowerBound;
final Tuple2f upperBound = nodeAABB.upperBound;
lowerBound.x = aabb.lowerBound.x - Settings.aabbExtension;
lowerBound.y = aabb.lowerBound.y - Settings.aabbExtension;
upperBound.x = aabb.upperBound.x + Settings.aabbExtension;
upperBound.y = aabb.upperBound.y + Settings.aabbExtension;
// Predict AABB displacement.
final float dx = displacement.x * Settings.aabbMultiplier;
final float dy = displacement.y * Settings.aabbMultiplier;
if (dx < 0.0f) {
lowerBound.x += dx;
} else {
upperBound.x += dx;
}
if (dy < 0.0f) {
lowerBound.y += dy;
} else {
upperBound.y += dy;
}
insertLeaf(proxyId);
return true;
}
use of spacegraph.space2d.phys.collision.AABB in project narchy by automenta.
the class DynamicTreeFlatNodes method insertLeaf.
private final void insertLeaf(int leaf) {
if (m_root == NULL_NODE) {
m_root = leaf;
m_parent[m_root] = NULL_NODE;
return;
}
// find the best sibling
AABB leafAABB = m_aabb[leaf];
int index = m_root;
while (m_child1[index] != NULL_NODE) {
final int node = index;
int child1 = m_child1[node];
int child2 = m_child2[node];
final AABB nodeAABB = m_aabb[node];
float area = nodeAABB.getPerimeter();
combinedAABB.combine(nodeAABB, leafAABB);
float combinedArea = combinedAABB.getPerimeter();
// Cost of creating a new parent for this node and the new leaf
float cost = 2.0f * combinedArea;
// Minimum cost of pushing the leaf further down the tree
float inheritanceCost = 2.0f * (combinedArea - area);
// Cost of descending into child1
float cost1;
AABB child1AABB = m_aabb[child1];
if (m_child1[child1] == NULL_NODE) {
combinedAABB.combine(leafAABB, child1AABB);
cost1 = combinedAABB.getPerimeter() + inheritanceCost;
} else {
combinedAABB.combine(leafAABB, child1AABB);
float oldArea = child1AABB.getPerimeter();
float newArea = combinedAABB.getPerimeter();
cost1 = (newArea - oldArea) + inheritanceCost;
}
// Cost of descending into child2
float cost2;
AABB child2AABB = m_aabb[child2];
if (m_child1[child2] == NULL_NODE) {
combinedAABB.combine(leafAABB, child2AABB);
cost2 = combinedAABB.getPerimeter() + inheritanceCost;
} else {
combinedAABB.combine(leafAABB, child2AABB);
float oldArea = child2AABB.getPerimeter();
float newArea = combinedAABB.getPerimeter();
cost2 = newArea - oldArea + inheritanceCost;
}
// Descend according to the minimum cost.
if (cost < cost1 && cost < cost2) {
break;
}
// Descend
if (cost1 < cost2) {
index = child1;
} else {
index = child2;
}
}
int sibling = index;
int oldParent = m_parent[sibling];
final int newParent = allocateNode();
m_parent[newParent] = oldParent;
m_userData[newParent] = null;
m_aabb[newParent].combine(leafAABB, m_aabb[sibling]);
m_height[newParent] = m_height[sibling] + 1;
if (oldParent != NULL_NODE) {
// The sibling was not the root.
if (m_child1[oldParent] == sibling) {
m_child1[oldParent] = newParent;
} else {
m_child2[oldParent] = newParent;
}
m_child1[newParent] = sibling;
m_child2[newParent] = leaf;
m_parent[sibling] = newParent;
m_parent[leaf] = newParent;
} else {
// The sibling was the root.
m_child1[newParent] = sibling;
m_child2[newParent] = leaf;
m_parent[sibling] = newParent;
m_parent[leaf] = newParent;
m_root = newParent;
}
// Walk back up the tree fixing heights and AABBs
index = m_parent[leaf];
while (index != NULL_NODE) {
index = balance(index);
int child1 = m_child1[index];
int child2 = m_child2[index];
assert (child1 != NULL_NODE);
assert (child2 != NULL_NODE);
m_height[index] = 1 + MathUtils.max(m_height[child1], m_height[child2]);
m_aabb[index].combine(m_aabb[child1], m_aabb[child2]);
index = m_parent[index];
}
// validate();
}
use of spacegraph.space2d.phys.collision.AABB in project narchy by automenta.
the class ParticleSystem method solveCollision.
private void solveCollision(TimeStep step) {
final AABB aabb = temp;
final Tuple2f lowerBound = aabb.lowerBound;
final Tuple2f upperBound = aabb.upperBound;
lowerBound.x = Float.MAX_VALUE;
lowerBound.y = Float.MAX_VALUE;
upperBound.x = -Float.MAX_VALUE;
upperBound.y = -Float.MAX_VALUE;
v2[] V = m_velocityBuffer.data;
v2[] P = m_positionBuffer.data;
float dt = step.dt;
for (int i = 0; i < m_count; i++) {
final Tuple2f v = V[i];
final Tuple2f p1 = P[i];
final float p1x = p1.x;
final float p1y = p1.y;
final float p2x = p1x + dt * v.x;
final float p2y = p1y + dt * v.y;
final float bx = p1x < p2x ? p1x : p2x;
final float by = p1y < p2y ? p1y : p2y;
lowerBound.x = lowerBound.x < bx ? lowerBound.x : bx;
lowerBound.y = lowerBound.y < by ? lowerBound.y : by;
final float b1x = p1x > p2x ? p1x : p2x;
final float b1y = p1y > p2y ? p1y : p2y;
upperBound.x = upperBound.x > b1x ? upperBound.x : b1x;
upperBound.y = upperBound.y > b1y ? upperBound.y : b1y;
}
sccallback.step = step;
sccallback.system = this;
m_world.queryAABB(sccallback, aabb);
}
use of spacegraph.space2d.phys.collision.AABB in project narchy by automenta.
the class ParticleSystem method updateBodyContacts.
public void updateBodyContacts() {
final AABB aabb = temp;
aabb.lowerBound.x = Float.MAX_VALUE;
aabb.lowerBound.y = Float.MAX_VALUE;
aabb.upperBound.x = -Float.MAX_VALUE;
aabb.upperBound.y = -Float.MAX_VALUE;
for (int i = 0; i < m_count; i++) {
Tuple2f p = m_positionBuffer.data[i];
Tuple2f.minToOut(aabb.lowerBound, p, aabb.lowerBound);
Tuple2f.maxToOut(aabb.upperBound, p, aabb.upperBound);
}
aabb.lowerBound.x -= m_particleDiameter;
aabb.lowerBound.y -= m_particleDiameter;
aabb.upperBound.x += m_particleDiameter;
aabb.upperBound.y += m_particleDiameter;
m_bodyContactCount = 0;
ubccallback.system = this;
m_world.queryAABB(ubccallback, aabb);
}
Aggregations