Search in sources :

Example 26 with Matrix3

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;
}
Also used : OrientedBoundingBox(com.ardor3d.bounding.OrientedBoundingBox) Spatial(com.ardor3d.scenegraph.Spatial) UserData(org.concord.energy3d.model.UserData) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) Matrix3(com.ardor3d.math.Matrix3)

Example 27 with Matrix3

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);
        }
    }
}
Also used : Wall(org.concord.energy3d.model.Wall) Spatial(com.ardor3d.scenegraph.Spatial) CanvasRenderer(com.ardor3d.framework.CanvasRenderer) ArrayList(java.util.ArrayList) Foundation(org.concord.energy3d.model.Foundation) HousePart(org.concord.energy3d.model.HousePart) CullHint(com.ardor3d.scenegraph.hint.CullHint) Matrix3(com.ardor3d.math.Matrix3)

Example 28 with Matrix3

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;
}
Also used : Node(com.ardor3d.scenegraph.Node) ColladaImporter(com.ardor3d.extension.model.collada.jdom.ColladaImporter) URLResourceSource(com.ardor3d.util.resource.URLResourceSource) ArrayList(java.util.ArrayList) ReadOnlyTransform(com.ardor3d.math.type.ReadOnlyTransform) Mesh(com.ardor3d.scenegraph.Mesh) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) CullHint(com.ardor3d.scenegraph.hint.CullHint) Matrix3(com.ardor3d.math.Matrix3) MeshData(com.ardor3d.scenegraph.MeshData) ColladaStorage(com.ardor3d.extension.model.collada.jdom.data.ColladaStorage) File(java.io.File)

Example 29 with Matrix3

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);
}
Also used : Matrix3(com.ardor3d.math.Matrix3)

Example 30 with Matrix3

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);
}
Also used : ReadOnlyTransform(com.ardor3d.math.type.ReadOnlyTransform) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) FloatBuffer(java.nio.FloatBuffer) BloomRenderPass(com.ardor3d.extension.effect.bloom.BloomRenderPass) Matrix3(com.ardor3d.math.Matrix3)

Aggregations

Matrix3 (com.ardor3d.math.Matrix3)38 ReadOnlyVector3 (com.ardor3d.math.type.ReadOnlyVector3)31 Vector3 (com.ardor3d.math.Vector3)30 FloatBuffer (java.nio.FloatBuffer)12 CullHint (com.ardor3d.scenegraph.hint.CullHint)10 BloomRenderPass (com.ardor3d.extension.effect.bloom.BloomRenderPass)6 Node (com.ardor3d.scenegraph.Node)5 Spatial (com.ardor3d.scenegraph.Spatial)5 Mesh (com.ardor3d.scenegraph.Mesh)4 BoundingBox (com.ardor3d.bounding.BoundingBox)3 ColladaImporter (com.ardor3d.extension.model.collada.jdom.ColladaImporter)3 ColladaStorage (com.ardor3d.extension.model.collada.jdom.data.ColladaStorage)3 ReadOnlyTransform (com.ardor3d.math.type.ReadOnlyTransform)3 DirectionalLight (com.ardor3d.light.DirectionalLight)2 BlendState (com.ardor3d.renderer.state.BlendState)2 LightState (com.ardor3d.renderer.state.LightState)2 BillboardNode (com.ardor3d.scenegraph.extension.BillboardNode)2 CameraNode (com.ardor3d.scenegraph.extension.CameraNode)2 Quad (com.ardor3d.scenegraph.shape.Quad)2 ResourceSource (com.ardor3d.util.resource.ResourceSource)2