X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fg3d%2Fshape%2FArcCylinder.java;fp=org.simantics.g3d%2Fsrc%2Forg%2Fsimantics%2Fg3d%2Fshape%2FArcCylinder.java;h=ab6178440ab04a8772dd25902eb59cdfcc0d0dd9;hb=58ebeb2baac48f9066c1395a9071f99745574ef9;hp=0000000000000000000000000000000000000000;hpb=498c60eb6adbad0449879bdff55a2e203bfcbb01;p=simantics%2F3d.git diff --git a/org.simantics.g3d/src/org/simantics/g3d/shape/ArcCylinder.java b/org.simantics.g3d/src/org/simantics/g3d/shape/ArcCylinder.java new file mode 100644 index 00000000..ab617844 --- /dev/null +++ b/org.simantics.g3d/src/org/simantics/g3d/shape/ArcCylinder.java @@ -0,0 +1,152 @@ +package org.simantics.g3d.shape; + +import java.util.ArrayList; +import java.util.List; + +import javax.vecmath.AxisAngle4d; +import javax.vecmath.Point3d; +import javax.vecmath.Quat4d; +import javax.vecmath.Tuple3d; +import javax.vecmath.Vector3d; + +import org.simantics.g3d.math.MathTools; + +public class ArcCylinder { + + public Mesh create(Point3d s, Point3d v, Point3d e, double rad, int res) { + + Vector3d v1 = new Vector3d(s); + v1.sub(v); + + Vector3d v2 = new Vector3d(e); + v2.sub(v); + + double a = v2.angle(v1); + int steps = 0; + double sa = 0.0; + + Vector3d rn = new Vector3d(); + Vector3d r1 = null; + Vector3d c = null; + + if ((a +0.0001) > Math.PI) { + steps = 1; + } else { + c = new Vector3d(v2); + c.add(v1); + c.normalize(); + c.scale(v1.length() * (1.0/Math.cos(a*0.5))); + c.add(v); + + r1 = new Vector3d(s); + r1.sub(c); + + Vector3d r2 = new Vector3d(e); + r2.sub(c); + + a = r2.angle(r1); + + rn.cross(v2, v1); + rn.normalize(); + + steps = (int)(Math.ceil(a/0.1)); + if (steps == 0) + steps = 1; + sa = a/steps; + } + + + List vertices = new ArrayList(res * (steps+1)); + List normals = new ArrayList(res * (steps+1)); + List indices = new ArrayList(); + + for (int i = 0; i <= steps; i++) { + Vector3d p; + Vector3d t; + if (i == 0) { + p = new Vector3d(s); + t = new Vector3d(v1); + t.negate(); + t.normalize(); + } else if (i == steps) { + p = new Vector3d(e); + t = new Vector3d(v2); + t.normalize(); + } else { + p = new Vector3d(); + double ca = sa * i; + Quat4d q = MathTools.getQuat(new AxisAngle4d(rn, ca)); + MathTools.rotate(q, r1, p); + t = new Vector3d(); + t.cross(rn,p); + t.normalize(); + p.add(c); + + } + createCircle(vertices, normals, p, t, rn, res, rad); + } + int count = steps*res*6; + for (int i = 0; i < count; i++) { + indices.add(-1); + } + createIndices(steps, res, indices); + return new Mesh(vertices, normals, indices); + } + + private static void createCircle(List points, List normals, Tuple3d p, Vector3d t, Vector3d n, int res, double radius) { + n = new Vector3d(n); + n.scale(radius); + + for (int index = 0; index < res; index ++) { + Vector3d v; + if (index == 0) { + v = new Vector3d(n); + + } else { + AxisAngle4d aa = new AxisAngle4d(t, (Math.PI * 2 * (double)index)/(double)res); + v = new Vector3d(); + MathTools.rotate(MathTools.getQuat(aa), n, v); + } + //int vIndex = (i*resolution + index)*3; + Vector3d pt = new Vector3d(p); + pt.add(v); + //points.set(vIndex, pt); + points.add(pt); + v.normalize(); + //normals.set(vIndex, v); + normals.add(v); + } + } + private static void createIndices(int steps, int resolution, List index) { + for (int c = 0; c < steps; c++) { + for (int s = 0; s < resolution; s++) { + int ii = (c * resolution + s) * 6; + int iv = c*resolution + s; + + /* + iv+1 ---- iv + resolution + 1 + | /| + |/ | + iv ---- iv + resolution + */ + if (s < resolution - 1) { + index.set(ii+2,iv); + index.set(ii+1,iv+resolution); + index.set(ii+0,iv+resolution+1); + + index.set(ii+5,iv); + index.set(ii+4,iv+resolution+1); + index.set(ii+3,iv+1); + } else { + index.set(ii+2,iv); + index.set(ii+1,iv+resolution); + index.set(ii+0,iv+1); + + index.set(ii+5,iv); + index.set(ii+4,iv+1); + index.set(ii+3,iv+1-resolution); + } + } + } + } +}