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