heightfieldParticle method
bool
heightfieldParticle(
- Heightfield si,
- Particle sj,
- Vector3 xi,
- Vector3 xj,
- Quaternion qi,
- Quaternion qj,
- Body bi,
- Body bj, [
- Shape? rsi,
- Shape? rsj,
- bool justTest = false,
])
Implementation
bool heightfieldParticle(
Heightfield si,
Particle sj,
Vector3 xi,
Vector3 xj,
Quaternion qi,
Quaternion qj,
Body bi,
Body bj,
[
Shape? rsi,
Shape? rsj,
bool justTest = false
]){
final data = si.data;
final radius = sj.boundingSphereRadius;
final w = si.elementSize;
final worldPillarOffset = _convexHeightfieldTmp2;
// Get sphere position to heightfield local!
final localConvexPos = _convexHeightfieldTmp1;
Transform.pointToLocalFrame(xi, qi, xj, localConvexPos);
// Get the index of the data points to test against
int iMinX = ((localConvexPos.x - radius) / w).floor() - 1;
int iMaxX = ((localConvexPos.x + radius) / w).ceil() + 1;
int iMinY = ((localConvexPos.y - radius) / w).floor() - 1;
int iMaxY = ((localConvexPos.y + radius) / w).ceil() + 1;
// Bail out if we are out of the terrain
if (iMaxX < 0 || iMaxY < 0 || iMinX > data.length || iMinY > data[0].length) {
return false;
}
// Clamp index to edges
if (iMinX < 0) {
iMinX = 0;
}
if (iMaxX < 0) {
iMaxX = 0;
}
if (iMinY < 0) {
iMinY = 0;
}
if (iMaxY < 0) {
iMaxY = 0;
}
if (iMinX >= data.length) {
iMinX = data.length - 1;
}
if (iMaxX >= data.length) {
iMaxX = data.length - 1;
}
if (iMaxY >= data[0].length) {
iMaxY = data[0].length - 1;
}
if (iMinY >= data[0].length) {
iMinY = data[0].length - 1;
}
List<double> minMax = [0,0];
si.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax);
final min = minMax[0];
final max = minMax[1];
// Bail out if we can't touch the bounding height box
if (localConvexPos.z - radius > max || localConvexPos.z + radius < min) {
return false;
}
for (int i = iMinX; i < iMaxX; i++) {
for (int j = iMinY; j < iMaxY; j++) {
bool intersecting = false;
// Lower triangle
si.getConvexTrianglePillar(i, j, false);
Transform.pointToWorldFrame(xi, qi, si.pillarOffset, worldPillarOffset);
if (
xj.distanceTo(worldPillarOffset) <= si.pillarConvex.boundingSphereRadius
) {
intersecting = particleConvex(si.pillarConvex, sj, worldPillarOffset, xj, qi, qj, bi, bj, rsi, rsj, justTest);
}
if (justTest && intersecting) {
return true;
}
// Upper triangle
si.getConvexTrianglePillar(i, j, true);
Transform.pointToWorldFrame(xi, qi, si.pillarOffset, worldPillarOffset);
if (
xj.distanceTo(worldPillarOffset) <= si.pillarConvex.boundingSphereRadius
) {
intersecting = particleConvex(si.pillarConvex, sj, worldPillarOffset, xj, qi, qj, bi, bj, rsi, rsj, justTest);
}
if (justTest && intersecting) {
return true;
}
}
}
return false;
}