Search in sources :

Example 1 with ReadOnlyTransform

use of com.ardor3d.math.type.ReadOnlyTransform 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();
            }
        }
    }));
}
Also used : IntersectionRecord(com.ardor3d.intersection.IntersectionRecord) TriggerAction(com.ardor3d.input.logical.TriggerAction) MouseButtonReleasedCondition(com.ardor3d.input.logical.MouseButtonReleasedCondition) KeyPressedCondition(com.ardor3d.input.logical.KeyPressedCondition) MouseMovedCondition(com.ardor3d.input.logical.MouseMovedCondition) InputTrigger(com.ardor3d.input.logical.InputTrigger) Canvas(com.ardor3d.framework.Canvas) ReadOnlyTransform(com.ardor3d.math.type.ReadOnlyTransform) MouseButtonPressedCondition(com.ardor3d.input.logical.MouseButtonPressedCondition) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) FloatBuffer(java.nio.FloatBuffer) ChangeTimeAndDateWithHeliodonCommand(org.concord.energy3d.undo.ChangeTimeAndDateWithHeliodonCommand) CullHint(com.ardor3d.scenegraph.hint.CullHint) Ray3(com.ardor3d.math.Ray3) Vector2(com.ardor3d.math.Vector2) MouseState(com.ardor3d.input.MouseState) TwoInputStates(com.ardor3d.input.logical.TwoInputStates)

Example 2 with ReadOnlyTransform

use of com.ardor3d.math.type.ReadOnlyTransform in project energy3d by concord-consortium.

the class Window method makeRectangle.

private Rectangle2D makeRectangle(final Window window, final boolean isRoof) {
    final ReadOnlyTransform transform;
    if (isRoof) {
        transform = ((Roof) container).getRoofPartsRoot().getChild(window.containerRoofIndex).getWorldTransform();
    } else {
        transform = null;
    }
    Rectangle2D thisWindow = null;
    for (int i = 0; i < window.points.size(); i++) {
        final Vector3 p = window.points.get(i);
        if (isRoof) {
            transform.applyInverse(p);
        }
        final double y = isRoof ? p.getY() : p.getZ();
        if (thisWindow == null) {
            thisWindow = new Rectangle2D.Double(p.getX(), y, 0, 0);
        }
        thisWindow.add(p.getX(), y);
    }
    return thisWindow;
}
Also used : ReadOnlyTransform(com.ardor3d.math.type.ReadOnlyTransform) Rectangle2D(java.awt.geom.Rectangle2D) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) CullHint(com.ardor3d.scenegraph.hint.CullHint)

Example 3 with ReadOnlyTransform

use of com.ardor3d.math.type.ReadOnlyTransform 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 4 with ReadOnlyTransform

use of com.ardor3d.math.type.ReadOnlyTransform 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)

Example 5 with ReadOnlyTransform

use of com.ardor3d.math.type.ReadOnlyTransform in project energy3d by concord-consortium.

the class SolarPanel method drawSolarCellOutlines.

// draw solar cell outlines when in heat map mode
private void drawSolarCellOutlines() {
    final FloatBuffer vertexBuffer = mesh.getMeshData().getVertexBuffer();
    // do not use WorldTransform
    final ReadOnlyTransform trans = mesh.getTransform();
    // (0, 0)
    final Vector3 p0 = trans.applyForward(new Vector3(vertexBuffer.get(3), vertexBuffer.get(4), vertexBuffer.get(5)));
    // (1, 0)
    final Vector3 p1 = trans.applyForward(new Vector3(vertexBuffer.get(6), vertexBuffer.get(7), vertexBuffer.get(8)));
    // (0, 1)
    final Vector3 p2 = trans.applyForward(new Vector3(vertexBuffer.get(0), vertexBuffer.get(1), vertexBuffer.get(2)));
    final int bufferSize = (getNumberOfCellsInX() + getNumberOfCellsInY() + 2) * 6;
    FloatBuffer vertices = solarCellOutlines.getMeshData().getVertexBuffer();
    if (vertices.capacity() != bufferSize) {
        vertices = BufferUtils.createFloatBuffer(bufferSize);
        solarCellOutlines.getMeshData().setVertexBuffer(vertices);
    } else {
        vertices.rewind();
        vertices.limit(vertices.capacity());
    }
    final int nx = rotated ? getNumberOfCellsInY() : getNumberOfCellsInX();
    final int ny = rotated ? getNumberOfCellsInX() : getNumberOfCellsInY();
    final Vector3 u = p1.subtract(p0, null).normalizeLocal();
    final Vector3 v = p2.subtract(p0, null).normalizeLocal();
    final double margin = 0.3;
    final double dx = (p1.distance(p0) - margin * 2) / ny;
    final double dy = (p2.distance(p0) - margin * 2) / nx;
    final Vector3 ud = u.multiply(dx, null);
    final Vector3 vd = v.multiply(dy, null);
    final Vector3 um = u.multiply(margin, null);
    final Vector3 vm = v.multiply(margin, null);
    Vector3 p, q;
    // draw x-lines
    for (int i = 0; i <= nx; i++) {
        q = vm.add(vd.multiply(i, null), null);
        p = p0.add(um, null).addLocal(q);
        vertices.put(p.getXf()).put(p.getYf()).put(p.getZf());
        p = p1.subtract(um, null).addLocal(q);
        vertices.put(p.getXf()).put(p.getYf()).put(p.getZf());
    }
    // draw y-lines
    for (int i = 0; i <= ny; i++) {
        q = um.add(ud.multiply(i, null), null);
        p = p0.add(vm, null).addLocal(q);
        vertices.put(p.getXf()).put(p.getYf()).put(p.getZf());
        p = p2.subtract(vm, null).addLocal(q);
        vertices.put(p.getXf()).put(p.getYf()).put(p.getZf());
    }
    solarCellOutlines.updateModelBound();
    solarCellOutlines.setVisible(true);
}
Also used : ReadOnlyTransform(com.ardor3d.math.type.ReadOnlyTransform) FloatBuffer(java.nio.FloatBuffer) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) CullHint(com.ardor3d.scenegraph.hint.CullHint)

Aggregations

Vector3 (com.ardor3d.math.Vector3)12 ReadOnlyTransform (com.ardor3d.math.type.ReadOnlyTransform)12 ReadOnlyVector3 (com.ardor3d.math.type.ReadOnlyVector3)12 FloatBuffer (java.nio.FloatBuffer)10 CullHint (com.ardor3d.scenegraph.hint.CullHint)8 Matrix3 (com.ardor3d.math.Matrix3)3 ReadOnlyColorRGBA (com.ardor3d.math.type.ReadOnlyColorRGBA)3 BloomRenderPass (com.ardor3d.extension.effect.bloom.BloomRenderPass)2 ColladaImporter (com.ardor3d.extension.model.collada.jdom.ColladaImporter)1 ColladaStorage (com.ardor3d.extension.model.collada.jdom.data.ColladaStorage)1 Canvas (com.ardor3d.framework.Canvas)1 MouseState (com.ardor3d.input.MouseState)1 InputTrigger (com.ardor3d.input.logical.InputTrigger)1 KeyPressedCondition (com.ardor3d.input.logical.KeyPressedCondition)1 MouseButtonPressedCondition (com.ardor3d.input.logical.MouseButtonPressedCondition)1 MouseButtonReleasedCondition (com.ardor3d.input.logical.MouseButtonReleasedCondition)1 MouseMovedCondition (com.ardor3d.input.logical.MouseMovedCondition)1 TriggerAction (com.ardor3d.input.logical.TriggerAction)1 TwoInputStates (com.ardor3d.input.logical.TwoInputStates)1 IntersectionRecord (com.ardor3d.intersection.IntersectionRecord)1