ClipmapLevel level = _clipmapLevels.get(index);
// start our tracer
tracer.startWalk(_workRay);
final Vector3 intersection = store != null ? store : new Vector3();
if (tracer.isRayPerpendicularToGrid()) {
// XXX: "HACK" for perpendicular ray
level.getCache().getEyeCoords(tileStore, tracer.getGridLocation()[0], tracer.getGridLocation()[1],
_workEyePos);
final float scaledClipSideSize = level.getClipSideSize() * level.getVertexDistance() * 0.5f;
final float h1 = getWeightedHeight(tileStore[0], tileStore[1], tileStore[2], tileStore[3],
scaledClipSideSize);
final float h2 = getWeightedHeight(tileStore[4], tileStore[5], tileStore[6], tileStore[7],
scaledClipSideSize);
final float h3 = getWeightedHeight(tileStore[8], tileStore[9], tileStore[10], tileStore[11],
scaledClipSideSize);
final float h4 = getWeightedHeight(tileStore[12], tileStore[13], tileStore[14], tileStore[15],
scaledClipSideSize);
final double x = _workEyePos.getX();
final double z = _workEyePos.getZ();
final double intOnX = x - Math.floor(x), intOnZ = z - Math.floor(z);
final double height = MathUtils
.lerp(intOnZ, MathUtils.lerp(intOnX, h1, h2), MathUtils.lerp(intOnX, h3, h4));
intersection.set(x, height, z);
terrainWorldTransform.applyForward(intersection, intersection);
return intersection;
}
// walk our way along the ray, asking for intersections along the way
int iter = 0;
while (iter < _maxChecks) {
// check the triangles of main square for intersection.
if (checkTriangles(tracer.getGridLocation()[0], tracer.getGridLocation()[1], intersection, normalStore,
tracer, level, _workEyePos)) {
// we found an intersection, so return that!
terrainWorldTransform.applyForward(intersection, intersection);
terrainWorldTransform.applyForward(normalStore, normalStore);
return intersection;
}
// because of how we get our height coords, we will
// sometimes be off be a grid spot, so we check the next
// grid space up.
int dx = 0, dy = 0;
final Direction d = tracer.getLastStepDirection();
switch (d) {
case PositiveX:
case NegativeX:
dx = 0;
dy = 1;
break;
case PositiveZ:
case NegativeZ:
dx = 1;
dy = 0;
break;
}
if (checkTriangles(tracer.getGridLocation()[0] + dx, tracer.getGridLocation()[1] + dy, intersection,
normalStore, tracer, level, _workEyePos)) {
// we found an intersection, so return that!
terrainWorldTransform.applyForward(intersection, intersection);
terrainWorldTransform.applyForward(normalStore, normalStore);
return intersection;
}
final double dist = tracer.getTotalTraveled();
// look at where we are and switch to the next cliplevel if needed
final Vector3 loc = new Vector3(_workRay.getDirection()).multiplyLocal(dist).addLocal(_workRay.getOrigin());
final int newIndex = findClipIndex(loc.subtract(_workEyePos, null));
// simple test to see if our next level at least has SOME data. XXX: could look to the tile level.
if (newIndex != index && _clipmapLevels.get(index).isReady()) {
_workRay.setOrigin(loc);
index = newIndex;
tracer = _tracers.get(index);