use of com.ardor3d.scenegraph.Node 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.scenegraph.Node 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.scenegraph.Node in project energy3d by concord-consortium.
the class Util method drawBoundingBox.
public static void drawBoundingBox(final Spatial spatial, final Line boundingBox) {
OrientedBoundingBox box = null;
if (spatial instanceof Mesh) {
box = getOrientedBoundingBox((Mesh) spatial);
} else if (spatial instanceof Node) {
box = getOrientedBoundingBox((Node) spatial);
} else {
return;
}
FloatBuffer buf = boundingBox.getMeshData().getVertexBuffer();
if (buf == null || buf.capacity() != 24) {
buf = BufferUtils.createVector3Buffer(24);
boundingBox.getMeshData().setVertexBuffer(buf);
} else {
buf.rewind();
buf.limit(buf.capacity());
}
final ReadOnlyVector3 center = box.getCenter();
final ReadOnlyVector3 extent = box.getExtent();
final ReadOnlyVector3 vx = box.getXAxis().multiply(extent.getX(), null);
final ReadOnlyVector3 vy = box.getYAxis().multiply(extent.getY(), null);
final ReadOnlyVector3 vz = box.getZAxis().multiply(extent.getZ(), null);
double x, y, z;
// #1: (1, 1, 1) to (-1, 1, 1)
x = center.getX() + vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() - vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #2: (1, 1, 1) to (1, -1, 1)
x = center.getX() + vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() + vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #3: (1, 1, 1) to (1, 1, -1)
x = center.getX() + vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() + vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #4: (-1, -1, -1) to (1, -1, -1)
x = center.getX() - vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() + vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #5: (-1, -1, -1) to (-1, 1, -1)
x = center.getX() - vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() - vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #6: (-1, -1, -1) to (-1, -1, 1)
x = center.getX() - vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() - vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #7: (-1, 1, 1) to (-1, -1, 1)
x = center.getX() - vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() - vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #8: (-1, 1, 1) to (-1, 1, -1)
x = center.getX() - vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() - vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #9: (1, -1, 1) to (-1, -1, 1)
x = center.getX() + vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() - vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #10: (1, -1, 1) to (1, -1, -1)
x = center.getX() + vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() + vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() + vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #11: (1, 1, -1) to (-1, 1, -1)
x = center.getX() + vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() - vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
// #12: (1, 1, -1) to (1, -1, -1)
x = center.getX() + vx.getX();
y = center.getY() + vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
x = center.getX() + vx.getX();
y = center.getY() - vy.getY();
z = center.getZ() - vz.getZ();
buf.put((float) x).put((float) y).put((float) z);
boundingBox.updateModelBound();
boundingBox.setVisible(true);
}
use of com.ardor3d.scenegraph.Node in project energy3d by concord-consortium.
the class Scene method countMeshes.
public int countMeshes() {
int count = 0;
final List<Foundation> foundations = getAllFoundations();
for (final Foundation f : foundations) {
if (f.getImportedNodes() != null) {
for (final Node n : f.getImportedNodes()) {
count += n.getNumberOfChildren();
}
}
}
return count;
}
use of com.ardor3d.scenegraph.Node in project energy3d by concord-consortium.
the class Scene method importCollada.
public void importCollada(final File file) throws Exception {
boolean success = true;
Vector3 position = SceneManager.getInstance().getPickedLocationOnLand();
if (position == null) {
position = new Vector3();
}
final Foundation foundation = new Foundation(100, 100);
for (final Vector3 p : foundation.getPoints()) {
p.addLocal(position);
}
Scene.getInstance().add(foundation, false);
try {
final Node n = foundation.importCollada(file.toURI().toURL(), position);
if (n != null) {
// TODO: automatically center the model at the center
}
} catch (final Throwable t) {
BugReporter.report(t);
success = false;
}
if (success) {
SceneManager.getInstance().getUndoManager().addEdit(new AddNodeCommand(foundation));
}
setEdited(true);
}
Aggregations