/*******************************************************************************
* Breakout Cave Survey Visualizer
*
* Copyright (C) 2014 James Edwards
*
* jedwards8 at fastmail dot fm
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*******************************************************************************/
package org.breakout;
import java.util.Set;
import org.andork.func.FloatBinaryOperator;
import org.andork.math3d.Vecmath;
import org.andork.spatial.RTraversal;
import org.andork.spatial.Rectmath;
import org.breakout.model.Survey3dModel;
import org.breakout.model.Survey3dModel.Shot3d;
import org.omg.CORBA.FloatHolder;
public class FluidPerspectiveToOrtho {
private static float getFarthestExtent(Survey3dModel model, Set<Shot3d> shotsInView, float[] shotsInViewMbr,
float[] direction, FloatBinaryOperator extentFunction) {
FloatHolder farthest = new FloatHolder(Float.NaN);
float[] testPoint = new float[3];
RTraversal.traverse(model.getTree().getRoot(),
node -> {
if (!Rectmath.intersects3(shotsInViewMbr, node.mbr())) {
return false;
}
return Rectmath.findCorner3(node.mbr(), testPoint, corner -> {
float dist = Vecmath.dot3(corner, direction);
return farthest.value != extentFunction.applyAsFloat(farthest.value, dist) ? true : null;
}) ? true : false; // make sure we don't return null!
} ,
leaf -> {
if (shotsInView.contains(leaf.object())) {
for (float[] coord : leaf.object().coordIterable()) {
float dist = Vecmath.dot3(coord, direction);
farthest.value = extentFunction.applyAsFloat(farthest.value, dist);
}
}
return true;
});
return farthest.value;
}
public static float[] getOrthoBounds(Survey3dModel model, Set<Shot3d> shotsInView, float[] orthoRight,
float[] orthoUp, float[] orthoForward) {
float[] result = new float[4];
float[] shotsInViewMbr = Rectmath.voidRectf(3);
for (Shot3d shot : shotsInView) {
shot.unionMbrInto(shotsInViewMbr);
}
FloatBinaryOperator minFunc = (a, b) -> Float.isNaN(a) || b < a ? b : a;
FloatBinaryOperator maxFunc = (a, b) -> Float.isNaN(a) || b > a ? b : a;
result[0] = getFarthestExtent(model, shotsInView, shotsInViewMbr, orthoRight, minFunc);
result[1] = getFarthestExtent(model, shotsInView, shotsInViewMbr, orthoUp, minFunc);
result[2] = getFarthestExtent(model, shotsInView, shotsInViewMbr, orthoForward, minFunc);
result[3] = getFarthestExtent(model, shotsInView, shotsInViewMbr, orthoRight, maxFunc);
result[4] = getFarthestExtent(model, shotsInView, shotsInViewMbr, orthoUp, maxFunc);
result[5] = getFarthestExtent(model, shotsInView, shotsInViewMbr, orthoForward, maxFunc);
return result;
}
}