Project

General

Profile

Download (19.7 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / meshfile / FactoryCubit.java @ 33647db9

1 7edab735 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is free software: you can redistribute it and/or modify                            //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Magic Cube is distributed in the hope that it will be useful,                                 //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.examples.meshfile;
21
22
import org.distorted.library.effect.VertexEffect;
23
import org.distorted.library.effect.VertexEffectDeform;
24
import org.distorted.library.effect.VertexEffectMove;
25 33647db9 Leszek Koltunski
import org.distorted.library.effect.VertexEffectQuaternion;
26 7edab735 Leszek Koltunski
import org.distorted.library.effect.VertexEffectScale;
27
import org.distorted.library.mesh.MeshBase;
28
import org.distorted.library.mesh.MeshJoined;
29
import org.distorted.library.mesh.MeshPolygon;
30
import org.distorted.library.type.Static1D;
31
import org.distorted.library.type.Static3D;
32
import org.distorted.library.type.Static4D;
33
34 33647db9 Leszek Koltunski
import java.util.ArrayList;
35
36 7edab735 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
37
38 55f20739 Leszek Koltunski
class FactoryCubit
39 7edab735 Leszek Koltunski
  {
40 33647db9 Leszek Koltunski
  static final float SQ5   = (float)Math.sqrt(5);
41
  static final float SIN18 = (SQ5-1)/4;
42
  static final float COS18 = (float)(0.25f*Math.sqrt(10.0f+2.0f*SQ5));
43
44
  private static final float[] mBuffer = new float[3];
45
  private static final float[] mQuat1  = new float[4];
46
  private static final float[] mQuat2  = new float[4];
47
  private static final float[] mQuat3  = new float[4];
48 6d020cb6 Leszek Koltunski
49 7edab735 Leszek Koltunski
  private static final Static1D RADIUS = new Static1D(1);
50
51 55f20739 Leszek Koltunski
  private static FactoryCubit mThis;
52 7edab735 Leszek Koltunski
53 33647db9 Leszek Koltunski
  private static class FaceInfo
54
    {
55
    float[] vertices;
56
    float vx,vy,vz;
57
    float scale;
58
    float qx,qy,qz,qw;
59
    boolean flip;
60
    }
61
62
  private static final ArrayList<FaceInfo> mFaceInfo = new ArrayList<>();
63
64 7edab735 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
65
66 55f20739 Leszek Koltunski
  private FactoryCubit()
67 7edab735 Leszek Koltunski
    {
68
69
    }
70
71
///////////////////////////////////////////////////////////////////////////////////////////////////
72
73 55f20739 Leszek Koltunski
  public static FactoryCubit getInstance()
74 7edab735 Leszek Koltunski
    {
75 55f20739 Leszek Koltunski
    if( mThis==null ) mThis = new FactoryCubit();
76 7edab735 Leszek Koltunski
77
    return mThis;
78
    }
79
80
///////////////////////////////////////////////////////////////////////////////////////////////////
81
// H - height of the band in the middle
82
// alpha - angle of the edge  [0,90]
83
// dist - often in a polygon the distance from edge to center is not 1, but something else.
84
// This is the distance.
85
// K - where to begin the second, much more flat part of the band. [0,1]
86
// N - number of bands. N>=3
87
//
88
// theory: two distinct parts to the band:
89
// 1) (0,B) - steep
90
// 2) (B,1) - flat
91
//
92
// In first part, we have y = g(x) ; in second - y = g(f(x)) where
93
//
94
// g(x) = sqrt( R^2 - (x-D)^2 ) - R*cos(alpha)
95
// f(x) = ((D-B)/(1-B)*x + B*(1-D)/(1-B)
96
// h(x) = R*(sin(alpha) - sin(x))
97
// R = H/(1-cos(alpha))
98
// D = H*sin(alpha)
99
// B = h(K*alpha)
100
//
101
// The N points are taken at:
102
//
103
// 1) in the second part, there are K2 = (N-3)/3 such points
104
// 2) in the first - K1 = (N-3) - K2
105
// 3) also, the 3 points 0,B,1
106
//
107
// so we have the sequence A[i] of N points
108
//
109
// 0
110
// h((i+1)*(1-K)*alpha/(K1+1)) (i=0,1,...,K1-1)
111
// B
112
// (1-B)*(i+1)/(K2+1) + B   (i=0,i,...,K2-1)
113
// 1
114
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116
117
  private float f(float D, float B, float x)
118
    {
119
    return ((D-B)*x + B*(1-D))/(1-B);
120
    }
121
122
///////////////////////////////////////////////////////////////////////////////////////////////////
123
124
  private float g(float R, float D, float x, float cosAlpha)
125
    {
126
    float d = x-D;
127
    return (float)(Math.sqrt(R*R-d*d)-R*cosAlpha);
128
    }
129
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131
132
  private float h(float R, float sinAlpha, float x)
133
    {
134
    return R*(sinAlpha-(float)Math.sin(x));
135
    }
136
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138
139 55f20739 Leszek Koltunski
  float[] computeBands(float H, int alpha, float dist, float K, int N)
140 7edab735 Leszek Koltunski
    {
141
    float[] bands = new float[2*N];
142
143
    bands[0] = 1.0f;
144
    bands[1] = 0.0f;
145
146
    float beta = (float)Math.atan(dist*Math.tan(Math.PI*alpha/180));
147
    float sinBeta = (float)Math.sin(beta);
148
    float cosBeta = (float)Math.cos(beta);
149
    float R = cosBeta<1.0f ? H/(1.0f-cosBeta) : 0.0f;
150
    float D = R*sinBeta;
151
    float B = h(R,sinBeta,K*beta);
152
153
    if( D>1.0f )
154
      {
155
      for(int i=1; i<N; i++)
156
        {
157
        bands[2*i  ] = (float)(N-1-i)/(N-1);
158
        bands[2*i+1] = H*(1-bands[2*i]);
159
        }
160
      }
161
    else
162
      {
163 55f20739 Leszek Koltunski
      int K2 = (int)((N-3)*K);
164 7edab735 Leszek Koltunski
      int K1 = (N-3)-K2;
165
166
      for(int i=0; i<=K1; i++)
167
        {
168
        float angle = K*beta + (1-K)*beta*(K1-i)/(K1+1);
169
        float x = h(R,sinBeta,angle);
170
        bands[2*i+2] = 1.0f - x;
171
        bands[2*i+3] = g(R,D,x,cosBeta);
172
        }
173
174
      for(int i=0; i<=K2; i++)
175
        {
176
        float x = (1-B)*(i+1)/(K2+1) + B;
177
        bands[2*K1+2 + 2*i+2] = 1.0f - x;
178
        bands[2*K1+2 + 2*i+3] = g(R,D,f(D,B,x),cosBeta);
179
        }
180
      }
181
182 55f20739 Leszek Koltunski
    bands[2*N-2] = 0.0f;
183
    bands[2*N-1] =    H;
184
185 7edab735 Leszek Koltunski
    return bands;
186
    }
187
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189
190
  private void roundCorners(MeshBase mesh, Static3D center, Static3D[] vertices, float strength, float regionRadius)
191
    {
192
    Static4D reg= new Static4D(0,0,0,regionRadius);
193
194
    float centX = center.get0();
195
    float centY = center.get1();
196
    float centZ = center.get2();
197
198
    for (Static3D vertex : vertices)
199
      {
200
      float x = strength*(centX - vertex.get0());
201
      float y = strength*(centY - vertex.get1());
202
      float z = strength*(centZ - vertex.get2());
203
204
      VertexEffect effect = new VertexEffectDeform(new Static3D(x,y,z), RADIUS, vertex, reg);
205
      mesh.apply(effect);
206
      }
207
    }
208
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
211 33647db9 Leszek Koltunski
  private boolean areColinear(float[][] vertices, int index1, int index2, int index3)
212 7edab735 Leszek Koltunski
    {
213 33647db9 Leszek Koltunski
    float x1 = vertices[index1][0];
214
    float y1 = vertices[index1][1];
215
    float z1 = vertices[index1][2];
216
    float x2 = vertices[index2][0];
217
    float y2 = vertices[index2][1];
218
    float z2 = vertices[index2][2];
219
    float x3 = vertices[index3][0];
220
    float y3 = vertices[index3][1];
221
    float z3 = vertices[index3][2];
222 7edab735 Leszek Koltunski
223 33647db9 Leszek Koltunski
    float v1x = x2-x1;
224
    float v1y = y2-y1;
225
    float v1z = z2-z1;
226
    float v2x = x3-x1;
227
    float v2y = y3-y1;
228
    float v2z = z3-z1;
229 7edab735 Leszek Koltunski
230 33647db9 Leszek Koltunski
    float A = (float)Math.sqrt( (v1x*v1x+v1y*v1y+v1z*v1z) / (v2x*v2x+v2y*v2y+v2z*v2z) );
231 7edab735 Leszek Koltunski
232 33647db9 Leszek Koltunski
//android.util.Log.e("D", "("+x1+","+y1+","+z1+") , ("+x2+","+y2+","+z2+") , ("+x3+","+y3+","+z3+")" );
233 7edab735 Leszek Koltunski
234 33647db9 Leszek Koltunski
//boolean result = (v1x==A*v2x && v1y==A*v2y && v1z==A*v2z);
235 7edab735 Leszek Koltunski
236 33647db9 Leszek Koltunski
//android.util.Log.e("D", "are those colinear? : "+result);
237 7edab735 Leszek Koltunski
238 33647db9 Leszek Koltunski
    return (v1x==A*v2x && v1y==A*v2y && v1z==A*v2z);
239 7edab735 Leszek Koltunski
    }
240
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242
243 33647db9 Leszek Koltunski
  private void computeNormalVector(float[][] vertices, int index1, int index2, int index3)
244 7edab735 Leszek Koltunski
    {
245 33647db9 Leszek Koltunski
    float x1 = vertices[index1][0];
246
    float y1 = vertices[index1][1];
247
    float z1 = vertices[index1][2];
248
    float x2 = vertices[index2][0];
249
    float y2 = vertices[index2][1];
250
    float z2 = vertices[index2][2];
251
    float x3 = vertices[index3][0];
252
    float y3 = vertices[index3][1];
253
    float z3 = vertices[index3][2];
254 7edab735 Leszek Koltunski
255 33647db9 Leszek Koltunski
    float v1x = x2-x1;
256
    float v1y = y2-y1;
257
    float v1z = z2-z1;
258
    float v2x = x3-x1;
259
    float v2y = y3-y1;
260
    float v2z = z3-z1;
261 7edab735 Leszek Koltunski
262 33647db9 Leszek Koltunski
    mBuffer[0] = v1y*v2z - v2y*v1z;
263
    mBuffer[1] = v1z*v2x - v2z*v1x;
264
    mBuffer[2] = v1x*v2y - v2x*v1y;
265 7edab735 Leszek Koltunski
    }
266
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268 33647db9 Leszek Koltunski
// return quat1*quat2
269 7edab735 Leszek Koltunski
270 33647db9 Leszek Koltunski
  private static void quatMultiply( float[] quat1, float[] quat2, float[] result )
271 7edab735 Leszek Koltunski
    {
272 33647db9 Leszek Koltunski
    float qx = quat1[0];
273
    float qy = quat1[1];
274
    float qz = quat1[2];
275
    float qw = quat1[3];
276 7edab735 Leszek Koltunski
277 33647db9 Leszek Koltunski
    float rx = quat2[0];
278
    float ry = quat2[1];
279
    float rz = quat2[2];
280
    float rw = quat2[3];
281 7edab735 Leszek Koltunski
282 33647db9 Leszek Koltunski
    result[0] = rw*qx - rz*qy + ry*qz + rx*qw;
283
    result[1] = rw*qy + rz*qx + ry*qw - rx*qz;
284
    result[2] = rw*qz + rz*qw - ry*qx + rx*qy;
285
    result[3] = rw*qw - rz*qz - ry*qy - rx*qx;
286 7edab735 Leszek Koltunski
    }
287
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289
290 33647db9 Leszek Koltunski
  private void fitInSquare(FaceInfo info, float[][] vert3D)
291 7edab735 Leszek Koltunski
    {
292 33647db9 Leszek Koltunski
    float minX = Float.MAX_VALUE;
293
    float maxX =-Float.MAX_VALUE;
294
    float minY = Float.MAX_VALUE;
295
    float maxY =-Float.MAX_VALUE;
296 55f20739 Leszek Koltunski
297 33647db9 Leszek Koltunski
    for (float[] vert : vert3D)
298
      {
299
      float x = vert[0];
300
      float y = vert[1];
301 55f20739 Leszek Koltunski
302 33647db9 Leszek Koltunski
      if (x > maxX) maxX = x;
303
      if (x < minX) minX = x;
304
      if (y > maxY) maxY = y;
305
      if (y < minY) minY = y;
306
      }
307 55f20739 Leszek Koltunski
308 33647db9 Leszek Koltunski
    info.scale = Math.max(maxX-minX,maxY-minY);
309
    int len = vert3D.length;
310
    info.vertices = new float[2*len];
311 55f20739 Leszek Koltunski
312 33647db9 Leszek Koltunski
    for( int vertex=0; vertex<len; vertex++ )
313 55f20739 Leszek Koltunski
      {
314 33647db9 Leszek Koltunski
      info.vertices[2*vertex  ] = vert3D[vertex][0] / info.scale;
315
      info.vertices[2*vertex+1] = vert3D[vertex][1] / info.scale;
316 55f20739 Leszek Koltunski
      }
317
318 33647db9 Leszek Koltunski
    info.flip = false;
319 55f20739 Leszek Koltunski
    }
320
321
///////////////////////////////////////////////////////////////////////////////////////////////////
322
323 33647db9 Leszek Koltunski
  private void constructNew(FaceInfo info, final float[][] vert3D)
324 55f20739 Leszek Koltunski
    {
325 33647db9 Leszek Koltunski
    // compute center of gravity
326
    info.vx = 0.0f;
327
    info.vy = 0.0f;
328
    info.vz = 0.0f;
329
    int len = vert3D.length;
330 55f20739 Leszek Koltunski
331 33647db9 Leszek Koltunski
    for (float[] vert : vert3D)
332 55f20739 Leszek Koltunski
      {
333 33647db9 Leszek Koltunski
      info.vx += vert[0];
334
      info.vy += vert[1];
335
      info.vz += vert[2];
336 55f20739 Leszek Koltunski
      }
337
338 33647db9 Leszek Koltunski
    info.vx /= len;
339
    info.vy /= len;
340
    info.vz /= len;
341 55f20739 Leszek Koltunski
342 33647db9 Leszek Koltunski
    // move all vertices so that their center of gravity is at (0,0,0)
343
    for (int i=0; i<len; i++)
344 7cd30f7c Leszek Koltunski
      {
345 33647db9 Leszek Koltunski
      vert3D[i][0] -= info.vx;
346
      vert3D[i][1] -= info.vy;
347
      vert3D[i][2] -= info.vz;
348 7cd30f7c Leszek Koltunski
      }
349
350 33647db9 Leszek Koltunski
    // find 3 non-colinear vertices
351
    int foundIndex = -1;
352 7cd30f7c Leszek Koltunski
353 33647db9 Leszek Koltunski
    for(int vertex=2; vertex<len; vertex++)
354 7cd30f7c Leszek Koltunski
      {
355 33647db9 Leszek Koltunski
      if( !areColinear(vert3D,0,1,vertex) )
356
        {
357
        foundIndex = vertex;
358
        break;
359
        }
360 7cd30f7c Leszek Koltunski
      }
361
362 33647db9 Leszek Koltunski
    // compute the normal vector
363
    if( foundIndex==-1 )
364
      {
365
      throw new RuntimeException("all vertices colinear");
366
      }
367 7cd30f7c Leszek Koltunski
368 33647db9 Leszek Koltunski
    computeNormalVector(vert3D,0,1,foundIndex);
369
370
    // rotate so that the normal vector becomes (0,0,1)
371
    float axisX = -mBuffer[1];
372
    float axisY =  mBuffer[0];
373
    float axisZ = 0.0f;
374
375
    float vecLen = mBuffer[0]*mBuffer[0] + mBuffer[1]*mBuffer[1] + mBuffer[2]*mBuffer[2];
376
    vecLen = (float)Math.sqrt(vecLen);
377
    mBuffer[0] /= vecLen;
378
    mBuffer[1] /= vecLen;
379
    mBuffer[2] /= vecLen;
380
381
    float axiLen = axisX*axisX + axisY*axisY + axisZ*axisZ;
382
    axiLen = (float)Math.sqrt(axiLen);
383
    axisX /= axiLen;
384
    axisY /= axiLen;
385
    axisZ /= axiLen;
386
387
    float cosTheta = mBuffer[2];
388
    float sinTheta = axiLen / vecLen;
389
390
    mQuat1[0] = axisX*sinTheta;
391
    mQuat1[1] = axisY*sinTheta;
392
    mQuat1[2] = axisZ*sinTheta;
393
    mQuat1[3] = cosTheta;
394
    mQuat2[0] = axisX*sinTheta;
395
    mQuat2[1] = axisY*sinTheta;
396
    mQuat2[2] = axisZ*sinTheta;
397
    mQuat2[3] = -cosTheta;
398
399
    for (float[] vert : vert3D)
400
      {
401
      quatMultiply(mQuat1, vert, mQuat3);
402
      quatMultiply(mQuat3, mQuat2, vert);
403
      }
404 7cd30f7c Leszek Koltunski
405 33647db9 Leszek Koltunski
    // fit the whole thing in a square and remember the scale & 2D vertices
406
    fitInSquare(info, vert3D);
407 7cd30f7c Leszek Koltunski
408 33647db9 Leszek Koltunski
    // remember the rotation
409
    info.qx = mQuat1[0];
410
    info.qy = mQuat1[1];
411
    info.qz = mQuat1[2];
412
    info.qw =-mQuat1[3];
413 7cd30f7c Leszek Koltunski
    }
414
415 fe032f52 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417 33647db9 Leszek Koltunski
  private float computeCos(float x1, float y1, float x2, float y2, float len1, float len2)
418 fe032f52 Leszek Koltunski
    {
419 33647db9 Leszek Koltunski
    return (x1*x2+y1*y2) / (len1*len2);
420 fe032f52 Leszek Koltunski
    }
421
422 b3d28a81 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
423 33647db9 Leszek Koltunski
// sin of (signed!) angle between vectors (x1,y1) and (x2,y2), counterclockwise!
424 b3d28a81 Leszek Koltunski
425 33647db9 Leszek Koltunski
  private float computeSin(float x1, float y1, float x2, float y2, float len1, float len2)
426 b3d28a81 Leszek Koltunski
    {
427 33647db9 Leszek Koltunski
    return (x2*y1-x1*y2) / (len1*len2);
428 b3d28a81 Leszek Koltunski
    }
429
430 54e47d9b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
431
432 33647db9 Leszek Koltunski
  private void rotateAllVertices(float[] result, int len, float[] vertices, float sin, float cos)
433 54e47d9b Leszek Koltunski
    {
434 33647db9 Leszek Koltunski
    for(int i=0; i<len; i++)
435 54e47d9b Leszek Koltunski
      {
436 33647db9 Leszek Koltunski
      result[2*i  ] = vertices[2*i  ]*cos - vertices[2*i+1]*sin;
437
      result[2*i+1] = vertices[2*i  ]*sin + vertices[2*i+1]*cos;
438 54e47d9b Leszek Koltunski
      }
439
    }
440
441 6d020cb6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
442
443 33647db9 Leszek Koltunski
  private boolean isScaledVersionOf(float[] v1, float[] v2, int len)
444 6d020cb6 Leszek Koltunski
    {
445 33647db9 Leszek Koltunski
    float EPSILON = 0.001f;
446
    float scale = v1[0]!=0.0f ? v2[0]/v1[0] : v2[1]/v1[1];
447 55f20739 Leszek Koltunski
448 33647db9 Leszek Koltunski
    for(int i=1; i<len; i++)
449
      {
450
      float horz = v2[2*i  ] - scale*v1[2*i  ];
451
      float vert = v2[2*i+1] - scale*v1[2*i+1];
452 7edab735 Leszek Koltunski
453 33647db9 Leszek Koltunski
      if( horz>EPSILON || horz<-EPSILON || vert>EPSILON || vert<-EPSILON ) return false;
454
      }
455 55f20739 Leszek Koltunski
456 33647db9 Leszek Koltunski
    return true;
457 7edab735 Leszek Koltunski
    }
458
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460
461 33647db9 Leszek Koltunski
  private void mirrorAllVertices(float[] output, int len, float[] input)
462 7edab735 Leszek Koltunski
    {
463 33647db9 Leszek Koltunski
    for(int vertex=0; vertex<len; vertex++)
464
      {
465
      output[2*vertex  ] = input[2*vertex  ];
466
      output[2*vertex+1] =-input[2*vertex+1];
467
      }
468 7edab735 Leszek Koltunski
    }
469
470
///////////////////////////////////////////////////////////////////////////////////////////////////
471
472 33647db9 Leszek Koltunski
  private void correctInfo(FaceInfo info, float[] rotatedVertices, int len, float[] originalVertices, float sin, float cos, boolean flip)
473 7edab735 Leszek Koltunski
    {
474 33647db9 Leszek Koltunski
    info.flip = flip;
475 7edab735 Leszek Koltunski
476 33647db9 Leszek Koltunski
    System.arraycopy(originalVertices, 0, info.vertices, 0, 2*len);
477 7edab735 Leszek Koltunski
478 33647db9 Leszek Koltunski
    float scale = rotatedVertices[0]!=0.0f ? originalVertices[0]/rotatedVertices[0] :
479
                                             originalVertices[1]/rotatedVertices[1];
480
    info.scale *= scale;
481 7edab735 Leszek Koltunski
482 33647db9 Leszek Koltunski
    mQuat1[0] = 0.0f;
483
    mQuat1[1] = 0.0f;
484
    mQuat1[2] = sin;
485
    mQuat1[3] = cos;
486 55f20739 Leszek Koltunski
487 33647db9 Leszek Koltunski
    mQuat2[0] = info.qx;
488
    mQuat2[1] = info.qy;
489
    mQuat2[2] = info.qz;
490
    mQuat2[3] = info.qw;
491 7edab735 Leszek Koltunski
492 33647db9 Leszek Koltunski
    quatMultiply( mQuat1, mQuat2, mQuat3 );
493 55f20739 Leszek Koltunski
494 33647db9 Leszek Koltunski
    info.qx = mQuat3[0];
495
    info.qy = mQuat3[1];
496
    info.qz = mQuat3[2];
497
    info.qw = mQuat3[3];
498 7edab735 Leszek Koltunski
    }
499
500
///////////////////////////////////////////////////////////////////////////////////////////////////
501
502 33647db9 Leszek Koltunski
  private boolean foundVertex(FaceInfo info, float[] buffer, int len, boolean inverted, float[] vertices, float[] vert2D, float lenVert)
503 7edab735 Leszek Koltunski
    {
504 33647db9 Leszek Koltunski
    for(int vertex=0; vertex<len; vertex++)
505
      {
506
      float xR = vertices[2*vertex  ];
507
      float yR = vertices[2*vertex+1];
508
      float lenRotV = (float)Math.sqrt(xR*xR+yR*yR);
509
      float cos = computeCos(xR,yR,vert2D[0],vert2D[1], lenRotV, lenVert);
510
      float sin = computeSin(xR,yR,vert2D[0],vert2D[1], lenRotV, lenVert);
511 7edab735 Leszek Koltunski
512 33647db9 Leszek Koltunski
      rotateAllVertices(buffer,len,vertices,sin,cos);
513 7edab735 Leszek Koltunski
514 33647db9 Leszek Koltunski
      if( isScaledVersionOf(buffer,vert2D,len) )
515
        {
516
        correctInfo(info,buffer,len,vert2D,sin,cos,inverted);
517
        return true;
518
        }
519
      }
520 55f20739 Leszek Koltunski
521 33647db9 Leszek Koltunski
    return false;
522 7edab735 Leszek Koltunski
    }
523
524
///////////////////////////////////////////////////////////////////////////////////////////////////
525
526 33647db9 Leszek Koltunski
  private boolean tryFindingRotation(final FaceInfo info, final float[] vert2D)
527 7edab735 Leszek Koltunski
    {
528 33647db9 Leszek Koltunski
    int len = vert2D.length/2;
529 7edab735 Leszek Koltunski
530 33647db9 Leszek Koltunski
    if( len == info.vertices.length/2 )
531
      {
532
      float[] tmp1 = new float[2*len];
533
      float lenVert = (float)Math.sqrt(vert2D[0]*vert2D[0] + vert2D[1]*vert2D[1]);
534
      if( foundVertex(info,tmp1,len,false,info.vertices,vert2D,lenVert) ) return true;
535
      float[] tmp2 = new float[2*len];
536
      mirrorAllVertices(tmp2,len,info.vertices);
537
      if( foundVertex(info,tmp1,len,true ,tmp2         ,vert2D,lenVert) ) return true;
538
      }
539 55f20739 Leszek Koltunski
540 33647db9 Leszek Koltunski
    return false;
541 7edab735 Leszek Koltunski
    }
542
543
///////////////////////////////////////////////////////////////////////////////////////////////////
544
545 33647db9 Leszek Koltunski
  private float[][] constructVert(float[][] vertices, int[] index)
546 7edab735 Leszek Koltunski
    {
547 33647db9 Leszek Koltunski
    int len = index.length;
548
    float[][] ret = new float[len][4];
549 7edab735 Leszek Koltunski
550 33647db9 Leszek Koltunski
    for(int i=0; i<len; i++)
551
      {
552
      ret[i][0] = vertices[index[i]][0];
553
      ret[i][1] = vertices[index[i]][1];
554
      ret[i][2] = vertices[index[i]][2];
555
      ret[i][3] = 1.0f;
556
      }
557 7edab735 Leszek Koltunski
558 33647db9 Leszek Koltunski
    return ret;
559 7edab735 Leszek Koltunski
    }
560
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562
563 33647db9 Leszek Koltunski
  private void prepareFaceInfo( final float[][] vertices, final int[][] indexes)
564 7edab735 Leszek Koltunski
    {
565 33647db9 Leszek Koltunski
    mFaceInfo.clear();
566 7edab735 Leszek Koltunski
567 33647db9 Leszek Koltunski
    int numFaces = indexes.length;
568
    FaceInfo info;
569 7edab735 Leszek Koltunski
570 33647db9 Leszek Koltunski
    for(int face=0; face<numFaces; face++)
571
      {
572
      FaceInfo newInfo = new FaceInfo();
573
      int[] index = indexes[face];
574
      float[][] vert = constructVert(vertices,index);
575
      constructNew(newInfo,vert);
576 55f20739 Leszek Koltunski
577 33647db9 Leszek Koltunski
      for(int previous=0; previous<face; previous++)
578
        {
579
        info = mFaceInfo.get(previous);
580
        if( tryFindingRotation(info,newInfo.vertices) ) break;
581
        }
582 7edab735 Leszek Koltunski
583 33647db9 Leszek Koltunski
      mFaceInfo.add(newInfo);
584
      }
585 7edab735 Leszek Koltunski
    }
586
587
///////////////////////////////////////////////////////////////////////////////////////////////////
588
589 33647db9 Leszek Koltunski
  MeshBase createRoundedSolid(final float[][] vertices, final int[][] vertIndexes, final float[][] bands, final int[] bandIndexes)
590 7edab735 Leszek Koltunski
    {
591 33647db9 Leszek Koltunski
    int EFFECTS_PER_FACE = 3;
592 7edab735 Leszek Koltunski
593 33647db9 Leszek Koltunski
    prepareFaceInfo(vertices,vertIndexes);
594 7edab735 Leszek Koltunski
595 33647db9 Leszek Koltunski
    int numFaces = vertIndexes.length;
596
    float[] band, bandsComputed;
597
    MeshBase[] meshes = new MeshBase[numFaces];
598
    FaceInfo info;
599 55f20739 Leszek Koltunski
600 33647db9 Leszek Koltunski
    for(int face=0; face<numFaces; face++)
601
      {
602
      info = mFaceInfo.get(face);
603
      band = bands[bandIndexes[face]];
604
      bandsComputed = computeBands( band[0], (int)band[1], band[2], band[3], (int)band[4]);
605
      meshes[face] = new MeshPolygon(info.vertices,bandsComputed,(int)band[5],(int)band[6]);
606
      meshes[face].setEffectAssociation(0,(1<<face),0);
607
      }
608 7edab735 Leszek Koltunski
609 33647db9 Leszek Koltunski
    MeshBase mesh = new MeshJoined(meshes);
610
    VertexEffect[] effects = new VertexEffect[EFFECTS_PER_FACE*numFaces];
611 7edab735 Leszek Koltunski
    Static3D center = new Static3D(0,0,0);
612 fe032f52 Leszek Koltunski
613 33647db9 Leszek Koltunski
    for(int face=0; face<numFaces; face++)
614
      {
615
      int assoc = (1<<face);
616
      info = mFaceInfo.get(face);
617 6d020cb6 Leszek Koltunski
618 33647db9 Leszek Koltunski
      Static3D move3D= new Static3D(info.vx,info.vy,info.vz);
619
      Static3D scale = new Static3D(info.scale,info.scale, info.flip ? -info.scale : info.scale);
620
      Static4D quat  = new Static4D(info.qx,info.qy,info.qz,info.qw);
621 6d020cb6 Leszek Koltunski
622 33647db9 Leszek Koltunski
      effects[EFFECTS_PER_FACE*face  ] = new VertexEffectScale(scale);
623
      effects[EFFECTS_PER_FACE*face+1] = new VertexEffectQuaternion(quat,center);
624
      effects[EFFECTS_PER_FACE*face+2] = new VertexEffectMove(move3D);
625 a65604a7 Leszek Koltunski
626 33647db9 Leszek Koltunski
      effects[EFFECTS_PER_FACE*face  ].setMeshAssociation(assoc,-1);
627
      effects[EFFECTS_PER_FACE*face+1].setMeshAssociation(assoc,-1);
628
      effects[EFFECTS_PER_FACE*face+2].setMeshAssociation(assoc,-1);
629
      }
630 a65604a7 Leszek Koltunski
631
    for( VertexEffect effect : effects ) mesh.apply(effect);
632
633 7edab735 Leszek Koltunski
    return mesh;
634
    }
635
  }