Refine RayTracing.

* Better coverage of block-transitions: One step per axis, dT can be 0.
* Cover one step always, also if no distance is covered.

There might be more false positives, due to newly intoduced bugs, or due
to not all block-transitions being checked (a x + z transition will have
two variations to test extra to the ordinary diagonal path, but only one
is checked).
This commit is contained in:
asofold 2014-08-05 18:55:15 +02:00
parent 4e9e935b1e
commit 4c7f88ec5c

View File

@ -76,10 +76,20 @@ public abstract class RayTracing {
private static final double tDiff(final double dTotal, final double offset){ private static final double tDiff(final double dTotal, final double offset){
if (dTotal > 0.0){ if (dTotal > 0.0){
return (1.0 - offset) / dTotal; if (offset >= 1.0) {
// Static block change (e.g. diagonal move).
return 0.0;
} else {
return (1.0 - offset) / dTotal;
}
} }
else if (dTotal < 0.0){ else if (dTotal < 0.0){
return offset / -dTotal; if (offset <= 0.0) {
// Static block change (e.g. diagonal move).
return 0.0;
} else {
return offset / -dTotal;
}
} }
else{ else{
return Double.MAX_VALUE; return Double.MAX_VALUE;
@ -103,7 +113,12 @@ public abstract class RayTracing {
tMin = Math.min(tX, Math.min(tY, tZ)); tMin = Math.min(tX, Math.min(tY, tZ));
if (tMin == Double.MAX_VALUE) { if (tMin == Double.MAX_VALUE) {
// All differences are 0 (no progress). // All differences are 0 (no progress).
break; if (step < 1) {
// Allow one step.
tMin = 0.0;
} else {
break;
}
} }
if (t + tMin > 1.0) { if (t + tMin > 1.0) {
// Set to the remaining distance (does trigger). // Set to the remaining distance (does trigger).
@ -112,16 +127,17 @@ public abstract class RayTracing {
// Call step with appropriate arguments. // Call step with appropriate arguments.
step ++; step ++;
if (!step(blockX, blockY, blockZ, oX, oY, oZ, tMin)) { if (!step(blockX, blockY, blockZ, oX, oY, oZ, tMin)) {
break; // || tMin == 0) break; break;
} }
if (t + tMin >= 1.0 - tol) { if (t + tMin >= 1.0 - tol) {
break; break;
} }
// Advance (add to t etc.). // Advance (add to t etc.).
changed = false; changed = false;
// TODO: Some not handled cases would mean errors. oX = Math.min(1.0, Math.max(0.0, oX + tMin * dX));
oY = Math.min(1.0, Math.max(0.0, oY + tMin * dY));
oZ = Math.min(1.0, Math.max(0.0, oZ + tMin * dZ));
// x // x
oX += tMin * dX;
if (tX == tMin){ if (tX == tMin){
if (dX < 0){ if (dX < 0){
oX = 1.0; oX = 1.0;
@ -134,64 +150,36 @@ public abstract class RayTracing {
changed = true; changed = true;
} }
} }
else if (oX >= 1.0 && dX > 0.0){ if (!changed) {
oX -= 1.0; // y
blockX ++; if (tY == tMin){
changed = true; if (dY < 0){
} oY = 1.0;
else if (oX < 0 && dX < 0.0){ blockY --;
oX += 1.0; changed = true;
blockX --; }
changed = true; else if (dY > 0){
} oY = 0.0;
// y blockY ++;
oY += tMin * dY; changed = true;
if (tY == tMin){ }
if (dY < 0){
oY = 1.0;
blockY --;
changed = true;
} }
else if (dY > 0){ if (!changed) {
oY = 0.0; // z
blockY ++; if (tZ == tMin){
changed = true; if (dZ < 0){
oZ = 1.0;
blockZ --;
changed = true;
}
else if (dZ > 0){
oZ = 0.0;
blockZ ++;
changed = true;
}
}
} }
} }
else if (oY >= 1 && dY > 0.0){
oY -= 1.0;
blockY ++;
changed = true;
}
else if (oY < 0 && dY < 0.0){
oY += 1.0;
blockY --;
changed = true;
}
// z
oZ += tMin * dZ;
if (tZ == tMin){
if (dZ < 0){
oZ = 1.0;
blockZ --;
changed = true;
}
else if (dZ > 0){
oZ = 0.0;
blockZ ++;
changed = true;
}
}
else if (oZ >= 1 && dZ > 0.0){
oZ -= 1.0;
blockZ ++;
changed = true;
}
else if (oZ < 0 && dZ < 0.0){
oZ += 1.0;
blockZ --;
changed = true;
}
t += tMin; t += tMin;
if (!changed || step >= maxSteps){ if (!changed || step >= maxSteps){
break; break;