use of com.ardor3d.math.Matrix3 in project energy3d by concord-consortium.
the class PrintController method fitInPage.
private boolean fitInPage(final Spatial printPart, final ArrayList<Spatial> page) {
for (final Spatial neighborPart : page) {
final Vector3 neighborPartCenter = ((UserData) neighborPart.getUserData()).getPrintCenter();
final OrientedBoundingBox neighborBound = (OrientedBoundingBox) neighborPart.getWorldBound().asType(Type.OBB);
final OrientedBoundingBox printPartBound = (OrientedBoundingBox) printPart.getWorldBound().asType(Type.OBB);
final double xExtend = neighborBound.getExtent().getX() + printPartBound.getExtent().getX() + spaceBetweenParts;
final double zExtend = neighborBound.getExtent().getZ() + printPartBound.getExtent().getZ() + spaceBetweenParts;
for (double angleQuarter = 0; angleQuarter < 4; angleQuarter++) {
final boolean isHorizontal = angleQuarter % 2 == 0;
final Vector3 tryCenter = new Matrix3().fromAngles(0, angleQuarter * Math.PI / 2.0, 0).applyPost(new Vector3(isHorizontal ? xExtend : zExtend, 0, 0), null);
tryCenter.addLocal(neighborPartCenter);
if (!isHorizontal) {
tryCenter.setX(pageLeft + printPartBound.getExtent().getX());
}
if (!isHorizontal) {
tryCenter.setX(MathUtils.clamp(tryCenter.getX(), pageLeft + printPartBound.getExtent().getX(), pageRight - printPartBound.getExtent().getX()));
} else {
tryCenter.setZ(MathUtils.clamp(tryCenter.getZ(), -pageBottom + printPartBound.getExtent().getZ(), -pageTop - printPartBound.getExtent().getZ()));
}
tryCenter.setY(Scene.getOriginalHouseRoot().getWorldBound().getCenter().getY());
boolean collision = false;
if (tryCenter.getX() - printPartBound.getExtent().getX() < pageLeft - MathUtils.ZERO_TOLERANCE || tryCenter.getX() + printPartBound.getExtent().getX() > pageRight + MathUtils.ZERO_TOLERANCE || tryCenter.getZ() + printPartBound.getExtent().getZ() > -pageTop + MathUtils.ZERO_TOLERANCE || tryCenter.getZ() - printPartBound.getExtent().getZ() < -pageBottom - MathUtils.ZERO_TOLERANCE) {
collision = true;
} else {
for (final Spatial otherPart : page) {
printPartBound.setCenter(tryCenter);
final OrientedBoundingBox otherPartBound = (OrientedBoundingBox) otherPart.getWorldBound().asType(Type.OBB);
otherPartBound.setCenter(((UserData) otherPart.getUserData()).getPrintCenter());
if (printPartBound.getExtent().getX() + otherPartBound.getExtent().getX() > Math.abs(printPartBound.getCenter().getX() - otherPartBound.getCenter().getX()) - spaceBetweenParts + MathUtils.ZERO_TOLERANCE && printPartBound.getExtent().getZ() + otherPartBound.getExtent().getZ() > Math.abs(printPartBound.getCenter().getZ() - otherPartBound.getCenter().getZ()) - spaceBetweenParts + MathUtils.ZERO_TOLERANCE) {
collision = true;
break;
}
}
}
if (!collision) {
((UserData) printPart.getUserData()).setPrintCenter(tryCenter);
page.add(printPart);
return true;
}
}
}
return false;
}
use of com.ardor3d.math.Matrix3 in project energy3d by concord-consortium.
the class PrintController method update.
@Override
public void update(final ReadOnlyTimer globalTimer) {
if (isPrintPreview) {
rotate();
}
if (isFinished()) {
return;
}
final Spatial originalHouseRoot = Scene.getOriginalHouseRoot();
if (init) {
init = false;
finish = false;
if (!isPrintPreview) {
Scene.getRoot().detachChild(pagesRoot);
pagesRoot.detachAllChildren();
for (final HousePart part : printParts) {
if (part instanceof Wall) {
((Wall) part).setBackMeshesVisible(true);
}
}
for (final HousePart part : printParts) {
part.hideLabels();
part.getOriginal().hideLabels();
}
} else {
printParts = new ArrayList<HousePart>(Scene.getInstance().getParts().size());
final boolean orgSolarHeatMap = SceneManager.getInstance().getSolarHeatMap();
SceneManager.getInstance().setSolarHeatMapWithoutUpdate(false);
for (final HousePart part : Scene.getInstance().getParts()) {
if (part.isPrintable()) {
final HousePart printPart = (HousePart) ObjectCloner.deepCopy(part);
printParts.add(printPart);
Scene.getRoot().attachChild(printPart.getRoot());
printPart.setOriginal(part);
printPart.flatten(1.0);
}
}
SceneManager.getInstance().setSolarHeatMapWithoutUpdate(orgSolarHeatMap);
final ArrayList<ArrayList<Spatial>> pages = new ArrayList<ArrayList<Spatial>>();
computePageDimension();
computePrintCenters(pages);
arrangePrintPages(pages);
if (!restartFlag) {
SceneManager.getInstance().updatePrintPreviewScene(true);
}
drawPrintParts(0);
}
originalHouseRoot.getSceneHints().setCullHint(CullHint.Always);
timer.reset();
}
final double viewSwitchDelay = 0.5;
if (!finish && (!isPrintPreview || timer.getTimeInSeconds() > viewSwitchDelay)) {
final double t = timer.getTimeInSeconds() - (isPrintPreview ? viewSwitchDelay : 0);
drawPrintParts(isPrintPreview ? t : 1 - t);
finish = t > 1;
if (finish) {
timer.reset();
}
}
if (finish) {
if (isPrintPreview) {
Scene.getRoot().attachChild(pagesRoot);
}
if (isPrintPreview && restartFlag) {
restartFlag = false;
}
// (time - startTime) > 1.0;
final boolean doTheEndAnimation = timer.getTimeInSeconds() > viewSwitchDelay;
if (!isPrintPreview && doTheEndAnimation) {
originalHouseRoot.setRotation(new Matrix3().fromAngles(0, 0, 0));
angle = 0;
for (final HousePart housePart : printParts) {
Scene.getRoot().detachChild(housePart.getRoot());
}
printParts = null;
if (!isPrintPreview && restartFlag) {
/* to force redraw when animated back to normal scene */
// redraw does not stretch the walls of print parts the roof. there is also no need for redraw since nothing has changed
Scene.getInstance().redrawAllNow();
setPrintPreview(true);
return;
}
originalHouseRoot.setScale(1);
originalHouseRoot.setTranslation(0, 0, 0);
originalHouseRoot.updateGeometricState(timer.getTimePerFrame(), true);
final CanvasRenderer renderer = SceneManager.getInstance().getCanvas().getCanvasRenderer();
renderer.makeCurrentContext();
renderer.getRenderer().setBackgroundColor(ColorRGBA.BLACK);
renderer.releaseCurrentContext();
SceneManager.getInstance().setShading(shadingSelected);
SceneManager.getInstance().setShadow(shadowSelected);
Heliodon.getInstance().setVisible(heliodonSelected);
SceneManager.getInstance().updatePrintPreviewScene(false);
if (!doTheEndAnimation) {
// to avoid concurrency exception
setFinished(true);
}
}
if (printParts != null) {
for (final HousePart part : printParts) {
if (part instanceof Foundation) {
part.getRoot().getSceneHints().setCullHint(isPrintPreview ? CullHint.Always : CullHint.Inherit);
}
}
}
if (isPrintPreview && printParts != null) {
for (final HousePart part : printParts) {
if (part instanceof Wall) {
((Wall) part).setBackMeshesVisible(false);
}
}
}
if (isPrintPreview || doTheEndAnimation) {
originalHouseRoot.getSceneHints().setCullHint(CullHint.Inherit);
if (isPrintPreview && printParts != null) {
int printSequence = 0;
for (final HousePart part : printParts) {
part.getOriginal().drawLabels(printSequence);
printSequence = part.drawLabels(printSequence);
}
SceneManager.getInstance().refresh();
}
setFinished(true);
}
}
}
use of com.ardor3d.math.Matrix3 in project energy3d by concord-consortium.
the class Foundation method importCollada.
public Node importCollada(final URL file, final Vector3 position) throws Exception {
if (importedNodes == null) {
importedNodes = new ArrayList<Node>();
}
if (importedNodeStates == null) {
importedNodeStates = new ArrayList<NodeState>();
}
if (position != null) {
// when position is null, the cursor is already set to be wait by the loading method
SceneManager.getInstance().cursorWait(true);
}
File sourceFile = new File(file.toURI());
if (!sourceFile.exists() && Scene.getURL() != null) {
sourceFile = new File(new File(Scene.getURL().toURI()).getParentFile(), Util.getFileName(file.getPath()).replaceAll("%20", " "));
}
if (sourceFile.exists()) {
final double az = Math.toRadians(getAzimuth());
final boolean zeroAz = Util.isZero(az);
// 0.633 is determined by fitting the length in Energy3D to the length in SketchUp
final double scale = Scene.getInstance().getAnnotationScale() * 0.633;
final ColladaStorage storage = new ColladaImporter().load(new URLResourceSource(sourceFile.toURI().toURL()));
final Node originalNode = storage.getScene();
originalNode.setScale(scale);
if (position != null) {
// when position is null, the node uses the position saved in the associated NodeState object
final NodeState ns = new NodeState();
ns.setSourceURL(file);
ns.setAbsolutePosition(position.clone());
importedNodeStates.add(ns);
originalNode.setTranslation(position);
final Vector3 relativePosition = position.subtract(getAbsCenter().multiplyLocal(1, 1, 0), null).addLocal(0, 0, height);
// why not -getAzimuth()?
ns.setRelativePosition(zeroAz ? relativePosition : new Matrix3().fromAngles(0, 0, az).applyPost(relativePosition, null));
}
// now construct a new node that is a parent of all planar meshes
final Node newNode = new Node(originalNode.getName());
final String nodeString = "Node #" + importedNodes.size() + ", Foundation #" + id;
final List<Mesh> meshes = new ArrayList<Mesh>();
Util.getMeshes(originalNode, meshes);
String warnInfo = null;
final int nodeIndex = importedNodes.size();
int meshIndex = 0;
for (final Mesh m : meshes) {
final ReadOnlyTransform t = m.getWorldTransform();
final MeshData md = m.getMeshData();
switch(md.getIndexMode(0)) {
case Triangles:
final List<Mesh> children = TriangleMeshLib.getPlanarMeshes(m);
if (!children.isEmpty()) {
for (final Mesh s : children) {
s.setTransform(t);
final UserData ud = new UserData(this, nodeIndex, meshIndex);
ud.setNormal((Vector3) s.getUserData());
ud.setRenderState(s.getLocalRenderState(StateType.Texture));
ud.setTextureBuffer(s.getMeshData().getTextureBuffer(0));
s.setUserData(ud);
s.setName("Mesh #" + meshIndex + ", " + nodeString);
newNode.attachChild(s);
meshIndex++;
}
}
break;
case Lines:
break;
default:
warnInfo = md.getIndexMode(0).name();
break;
}
}
if (warnInfo != null) {
JOptionPane.showMessageDialog(MainFrame.getInstance(), "Non-triangular mesh " + warnInfo + " is found.", "Warning", JOptionPane.WARNING_MESSAGE);
}
if (newNode.getNumberOfChildren() > 0) {
importedNodes.add(newNode);
newNode.setScale(scale);
newNode.updateWorldTransform(true);
root.attachChild(newNode);
createMeshThickness(newNode);
if (!zeroAz) {
setRotatedNormalsForImportedMeshes();
}
return newNode;
}
if (position != null) {
SceneManager.getInstance().cursorWait(false);
}
} else {
if (position != null) {
// get rid of the dead nodes no longer linked to files
for (final Iterator<NodeState> it = importedNodeStates.iterator(); it.hasNext(); ) {
if (file.equals(it.next().getSourceURL())) {
it.remove();
}
}
}
}
return null;
}
use of com.ardor3d.math.Matrix3 in project energy3d by concord-consortium.
the class Foundation method flatten.
@Override
public void flatten(final double flattenTime) {
root.setRotation((new Matrix3().fromAngles(flattenTime * Math.PI / 2, 0, 0)));
super.flatten(flattenTime);
}
use of com.ardor3d.math.Matrix3 in project energy3d by concord-consortium.
the class SolarPanel method drawSunBeam.
@Override
public void drawSunBeam() {
if (Heliodon.getInstance().isNightTime() || !drawSunBeam) {
sunBeam.setVisible(false);
normalVector.setVisible(false);
sunAngle.setVisible(false);
return;
}
final Vector3 o = (!onFlatSurface() || container instanceof Rack) ? getAbsPoint(0) : getAbsPoint(0).addLocal(0, 0, baseHeight);
final Vector3 sunLocation = Heliodon.getInstance().computeSunLocation(Heliodon.getInstance().getCalendar()).normalizeLocal();
final FloatBuffer beamsVertices = sunBeam.getMeshData().getVertexBuffer();
beamsVertices.rewind();
// draw sun vector
Vector3 r = o.clone();
r.addLocal(sunLocation.multiply(5000, null));
beamsVertices.put(o.getXf()).put(o.getYf()).put(o.getZf());
beamsVertices.put(r.getXf()).put(r.getYf()).put(r.getZf());
sunBeam.updateModelBound();
sunBeam.setVisible(true);
if (bloomRenderPass == null) {
bloomRenderPass = new BloomRenderPass(SceneManager.getInstance().getCamera(), 10);
bloomRenderPass.setBlurIntensityMultiplier(0.5f);
bloomRenderPass.setNrBlurPasses(2);
SceneManager.getInstance().getPassManager().add(bloomRenderPass);
}
if (!bloomRenderPass.contains(sunBeam)) {
bloomRenderPass.add(sunBeam);
}
final FloatBuffer normalVertices = normalVector.getMeshData().getVertexBuffer();
normalVertices.rewind();
// draw normal vector
r = o.clone();
r.addLocal(normal.multiply(normalVectorLength, null));
normalVertices.put(o.getXf()).put(o.getYf()).put(o.getZf());
normalVertices.put(r.getXf()).put(r.getYf()).put(r.getZf());
// draw arrows of the normal vector
final double arrowLength = 0.75;
final double arrowAngle = Math.toRadians(20);
final Matrix3 matrix = new Matrix3();
final FloatBuffer buf = mesh.getMeshData().getVertexBuffer();
final ReadOnlyTransform trans = mesh.getWorldTransform();
final Vector3 v1 = new Vector3();
final Vector3 v2 = new Vector3();
BufferUtils.populateFromBuffer(v1, buf, 1);
BufferUtils.populateFromBuffer(v2, buf, 2);
Vector3 a = trans.applyForward(v1).subtract(trans.applyForward(v2), null).normalizeLocal();
a = a.crossLocal(normal);
Vector3 s = normal.clone();
s = matrix.fromAngleNormalAxis(arrowAngle, a).applyPost(s, null).multiplyLocal(arrowLength);
s = r.subtract(s, null);
normalVertices.put(r.getXf()).put(r.getYf()).put(r.getZf());
normalVertices.put(s.getXf()).put(s.getYf()).put(s.getZf());
s = normal.clone();
s = matrix.fromAngleNormalAxis(-arrowAngle, a).applyPost(s, null).multiplyLocal(arrowLength);
s = r.subtract(s, null);
normalVertices.put(r.getXf()).put(r.getYf()).put(r.getZf());
normalVertices.put(s.getXf()).put(s.getYf()).put(s.getZf());
// draw the angle between the sun beam and the normal vector
normal.cross(sunLocation, a);
sunAngle.setRange(o, o.add(sunLocation, null), o.add(normal, null), a);
sunAngle.setVisible(true);
normalVector.updateModelBound();
normalVector.setVisible(true);
}
Aggregations