use of com.ardor3d.math.Vector2 in project energy3d by concord-consortium.
the class SelectUtil method pickPart.
public static PickedHousePart pickPart(final int x, final int y, final Class<?>[] typesOfHousePart) {
pickResults.clear();
final Ray3 pickRay = SceneManager.getInstance().getCamera().getPickRay(new Vector2(x, y), false, null);
for (final Class<?> typeOfHousePart : typesOfHousePart) {
if (typeOfHousePart == null) {
PickingUtil.findPick(SceneManager.getInstance().getLand(), pickRay, pickResults, false);
} else {
for (final HousePart part : Scene.getInstance().getParts()) {
if (!part.getLockEdit() && typeOfHousePart.isInstance(part)) {
PickingUtil.findPick(part.getCollisionSpatial(), pickRay, pickResults, false);
}
}
}
}
final PickedHousePart picked = getPickResultForImportedMesh();
if (picked != null) {
return picked;
}
return getPickResult(pickRay);
}
use of com.ardor3d.math.Vector2 in project energy3d by concord-consortium.
the class SelectUtil method pickPart.
public static PickedHousePart pickPart(final int x, final int y, final Mesh mesh) {
pickResults.clear();
final Ray3 pickRay = SceneManager.getInstance().getCamera().getPickRay(new Vector2(x, y), false, null);
PickingUtil.findPick(mesh, pickRay, pickResults, false);
final PickedHousePart picked = getPickResultForImportedMesh();
if (picked != null) {
return picked;
}
return getPickResult(pickRay);
}
use of com.ardor3d.math.Vector2 in project energy3d by concord-consortium.
the class Util method snapToPolygon.
public static Vector2 snapToPolygon(final ReadOnlyVector3 point, final List<ReadOnlyVector3> polygon, final List<ReadOnlyVector3> wallNormals) {
final Vector2 p = new Vector2(point.getX(), point.getY());
final Vector2 l1 = new Vector2();
final Vector2 l2 = new Vector2();
double shortestDistance = Double.MAX_VALUE;
Vector2 closestPoint = null;
ReadOnlyVector3 closestNormal = null;
final int n = polygon.size();
for (int i = 0; i < n; i++) {
final ReadOnlyVector3 pp1 = polygon.get(i);
l1.set(pp1.getX(), pp1.getY());
final ReadOnlyVector3 pp2 = polygon.get((i + 1) % n);
l2.set(pp2.getX(), pp2.getY());
if (l1.distanceSquared(l2) > MathUtils.ZERO_TOLERANCE) {
final Vector2 pointOnLine = projectPointOnLine(p, l1, l2, true);
final double distance = pointOnLine.distanceSquared(p);
if (distance < shortestDistance) {
shortestDistance = distance;
closestPoint = pointOnLine;
if (wallNormals != null) {
if (l1.distanceSquared(closestPoint) <= l2.distanceSquared(pointOnLine)) {
closestNormal = wallNormals.get(i);
} else {
closestNormal = wallNormals.get((i + 1) % n);
}
}
}
}
}
if (wallNormals != null) {
closestPoint.addLocal(-closestNormal.getX() / 100.0, -closestNormal.getY() / 100.0);
}
return closestPoint;
}
use of com.ardor3d.math.Vector2 in project energy3d by concord-consortium.
the class SolarRadiation method initMeshTextureData.
private MeshDataStore initMeshTextureData(final Mesh drawMesh, final Mesh collisionMesh, final ReadOnlyVector3 normal, final boolean updateTexture) {
final MeshDataStore data = new MeshDataStore();
if (normal != null) {
final AnyToXYTransform toXY = new AnyToXYTransform(normal.getX(), normal.getY(), normal.getZ());
final XYToAnyTransform fromXY = new XYToAnyTransform(normal.getX(), normal.getY(), normal.getZ());
final FloatBuffer vertexBuffer = collisionMesh.getMeshData().getVertexBuffer();
vertexBuffer.rewind();
double minX, minY, maxX, maxY;
minX = minY = Double.POSITIVE_INFINITY;
maxX = maxY = Double.NEGATIVE_INFINITY;
double z = Double.NaN;
final List<ReadOnlyVector2> points = new ArrayList<ReadOnlyVector2>(vertexBuffer.limit() / 3);
while (vertexBuffer.hasRemaining()) {
final Vector3 pWorld = drawMesh.localToWorld(new Vector3(vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get()), null);
final Point p = new TPoint(pWorld.getX(), pWorld.getY(), pWorld.getZ());
toXY.transform(p);
if (p.getX() < minX) {
minX = p.getX();
}
if (p.getX() > maxX) {
maxX = p.getX();
}
if (p.getY() < minY) {
minY = p.getY();
}
if (p.getY() > maxY) {
maxY = p.getY();
}
if (Double.isNaN(z)) {
z = p.getZ();
}
points.add(new Vector2(p.getX(), p.getY()));
}
final Point tmp = new TPoint(minX, minY, z);
fromXY.transform(tmp);
data.p0 = new Vector3(tmp.getX(), tmp.getY(), tmp.getZ());
tmp.set(minX, maxY, z);
fromXY.transform(tmp);
data.p1 = new Vector3(tmp.getX(), tmp.getY(), tmp.getZ());
tmp.set(maxX, minY, z);
fromXY.transform(tmp);
data.p2 = new Vector3(tmp.getX(), tmp.getY(), tmp.getZ());
final double solarStep = Scene.getInstance().getSolarStep();
data.rows = Math.max(1, (int) Math.ceil(data.p1.subtract(data.p0, null).length() / solarStep));
data.cols = Math.max(1, (int) Math.ceil(data.p2.subtract(data.p0, null).length() / solarStep));
data.dailySolarIntensity = new double[Util.roundToPowerOfTwo(data.rows)][Util.roundToPowerOfTwo(data.cols)];
final ReadOnlyVector2 originXY = new Vector2(minX, minY);
final ReadOnlyVector2 uXY = new Vector2(maxX - minX, 0).normalizeLocal();
final ReadOnlyVector2 vXY = new Vector2(0, maxY - minY).normalizeLocal();
final int nrow = data.dailySolarIntensity.length;
final int ncol = data.dailySolarIntensity[0].length;
for (int row = 0; row < nrow; row++) {
for (int col = 0; col < ncol; col++) {
if (row >= data.rows || col >= data.cols) {
// overshot cells
data.dailySolarIntensity[row][col] = -1;
} else {
final ReadOnlyVector2 p = originXY.add(uXY.multiply(col * solarStep, null), null).add(vXY.multiply(row * solarStep, null), null);
boolean isInside = false;
final int numberOfPoints = points.size();
if (numberOfPoints >= 3) {
// FIXME: sometimes we can end up with less than three points
for (int i = 0; i < numberOfPoints; i += 3) {
if (i + 2 < points.size()) {
if (Util.isPointInsideTriangle(p, points.get(i), points.get(i + 1), points.get(i + 2))) {
isInside = true;
break;
}
}
}
}
if (!isInside && col > 0 && row > 0) {
// must at least include one column or row
data.dailySolarIntensity[row][col] = -1;
}
}
}
}
data.u = data.p2.subtract(data.p0, null).normalizeLocal();
data.v = data.p1.subtract(data.p0, null).normalizeLocal();
onMesh.put(drawMesh, data);
if (updateTexture) {
updateTextureCoords(drawMesh);
}
}
return data;
}
use of com.ardor3d.math.Vector2 in project energy3d by concord-consortium.
the class Heliodon method initMouse.
private void initMouse(final LogicalLayer logicalLayer) {
logicalLayer.registerTrigger(new InputTrigger(new KeyPressedCondition(Key.F), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
setSunRegionAlwaysVisible(!forceSunRegionOn);
}
}));
logicalLayer.registerTrigger(new InputTrigger(new MouseButtonPressedCondition(MouseButton.LEFT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
oldHourAngle = hourAngle;
changeTimeAndDateCommand = new ChangeTimeAndDateWithHeliodonCommand(calendar.getTime());
final int x = inputStates.getCurrent().getMouseState().getX();
final int y = inputStates.getCurrent().getMouseState().getY();
final Ray3 pickRay = SceneManager.getInstance().getCanvas().getCanvasRenderer().getCamera().getPickRay(new Vector2(x, y), false, null);
pickResults.clear();
PickingUtil.findPick(sun, pickRay, pickResults);
if (pickResults.getNumber() != 0) {
sunGrabbed = true;
} else {
sunGrabbed = false;
}
if (forceSunRegionOn) {
selectDifferentDeclinationWithMouse = true;
} else {
selectDifferentDeclinationWithMouse = false;
}
SceneManager.getInstance().setMouseControlEnabled(!sunGrabbed);
}
}));
logicalLayer.registerTrigger(new InputTrigger(new MouseButtonReleasedCondition(MouseButton.LEFT), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
sunGrabbed = false;
if (!forceSunRegionOn) {
sunRegion.getSceneHints().setCullHint(CullHint.Always);
}
SceneManager.getInstance().setMouseControlEnabled(true);
if (!Util.isEqual(oldHourAngle, hourAngle) && changeTimeAndDateCommand != null) {
SceneManager.getInstance().getUndoManager().addEdit(changeTimeAndDateCommand);
}
}
}));
logicalLayer.registerTrigger(new InputTrigger(new MouseMovedCondition(), new TriggerAction() {
@Override
public void perform(final Canvas source, final TwoInputStates inputStates, final double tpf) {
if (!sunGrabbed) {
return;
}
final MouseState mouse = inputStates.getCurrent().getMouseState();
final Ray3 pickRay = SceneManager.getInstance().getCamera().getPickRay(new Vector2(mouse.getX(), mouse.getY()), false, null);
pickResults.clear();
PickingUtil.findPick(sunRegion, pickRay, pickResults);
final Vector3 intersectionPoint;
if (pickResults.getNumber() > 0) {
final IntersectionRecord intersectionRecord = pickResults.getPickData(0).getIntersectionRecord();
intersectionPoint = intersectionRecord.getIntersectionPoint(intersectionRecord.getClosestIntersection());
} else {
intersectionPoint = null;
}
double smallestDistance = Double.MAX_VALUE;
int hourVertex = -1;
int totalHourVertices = 0;
final Vector3 newSunLocation = new Vector3();
final Vector3 p = new Vector3();
final Vector3 p_abs = new Vector3();
final ReadOnlyTransform rootTansform = root.getTransform();
if (!selectDifferentDeclinationWithMouse) {
final FloatBuffer buf = sunPath.getMeshData().getVertexBuffer();
buf.rewind();
while (buf.hasRemaining()) {
p.set(buf.get(), buf.get(), buf.get());
rootTansform.applyForward(p, p_abs);
final double d;
d = pickRay.distanceSquared(p_abs, null);
if (d < smallestDistance) {
smallestDistance = d;
hourVertex = buf.position() / 3 - 1;
newSunLocation.set(p);
}
}
totalHourVertices = buf.limit() / 3;
}
if (smallestDistance > 5.0 * root.getTransform().getScale().getX() * root.getTransform().getScale().getX()) {
selectDifferentDeclinationWithMouse = true;
}
boolean declinationChanged = false;
if (selectDifferentDeclinationWithMouse) {
sunRegion.getSceneHints().setCullHint(CullHint.Inherit);
int rowCounter = 0;
int resultRow = -1;
final FloatBuffer buf = sunRegion.getMeshData().getVertexBuffer();
buf.rewind();
final double r = 5.0 / 2.0;
final Vector3 prev = new Vector3();
int quadVertexCounter = 0;
final double maxVertexInRow = HOUR_DIVISIONS * 4.0;
int rowVertexCounter = 0;
boolean foundInThisRow = false;
while (buf.hasRemaining()) {
p.set(buf.get(), buf.get(), buf.get());
rootTansform.applyForward(p, p_abs);
final double d;
if (intersectionPoint != null) {
d = intersectionPoint.distanceSquared(p_abs);
} else {
d = pickRay.distanceSquared(p_abs, null);
}
if (d < smallestDistance && p.getZ() >= -MathUtils.ZERO_TOLERANCE) {
smallestDistance = d;
newSunLocation.set(p);
resultRow = rowCounter + (quadVertexCounter >= 2 ? 1 : 0);
hourVertex = rowVertexCounter / 4 + (quadVertexCounter == 1 || quadVertexCounter == 2 ? 1 : 0);
foundInThisRow = true;
}
if (prev.lengthSquared() != 0 && (prev.distance(p) > r || rowVertexCounter >= maxVertexInRow)) {
rowCounter++;
if (foundInThisRow) {
totalHourVertices = rowVertexCounter / 4;
}
foundInThisRow = false;
rowVertexCounter = 0;
}
prev.set(p);
quadVertexCounter = (quadVertexCounter + 1) % 4;
rowVertexCounter++;
}
rowCounter++;
if (resultRow != -1) {
if (rowCounter < DECLINATION_DIVISIONS && latitude > 0) {
resultRow += DECLINATION_DIVISIONS - rowCounter;
}
final double newDeclinationAngle = -TILT_ANGLE + (2.0 * TILT_ANGLE * resultRow / DECLINATION_DIVISIONS);
declinationChanged = !Util.isEqual(newDeclinationAngle, declinationAngle);
if (declinationChanged) {
setDeclinationAngle(newDeclinationAngle, false, true);
dirtySunPath = true;
}
}
}
final double newHourAngle = (hourVertex - Math.floor(totalHourVertices / 2.0)) * Math.PI / 48.0;
final boolean hourAngleChanged = !Util.isEqual(newHourAngle, hourAngle);
if (hourAngleChanged) {
setHourAngle(newHourAngle, false, true, false);
}
if (declinationChanged || hourAngleChanged) {
setSunLocation(newSunLocation);
drawSunTriangle();
EnergyPanel.getInstance().updateRadiationHeatMap();
}
}
}));
}
Aggregations