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);
}
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);
}
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);
}
}
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();
}
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();
}
Aggregations