]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/g3d/shape/ArcCylinder.java
Fix error in inserting dual inline components
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / shape / ArcCylinder.java
1 package org.simantics.g3d.shape;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import javax.vecmath.AxisAngle4d;
7 import javax.vecmath.Point3d;
8 import javax.vecmath.Quat4d;
9 import javax.vecmath.Tuple3d;
10 import javax.vecmath.Vector3d;
11
12 import org.simantics.g3d.math.MathTools;
13
14 public class ArcCylinder {
15         
16         public Mesh create(Point3d s, Point3d v, Point3d e, double r, int res) {
17                 return create(s, v, e, r, res, 0.15);
18         }
19
20         public Mesh create(Point3d s, Point3d v, Point3d e, double r, int res, double res2) {
21                 
22                 Vector3d v1 = new Vector3d(s);
23                 v1.sub(v);
24                 
25                 Vector3d v2 = new Vector3d(e);
26                 v2.sub(v);
27                 
28                 double a = v2.angle(v1);
29                 int steps = 0;
30                 double sa = 0.0;
31                 
32                 Vector3d rn = new Vector3d();
33                 Vector3d r1 = null;
34                 Vector3d c = null;
35                 
36                 if ((a +0.0001) > Math.PI) {
37                         steps = 1;
38                 } else {
39                         c = new Vector3d(v2);
40                         c.add(v1);
41                         c.normalize();
42                         c.scale(v1.length() * (1.0/Math.cos(a*0.5)));
43                         c.add(v);
44                         
45                         r1 = new Vector3d(s);
46                         r1.sub(c);
47                         
48                         Vector3d r2 = new Vector3d(e);
49                         r2.sub(c);
50                         
51                         a = r2.angle(r1);
52                         
53                         rn.cross(v2, v1);
54                         rn.normalize();
55                         
56                         steps = (int)(Math.ceil(a/res2));
57                         if (steps == 0)
58                                 steps = 1;
59                         sa = a/steps;
60                 }
61
62                 
63                 List<Tuple3d> vertices = new ArrayList<Tuple3d>(res * (steps+1));
64                 List<Tuple3d> normals = new ArrayList<Tuple3d>(res * (steps+1));
65                 List<Integer> indices = new ArrayList<Integer>();
66                 
67                 for (int i = 0; i <= steps; i++) {
68                         Vector3d p;
69                         Vector3d t;
70                         if (i == 0) {
71                                 p = new Vector3d(s);
72                                 t = new Vector3d(v1);
73                                 t.negate();
74                                 t.normalize();
75                         } else if (i == steps) {
76                                 p = new Vector3d(e);
77                                 t = new Vector3d(v2);
78                                 t.normalize();
79                         } else {
80                                 p = new Vector3d();
81                                 double ca = sa * i;
82                                 Quat4d q = MathTools.getQuat(new AxisAngle4d(rn, ca));
83                                 MathTools.rotate(q, r1, p);
84                                 t = new Vector3d();
85                                 t.cross(rn,p);
86                                 t.normalize();
87                                 p.add(c);
88                                 
89                         }
90                         createCircle(vertices, normals, p, t, rn, res, r);
91                 }
92                 int count = steps*res*6;
93                 for (int i = 0; i < count; i++) {
94                         indices.add(-1);
95                 }       
96                 createIndices(steps, res, indices);
97                 return new Mesh(vertices, normals, indices);
98         }
99         
100         public Mesh create(Point3d c, Vector3d axis, Vector3d an, double R, double r, double a, int res, double res2) {
101                 
102         
103                 
104                 int steps = 0;
105                 double sa = 0.0;
106                 
107                 Vector3d rn = new Vector3d(axis);
108                 rn.normalize();
109                 Vector3d r1 = new Vector3d(an);
110                 r1.normalize();
111                 r1.scale(R);
112
113                 
114                 if ((a +0.0001) > Math.PI) {
115                         steps = 1;
116                 } else {
117                         steps = (int)(Math.ceil(a/res2));
118                         if (steps == 0)
119                                 steps = 1;
120                         sa = a/steps;
121                 }
122
123                 List<Tuple3d> vertices = new ArrayList<Tuple3d>(res * (steps+1));
124                 List<Tuple3d> normals = new ArrayList<Tuple3d>(res * (steps+1));
125                 List<Integer> indices = new ArrayList<Integer>();
126                 
127                 for (int i = 0; i <= steps; i++) {
128                         Vector3d p;
129                         Vector3d t;
130                         p = new Vector3d();
131                         double ca = sa * i;
132                         Quat4d q = MathTools.getQuat(new AxisAngle4d(rn, ca));
133                         MathTools.rotate(q, r1, p);
134                         t = new Vector3d();
135                         t.cross(rn,p);
136                         t.normalize();
137                         p.add(c);
138                                 
139                         
140                         createCircle(vertices, normals, p, t, rn, res, r);
141                 }
142                 int count = steps*res*6;
143                 for (int i = 0; i < count; i++) {
144                         indices.add(-1);
145                 }       
146                 createIndices(steps, res, indices);
147                 return new Mesh(vertices, normals, indices);
148         }
149         
150 public Mesh create(Point3d c, Vector3d axis, Vector3d an, double R, double r, double starta, double a, int res, double res2) {
151         
152     
153         
154         int steps = 0;
155         double sa = 0.0;
156         
157         Vector3d rn = new Vector3d(axis);
158         rn.normalize();
159         Vector3d r1 = new Vector3d(an);
160         r1.normalize();
161         r1.scale(R);
162
163         
164         if ((a +0.0001) > Math.PI) {
165             steps = 1;
166         } else {
167             steps = (int)(Math.ceil(a/res2));
168             if (steps == 0)
169                 steps = 1;
170             sa = a/steps;
171         }
172
173         List<Tuple3d> vertices = new ArrayList<Tuple3d>(res * (steps+1));
174         List<Tuple3d> normals = new ArrayList<Tuple3d>(res * (steps+1));
175         List<Integer> indices = new ArrayList<Integer>();
176         
177         for (int i = 0; i <= steps; i++) {
178             Vector3d p;
179             Vector3d t;
180             p = new Vector3d();
181             double ca = sa * i + starta;
182             Quat4d q = MathTools.getQuat(new AxisAngle4d(rn, ca));
183             MathTools.rotate(q, r1, p);
184             t = new Vector3d();
185             t.cross(rn,p);
186             t.normalize();
187             p.add(c);
188                 
189             
190             createCircle(vertices, normals, p, t, rn, res, r);
191         }
192         int count = steps*res*6;
193         for (int i = 0; i < count; i++) {
194             indices.add(-1);
195         }   
196         createIndices(steps, res, indices);
197         return new Mesh(vertices, normals, indices);
198     }
199         
200         private static void createCircle(List<Tuple3d> points, List<Tuple3d> normals, Tuple3d p, Vector3d t, Vector3d n, int res, double radius) {
201                 n = new Vector3d(n);
202                 n.scale(radius);
203                 
204                 for (int index = 0; index < res; index ++) {
205                         Vector3d v;
206                         if (index == 0) {
207                                 v = new Vector3d(n);
208                                 
209                         } else {
210                                 AxisAngle4d aa = new AxisAngle4d(t, (Math.PI * 2 * (double)index)/(double)res);
211                                 v = new Vector3d();
212                                 MathTools.rotate(MathTools.getQuat(aa), n, v);
213                         }
214                         //int vIndex = (i*resolution + index)*3;
215                         Vector3d pt = new Vector3d(p);
216                         pt.add(v);
217                         //points.set(vIndex, pt);
218                         points.add(pt);
219                         v.normalize();
220                         //normals.set(vIndex, v);
221                         normals.add(v);
222                 }
223         }
224         private static void createIndices(int steps, int resolution, List<Integer> index) {
225                 for (int c = 0; c < steps; c++) {
226                         for (int s = 0; s < resolution; s++) {
227                                 int ii = (c * resolution + s) * 6;
228                                 int iv = c*resolution + s;
229                                 
230                                 /*
231                                  iv+1 ---- iv + resolution + 1
232                                           | /|
233                                           |/ |
234                                    iv ---- iv + resolution 
235                                 */
236                                 if (s < resolution - 1) {
237                                         index.set(ii+2,iv);
238                                         index.set(ii+1,iv+resolution);
239                                         index.set(ii+0,iv+resolution+1);
240                                         
241                                         index.set(ii+5,iv);
242                                         index.set(ii+4,iv+resolution+1);
243                                         index.set(ii+3,iv+1);
244                                 } else {
245                                         index.set(ii+2,iv);
246                                         index.set(ii+1,iv+resolution);
247                                         index.set(ii+0,iv+1);
248                                         
249                                         index.set(ii+5,iv);
250                                         index.set(ii+4,iv+1);
251                                         index.set(ii+3,iv+1-resolution);
252                                 }
253                         }
254                 }
255         }
256 }