use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class Roof method stretchToRoof.
private void stretchToRoof(final ArrayList<ReadOnlyVector3> result, final Mesh roof, final ReadOnlyVector3 p1, final ReadOnlyVector3 p2, final double z) {
final Vector3 dir = p2.subtract(p1, null).multiplyLocal(1, 1, 0);
final double length = dir.length();
dir.normalizeLocal();
Vector3 direction = null;
ReadOnlyVector3 previousStretchPoint = null;
boolean firstInsert = false;
final boolean isSingleMesh = isSingleFlatMesh();
final double minDistance = STRETCH_ROOF_STEP * 3;
final Vector3 p = new Vector3();
for (double d = STRETCH_ROOF_STEP; d < length; d += STRETCH_ROOF_STEP) {
dir.multiply(d, p).addLocal(p1);
final ReadOnlyVector3 currentStretchPoint;
if (isSingleMesh) {
p.setZ(z);
currentStretchPoint = p.clone();
} else {
currentStretchPoint = findRoofIntersection(roof, p);
}
if (currentStretchPoint != null && !firstInsert) {
result.add(currentStretchPoint);
firstInsert = true;
} else if (currentStretchPoint == null) {
if (previousStretchPoint != null) {
result.add(previousStretchPoint);
}
direction = null;
firstInsert = false;
} else {
final Vector3 currentDirection = currentStretchPoint.subtract(previousStretchPoint, null).normalizeLocal();
if (direction == null) {
direction = currentDirection;
} else if (direction.dot(currentDirection) < 1.0 - MathUtils.ZERO_TOLERANCE) {
result.add(currentStretchPoint);
result.add(currentStretchPoint);
direction = null;
}
}
previousStretchPoint = currentStretchPoint;
}
if (previousStretchPoint != null) {
if (previousStretchPoint.distance(result.get(result.size() - 1)) > minDistance) {
result.add(previousStretchPoint);
} else {
result.remove(result.size() - 1);
}
}
}
use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class Roof method drawDashLines.
private void drawDashLines() {
if (container == null) {
return;
}
if (lockEdit) {
for (final Spatial roofPart : roofPartsRoot.getChildren()) {
if (roofPart.getSceneHints().getCullHint() != CullHint.Always) {
final Node roofPartNode = (Node) roofPart;
final Mesh dashLinesMesh = (Mesh) roofPartNode.getChild(5);
dashLinesMesh.setVisible(false);
}
}
} else {
for (final Spatial roofPart : roofPartsRoot.getChildren()) {
if (roofPart.getSceneHints().getCullHint() != CullHint.Always) {
final Node roofPartNode = (Node) roofPart;
final Mesh roofPartMesh = (Mesh) roofPartNode.getChild(0);
final Mesh dashLinesMesh = (Mesh) roofPartNode.getChild(5);
final List<ReadOnlyVector3> result = computeDashPoints(roofPartMesh);
if (result.isEmpty()) {
dashLinesMesh.setVisible(false);
} else {
dashLinesMesh.setVisible(true);
FloatBuffer vertexBuffer = dashLinesMesh.getMeshData().getVertexBuffer();
if (vertexBuffer == null || vertexBuffer.capacity() < result.size() * 3) {
vertexBuffer = BufferUtils.createVector3Buffer(result.size());
dashLinesMesh.getMeshData().setVertexBuffer(vertexBuffer);
}
vertexBuffer.limit(result.size() * 3);
vertexBuffer.rewind();
for (final ReadOnlyVector3 p : result) {
vertexBuffer.put(p.getXf()).put(p.getYf()).put(p.getZf());
}
dashLinesMesh.getMeshData().updateVertexCount();
dashLinesMesh.updateModelBound();
}
}
}
}
updateDashLinesColor();
}
use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class Roof method computeDashPoints.
public List<ReadOnlyVector3> computeDashPoints(final Mesh roofPartMesh) {
if (dashPointsCache.get(roofPartMesh) == null) {
final ArrayList<ReadOnlyVector3> resultBeforeBreak = new ArrayList<ReadOnlyVector3>();
final ArrayList<ReadOnlyVector3> resultAfterBreak = new ArrayList<ReadOnlyVector3>();
final boolean[] foundBreak = { false };
((Wall) container).visitNeighbors(new WallVisitor() {
@Override
public void visit(final Wall currentWall, final Snap prevSnap, final Snap nextSnap) {
final int indexP1, indexP2;
if (nextSnap != null) {
indexP2 = nextSnap.getSnapPointIndexOf(currentWall);
indexP1 = indexP2 == 2 ? 0 : 2;
} else if (prevSnap != null) {
indexP1 = prevSnap.getSnapPointIndexOf(currentWall);
indexP2 = indexP1 == 2 ? 0 : 2;
} else {
indexP1 = 0;
indexP2 = 2;
}
final ArrayList<ReadOnlyVector3> array = foundBreak[0] ? resultAfterBreak : resultBeforeBreak;
final int orgSize = array.size();
stretchToRoof(array, roofPartMesh, currentWall.getAbsPoint(indexP1), currentWall.getAbsPoint(indexP2), currentWall.points.get(1).getZ());
if (!foundBreak[0] && array.size() == orgSize) {
foundBreak[0] = true;
}
}
});
if (foundBreak[0]) {
resultAfterBreak.addAll(resultBeforeBreak);
dashPointsCache.put(roofPartMesh, resultAfterBreak);
} else {
dashPointsCache.put(roofPartMesh, resultBeforeBreak);
}
}
return dashPointsCache.get(roofPartMesh);
}
use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class Roof method ensureEditPointsInside.
private void ensureEditPointsInside() {
for (int i = 1; i < points.size(); i++) {
final Vector3 editPoint = getAbsPoint(i);
final Vector2 p = new Vector2(editPoint.getX(), editPoint.getY());
if (!insideWallsPolygon(editPoint)) {
double closestDistance = Double.MAX_VALUE;
int closestIndex = 0;
for (int j = 0; j < wallUpperPoints.size(); j++) {
final Vector2 l1 = new Vector2(wallUpperPoints.get(j).getX(), wallUpperPoints.get(j).getY());
final Vector2 l2 = new Vector2(wallUpperPoints.get((j + 1) % wallUpperPoints.size()).getX(), wallUpperPoints.get((j + 1) % wallUpperPoints.size()).getY());
final double distance = p.distance(l1) + p.distance(l2);
if (distance < closestDistance) {
closestDistance = distance;
closestIndex = j;
}
}
final List<ReadOnlyVector3> wallPoints = new ArrayList<ReadOnlyVector3>(2);
wallPoints.add(wallUpperPoints.get(closestIndex));
wallPoints.add(wallUpperPoints.get((closestIndex + 1) % wallUpperPoints.size()));
final ReadOnlyVector2 p2D = Util.snapToPolygon(editPoint, wallPoints, null);
editPoint.setX(p2D.getX());
editPoint.setY(p2D.getY());
if (closestIndex < walls.size()) {
editPoint.subtractLocal(walls.get(closestIndex).getNormal().multiply(0.01, null));
}
points.get(i).set(toRelative(editPoint));
}
}
}
use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class Roof method computeArea.
@Override
protected void computeArea() {
this.area = 0;
if (container == null) {
return;
}
if (areaByPartWithOverhang == null) {
areaByPartWithOverhang = new HashMap<Mesh, Double>();
} else {
areaByPartWithOverhang.clear();
}
if (areaByPartWithoutOverhang == null) {
areaByPartWithoutOverhang = new HashMap<Mesh, Double>();
} else {
areaByPartWithoutOverhang.clear();
}
for (final Spatial roofPart : roofPartsRoot.getChildren()) {
if (roofPart.getSceneHints().getCullHint() != CullHint.Always) {
final Node roofPartNode = (Node) roofPart;
final Mesh roofPartMesh = (Mesh) roofPartNode.getChild(REAL_MESH_INDEX);
areaByPartWithOverhang.put(roofPartMesh, Util.computeArea(roofPartMesh));
final FloatBuffer vertexBuffer = roofPartMesh.getMeshData().getVertexBuffer();
final Vector3 p = new Vector3();
if (overhangLength <= OVERHANG_MIN) {
final double a = Util.computeArea(roofPartMesh);
areaByPartWithoutOverhang.put(roofPartMesh, a);
area += a;
} else {
final List<ReadOnlyVector3> result = computeDashPoints(roofPartMesh);
if (result.isEmpty()) {
vertexBuffer.rewind();
p.set(vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get());
final double a;
if (Util.insidePolygon(p, wallUpperPointsWithoutOverhang)) {
a = Util.computeArea(roofPartMesh);
} else {
a = 0;
}
areaByPartWithoutOverhang.put(roofPartMesh, a);
area += a;
} else {
// if (roofPartsRoot.getNumberOfChildren() > 1) {
double highPointZ = Double.NEGATIVE_INFINITY;
vertexBuffer.rewind();
while (vertexBuffer.hasRemaining()) {
p.set(vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get());
if (p.getZ() > highPointZ) {
highPointZ = p.getZ();
}
}
final List<ReadOnlyVector3> highPoints = new ArrayList<ReadOnlyVector3>();
vertexBuffer.rewind();
while (vertexBuffer.hasRemaining()) {
p.set(vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get());
if (p.getZ() >= highPointZ - MathUtils.ZERO_TOLERANCE && Util.insidePolygon(p, wallUpperPointsWithoutOverhang)) {
highPoints.add(new Vector3(p));
}
}
if (highPoints.size() == 1) {
result.add(highPoints.get(0));
} else {
final ReadOnlyVector3 lastPoint = result.get(result.size() - 1);
while (!highPoints.isEmpty()) {
double shortestDistance = Double.MAX_VALUE;
ReadOnlyVector3 nearestPoint = null;
for (final ReadOnlyVector3 hp : highPoints) {
final double distance = hp.distance(lastPoint);
if (distance < shortestDistance) {
shortestDistance = distance;
nearestPoint = hp;
}
}
result.add(nearestPoint);
highPoints.remove(nearestPoint);
}
}
result.add(result.get(0));
final double annotationScale = Scene.getInstance().getAnnotationScale();
final double a = Util.area3D_Polygon(result, (ReadOnlyVector3) roofPart.getUserData()) * annotationScale * annotationScale;
areaByPartWithoutOverhang.put(roofPartMesh, a);
this.area += a;
}
}
}
}
}
Aggregations