use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class MeshLib method applyHoles.
public static void applyHoles(final Node root, final List<Window> windows) {
final Map<Window, List<ReadOnlyVector3>> holes = new HashMap<Window, List<ReadOnlyVector3>>();
for (final Window window : windows) {
final ArrayList<ReadOnlyVector3> hole = new ArrayList<ReadOnlyVector3>();
hole.add(window.getAbsPoint(0).multiplyLocal(1, 1, 0));
hole.add(window.getAbsPoint(2).multiplyLocal(1, 1, 0));
hole.add(window.getAbsPoint(3).multiplyLocal(1, 1, 0));
hole.add(window.getAbsPoint(1).multiplyLocal(1, 1, 0));
holes.put(window, hole);
}
for (int roofIndex = 0; roofIndex < root.getChildren().size(); roofIndex++) {
final Spatial roofPart = root.getChildren().get(roofIndex);
if (roofPart.getSceneHints().getCullHint() != CullHint.Always) {
final ReadOnlyVector3 normal = (ReadOnlyVector3) roofPart.getUserData();
final AnyToXYTransform toXY = new AnyToXYTransform(normal.getX(), normal.getY(), normal.getZ());
final XYToAnyTransform fromXY = new XYToAnyTransform(normal.getX(), normal.getY(), normal.getZ());
final Mesh mesh = (Mesh) ((Node) roofPart).getChild(0);
final ArrayList<ReadOnlyVector3> points3D = computeOutline(mesh.getMeshData().getVertexBuffer());
final List<PolygonPoint> points2D = new ArrayList<PolygonPoint>();
final ReadOnlyVector3 firstPoint = points3D.get(0);
final double scale = Scene.getInstance().getTextureMode() == TextureMode.Simple ? 0.5 : 0.1;
final TPoint o;
final TPoint u;
final TPoint v;
if (normal.dot(Vector3.UNIT_Z) == 1) {
o = new TPoint(firstPoint.getX(), firstPoint.getY(), firstPoint.getZ());
u = new TPoint(1 / scale, 0, 0);
v = new TPoint(0, 1 / scale, 0);
} else {
final ReadOnlyVector3 u3 = Vector3.UNIT_Z.cross(normal, null).normalizeLocal();
final ReadOnlyVector3 ou3 = u3.divide(scale, null).add(firstPoint, null);
final ReadOnlyVector3 ov3 = normal.cross(u3, null).divideLocal(scale).addLocal(firstPoint);
o = new TPoint(firstPoint.getX(), firstPoint.getY(), firstPoint.getZ());
u = new TPoint(ou3.getX(), ou3.getY(), ou3.getZ());
v = new TPoint(ov3.getX(), ov3.getY(), ov3.getZ());
toXY.transform(o);
toXY.transform(u);
toXY.transform(v);
u.set(u.getX() - o.getX(), u.getY() - o.getY(), 0);
v.set(v.getX() - o.getX(), v.getY() - o.getY(), 0);
}
final Vector2 o2 = new Vector2(firstPoint.getX(), firstPoint.getY());
final Vector2 ou2 = o2.add(new Vector2(u.getX(), u.getY()), null);
final Vector2 ov2 = o2.add(new Vector2(v.getX(), v.getY()), null);
double minLineScaleU = Double.MAX_VALUE;
double minLineScaleV = Double.MAX_VALUE;
for (final ReadOnlyVector3 p : points3D) {
final PolygonPoint polygonPoint = new PolygonPoint(p.getX(), p.getY(), p.getZ());
toXY.transform(polygonPoint);
points2D.add(polygonPoint);
final Vector2 p2 = new Vector2(polygonPoint.getX(), polygonPoint.getY());
final double lineScaleU = Util.projectPointOnLineScale(p2, o2, ou2);
final double lineScaleV = Util.projectPointOnLineScale(p2, o2, ov2);
if (lineScaleU < minLineScaleU) {
minLineScaleU = lineScaleU;
}
if (lineScaleV < minLineScaleV) {
minLineScaleV = lineScaleV;
}
}
o2.addLocal(new Vector2(u.getX(), u.getY()).multiplyLocal(minLineScaleU));
o2.addLocal(new Vector2(v.getX(), v.getY()).multiplyLocal(minLineScaleV));
final PolygonWithHoles polygon = new PolygonWithHoles(points2D);
o.set(o2.getX(), o2.getY(), 0);
roofPart.updateWorldBound(true);
for (final Window window : windows) {
if (holes.get(window) == null) {
continue;
}
final List<PolygonPoint> holePolygon = new ArrayList<PolygonPoint>();
boolean outside = false;
for (final ReadOnlyVector3 holePoint : holes.get(window)) {
final PickResults pickResults = new PrimitivePickResults();
PickingUtil.findPick(((Node) roofPart).getChild(0), new Ray3(holePoint, Vector3.UNIT_Z), pickResults, false);
if (pickResults.getNumber() > 0) {
final ReadOnlyVector3 intersectionPoint = pickResults.getPickData(0).getIntersectionRecord().getIntersectionPoint(0);
final PolygonPoint polygonPoint = new PolygonPoint(intersectionPoint.getX(), intersectionPoint.getY(), intersectionPoint.getZ());
toXY.transform(polygonPoint);
holePolygon.add(polygonPoint);
} else {
outside = true;
break;
}
}
if (!outside) {
polygon.addHole(new PolygonWithHoles(holePolygon));
holes.remove(window);
window.setRoofIndex(roofIndex);
}
}
final Mesh meshWithHoles = (Mesh) ((Node) roofPart).getChild(6);
try {
fillMeshWithPolygon(meshWithHoles, polygon, fromXY, true, o, v, u, false);
} catch (final RuntimeException e) {
e.printStackTrace();
final Mesh meshWithoutHoles = (Mesh) ((Node) roofPart).getChild(0);
meshWithHoles.setMeshData(meshWithoutHoles.getMeshData());
}
}
}
}
use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class MeshLib method createMeshes.
public static void createMeshes(final Node root, final ArrayList<GroupData> groups) {
if (groups.size() != root.getNumberOfChildren()) {
root.detachAllChildren();
}
int meshIndex = 0;
for (final GroupData group : groups) {
final Node node;
final Mesh mesh;
final Mesh meshWithHoles;
final BMText label;
if (meshIndex < root.getNumberOfChildren()) {
node = (Node) root.getChild(meshIndex);
mesh = (Mesh) node.getChild(0);
label = (BMText) node.getChild(3);
meshWithHoles = (Mesh) node.getChild(6);
node.getSceneHints().setAllPickingHints(true);
} else {
node = new Node("Roof Part #" + meshIndex);
mesh = new Mesh("Roof Mesh #" + meshIndex);
meshWithHoles = new Mesh("Roof Mesh with Holes #" + meshIndex);
mesh.setVisible(false);
mesh.setModelBound(new BoundingBox());
meshWithHoles.setModelBound(new BoundingBox());
meshWithHoles.setRenderState(HousePart.offsetState);
label = new BMText("Label Text", "", FontManager.getInstance().getPartNumberFont(), Align.South, Justify.Center);
Util.initHousePartLabel(label);
final Mesh wireframeMesh = new Line("Roof (wireframe)");
wireframeMesh.setDefaultColor(ColorRGBA.BLACK);
wireframeMesh.setModelBound(new BoundingBox());
wireframeMesh.getMeshData().setVertexBuffer(BufferUtils.createVector3Buffer(10));
// offset to avoid z-fighting
wireframeMesh.setTranslation(group.key.multiply(0.001, null));
final Line dashLineMesh = new Line("Roof (dash line)");
dashLineMesh.setStipplePattern((short) 0xFF00);
dashLineMesh.setVisible(false);
dashLineMesh.setModelBound(new BoundingBox());
final Node sizeAnnotation = new Node("Roof Size Annot");
final Node angleAnnotation = new Node("Roof Angle Annot");
// disable picking for all except mesh
Util.disablePickShadowLight(sizeAnnotation);
Util.disablePickShadowLight(angleAnnotation);
Util.disablePickShadowLight(wireframeMesh);
Util.disablePickShadowLight(dashLineMesh);
// meshWithHoles.getSceneHints().setAllPickingHints(false);
node.attachChild(mesh);
node.attachChild(sizeAnnotation);
node.attachChild(angleAnnotation);
node.attachChild(label);
node.attachChild(wireframeMesh);
node.attachChild(dashLineMesh);
node.attachChild(meshWithHoles);
root.attachChild(node);
}
node.getSceneHints().setCullHint(CullHint.Never);
CollisionTreeManager.getInstance().removeCollisionTree(mesh);
CollisionTreeManager.getInstance().removeCollisionTree(meshWithHoles);
final Vector3 normal = group.key;
node.setUserData(normal);
final FloatBuffer buf = BufferUtils.createVector3Buffer(group.vertices.size());
mesh.getMeshData().setVertexBuffer(buf);
final Vector3 center = new Vector3();
for (final ReadOnlyVector3 v : group.vertices) {
buf.put(v.getXf()).put(v.getYf()).put(v.getZf());
center.addLocal(v);
}
center.multiplyLocal(1.0 / group.vertices.size());
label.setTranslation(center.add(normal.multiply(0.1, null), null));
mesh.updateModelBound();
meshIndex++;
}
}
use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class MeshLib method combineGroups.
static void combineGroups(final ArrayList<GroupData> groups) {
boolean changed = true;
while (changed) {
changed = false;
for (int i = 0; i < groups.size(); i++) {
final GroupData group1 = groups.get(i);
for (int j = i + 1; j < groups.size(); j++) {
final GroupData group2 = groups.get(j);
if (isSameDirection(group1.key, group2.key)) {
for (int w = 0; w < group2.vertices.size(); w += 3) {
final ReadOnlyVector3 p1 = group2.vertices.get(w);
final ReadOnlyVector3 p2 = group2.vertices.get(w + 1);
final ReadOnlyVector3 p3 = group2.vertices.get(w + 2);
if (hasCommonEdge(group1, p1, p2, p3)) {
group1.vertices.addAll(group2.vertices);
// group1.normals.addAll(group2.normals);
group1.textures.addAll(group2.textures);
groups.remove(group2);
j--;
changed = true;
break;
}
}
}
}
}
}
}
use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class MeshLib method computeOutline.
public static ArrayList<ReadOnlyVector3> computeOutline(final FloatBuffer buf) {
final Map<LineSegment3, Boolean> visitMap = new HashMap<LineSegment3, Boolean>();
for (int i = 0; i < buf.limit(); i += 9) {
for (int trianglePointIndex = 0; trianglePointIndex < 9; trianglePointIndex += 3) {
buf.position(i + trianglePointIndex);
Vector3 p1 = new Vector3(buf.get(), buf.get(), buf.get());
buf.position(i + (trianglePointIndex + 3) % 9);
Vector3 p2 = new Vector3(buf.get(), buf.get(), buf.get());
if (p2.getX() < p1.getX() || (p2.getX() == p1.getX() && p2.getY() < p1.getY())) {
final Vector3 tmp = p1;
p1 = p2;
p2 = tmp;
}
final LineSegment3 line = new LineSegment3(p1, p2);
final Boolean pastVisit = visitMap.get(line);
if (pastVisit == null) {
visitMap.put(line, true);
} else {
visitMap.put(line, false);
}
}
}
final ArrayList<ReadOnlyVector3> outlinePoints = new ArrayList<ReadOnlyVector3>();
for (final LineSegment3 line : visitMap.keySet()) {
if (visitMap.get(line)) {
final Vector3 negativeEnd = line.getNegativeEnd(null);
outlinePoints.add(negativeEnd);
outlinePoints.add(line.getPositiveEnd(null));
}
}
final ArrayList<ReadOnlyVector3> sortedOutlinePoints = new ArrayList<ReadOnlyVector3>(outlinePoints.size() / 2);
sortedOutlinePoints.add(outlinePoints.get(0));
ReadOnlyVector3 lastPoint = outlinePoints.get(1);
sortedOutlinePoints.add(lastPoint);
outlinePoints.remove(1);
outlinePoints.remove(0);
while (!outlinePoints.isEmpty()) {
boolean foundSomething = false;
for (int i = 0; i < outlinePoints.size(); i++) {
if (Util.isEqual(outlinePoints.get(i), lastPoint)) {
final int otherEndIndex = i % 2 == 0 ? i + 1 : i - 1;
lastPoint = outlinePoints.get(otherEndIndex);
sortedOutlinePoints.add(lastPoint);
outlinePoints.remove(Math.max(i, otherEndIndex));
outlinePoints.remove(Math.min(i, otherEndIndex));
foundSomething = true;
break;
}
}
if (!foundSomething) {
break;
}
}
// remove last point if duplicated of first point
if (Util.isEqual(sortedOutlinePoints.get(0), sortedOutlinePoints.get(sortedOutlinePoints.size() - 1))) {
sortedOutlinePoints.remove(sortedOutlinePoints.size() - 1);
}
return sortedOutlinePoints;
}
use of com.ardor3d.math.type.ReadOnlyVector3 in project energy3d by concord-consortium.
the class Printout method getScreenShot.
private BufferedImage getScreenShot(final Renderer renderer, final ReadOnlyVector3 printCorner) {
final Camera camera = Camera.getCurrentCamera();
final int width = camera.getWidth(), height = camera.getHeight();
final Vector3 cameraLocation = new Vector3(printCorner).addLocal(visibleSceneWidth / 2.0, Scene.getOriginalHouseRoot().getWorldBound().getCenter().getY() - 10, -visibleSceneHeight / 2.0);
final double pageToX = printCorner.getX() + PrintController.getInstance().getPageWidth() + visibleSceneWidth / 2.0;
final double pageToZ = printCorner.getZ() - PrintController.getInstance().getPageHeight() - visibleSceneHeight / 2.0;
int currentX = 0;
int currentY = 0;
while (true) {
camera.setLocation(cameraLocation);
camera.lookAt(cameraLocation.add(0, 1, 0, null), Vector3.UNIT_Z);
SceneManager.getInstance().getFrameHandler().updateFrame();
SceneManager.getInstance().getFrameHandler().updateFrame();
// Ask the renderer for the current scene to be stored in the buffer
takeSnapShot(image, _scratch, renderer, width, height, currentX, currentY);
currentX += width;
if (currentX > targetSize.width) {
currentX = 0;
currentY += height;
}
if (cameraLocation.getX() + visibleSceneWidth < pageToX) {
cameraLocation.addLocal(visibleSceneWidth, 0, 0);
} else if (cameraLocation.getZ() - visibleSceneHeight > pageToZ) {
cameraLocation.setX(printCorner.getX() + visibleSceneWidth / 2.0);
cameraLocation.addLocal(0, 0, -visibleSceneHeight);
} else {
break;
}
}
return image;
}
Aggregations