Search in sources :

Example 16 with Matrix3

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

the class Wall method flatten.

@Override
public void flatten(final double flattenTime) {
    final ReadOnlyVector3 n = getNormal();
    double angle = n.smallestAngleBetween(Vector3.NEG_UNIT_Y);
    if (n.dot(Vector3.UNIT_X) < 0) {
        angle = -angle;
    }
    root.setRotation((new Matrix3().fromAngles(0, 0, -flattenTime * angle)));
    super.flatten(flattenTime);
    for (final HousePart part : children) {
        if (!part.isPrintable()) {
            part.getRoot().setTransform(root.getTransform());
            part.getRoot().updateGeometricState(0);
        }
    }
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Matrix3(com.ardor3d.math.Matrix3)

Example 17 with Matrix3

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

the class CameraControl method getCurrentExtent.

// the extent that depends on the camera orientation (not a perfect solution)
private static double getCurrentExtent() {
    double extent = 10;
    final BoundingVolume volume = Scene.getRoot().getWorldBound();
    if (volume instanceof BoundingBox) {
        final BoundingBox box = (BoundingBox) volume;
        final ReadOnlyVector3 cameraDirection = SceneManager.getInstance().getCamera().getDirection();
        final Vector3 e1 = box.getExtent(null);
        final double extent1 = Math.abs(e1.cross(cameraDirection, null).length());
        final Vector3 e2 = new Matrix3().applyRotationZ(Math.PI / 2).applyPost(e1, null);
        final double extent2 = Math.abs(e2.cross(cameraDirection, null).length());
        extent = 0.45 * (extent1 + extent2);
    }
    return extent;
}
Also used : ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) BoundingBox(com.ardor3d.bounding.BoundingBox) BoundingVolume(com.ardor3d.bounding.BoundingVolume) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) Matrix3(com.ardor3d.math.Matrix3)

Example 18 with Matrix3

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

the class ParabolicDish method drawMesh.

@Override
protected void drawMesh() {
    if (container == null) {
        return;
    }
    getEditPointShape(0).setDefaultColor(ColorRGBA.ORANGE);
    normal = Heliodon.getInstance().computeSunLocation(Heliodon.getInstance().getCalendar()).normalizeLocal();
    if (Util.isEqual(normal, Vector3.UNIT_Z)) {
        normal = new Vector3(-0.001, 0, 1).normalizeLocal();
    }
    final double annotationScale = Scene.getInstance().getAnnotationScale();
    dish.setRimRadius(rimRadius / annotationScale);
    dish.updateModelBound();
    baseZ = container instanceof Foundation ? container.getHeight() : container.getPoints().get(0).getZ();
    points.get(0).setZ(baseZ + baseHeight);
    final FloatBuffer vertexBuffer = mesh.getMeshData().getVertexBuffer();
    FloatBuffer outlineBuffer = outlines.getMeshData().getVertexBuffer();
    final int vertexCount = vertexBuffer.limit() / 3;
    final Vector3 center = getAbsPoint(0);
    final int rSamples = dish.getRSamples() + 1;
    final int zSamples = dish.getZSamples() - 1;
    final int outlineBufferSize = 6 * (rSamples * 3 + zSamples * nrib);
    if (outlineBuffer.capacity() < outlineBufferSize) {
        outlineBuffer = BufferUtils.createFloatBuffer(outlineBufferSize);
        outlines.getMeshData().setVertexBuffer(outlineBuffer);
    } else {
        outlineBuffer.rewind();
        outlineBuffer.limit(outlineBufferSize);
    }
    // draw the rim line
    int i3;
    for (int i = vertexCount - rSamples * 2; i < vertexCount - 1 - rSamples; i++) {
        i3 = i * 3;
        outlineBuffer.put(vertexBuffer.get(i3)).put(vertexBuffer.get(i3 + 1)).put(vertexBuffer.get(i3 + 2));
        outlineBuffer.put(vertexBuffer.get(i3 + 3)).put(vertexBuffer.get(i3 + 4)).put(vertexBuffer.get(i3 + 5));
    }
    for (int i = (vertexCount - rSamples * 3) / 4; i < (vertexCount + rSamples) / 4; i++) {
        i3 = i * 3;
        outlineBuffer.put(vertexBuffer.get(i3)).put(vertexBuffer.get(i3 + 1)).put(vertexBuffer.get(i3 + 2) + zOffset);
        outlineBuffer.put(vertexBuffer.get(i3 + 3)).put(vertexBuffer.get(i3 + 4)).put(vertexBuffer.get(i3 + 5) + zOffset);
    }
    // draw the rib lines
    double xi, yi, zi, angle;
    final double delta = dish.getRimRadius() * 2.0 / (zSamples + 1);
    double cos, sin;
    for (int i = 0; i < zSamples; i++) {
        for (int j = 0; j < nrib; j++) {
            angle = Math.PI / nrib * j;
            cos = Math.cos(angle);
            sin = Math.sin(angle);
            xi = cos * (dish.getRimRadius() - delta * (i + 0.5));
            yi = sin * (dish.getRimRadius() - delta * (i + 0.5));
            zi = (xi * xi + yi * yi) / (dish.getCurvatureParameter() * dish.getCurvatureParameter());
            outlineBuffer.put((float) xi).put((float) yi).put((float) zi + zOffset);
            xi -= cos * delta;
            yi -= sin * delta;
            zi = (xi * xi + yi * yi) / (dish.getCurvatureParameter() * dish.getCurvatureParameter());
            outlineBuffer.put((float) xi).put((float) yi).put((float) zi + zOffset);
        }
    }
    final Matrix3 rotation = new Matrix3().lookAt(normal, Vector3.UNIT_Y);
    mesh.setRotation(rotation);
    mesh.setTranslation(center);
    mesh.updateModelBound();
    dishBack.setRotation(rotation);
    dishBack.setTranslation(mesh.getTranslation());
    outlines.setRotation(rotation);
    outlines.setTranslation(mesh.getTranslation());
    outlines.updateModelBound();
    // slightly shorter so that the pole won't penetrate the surface of the dish
    post.setHeight(baseHeight - 0.5 * post.getRadius());
    final Vector3 p = center.clone();
    p.setZ(baseZ + post.getHeight() / 2);
    post.setTranslation(p);
    final double flScaled = focalLength / annotationScale;
    receiver.setRotation(rotation);
    receiver.setTranslation(center.clone().addLocal(normal.multiply(flScaled, null)));
    switch(structureType) {
        case STRUCTURE_CENTRAL_POLE:
            duct.setHeight(flScaled + receiver.getHeight());
            duct.setRotation(rotation);
            duct.setTranslation(center.clone().addLocal(normal.multiply(flScaled * 0.5, null)));
            break;
        case STRUCTURE_TRIPOD:
            final Vector3 vi = new Vector3();
            final Vector3 v0 = new Vector3(0, 0, flScaled);
            for (int i = 0; i < 3; i++) {
                angle = 2 * Math.PI / 3 * i;
                xi = dish.getRimRadius() * 0.98 * Math.cos(angle);
                yi = dish.getRimRadius() * 0.98 * Math.sin(angle);
                zi = (xi * xi + yi * yi) / (dish.getCurvatureParameter() * dish.getCurvatureParameter());
                vi.set(xi, yi, zi);
                tripod[i].setHeight(vi.distance(v0));
                final Vector3 ui = rotation.applyPost(vi, null);
                final Vector3 u0 = rotation.applyPost(v0, null);
                tripod[i].setTranslation(center.add(ui.addLocal(u0).multiplyLocal(0.5), null));
                tripod[i].setRotation(rotation.multiply(new Matrix3().fromStartEndLocal(Vector3.UNIT_Z, vi.subtract(v0, null).normalizeLocal()), null));
            }
            duct.setHeight(receiver.getHeight());
            duct.setRotation(mesh.getRotation());
            duct.setTranslation(center.clone().subtractLocal(normal.multiply(duct.getHeight() * 0.5, null)));
            break;
    }
    if (bloomRenderPassReceiver == null) {
        bloomRenderPassReceiver = new BloomRenderPass(SceneManager.getInstance().getCamera(), 10);
        bloomRenderPassReceiver.setBlurIntensityMultiplier(0.5f);
        // bloomRenderPassTube.setNrBlurPasses(2);
        SceneManager.getInstance().getPassManager().add(bloomRenderPassReceiver);
    }
    if (!bloomRenderPassReceiver.contains(receiver)) {
        bloomRenderPassReceiver.add(receiver);
    }
    if (beamsVisible) {
        drawSunBeam();
    }
    updateLabel();
    CollisionTreeManager.INSTANCE.removeCollisionTree(mesh);
    root.updateGeometricState(0);
}
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 19 with Matrix3

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

the class ParabolicTrough method drawMesh.

@Override
protected void drawMesh() {
    if (container == null) {
        return;
    }
    getEditPointShape(0).setDefaultColor(ColorRGBA.ORANGE);
    final double az = Math.toRadians(relativeAzimuth);
    final double annotationScale = Scene.getInstance().getAnnotationScale();
    reflector.setSize(apertureWidth / annotationScale, troughLength / annotationScale);
    reflector.setSemilatusRectum(semilatusRectum / annotationScale);
    reflector.updateModelBound();
    baseZ = container instanceof Foundation ? container.getHeight() : container.getPoints().get(0).getZ();
    points.get(0).setZ(baseZ + baseHeight);
    absorber.setHeight(reflector.getHeight());
    absorberEnd1.setHeight(0.5 * reflector.getSemilatusRectum());
    absorberEnd2.setHeight(absorberEnd1.getHeight());
    if (detailed) {
        absorberCore.setHeight(reflector.getHeight() - 1);
        absorberEnd1Core.setHeight(absorberEnd1.getHeight() - 1);
        absorberEnd2Core.setHeight(absorberEnd2.getHeight() - 1);
    }
    final FloatBuffer vertexBuffer = mesh.getMeshData().getVertexBuffer();
    FloatBuffer outlineBuffer = outlines.getMeshData().getVertexBuffer();
    FloatBuffer steelFrameBuffer = steelFrame.getMeshData().getVertexBuffer();
    final int vertexCount = vertexBuffer.limit() / 6;
    // number of vertex coordinates on each end
    final int j = vertexCount * 3;
    // start index of middle point on end 1
    final int j1 = (j - 3) / 2;
    // start index of middle point on end 2
    final int j2 = j + j1;
    // middle point on end 1
    final Vector3 p1 = new Vector3(vertexBuffer.get(j1), vertexBuffer.get(j1 + 1), vertexBuffer.get(j1 + 2));
    // middle point on end 2
    final Vector3 p2 = new Vector3(vertexBuffer.get(j2), vertexBuffer.get(j2 + 1), vertexBuffer.get(j2 + 2));
    // normal in the direction of cylinder axis
    final Vector3 pd = p2.subtract(p1, null).normalizeLocal();
    final double halfLength = troughLength * 0.5;
    final Vector3 center = getAbsPoint(0);
    final int nModules = Math.max(1, getNumberOfModules());
    // 12 is for the two lateral lines
    final int outlineBufferSize = 6 * (vertexCount - 1) * (nModules + 2) + 12;
    if (outlineBuffer.capacity() < outlineBufferSize) {
        outlineBuffer = BufferUtils.createFloatBuffer(outlineBufferSize);
        outlines.getMeshData().setVertexBuffer(outlineBuffer);
    } else {
        outlineBuffer.rewind();
        outlineBuffer.limit(outlineBufferSize);
    }
    // draw parabolic lines of the two end faces
    int i3;
    for (int i = 0; i < vertexCount - 1; i++) {
        i3 = i * 3;
        outlineBuffer.put(vertexBuffer.get(i3)).put(vertexBuffer.get(i3 + 1)).put(vertexBuffer.get(i3 + 2));
        outlineBuffer.put(vertexBuffer.get(i3 + 3)).put(vertexBuffer.get(i3 + 4)).put(vertexBuffer.get(i3 + 5));
        outlineBuffer.put(vertexBuffer.get(j + i3)).put(vertexBuffer.get(j + i3 + 1)).put(vertexBuffer.get(j + i3 + 2));
        outlineBuffer.put(vertexBuffer.get(j + i3 + 3)).put(vertexBuffer.get(j + i3 + 4)).put(vertexBuffer.get(j + i3 + 5));
    }
    // draw lateral lines connecting the two end faces
    outlineBuffer.put(vertexBuffer.get(0)).put(vertexBuffer.get(1)).put(vertexBuffer.get(2));
    outlineBuffer.put(vertexBuffer.get(j)).put(vertexBuffer.get(j + 1)).put(vertexBuffer.get(j + 2));
    outlineBuffer.put(vertexBuffer.get(j - 3)).put(vertexBuffer.get(j - 2)).put(vertexBuffer.get(j - 1));
    outlineBuffer.put(vertexBuffer.get(2 * j - 3)).put(vertexBuffer.get(2 * j - 2)).put(vertexBuffer.get(2 * j - 1));
    // draw seam lines between units
    if (nModules > 1) {
        // if there is only one module, don't draw
        for (int k = 1; k < nModules; k++) {
            final double ua = k * moduleLength / annotationScale;
            for (int i = 0; i < vertexCount - 1; i++) {
                i3 = i * 3;
                final Vector3 v1 = new Vector3(vertexBuffer.get(i3), vertexBuffer.get(i3 + 1), vertexBuffer.get(i3 + 2));
                final Vector3 v2 = new Vector3(vertexBuffer.get(i3 + 3), vertexBuffer.get(i3 + 4), vertexBuffer.get(i3 + 5));
                v1.addLocal(0, ua, 0);
                v2.addLocal(0, ua, 0);
                outlineBuffer.put(v1.getXf()).put(v1.getYf()).put(v1.getZf());
                outlineBuffer.put(v2.getXf()).put(v2.getYf()).put(v2.getZf());
            }
        }
    }
    outlineBuffer.limit(vertexCount * 12 + (vertexCount - 1) * 6 * (nModules - 1));
    // draw steel frame lines
    final int steelBufferSize = nModules * 6;
    if (steelFrameBuffer.capacity() < steelBufferSize) {
        steelFrameBuffer = BufferUtils.createFloatBuffer(steelBufferSize);
        steelFrame.getMeshData().setVertexBuffer(steelFrameBuffer);
    } else {
        steelFrameBuffer.rewind();
        steelFrameBuffer.limit(steelBufferSize);
    }
    modulesRoot.detachAllChildren();
    if (nModules > 1) {
        final Vector3 qd = new Matrix3().applyRotationZ(-az).applyPost(pd, null);
        for (double u = moduleLength; u < troughLength; u += moduleLength) {
            final double step = (u - halfLength) / annotationScale;
            final Vector3 p = pd.multiply(step, null);
            steelFrameBuffer.put(p.getXf()).put(p.getYf()).put(p.getZf());
            steelFrameBuffer.put(p.getXf()).put(p.getYf()).put((float) (p.getZ() + 0.5 * reflector.getSemilatusRectum()));
            final Vector3 q = qd.multiply(step, null);
            addPole(q.addLocal(center), baseHeight, baseZ);
        }
        steelFrameBuffer.limit((nModules - 1) * 6);
        steelFrame.getSceneHints().setCullHint(CullHint.Inherit);
    } else {
        addPole(center, baseHeight, baseZ);
        // if there is only one module, don't draw frames
        steelFrame.getSceneHints().setCullHint(CullHint.Always);
    }
    modulesRoot.getSceneHints().setCullHint(CullHint.Inherit);
    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 axis of the trough
    rotationAxis.multiplyLocal(Util.isZero(axisSunDot) ? 0.001 : axisSunDot);
    normal = sunDirection.subtractLocal(rotationAxis).normalizeLocal();
    if (Util.isEqual(normal, Vector3.UNIT_Z)) {
        normal = new Vector3(-0.001, 0, 1).normalizeLocal();
    }
    final Matrix3 rotation = new Matrix3().lookAt(normal, rotationAxis);
    mesh.setRotation(rotation);
    mesh.setTranslation(center);
    reflectorBack.setRotation(rotation);
    reflectorBack.setTranslation(mesh.getTranslation());
    outlines.setRotation(rotation);
    outlines.setTranslation(mesh.getTranslation());
    final Vector3 axis = rotationAxis.cross(Vector3.UNIT_Z, null);
    absorber.setRotation(new Matrix3().fromAngleAxis(Math.acos(rotationAxis.dot(Vector3.UNIT_Z)), axis));
    absorber.setTranslation(mesh.getTranslation().add(normal.multiply(0.5 * reflector.getSemilatusRectum(), null), null));
    final Vector3 endShift = normal.multiply(0.5 * absorberEnd1.getHeight(), null);
    absorberEnd1.setTranslation(mesh.getTranslation().add(rotation.applyPost(p1, null).add(endShift, null), null));
    absorberEnd2.setTranslation(mesh.getTranslation().add(rotation.applyPost(p2, null).add(endShift, null), null));
    absorberEnd1.setRotation(rotation);
    absorberEnd2.setRotation(rotation);
    steelFrame.setRotation(rotation);
    steelFrame.setTranslation(mesh.getTranslation());
    if (detailed) {
        absorberCore.setRotation(absorber.getRotation());
        absorberCore.setTranslation(absorber.getTranslation());
        absorberEnd1Core.setTranslation(absorberEnd1.getTranslation());
        absorberEnd2Core.setTranslation(absorberEnd2.getTranslation());
        absorberEnd1Core.setRotation(rotation);
        absorberEnd2Core.setRotation(rotation);
    }
    mesh.updateModelBound();
    outlines.updateModelBound();
    steelFrame.updateModelBound();
    absorber.updateModelBound();
    absorberEnd1.updateModelBound();
    absorberEnd2.updateModelBound();
    if (bloomRenderPassTube == null) {
        bloomRenderPassTube = new BloomRenderPass(SceneManager.getInstance().getCamera(), 10);
        bloomRenderPassTube.setBlurIntensityMultiplier(0.75f);
        // bloomRenderPassTube.setNrBlurPasses(2);
        SceneManager.getInstance().getPassManager().add(bloomRenderPassTube);
    }
    if (!bloomRenderPassTube.contains(absorber)) {
        bloomRenderPassTube.add(absorber);
    }
    if (beamsVisible) {
        drawSunBeam();
    }
    updateLabel();
    CollisionTreeManager.INSTANCE.removeCollisionTree(mesh);
    root.updateGeometricState(0);
}
Also used : FloatBuffer(java.nio.FloatBuffer) ReadOnlyVector3(com.ardor3d.math.type.ReadOnlyVector3) Vector3(com.ardor3d.math.Vector3) CullHint(com.ardor3d.scenegraph.hint.CullHint) Matrix3(com.ardor3d.math.Matrix3) BloomRenderPass(com.ardor3d.extension.effect.bloom.BloomRenderPass)

Example 20 with Matrix3

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

the class SolarPanel method setNormal.

// ensure that a solar panel 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