1 package org.simantics.g3d.shape;
\r
3 import java.util.ArrayList;
\r
4 import java.util.List;
\r
6 import javax.vecmath.AxisAngle4d;
\r
7 import javax.vecmath.Vector3d;
\r
9 import org.simantics.g3d.math.MathTools;
\r
13 List<Vector3d> vertices;
\r
14 List<Color4d> colors;
\r
15 List<Double> radiis;
\r
16 Double radius = 1.0;
\r
20 public void setResolution(int resolution) {
\r
22 this.resolution = resolution;
\r
25 public void setVertices(List<Vector3d> vertices) {
\r
26 this.vertices = vertices;
\r
29 public void setColors(List<Color4d> colors) {
\r
30 this.colors = colors;
\r
33 public void setRadiis(List<Double> radiis) {
\r
34 this.radiis = radiis;
\r
37 public void setRadius(Double radius) {
\r
38 this.radius = radius;
\r
43 public Mesh create() {
\r
44 if (vertices.size() < 2 )
\r
45 throw new IllegalArgumentException("Tube must have at least two vertices");
\r
47 Vector3d t = new Vector3d();
\r
49 for (int i = 0; i < vertices.size() - 1; i++) {
\r
50 t.set(vertices.get(i+1));
\r
51 t.sub(vertices.get(i));
\r
52 if (t.lengthSquared() < 0.0001)
\r
53 throw new IllegalArgumentException("vertices at index " + i + " are too close to each other");
\r
56 List<Vector3d> points = new ArrayList<Vector3d>(vertices.size()*resolution);
\r
57 List<Vector3d> normals = new ArrayList<Vector3d>(vertices.size()*resolution);
\r
59 for (int i = 0; i < vertices.size(); i++) {
\r
60 createCircle(i,points,normals);
\r
63 int index[] = new int[(vertices.size()-1)*resolution*6];
\r
65 createIndices(index);
\r
66 List<Integer> indices = new ArrayList<Integer>();
\r
67 for (int i = 0; i < index.length; i++) {
\r
68 indices.add(index[i]);
\r
79 return new Mesh(points, normals, indices);
\r
83 private void createCircle(int i, List<Vector3d> points, List<Vector3d> normals) {
\r
84 final Vector3d up = new Vector3d(0,1,0);
\r
85 final Vector3d up2 = new Vector3d(0,0,1);
\r
86 Vector3d p = vertices.get(i);
\r
87 Vector3d t = getTangent(i);
\r
88 Vector3d n = new Vector3d();
\r
89 if (up.dot(t) < 0.99) {
\r
95 if (radiis != null) {
\r
96 n.scale(radiis.get(i));
\r
101 for (int index = 0; index < resolution; index ++) {
\r
104 v = new Vector3d(n);
\r
107 AxisAngle4d aa = new AxisAngle4d(t, (Math.PI * 2 * (double)index)/(double)resolution);
\r
108 v = new Vector3d();
\r
109 MathTools.rotate(MathTools.getQuat(aa), n, v);
\r
111 //int vIndex = (i*resolution + index)*3;
\r
112 Vector3d pt = new Vector3d(p);
\r
114 //points.set(vIndex, pt);
\r
117 //normals.set(vIndex, v);
\r
122 private Vector3d getTangent(int i) {
\r
125 p = vertices.get(0);
\r
126 n = vertices.get(1);
\r
127 } else if (i == vertices.size() - 1) {
\r
128 p = vertices.get(i-1);
\r
129 n = vertices.get(i);
\r
131 p = vertices.get(i-1);
\r
132 n = vertices.get(i+1);
\r
134 n = new Vector3d(n);
\r
140 private void createIndices(int index[]) {
\r
141 for (int c = 0; c < vertices.size() - 1; c++) {
\r
142 for (int s = 0; s < resolution; s++) {
\r
143 int ii = (c * resolution + s) * 6;
\r
144 int iv = c*resolution + s;
\r
147 iv+1 ---- iv + resolution + 1
\r
150 iv ---- iv + resolution
\r
152 if (s < resolution - 1) {
\r
154 index[ii+1] = iv+resolution;
\r
155 index[ii+0] = iv+resolution+1;
\r
158 index[ii+4] = iv+resolution+1;
\r
159 index[ii+3] = iv+1;
\r
162 index[ii+1] = iv+resolution;
\r
163 index[ii+0] = iv+1;
\r
166 index[ii+4] = iv+1;
\r
167 index[ii+3] = iv+1-resolution;
\r