Search in sources :

Example 1 with AngleAnnotation

use of org.concord.energy3d.shapes.AngleAnnotation in project energy3d by concord-consortium.

the class HousePart method fetchAngleAnnot.

protected AngleAnnotation fetchAngleAnnot(final int annotCounter, final Node angleAnnotRoot) {
    final AngleAnnotation annot;
    if (annotCounter < angleAnnotRoot.getChildren().size()) {
        annot = (AngleAnnotation) angleAnnotRoot.getChild(annotCounter);
        annot.getSceneHints().setCullHint(CullHint.Inherit);
    } else {
        annot = new AngleAnnotation();
        angleAnnotRoot.attachChild(annot);
    }
    return annot;
}
Also used : AngleAnnotation(org.concord.energy3d.shapes.AngleAnnotation)

Example 2 with AngleAnnotation

use of org.concord.energy3d.shapes.AngleAnnotation in project energy3d by concord-consortium.

the class Rack method init.

@Override
protected void init() {
    super.init();
    if (Util.isZero(copyLayoutGap)) {
        // FIXME: Why is a transient member evaluated to zero?
        copyLayoutGap = 1;
    }
    if (Util.isZero(rackWidth)) {
        rackWidth = 4.95;
    }
    if (Util.isZero(rackHeight)) {
        rackHeight = 1.65;
    }
    if (monthlyTiltAngles == null) {
        monthlyTiltAngles = new double[12];
        Arrays.fill(monthlyTiltAngles, tiltAngle);
    }
    mesh = new Mesh("Rack");
    mesh.setDefaultColor(ColorRGBA.LIGHT_GRAY);
    mesh.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(6));
    mesh.getMeshData().setTextureBuffer(BufferUtils.createVector2Buffer(6), 0);
    mesh.setModelBound(new OrientedBoundingBox());
    mesh.setUserData(new UserData(this));
    root.attachChild(mesh);
    surround = new Box("Rack (Surround)");
    surround.setDefaultColor(ColorRGBA.LIGHT_GRAY);
    surround.setModelBound(new OrientedBoundingBox());
    final OffsetState offset = new OffsetState();
    // set a smaller value than solar panel so that the texture doesn't show up on the underside
    offset.setFactor(0.2f);
    offset.setUnits(1);
    surround.setRenderState(offset);
    root.attachChild(surround);
    outlineMesh = new Line("Rack (Outline)");
    outlineMesh.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(8));
    outlineMesh.setDefaultColor(ColorRGBA.BLACK);
    outlineMesh.setModelBound(new OrientedBoundingBox());
    root.attachChild(outlineMesh);
    sunBeam = new Line("Sun Beam");
    sunBeam.setLineWidth(1f);
    sunBeam.setStipplePattern((short) 0xffff);
    sunBeam.setModelBound(null);
    Util.disablePickShadowLight(sunBeam);
    sunBeam.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(4));
    sunBeam.setDefaultColor(new ColorRGBA(1f, 1f, 1f, 1f));
    root.attachChild(sunBeam);
    normalVector = new Line("Normal Vector");
    normalVector.setLineWidth(1f);
    normalVector.setStipplePattern((short) 0xffff);
    normalVector.setModelBound(null);
    Util.disablePickShadowLight(normalVector);
    normalVector.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(6));
    normalVector.setDefaultColor(new ColorRGBA(1f, 1f, 0f, 1f));
    root.attachChild(normalVector);
    angles = new Node("Angles");
    angles.getSceneHints().setAllPickingHints(false);
    Util.disablePickShadowLight(angles);
    root.attachChild(angles);
    // the angle between the sun beam and the normal vector
    sunAngle = new AngleAnnotation();
    sunAngle.setColor(ColorRGBA.WHITE);
    sunAngle.setLineWidth(1);
    sunAngle.setFontSize(1);
    sunAngle.setCustomRadius(normalVectorLength * 0.8);
    angles.attachChild(sunAngle);
    solarPanelOutlines = new Line("Solar Panel Outlines");
    solarPanelOutlines.setLineWidth(1f);
    solarPanelOutlines.setStipplePattern((short) 0xffff);
    solarPanelOutlines.setModelBound(null);
    Util.disablePickShadowLight(solarPanelOutlines);
    solarPanelOutlines.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(1));
    solarPanelOutlines.setDefaultColor(new ColorRGBA(0f, 0f, 0f, 1f));
    root.attachChild(solarPanelOutlines);
    label = new BMText("Label", "#" + id, FontManager.getInstance().getPartNumberFont(), Align.Center, Justify.Center);
    Util.initHousePartLabel(label);
    label.setFontScale(0.5);
    label.setVisible(false);
    root.attachChild(label);
    polesRoot = new Node("Poles Root");
    root.attachChild(polesRoot);
    updateTextureAndColor();
    if (sampleSolarPanel == null) {
        sampleSolarPanel = new SolarPanel();
    }
    // ugly fixes for zero initial values when sampleSolarPanel is previously serialized without new variables
    if (sampleSolarPanel.getPvModuleSpecs() == null) {
        sampleSolarPanel.setPvModuleSpecs(new PvModuleSpecs());
    }
    if (Util.isZero(sampleSolarPanel.getNominalOperatingCellTemperature())) {
        sampleSolarPanel.setNominalOperatingCellTemperature(48);
    }
    if (!points.isEmpty()) {
        oldRackCenter = points.get(0).clone();
    }
    oldRackWidth = rackWidth;
    oldRackHeight = rackHeight;
}
Also used : Line(com.ardor3d.scenegraph.Line) OrientedBoundingBox(com.ardor3d.bounding.OrientedBoundingBox) ReadOnlyColorRGBA(com.ardor3d.math.type.ReadOnlyColorRGBA) ColorRGBA(com.ardor3d.math.ColorRGBA) Node(com.ardor3d.scenegraph.Node) Mesh(com.ardor3d.scenegraph.Mesh) BoundingBox(com.ardor3d.bounding.BoundingBox) Box(com.ardor3d.scenegraph.shape.Box) OrientedBoundingBox(com.ardor3d.bounding.OrientedBoundingBox) AngleAnnotation(org.concord.energy3d.shapes.AngleAnnotation) BMText(com.ardor3d.ui.text.BMText) PvModuleSpecs(org.concord.energy3d.simulation.PvModuleSpecs) OffsetState(com.ardor3d.renderer.state.OffsetState)

Example 3 with AngleAnnotation

use of org.concord.energy3d.shapes.AngleAnnotation in project energy3d by concord-consortium.

the class SolarPanel method init.

@Override
protected void init() {
    super.init();
    if (Util.isZero(panelWidth)) {
        panelWidth = 0.99;
    }
    if (Util.isZero(panelHeight)) {
        panelHeight = 1.65;
    }
    if (Util.isZero(efficiency)) {
        // make it the same as the default one in PvModuleSpecs
        efficiency = 0.1833;
    }
    if (Util.isZero(temperatureCoefficientPmax)) {
        temperatureCoefficientPmax = -0.005;
    }
    if (Util.isZero(nominalOperatingCellTemperature)) {
        nominalOperatingCellTemperature = 48;
    }
    if (Util.isZero(inverterEfficiency)) {
        inverterEfficiency = 0.95;
    }
    if (Util.isZero(baseHeight)) {
        baseHeight = 5;
    }
    if (Util.isZero(numberOfCellsInX)) {
        numberOfCellsInX = 6;
    }
    if (Util.isZero(numberOfCellsInY)) {
        numberOfCellsInY = 10;
    }
    if (pvModuleSpecs == null) {
        // backward compatibility
        pvModuleSpecs = new PvModuleSpecs("Custom");
        pvModuleSpecs.setCellEfficiency(efficiency);
        pvModuleSpecs.setWidth(panelWidth);
        pvModuleSpecs.setLength(panelHeight);
        pvModuleSpecs.setNoct(nominalOperatingCellTemperature);
        pvModuleSpecs.setPmaxTc(temperatureCoefficientPmax);
        pvModuleSpecs.setLayout(numberOfCellsInX, numberOfCellsInY);
        switch(cellType) {
            case POLYCRYSTALLINE:
                pvModuleSpecs.setCellType("Polycrystalline");
                colorOption = COLOR_OPTION_BLUE;
                break;
            case MONOCRYSTALLINE:
                pvModuleSpecs.setCellType("Monocrystalline");
                colorOption = COLOR_OPTION_BLACK;
                break;
            case THIN_FILM:
                pvModuleSpecs.setCellType("Thin Film");
                colorOption = COLOR_OPTION_BLACK;
                break;
        }
    } else {
        convertStringPropertiesToIntegerProperties();
    }
    mesh = new Mesh("SolarPanel");
    mesh.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(6));
    mesh.getMeshData().setTextureBuffer(BufferUtils.createVector2Buffer(6), 0);
    mesh.setModelBound(new OrientedBoundingBox());
    mesh.setUserData(new UserData(this));
    root.attachChild(mesh);
    surround = new Box("SolarPanel (Surround)");
    surround.setModelBound(new OrientedBoundingBox());
    final OffsetState offset = new OffsetState();
    offset.setFactor(1);
    offset.setUnits(1);
    surround.setRenderState(offset);
    root.attachChild(surround);
    outlineMesh = new Line("SolarPanel (Outline)");
    outlineMesh.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(8));
    outlineMesh.setDefaultColor(ColorRGBA.BLACK);
    outlineMesh.setModelBound(new OrientedBoundingBox());
    root.attachChild(outlineMesh);
    supportFrame = new Mesh("Supporting Frame");
    supportFrame.getMeshData().setIndexMode(IndexMode.Quads);
    supportFrame.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(12));
    supportFrame.getMeshData().setNormalBuffer(BufferUtils.createVector3Buffer(12));
    supportFrame.setRenderState(offsetState);
    supportFrame.setModelBound(new BoundingBox());
    root.attachChild(supportFrame);
    sunBeam = new Line("Sun Beam");
    sunBeam.setLineWidth(1f);
    sunBeam.setStipplePattern((short) 0xffff);
    sunBeam.setModelBound(null);
    Util.disablePickShadowLight(sunBeam);
    sunBeam.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(4));
    sunBeam.setDefaultColor(new ColorRGBA(1f, 1f, 1f, 1f));
    root.attachChild(sunBeam);
    normalVector = new Line("Normal Vector");
    normalVector.setLineWidth(1f);
    normalVector.setStipplePattern((short) 0xffff);
    normalVector.setModelBound(null);
    Util.disablePickShadowLight(normalVector);
    normalVector.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(6));
    normalVector.setDefaultColor(new ColorRGBA(1f, 1f, 0f, 1f));
    root.attachChild(normalVector);
    angles = new Node("Angles");
    angles.getSceneHints().setAllPickingHints(false);
    Util.disablePickShadowLight(angles);
    root.attachChild(angles);
    // the angle between the sun beam and the normal vector
    sunAngle = new AngleAnnotation();
    sunAngle.setColor(ColorRGBA.WHITE);
    sunAngle.setLineWidth(1);
    sunAngle.setFontSize(1);
    sunAngle.setCustomRadius(normalVectorLength * 0.8);
    angles.attachChild(sunAngle);
    label = new BMText("Label", "# " + id, FontManager.getInstance().getPartNumberFont(), Align.Center, Justify.Center);
    Util.initHousePartLabel(label);
    label.setFontScale(0.5);
    label.setVisible(false);
    root.attachChild(label);
    solarCellOutlines = new Line("Solar Cell Outlines");
    solarCellOutlines.setLineWidth(1f);
    solarCellOutlines.setStipplePattern((short) 0xffff);
    solarCellOutlines.setModelBound(null);
    Util.disablePickShadowLight(solarCellOutlines);
    solarCellOutlines.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(1));
    solarCellOutlines.setDefaultColor(new ColorRGBA(0f, 0f, 0f, 1f));
    root.attachChild(solarCellOutlines);
    updateTextureAndColor();
}
Also used : Line(com.ardor3d.scenegraph.Line) OrientedBoundingBox(com.ardor3d.bounding.OrientedBoundingBox) ColorRGBA(com.ardor3d.math.ColorRGBA) BoundingBox(com.ardor3d.bounding.BoundingBox) OrientedBoundingBox(com.ardor3d.bounding.OrientedBoundingBox) Node(com.ardor3d.scenegraph.Node) Mesh(com.ardor3d.scenegraph.Mesh) BoundingBox(com.ardor3d.bounding.BoundingBox) Box(com.ardor3d.scenegraph.shape.Box) OrientedBoundingBox(com.ardor3d.bounding.OrientedBoundingBox) AngleAnnotation(org.concord.energy3d.shapes.AngleAnnotation) BMText(com.ardor3d.ui.text.BMText) PvModuleSpecs(org.concord.energy3d.simulation.PvModuleSpecs) OffsetState(com.ardor3d.renderer.state.OffsetState)

Example 4 with AngleAnnotation

use of org.concord.energy3d.shapes.AngleAnnotation in project energy3d by concord-consortium.

the class Wall method drawAnnotations.

@Override
public void drawAnnotations() {
    if (points.size() < 4) {
        return;
    }
    final ReadOnlyVector3 faceDirection = getNormal();
    int annotCounter = 0;
    int angleAnnotCounter = 0;
    if (wallAndWindowsPoints != null) {
        final List<Vector3> wallPolygonPoints = wallAndWindowsPoints.get(0);
        final Vector3 actualNormal = wallPolygonPoints.get(0).subtract(wallPolygonPoints.get(1), null).normalizeLocal().crossLocal(wallPolygonPoints.get(2).subtract(wallPolygonPoints.get(1), null).normalizeLocal()).negateLocal();
        final boolean reverse = actualNormal.dot(getNormal()) < 0;
        final double lowestWallZ = Math.min(wallPolygonPoints.get(0).getZ(), wallPolygonPoints.get(3).getZ());
        double low = lowestWallZ;
        double hi = Math.max(wallPolygonPoints.get(0).getZ(), wallPolygonPoints.get(3).getZ());
        for (int i = 4; i < wallPolygonPoints.size(); i++) {
            if (wallPolygonPoints.get(i).getZ() < low) {
                low = wallPolygonPoints.get(i).getZ();
            }
            if (wallPolygonPoints.get(i).getZ() > hi) {
                hi = wallPolygonPoints.get(i).getZ();
            }
        }
        final float lineWidth = original == null ? 1f : 2f;
        final boolean isRectangular = hi - low < 0.1;
        ;
        if (isRectangular) {
            final ReadOnlyVector3 p1 = wallPolygonPoints.get(0).multiply(new Vector3(1, 1, 0), null).addLocal(0, 0, lowestWallZ);
            final ReadOnlyVector3 p2 = wallPolygonPoints.get(1);
            final ReadOnlyVector3 p3 = wallPolygonPoints.get(2);
            final ReadOnlyVector3 p4 = wallPolygonPoints.get(3).multiply(new Vector3(1, 1, 0), null).addLocal(0, 0, lowestWallZ);
            final boolean front = false;
            fetchSizeAnnot(annotCounter++).setRange(p1, p2, getCenter(), faceDirection, front, front ? Align.South : Align.Center, true, reverse, Scene.isDrawAnnotationsInside());
            fetchSizeAnnot(annotCounter++).setRange(p2, p3, getCenter(), faceDirection, original == null, original == null ? Align.South : Align.Center, true, reverse, Scene.isDrawAnnotationsInside());
            fetchSizeAnnot(annotCounter++).setRange(p3, p4, getCenter(), faceDirection, front, front ? Align.South : Align.Center, true, reverse, Scene.isDrawAnnotationsInside());
            fetchSizeAnnot(annotCounter++).setRange(p4, p1, getCenter(), faceDirection, front, front ? Align.South : Align.Center, true, reverse, Scene.isDrawAnnotationsInside());
            for (int i = 0; i < annotCounter; i++) {
                fetchSizeAnnot(i).setLineWidth(lineWidth);
            }
            fetchAngleAnnot(angleAnnotCounter++).setRange(p2, p1, p3, getNormal());
            fetchAngleAnnot(angleAnnotCounter++).setRange(p3, p2, p4, getNormal());
            fetchAngleAnnot(angleAnnotCounter++).setRange(p4, p3, p1, getNormal());
            fetchAngleAnnot(angleAnnotCounter++).setRange(p1, p4, p2, getNormal());
            for (int i = 0; i < annotCounter; i++) {
                fetchAngleAnnot(i).setLineWidth(lineWidth);
            }
        } else {
            for (int i = 0; i < wallPolygonPoints.size(); i++) {
                final boolean front = i == 1 && original == null;
                final ReadOnlyVector3 p1 = wallPolygonPoints.get(i);
                final ReadOnlyVector3 p2 = wallPolygonPoints.get((i + 1) % wallPolygonPoints.size());
                final ReadOnlyVector3 p3 = wallPolygonPoints.get((i + 2) % wallPolygonPoints.size());
                final double minLength = 4.0;
                if (p1.distance(p2) > minLength) {
                    final ReadOnlyVector3 min = new Vector3(Math.min(p1.getX(), Math.min(p2.getX(), p3.getX())), Math.min(p1.getY(), Math.min(p2.getY(), p3.getY())), 0);
                    final ReadOnlyVector3 max = new Vector3(Math.max(p1.getX(), Math.max(p2.getX(), p3.getX())), Math.max(p1.getY(), Math.max(p2.getY(), p3.getY())), 0);
                    final ReadOnlyVector3 center = min.add(max, null).divideLocal(2.0).addLocal(0, 0, getCenter().getZ());
                    final SizeAnnotation sizeAnnot = fetchSizeAnnot(annotCounter++);
                    sizeAnnot.setRange(p1, p2, center, faceDirection, front, front ? Align.South : Align.Center, true, reverse, Scene.isDrawAnnotationsInside());
                    sizeAnnot.setLineWidth(lineWidth);
                }
                if (p1.distance(p2) > minLength && p2.distance(p3) > minLength) {
                    final AngleAnnotation angleAnnot = fetchAngleAnnot(angleAnnotCounter++);
                    angleAnnot.setRange(p2, p1, p3, getNormal());
                    angleAnnot.setLineWidth(lineWidth);
                }
            }
        }
    }
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) AngleAnnotation(org.concord.energy3d.shapes.AngleAnnotation) SizeAnnotation(org.concord.energy3d.shapes.SizeAnnotation) CullHint(com.ardor3d.scenegraph.hint.CullHint) PolygonPoint(org.poly2tri.geometry.polygon.PolygonPoint) ArdorVector3Point(org.poly2tri.triangulation.point.ardor3d.ArdorVector3Point) PickingHint(com.ardor3d.scenegraph.hint.PickingHint) TPoint(org.poly2tri.triangulation.point.TPoint) Point(org.poly2tri.geometry.primitives.Point)

Example 5 with AngleAnnotation

use of org.concord.energy3d.shapes.AngleAnnotation in project energy3d by concord-consortium.

the class Roof method drawAnnotations.

@Override
public void drawAnnotations() {
    if (container == null) {
        return;
    }
    for (final Spatial roofPart : roofPartsRoot.getChildren()) {
        if (roofPart.getSceneHints().getCullHint() != CullHint.Always) {
            int annotCounter = 0, angleAnnotCounter = 0;
            final Node roofPartNode = (Node) roofPart;
            final FloatBuffer buf = ((Mesh) roofPartNode.getChild(0)).getMeshData().getVertexBuffer();
            final ArrayList<ReadOnlyVector3> convexHull = MeshLib.computeOutline(buf);
            final ReadOnlyVector3 normal = (ReadOnlyVector3) roofPart.getUserData();
            final int n = convexHull.size();
            for (int i = 0; i < n; i++) {
                final ReadOnlyVector3 p1 = convexHull.get(i);
                final ReadOnlyVector3 p2 = convexHull.get((i + 1) % n);
                final ReadOnlyVector3 p3 = convexHull.get((i + 2) % n);
                // Size annotation
                final ReadOnlyVector3 center = p1.add(p2, null).addLocal(p3).multiplyLocal(1.0 / 3.0);
                final SizeAnnotation sizeAnnot = fetchSizeAnnot(annotCounter++, (Node) roofPartNode.getChild(1));
                final boolean drawAnnotationsInside = Scene.isDrawAnnotationsInside();
                sizeAnnot.setRange(p2, p3, center, normal, false, Align.Center, true, true, drawAnnotationsInside);
                sizeAnnot.setLineWidth(original == null ? 1f : 2f);
                if (drawAnnotationsInside) {
                    sizeAnnot.setColor(ColorRGBA.WHITE);
                } else {
                    sizeAnnot.setColor(ColorRGBA.BLACK);
                }
                // Angle annotations
                final AngleAnnotation angleAnnot = fetchAngleAnnot(angleAnnotCounter++, (Node) roofPartNode.getChild(2));
                angleAnnot.setLineWidth(original == null ? 1f : 2f);
                angleAnnot.setRange(p2, p1, p3, normal);
            }
        }
    }
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Spatial(com.ardor3d.scenegraph.Spatial) Node(com.ardor3d.scenegraph.Node) FloatBuffer(java.nio.FloatBuffer) AngleAnnotation(org.concord.energy3d.shapes.AngleAnnotation) SizeAnnotation(org.concord.energy3d.shapes.SizeAnnotation) CullHint(com.ardor3d.scenegraph.hint.CullHint) TPoint(org.poly2tri.triangulation.point.TPoint) TriangulationPoint(org.poly2tri.triangulation.TriangulationPoint) PolygonPoint(org.poly2tri.geometry.polygon.PolygonPoint)

Aggregations

AngleAnnotation (org.concord.energy3d.shapes.AngleAnnotation)5 Node (com.ardor3d.scenegraph.Node)3 BoundingBox (com.ardor3d.bounding.BoundingBox)2 OrientedBoundingBox (com.ardor3d.bounding.OrientedBoundingBox)2 ColorRGBA (com.ardor3d.math.ColorRGBA)2 ReadOnlyVector3 (com.ardor3d.math.type.ReadOnlyVector3)2 OffsetState (com.ardor3d.renderer.state.OffsetState)2 Line (com.ardor3d.scenegraph.Line)2 Mesh (com.ardor3d.scenegraph.Mesh)2 CullHint (com.ardor3d.scenegraph.hint.CullHint)2 Box (com.ardor3d.scenegraph.shape.Box)2 BMText (com.ardor3d.ui.text.BMText)2 SizeAnnotation (org.concord.energy3d.shapes.SizeAnnotation)2 PvModuleSpecs (org.concord.energy3d.simulation.PvModuleSpecs)2 PolygonPoint (org.poly2tri.geometry.polygon.PolygonPoint)2 TPoint (org.poly2tri.triangulation.point.TPoint)2 Vector3 (com.ardor3d.math.Vector3)1 ReadOnlyColorRGBA (com.ardor3d.math.type.ReadOnlyColorRGBA)1 Spatial (com.ardor3d.scenegraph.Spatial)1 PickingHint (com.ardor3d.scenegraph.hint.PickingHint)1