use of com.ardor3d.extension.effect.bloom.BloomRenderPass in project energy3d by concord-consortium.
the class Foundation method drawSolarReceiver.
public void drawSolarReceiver() {
if (solarReceiver == null) {
return;
}
int countHeliostats = 0;
for (final HousePart p : Scene.getInstance().getParts()) {
if (p instanceof Mirror) {
final Mirror m = (Mirror) p;
if (m.getReceiver() == this) {
countHeliostats++;
}
}
}
int countFresnelReflectors = 0;
for (final HousePart p : Scene.getInstance().getParts()) {
if (p instanceof FresnelReflector) {
final FresnelReflector r = (FresnelReflector) p;
if (r.getReceiver() == this) {
countFresnelReflectors++;
}
}
}
solarReceiver.setVisible(countHeliostats > 0 || countFresnelReflectors > 0);
if (solarReceiver.isVisible()) {
if (bloomRenderPass == null) {
bloomRenderPass = new BloomRenderPass(SceneManager.getInstance().getCamera(), 10);
// bloomRenderPass.setNrBlurPasses(1);
SceneManager.getInstance().getPassManager().add(bloomRenderPass);
}
if (!bloomRenderPass.contains(solarReceiver)) {
bloomRenderPass.add(solarReceiver);
}
double rx = 0;
double ry = 0;
final Vector3 center = getAbsCenter();
double xmin = center.getX();
double xmax = center.getX();
double ymin = center.getY();
double ymax = center.getY();
double lmax = -1;
int count = 0;
for (final HousePart p : children) {
if (p instanceof Wall) {
final Wall wall = (Wall) p;
final Vector3 c = p.getAbsCenter();
rx += c.getX();
ry += c.getY();
if (xmin > c.getX()) {
xmin = c.getX();
} else if (xmax < c.getX()) {
xmax = c.getX();
}
if (ymin > c.getY()) {
ymin = c.getY();
} else if (ymax < c.getY()) {
ymax = c.getY();
}
count++;
final double wallLength = wall.getAbsPoint(0).distance(wall.getAbsPoint(2));
if (wallLength > lmax) {
lmax = wallLength;
}
}
}
if (countHeliostats > 0) {
bloomRenderPass.setBlurIntensityMultiplier(Math.min(0.01f * countHeliostats, 0.8f));
solarReceiver.setHeight(getSolarReceiverHeight(0.1) * 0.15);
Vector3 o;
if (count == 0) {
o = getAbsCenter();
o.setZ(getSolarReceiverHeight(0.1) - solarReceiver.getHeight() * 0.5);
solarReceiver.setRadius(10);
} else {
o = new Vector3(rx / count, ry / count, getSolarReceiverHeight(0.1) - solarReceiver.getHeight() * 0.5);
final double r1 = Math.max((xmax - xmin), (ymax - ymin)) / 2;
final double r2 = Math.max(r1 * 0.4, 4);
solarReceiver.setRadius(r1 + r2);
}
solarReceiver.setTranslation(o);
} else if (countFresnelReflectors > 0) {
bloomRenderPass.setBlurIntensityMultiplier(Math.min(0.1f * countFresnelReflectors, 0.8f));
solarReceiver.setRadius(1);
solarReceiver.setHeight(lmax);
final double az = getAzimuth();
final Matrix3 rotateAroundZ = new Matrix3().applyRotationZ(Math.toRadians(-az));
final Matrix3 rotateAroundX = new Matrix3().applyRotationX(Math.PI * 0.5);
solarReceiver.setRotation(rotateAroundZ.multiplyLocal(rotateAroundX));
final Vector3 o = new Vector3((xmin + xmax) * 0.5, (ymin + ymax) * 0.5, getSolarReceiverHeight(solarReceiver.getRadius() * 1.2));
solarReceiver.setTranslation(o);
}
}
}
use of com.ardor3d.extension.effect.bloom.BloomRenderPass in project energy3d by concord-consortium.
the class ParabolicDish method drawSunBeam.
@Override
public void drawSunBeam() {
if (Heliodon.getInstance().isNightTime() || !beamsVisible) {
lightBeams.setVisible(false);
return;
}
final int nBeams = 6;
FloatBuffer beamsBuffer = lightBeams.getMeshData().getVertexBuffer();
final int beamsBufferSize = (nBeams + 1) * 12;
if (beamsBuffer.capacity() < beamsBufferSize) {
beamsBuffer = BufferUtils.createFloatBuffer(beamsBufferSize);
lightBeams.getMeshData().setVertexBuffer(beamsBuffer);
} else {
beamsBuffer.rewind();
}
final Vector3 sunLocation = Heliodon.getInstance().computeSunLocation(Heliodon.getInstance().getCalendar()).normalizeLocal();
double dx;
double dz;
sunLocation.multiplyLocal(10000);
final Vector3 f = getAbsPoint(0).addLocal(mesh.getRotation().applyPost(new Vector3(0, 0, focalLength / Scene.getInstance().getAnnotationScale()), null));
for (int i = 0; i <= nBeams; i++) {
dx = dish.getRimRadius() * (1 - 2.0 * i / nBeams) * 0.9;
dz = dx / dish.getCurvatureParameter();
dz *= dz;
final Vector3 o = getAbsPoint(0).addLocal(mesh.getRotation().applyPost(new Vector3(dx, 0, dz), null));
// draw line to sun
final Vector3 r = o.clone();
r.addLocal(sunLocation);
beamsBuffer.put(o.getXf()).put(o.getYf()).put(o.getZf() + zOffset);
beamsBuffer.put(r.getXf()).put(r.getYf()).put(r.getZf());
// draw line to focus
beamsBuffer.put(o.getXf()).put(o.getYf()).put(o.getZf() + zOffset);
beamsBuffer.put(f.getXf()).put(f.getYf()).put(f.getZf());
}
lightBeams.updateModelBound();
lightBeams.setVisible(true);
if (bloomRenderPassLight == null) {
bloomRenderPassLight = new BloomRenderPass(SceneManager.getInstance().getCamera(), 10);
bloomRenderPassLight.setBlurIntensityMultiplier(0.5f);
bloomRenderPassLight.setNrBlurPasses(2);
SceneManager.getInstance().getPassManager().add(bloomRenderPassLight);
}
if (!bloomRenderPassLight.contains(lightBeams)) {
bloomRenderPassLight.add(lightBeams);
}
}
use of com.ardor3d.extension.effect.bloom.BloomRenderPass 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);
}
use of com.ardor3d.extension.effect.bloom.BloomRenderPass 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);
}
use of com.ardor3d.extension.effect.bloom.BloomRenderPass in project energy3d by concord-consortium.
the class Heliodon method getBloomRenderPass.
private BloomRenderPass getBloomRenderPass() {
if (bloomRenderPass == null) {
bloomRenderPass = new BloomRenderPass(SceneManager.getInstance().getCamera(), 4);
// bloomRenderPass.setBlurIntensityMultiplier(0.8f);
passManager.add(bloomRenderPass);
}
return bloomRenderPass;
}
Aggregations