Search in sources :

Example 31 with Matrix3

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

the class SolarPanel method drawMesh.

@Override
protected void drawMesh() {
    if (container == null) {
        return;
    }
    final double az = Math.toRadians(relativeAzimuth);
    final boolean heatMap = SceneManager.getInstance().getSolarHeatMap();
    boolean onFlatSurface = onFlatSurface();
    // if this solar panel rests on an imported mesh or not?
    final Mesh host = meshLocator == null ? null : meshLocator.find();
    if (host == null) {
        normal = pickedNormal != null ? pickedNormal : computeNormalAndKeepOnSurface();
    } else {
        final UserData ud = (UserData) host.getUserData();
        normal = ud.getRotatedNormal() == null ? ud.getNormal() : ud.getRotatedNormal();
        onFlatSurface = Util.isEqual(normal, Vector3.UNIT_Z);
    }
    updateEditShapes();
    final double annotationScaleFactor = 0.5 / Scene.getInstance().getAnnotationScale();
    if (rotated) {
        surround.setData(new Vector3(), panelHeight * annotationScaleFactor, panelWidth * annotationScaleFactor, 0.15);
    } else {
        surround.setData(new Vector3(), panelWidth * annotationScaleFactor, panelHeight * annotationScaleFactor, 0.15);
    }
    surround.updateModelBound();
    final FloatBuffer boxVertexBuffer = surround.getMeshData().getVertexBuffer();
    final FloatBuffer vertexBuffer = mesh.getMeshData().getVertexBuffer();
    final FloatBuffer textureBuffer = mesh.getMeshData().getTextureBuffer(0);
    final FloatBuffer outlineBuffer = outlineMesh.getMeshData().getVertexBuffer();
    vertexBuffer.rewind();
    outlineBuffer.rewind();
    textureBuffer.rewind();
    int i = 8 * 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(1).put(0);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    i += 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(0).put(0);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    i += 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(0).put(1);
    textureBuffer.put(0).put(1);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    i += 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(1).put(1);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    i = 8 * 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(1).put(0);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    mesh.updateModelBound();
    outlineMesh.updateModelBound();
    switch(trackerType) {
        case ALTAZIMUTH_DUAL_AXIS_TRACKER:
            normal = Heliodon.getInstance().computeSunLocation(Heliodon.getInstance().getCalendar()).normalizeLocal();
            break;
        case HORIZONTAL_SINGLE_AXIS_TRACKER:
            final Vector3 sunDirection = Heliodon.getInstance().computeSunLocation(Heliodon.getInstance().getCalendar()).normalizeLocal();
            final Vector3 rotationAxis = new Vector3(Math.sin(az), Math.cos(az), 0);
            final double axisSunDot = sunDirection.dot(rotationAxis);
            // avoid singularity when the direction of the sun is perpendicular to the rotation axis
            rotationAxis.multiplyLocal(Util.isZero(axisSunDot) ? 0.001 : axisSunDot);
            normal = sunDirection.subtractLocal(rotationAxis).normalizeLocal();
            break;
        case VERTICAL_SINGLE_AXIS_TRACKER:
            final Vector3 a = Heliodon.getInstance().computeSunLocation(Heliodon.getInstance().getCalendar()).multiplyLocal(1, 1, 0).normalizeLocal();
            final Vector3 b = Vector3.UNIT_Z.cross(a, null);
            final Matrix3 m = new Matrix3().applyRotation(Math.toRadians(90 - tiltAngle), b.getX(), b.getY(), b.getZ());
            normal = m.applyPost(a, null);
            if (normal.getZ() < 0) {
                normal = normal.negate(null);
            }
            break;
        default:
            if (onFlatSurface) {
                // exactly 90 degrees will cause the solar panel to disappear
                setNormal(Util.isZero(tiltAngle) ? Math.PI / 2 * 0.9999 : Math.toRadians(90 - tiltAngle), Math.toRadians(relativeAzimuth));
            }
    }
    if (Util.isEqual(normal, Vector3.UNIT_Z)) {
        normal = new Vector3(-0.001, 0, 1).normalizeLocal();
    }
    mesh.setRotation(new Matrix3().lookAt(normal, normal.getX() > 0 ? Vector3.UNIT_Z : Vector3.NEG_UNIT_Z));
    mesh.setTranslation(onFlatSurface ? getAbsPoint(0).addLocal(0, 0, baseHeight) : getAbsPoint(0));
    surround.setTranslation(mesh.getTranslation());
    surround.setRotation(mesh.getRotation());
    outlineMesh.setTranslation(mesh.getTranslation());
    outlineMesh.setRotation(mesh.getRotation());
    if (onFlatSurface) {
        supportFrame.getSceneHints().setCullHint(CullHint.Inherit);
        drawSupporFrame();
    } else {
        supportFrame.getSceneHints().setCullHint(CullHint.Always);
    }
    if (drawSunBeam) {
        drawSunBeam();
    }
    if (heatMap) {
        drawSolarCellOutlines();
    } else {
        solarCellOutlines.setVisible(false);
    }
    drawFloatingLabel(onFlatSurface);
}
Also used : Mesh(com.ardor3d.scenegraph.Mesh) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) FloatBuffer(java.nio.FloatBuffer) CullHint(com.ardor3d.scenegraph.hint.CullHint) Matrix3(com.ardor3d.math.Matrix3)

Example 32 with Matrix3

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

the class Rack method drawSunBeam.

@Override
public void drawSunBeam() {
    if (Heliodon.getInstance().isNightTime() || !drawSunBeam) {
        sunBeam.setVisible(false);
        normalVector.setVisible(false);
        sunAngle.setVisible(false);
        return;
    }
    final Vector3 o = getAbsPoint(0);
    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(10000, 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 33 with Matrix3

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

the class Mirror method drawSunBeam.

@Override
public void drawSunBeam() {
    if (Heliodon.getInstance().isNightTime() || heliostatTarget == null || !Scene.getInstance().areLightBeamsVisible()) {
        lightBeams.setVisible(false);
        return;
    }
    final Vector3 o = getAbsPoint(0);
    final double length = heliostatTarget.getSolarReceiverCenter().distance(o);
    final Vector3 sunLocation = Heliodon.getInstance().computeSunLocation(Heliodon.getInstance().getCalendar()).normalizeLocal();
    final FloatBuffer beamsVertices = lightBeams.getMeshData().getVertexBuffer();
    beamsVertices.rewind();
    if (drawSunBeam) {
        final Vector3 r = new Vector3(o);
        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());
    }
    final Vector3 s = sunLocation.multiplyLocal(length);
    final Vector3 p = new Matrix3().fromAngleNormalAxis(Math.PI, normal).applyPost(s, null);
    p.addLocal(o);
    beamsVertices.put(o.getXf()).put(o.getYf()).put(o.getZf());
    beamsVertices.put(p.getXf()).put(p.getYf()).put(p.getZf());
    lightBeams.updateModelBound();
    lightBeams.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(lightBeams)) {
        bloomRenderPass.add(lightBeams);
    }
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) FloatBuffer(java.nio.FloatBuffer) Matrix3(com.ardor3d.math.Matrix3) BloomRenderPass(com.ardor3d.extension.effect.bloom.BloomRenderPass)

Example 34 with Matrix3

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

the class Mirror method drawMesh.

@Override
protected void drawMesh() {
    if (container == null) {
        return;
    }
    points.get(0).setZ(getTopContainer().getHeight() + baseHeight);
    final double annotationScale = Scene.getInstance().getAnnotationScale();
    surround.setData(new Vector3(), 0.5 * mirrorWidth / annotationScale, 0.5 * mirrorHeight / annotationScale, 0.15);
    surround.updateModelBound();
    final FloatBuffer boxVertexBuffer = surround.getMeshData().getVertexBuffer();
    final FloatBuffer vertexBuffer = mesh.getMeshData().getVertexBuffer();
    final FloatBuffer textureBuffer = mesh.getMeshData().getTextureBuffer(0);
    final FloatBuffer outlineBuffer = outlineMesh.getMeshData().getVertexBuffer();
    vertexBuffer.rewind();
    outlineBuffer.rewind();
    textureBuffer.rewind();
    int i = 8 * 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(1).put(0);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    i += 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(0).put(0);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    i += 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(0).put(1);
    textureBuffer.put(0).put(1);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    i += 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(1).put(1);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    i = 8 * 3;
    vertexBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    textureBuffer.put(1).put(0);
    outlineBuffer.put(boxVertexBuffer.get(i)).put(boxVertexBuffer.get(i + 1)).put(boxVertexBuffer.get(i + 2));
    mesh.updateModelBound();
    outlineMesh.updateModelBound();
    final Vector3 a = getAbsPoint(0);
    if (heliostatTarget == null) {
        // exactly 90 degrees will cause the mirror to disappear
        setNormal(Util.isZero(tiltAngle) ? Math.PI / 2 * 0.9999 : Math.toRadians(90 - tiltAngle), Math.toRadians(relativeAzimuth));
    } else {
        // TODO: cache this so that we don't have to compute the receiver position for every heliostat
        final ReadOnlyVector3 o = heliostatTarget.getSolarReceiverCenter();
        final Vector3 p = a.clone().subtractLocal(o).negateLocal().normalizeLocal();
        final Vector3 q = Heliodon.getInstance().computeSunLocation(Heliodon.getInstance().getCalendar()).normalizeLocal();
        normal = p.add(q, null).multiplyLocal(0.5).normalizeLocal();
    }
    mesh.setTranslation(a);
    mesh.setRotation(new Matrix3().lookAt(normal, Vector3.UNIT_Z));
    surround.setTranslation(mesh.getTranslation());
    surround.setRotation(mesh.getRotation());
    outlineMesh.setTranslation(mesh.getTranslation());
    outlineMesh.setRotation(mesh.getRotation());
    post.setHeight(baseHeight - 0.5 * post.getRadius());
    post.setTranslation(a.addLocal(0, 0, 0.5 * post.getHeight() - baseHeight));
    drawSunBeam();
    updateLabel();
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) FloatBuffer(java.nio.FloatBuffer) Matrix3(com.ardor3d.math.Matrix3)

Example 35 with Matrix3

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

the class Mirror method setNormal.

// ensure that a mirror in special cases (on a flat roof or at a tilt angle) will have correct orientation
private void setNormal(final double angle, final double azimuth) {
    final Foundation foundation = getTopContainer();
    Vector3 v = foundation.getAbsPoint(0);
    // x direction
    final Vector3 vx = foundation.getAbsPoint(2).subtractLocal(v);
    // y direction
    final Vector3 vy = foundation.getAbsPoint(1).subtractLocal(v);
    final Matrix3 m = new Matrix3().applyRotationZ(-azimuth);
    final Vector3 v1 = m.applyPost(vx, null);
    final Vector3 v2 = m.applyPost(vy, null);
    v = new Matrix3().fromAngleAxis(angle, v1).applyPost(v2, null);
    if (v.getZ() < 0) {
        v.negateLocal();
    }
    normal = v.normalizeLocal();
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) 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