use of org.twak.utils.geom.LinearForm3D in project chordatlas by twak.
the class GreebleEdge method cut.
private static LinearForm3D cut(Point3d a, Point3d b, Point3d c) {
Vector3d ab = new Vector3d(b);
ab.sub(a);
Vector3d bc = new Vector3d(c);
bc.sub(b);
ab.normalize();
bc.normalize();
// if ( true || ab.z > 0.0 || bc.z > 0.0) {
ab.add(bc);
ab.normalize();
return new LinearForm3D(toXZ(ab), toXZ(b));
// }
// Vector2d ab2 = new Vector2d( ab.x, ab.y ),
// bc2 = new Vector2d( bc.x, bc.y );
//
// ab2.normalize();
// bc2.normalize();
//
// ab2.add( bc2 );
//
// Vector3d normal = new Vector3d(ab2.x , ab2.y, 0);
// normal.normalize();
//
// return new LinearForm3D( toXZ( normal ), toXZ( b ) );
}
use of org.twak.utils.geom.LinearForm3D in project chordatlas by twak.
the class GreebleEdge method roofTween.
private static LinearForm3D roofTween(SharedEdge a, SharedEdge b, Face f) {
if (a == null || b == null)
return null;
Vector3d aD = a.dir(f);
if (aD == null)
return null;
aD.normalize();
Vector3d bD = b.dir(f);
if (bD == null)
return null;
bD.normalize();
aD.add(bD);
aD.normalize();
Point3d pt = a.getEnd(f);
return new LinearForm3D(new Vector3d(aD.x, aD.z, aD.y), new Point3d(pt.x, pt.z, pt.y));
}
use of org.twak.utils.geom.LinearForm3D in project chordatlas by twak.
the class GreebleGrid method moulding.
protected void moulding(Matrix4d to3d, DRectangle rect, MeshBuilder mb) {
double hh = rect.height / 2;
Point3d start = new Point3d(rect.x, 0, rect.y + hh), end = new Point3d(rect.getMaxX(), 0, rect.y + hh);
to3d.transform(start);
to3d.transform(end);
Line3d line = new Line3d(start, end);
Vector3d dir = line.dir();
dir.normalize();
Vector3d nDir = new Vector3d(dir);
nDir.scale(-1);
LinearForm3D left = new LinearForm3D(nDir, start), right = new LinearForm3D(dir, end);
LinearForm3D wall = new LinearForm3D(to3d.m01, to3d.m11, to3d.m21);
wall.findD(start);
Tube.tube(mb, Collections.singleton(left), Collections.singleton(right), line, wall, wall, new CrossGen() {
@Override
public List<Point2d> gen(Vector2d down, Vector2d up) {
Vector2d d = new Vector2d(down);
d.normalize();
Vector2d dP = new Vector2d(d.y, -d.x);
List<Point2d> out = new ArrayList();
for (double[] coords : new double[][] { { 1.00, 0.00 }, { 1.00, 0.05 }, { 0.66, 0.05 }, { 0.66, 0.10 }, { 0.33, 0.10 }, { 0.33, 0.17 }, { 0.00, 0.17 }, { 0.00, 0.00 } }) {
Point2d tmp = new Point2d(d);
tmp.scale(coords[0] * rect.height - hh);
Point2d tmp2 = new Point2d(dP);
tmp2.scale(coords[1]);
tmp.add(tmp2);
out.add(tmp);
}
return out;
}
});
}
use of org.twak.utils.geom.LinearForm3D in project chordatlas by twak.
the class GreebleSkel method mapTo2d.
protected void mapTo2d(Face f, Loop<LPoint3d> ll, MiniFacade mf, WallTag wallTag, Set<QuadF> features, MatMeshBuilder faceMaterial) {
Matrix4d to2dXY = new Matrix4d();
Vector3d up = f.edge.uphill, along = f.edge.direction(), out = f.edge.getPlaneNormal();
along.normalize();
to2dXY.setRow(2, up.x, up.y, up.z, 0);
to2dXY.setRow(1, out.x, out.y, out.z, 0);
to2dXY.setRow(0, -along.x, -along.y, -along.z, 0);
Point3d bottomS = f.definingSE.iterator().next().getStart(f), bottomE = f.definingSE.iterator().next().getEnd(f);
Point3d start = new Point3d(bottomS);
Point3d end = new Point3d(bottomE);
to2dXY.m33 = 1;
to2dXY.transform(start);
to2dXY.m03 = -start.x;
to2dXY.m13 = -start.y;
to2dXY.m23 = -start.z;
start = new Point3d(bottomS);
to2dXY.transform(start);
to2dXY.transform(end);
Loop<LPoint2d> flat = GreebleHelper.to2dLoop(GreebleHelper.transform(ll, to2dXY), 1);
Matrix4d to3d = new Matrix4d(to2dXY);
to3d.invert();
{
// face in z-up, we're in y-up
double[] one = new double[4], two = new double[4];
to3d.getRow(1, one);
to3d.getRow(2, two);
to3d.setRow(1, two);
to3d.setRow(2, one);
}
// now in jme space
Matrix4d to2d = new Matrix4d(to3d);
to2d.invert();
MiniFacade forFace = null;
if (mf != null) {
forFace = new MiniFacade(mf);
forFace.rects.clear();
}
LinearForm3D facePlane = new LinearForm3D(new Vector3d(out.x, out.z, out.y), new Point3d(bottomS.x, bottomS.z, bottomS.y));
LoopL<Point2d> sides = null;
DRectangle facadeRect = null;
if (wallTag != null) {
sides = findRectagle(flat, Pointz.to2(start), Pointz.to2(end));
if (sides != null)
facadeRect = findRect(sides.remove(0));
}
List<DRectangle> floors = new ArrayList();
List<MeshBuilder> materials = new ArrayList();
if (wallTag != null && facadeRect != null && mf != null && wallTag.isGroundFloor && mf.groundFloorHeight > 0 && wallTag.groundFloorColor != null && facadeRect.x < mf.groundFloorHeight && facadeRect.getMaxX() > mf.groundFloorHeight) {
floors.addAll(facadeRect.splitY(mf.groundFloorHeight));
MatMeshBuilder gfm = greebleGrid.mbs.get("brick", wallTag.groundFloorColor);
for (Loop<Point2d> loop : sides) {
Loop<Point2d>[] cut = Loopz.cutConvex(loop, new LinearForm(0, 1, mf.groundFloorHeight));
faceMaterial.add(cut[1].singleton(), to3d);
gfm.add(cut[0].singleton(), to3d);
}
materials.add(gfm);
materials.add(faceMaterial);
} else {
floors.add(facadeRect);
materials.add(faceMaterial);
if (sides != null)
faceMaterial.add(sides, to3d);
}
for (int j = 0; j < floors.size(); j++) {
DRectangle floorRect = floors.get(j);
MeshBuilder m = materials.get(j);
Iterator<QuadF> quit = features.iterator();
while (quit.hasNext()) {
QuadF n = quit.next();
if (n.project(to2d, to3d, flat, facePlane, new Vector3d(along.y, 0, -along.x)) && wallTag != null && floorRect != null && forFace != null) {
// set the vertical bounds, so we can just render in 2d
FRect bounds = new FRect(n.original);
n.setBounds(to2d, bounds);
if (floorRect.contains(bounds)) {
forFace.rects.put(n.original.f, bounds);
quit.remove();
}
}
}
if (wallTag == null || forFace == null || floorRect == null) {
m.add(flat.singleton(), to3d);
return;
}
List<DRectangle> occlusions = new ArrayList<>();
for (LineHeight lh : wallTag.occlusions) {
Point3d s = new Point3d(lh.start.x, lh.start.y, lh.min), e = new Point3d(lh.end.x, lh.end.y, lh.max);
to2dXY.transform(s);
to2dXY.transform(e);
occlusions.add(new DRectangle(Math.min(s.x, e.x), s.z, Math.abs(e.x - s.x), Math.abs(e.z - s.z)));
}
if (mf.texture == null)
greebleGrid.buildGrid(floorRect, to3d, forFace, m, wallTag);
else
greebleGrid.textureGrid(floorRect, to3d, mf);
}
}
use of org.twak.utils.geom.LinearForm3D in project chordatlas by twak.
the class ObjSlice method sliceTri.
public static List<Line> sliceTri(ObjRead mesh, double h, int majorAxis) {
int[] flatAxis = new int[] { (majorAxis + 1) % 3, (majorAxis + 2) % 3 };
if (flatAxis[0] > flatAxis[1]) {
int tmp = flatAxis[0];
flatAxis[0] = flatAxis[1];
flatAxis[1] = tmp;
}
Vector3d sliceNormal = new Vector3d(majorAxis == 0 ? 1 : 0, majorAxis == 1 ? 1 : 0, majorAxis == 2 ? 1 : 0), slicePt = new Vector3d(sliceNormal);
slicePt.scale(h);
LinearForm3D slicePlane = new LinearForm3D(sliceNormal, slicePt);
return slice(mesh, flatAxis, slicePlane, Double.MAX_VALUE, null, Double.MAX_VALUE).stream().map(l -> new Line(l.start.x, l.start.z, l.end.x, l.end.z)).collect(Collectors.toList());
}
Aggregations