Project

General

Profile

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

examples / src / main / java / org / distorted / examples / meshfile / FactoryCubit.java @ ef231eba

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 ef231eba Leszek Koltunski
266
android.util.Log.e("D", " buffer: "+mBuffer[0]+" "+mBuffer[1]+" "+mBuffer[2]);
267
268
269
    if( mBuffer[2]<0.0f )
270
      {
271
      mBuffer[0] *= -1.0f;
272
      mBuffer[1] *= -1.0f;
273
      mBuffer[2] *= -1.0f;
274
      }
275 7edab735 Leszek Koltunski
    }
276
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278 33647db9 Leszek Koltunski
// return quat1*quat2
279 7edab735 Leszek Koltunski
280 33647db9 Leszek Koltunski
  private static void quatMultiply( float[] quat1, float[] quat2, float[] result )
281 7edab735 Leszek Koltunski
    {
282 33647db9 Leszek Koltunski
    float qx = quat1[0];
283
    float qy = quat1[1];
284
    float qz = quat1[2];
285
    float qw = quat1[3];
286 7edab735 Leszek Koltunski
287 33647db9 Leszek Koltunski
    float rx = quat2[0];
288
    float ry = quat2[1];
289
    float rz = quat2[2];
290
    float rw = quat2[3];
291 7edab735 Leszek Koltunski
292 33647db9 Leszek Koltunski
    result[0] = rw*qx - rz*qy + ry*qz + rx*qw;
293
    result[1] = rw*qy + rz*qx + ry*qw - rx*qz;
294
    result[2] = rw*qz + rz*qw - ry*qx + rx*qy;
295
    result[3] = rw*qw - rz*qz - ry*qy - rx*qx;
296 7edab735 Leszek Koltunski
    }
297
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299
300 33647db9 Leszek Koltunski
  private void fitInSquare(FaceInfo info, float[][] vert3D)
301 7edab735 Leszek Koltunski
    {
302 33647db9 Leszek Koltunski
    float minX = Float.MAX_VALUE;
303
    float maxX =-Float.MAX_VALUE;
304
    float minY = Float.MAX_VALUE;
305
    float maxY =-Float.MAX_VALUE;
306 55f20739 Leszek Koltunski
307 33647db9 Leszek Koltunski
    for (float[] vert : vert3D)
308
      {
309
      float x = vert[0];
310
      float y = vert[1];
311 55f20739 Leszek Koltunski
312 33647db9 Leszek Koltunski
      if (x > maxX) maxX = x;
313
      if (x < minX) minX = x;
314
      if (y > maxY) maxY = y;
315
      if (y < minY) minY = y;
316
      }
317 55f20739 Leszek Koltunski
318 33647db9 Leszek Koltunski
    info.scale = Math.max(maxX-minX,maxY-minY);
319 ef231eba Leszek Koltunski
320 33647db9 Leszek Koltunski
    int len = vert3D.length;
321
    info.vertices = new float[2*len];
322 55f20739 Leszek Koltunski
323 33647db9 Leszek Koltunski
    for( int vertex=0; vertex<len; vertex++ )
324 55f20739 Leszek Koltunski
      {
325 33647db9 Leszek Koltunski
      info.vertices[2*vertex  ] = vert3D[vertex][0] / info.scale;
326
      info.vertices[2*vertex+1] = vert3D[vertex][1] / info.scale;
327 55f20739 Leszek Koltunski
      }
328
329 33647db9 Leszek Koltunski
    info.flip = false;
330 55f20739 Leszek Koltunski
    }
331
332
///////////////////////////////////////////////////////////////////////////////////////////////////
333
334 33647db9 Leszek Koltunski
  private void constructNew(FaceInfo info, final float[][] vert3D)
335 55f20739 Leszek Koltunski
    {
336 33647db9 Leszek Koltunski
    // compute center of gravity
337
    info.vx = 0.0f;
338
    info.vy = 0.0f;
339
    info.vz = 0.0f;
340
    int len = vert3D.length;
341 55f20739 Leszek Koltunski
342 33647db9 Leszek Koltunski
    for (float[] vert : vert3D)
343 55f20739 Leszek Koltunski
      {
344 33647db9 Leszek Koltunski
      info.vx += vert[0];
345
      info.vy += vert[1];
346
      info.vz += vert[2];
347 55f20739 Leszek Koltunski
      }
348
349 33647db9 Leszek Koltunski
    info.vx /= len;
350
    info.vy /= len;
351
    info.vz /= len;
352 55f20739 Leszek Koltunski
353 33647db9 Leszek Koltunski
    // move all vertices so that their center of gravity is at (0,0,0)
354
    for (int i=0; i<len; i++)
355 7cd30f7c Leszek Koltunski
      {
356 33647db9 Leszek Koltunski
      vert3D[i][0] -= info.vx;
357
      vert3D[i][1] -= info.vy;
358
      vert3D[i][2] -= info.vz;
359 7cd30f7c Leszek Koltunski
      }
360
361 33647db9 Leszek Koltunski
    // find 3 non-colinear vertices
362
    int foundIndex = -1;
363 7cd30f7c Leszek Koltunski
364 33647db9 Leszek Koltunski
    for(int vertex=2; vertex<len; vertex++)
365 7cd30f7c Leszek Koltunski
      {
366 33647db9 Leszek Koltunski
      if( !areColinear(vert3D,0,1,vertex) )
367
        {
368
        foundIndex = vertex;
369
        break;
370
        }
371 7cd30f7c Leszek Koltunski
      }
372
373 33647db9 Leszek Koltunski
    // compute the normal vector
374
    if( foundIndex==-1 )
375
      {
376
      throw new RuntimeException("all vertices colinear");
377
      }
378 7cd30f7c Leszek Koltunski
379 33647db9 Leszek Koltunski
    computeNormalVector(vert3D,0,1,foundIndex);
380
381 ef231eba Leszek Koltunski
    if( mBuffer[0]!=0.0f || mBuffer[1]!=0.0f )
382 33647db9 Leszek Koltunski
      {
383 ef231eba Leszek Koltunski
      // rotate so that the normal vector becomes (0,0,1)
384
      float axisX = -mBuffer[1];
385
      float axisY =  mBuffer[0];
386
      float axisZ = 0.0f;
387
388
      float vecLen = mBuffer[0]*mBuffer[0] + mBuffer[1]*mBuffer[1] + mBuffer[2]*mBuffer[2];
389
      vecLen = (float)Math.sqrt(vecLen);
390
      mBuffer[0] /= vecLen;
391
      mBuffer[1] /= vecLen;
392
      mBuffer[2] /= vecLen;
393
394
      float axiLen = axisX*axisX + axisY*axisY + axisZ*axisZ;
395
      axiLen = (float)Math.sqrt(axiLen);
396
      axisX /= axiLen;
397
      axisY /= axiLen;
398
      axisZ /= axiLen;
399
400
      float cosTheta = mBuffer[2];
401
      //float sinTheta = axiLen / vecLen;
402
403
      float sinHalfTheta = (float)Math.sqrt(0.5f*(1-cosTheta));
404
      float cosHalfTheta = (float)Math.sqrt(0.5f*(1+cosTheta));
405
406
      mQuat1[0] = axisX*sinHalfTheta;
407
      mQuat1[1] = axisY*sinHalfTheta;
408
      mQuat1[2] = axisZ*sinHalfTheta;
409
      mQuat1[3] = cosHalfTheta;
410
      mQuat2[0] = axisX*sinHalfTheta;
411
      mQuat2[1] = axisY*sinHalfTheta;
412
      mQuat2[2] = axisZ*sinHalfTheta;
413
      mQuat2[3] = -cosHalfTheta;
414
415
      for (float[] vert : vert3D)
416
        {
417
        quatMultiply(mQuat1, vert, mQuat3);
418
        quatMultiply(mQuat3, mQuat2, vert);
419
        }
420 33647db9 Leszek Koltunski
      }
421 7cd30f7c Leszek Koltunski
422 33647db9 Leszek Koltunski
    // fit the whole thing in a square and remember the scale & 2D vertices
423
    fitInSquare(info, vert3D);
424 7cd30f7c Leszek Koltunski
425 33647db9 Leszek Koltunski
    // remember the rotation
426
    info.qx = mQuat1[0];
427
    info.qy = mQuat1[1];
428
    info.qz = mQuat1[2];
429
    info.qw =-mQuat1[3];
430 7cd30f7c Leszek Koltunski
    }
431
432 fe032f52 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
433
434 33647db9 Leszek Koltunski
  private float computeCos(float x1, float y1, float x2, float y2, float len1, float len2)
435 fe032f52 Leszek Koltunski
    {
436 33647db9 Leszek Koltunski
    return (x1*x2+y1*y2) / (len1*len2);
437 fe032f52 Leszek Koltunski
    }
438
439 b3d28a81 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
440 33647db9 Leszek Koltunski
// sin of (signed!) angle between vectors (x1,y1) and (x2,y2), counterclockwise!
441 b3d28a81 Leszek Koltunski
442 33647db9 Leszek Koltunski
  private float computeSin(float x1, float y1, float x2, float y2, float len1, float len2)
443 b3d28a81 Leszek Koltunski
    {
444 33647db9 Leszek Koltunski
    return (x2*y1-x1*y2) / (len1*len2);
445 b3d28a81 Leszek Koltunski
    }
446
447 54e47d9b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
448
449 33647db9 Leszek Koltunski
  private void rotateAllVertices(float[] result, int len, float[] vertices, float sin, float cos)
450 54e47d9b Leszek Koltunski
    {
451 33647db9 Leszek Koltunski
    for(int i=0; i<len; i++)
452 54e47d9b Leszek Koltunski
      {
453 33647db9 Leszek Koltunski
      result[2*i  ] = vertices[2*i  ]*cos - vertices[2*i+1]*sin;
454
      result[2*i+1] = vertices[2*i  ]*sin + vertices[2*i+1]*cos;
455 54e47d9b Leszek Koltunski
      }
456
    }
457
458 6d020cb6 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
459
460 33647db9 Leszek Koltunski
  private boolean isScaledVersionOf(float[] v1, float[] v2, int len)
461 6d020cb6 Leszek Koltunski
    {
462 33647db9 Leszek Koltunski
    float EPSILON = 0.001f;
463
    float scale = v1[0]!=0.0f ? v2[0]/v1[0] : v2[1]/v1[1];
464 55f20739 Leszek Koltunski
465 33647db9 Leszek Koltunski
    for(int i=1; i<len; i++)
466
      {
467
      float horz = v2[2*i  ] - scale*v1[2*i  ];
468
      float vert = v2[2*i+1] - scale*v1[2*i+1];
469 7edab735 Leszek Koltunski
470 33647db9 Leszek Koltunski
      if( horz>EPSILON || horz<-EPSILON || vert>EPSILON || vert<-EPSILON ) return false;
471
      }
472 55f20739 Leszek Koltunski
473 33647db9 Leszek Koltunski
    return true;
474 7edab735 Leszek Koltunski
    }
475
476
///////////////////////////////////////////////////////////////////////////////////////////////////
477
478 33647db9 Leszek Koltunski
  private void mirrorAllVertices(float[] output, int len, float[] input)
479 7edab735 Leszek Koltunski
    {
480 33647db9 Leszek Koltunski
    for(int vertex=0; vertex<len; vertex++)
481
      {
482
      output[2*vertex  ] = input[2*vertex  ];
483
      output[2*vertex+1] =-input[2*vertex+1];
484
      }
485 7edab735 Leszek Koltunski
    }
486
487
///////////////////////////////////////////////////////////////////////////////////////////////////
488
489 33647db9 Leszek Koltunski
  private void correctInfo(FaceInfo info, float[] rotatedVertices, int len, float[] originalVertices, float sin, float cos, boolean flip)
490 7edab735 Leszek Koltunski
    {
491 33647db9 Leszek Koltunski
    info.flip = flip;
492 7edab735 Leszek Koltunski
493 33647db9 Leszek Koltunski
    System.arraycopy(originalVertices, 0, info.vertices, 0, 2*len);
494 7edab735 Leszek Koltunski
495 33647db9 Leszek Koltunski
    float scale = rotatedVertices[0]!=0.0f ? originalVertices[0]/rotatedVertices[0] :
496
                                             originalVertices[1]/rotatedVertices[1];
497
    info.scale *= scale;
498 7edab735 Leszek Koltunski
499 33647db9 Leszek Koltunski
    mQuat1[0] = 0.0f;
500
    mQuat1[1] = 0.0f;
501
    mQuat1[2] = sin;
502
    mQuat1[3] = cos;
503 55f20739 Leszek Koltunski
504 33647db9 Leszek Koltunski
    mQuat2[0] = info.qx;
505
    mQuat2[1] = info.qy;
506
    mQuat2[2] = info.qz;
507
    mQuat2[3] = info.qw;
508 7edab735 Leszek Koltunski
509 33647db9 Leszek Koltunski
    quatMultiply( mQuat1, mQuat2, mQuat3 );
510 55f20739 Leszek Koltunski
511 33647db9 Leszek Koltunski
    info.qx = mQuat3[0];
512
    info.qy = mQuat3[1];
513
    info.qz = mQuat3[2];
514
    info.qw = mQuat3[3];
515 7edab735 Leszek Koltunski
    }
516
517
///////////////////////////////////////////////////////////////////////////////////////////////////
518
519 33647db9 Leszek Koltunski
  private boolean foundVertex(FaceInfo info, float[] buffer, int len, boolean inverted, float[] vertices, float[] vert2D, float lenVert)
520 7edab735 Leszek Koltunski
    {
521 33647db9 Leszek Koltunski
    for(int vertex=0; vertex<len; vertex++)
522
      {
523
      float xR = vertices[2*vertex  ];
524
      float yR = vertices[2*vertex+1];
525
      float lenRotV = (float)Math.sqrt(xR*xR+yR*yR);
526
      float cos = computeCos(xR,yR,vert2D[0],vert2D[1], lenRotV, lenVert);
527
      float sin = computeSin(xR,yR,vert2D[0],vert2D[1], lenRotV, lenVert);
528 7edab735 Leszek Koltunski
529 33647db9 Leszek Koltunski
      rotateAllVertices(buffer,len,vertices,sin,cos);
530 7edab735 Leszek Koltunski
531 33647db9 Leszek Koltunski
      if( isScaledVersionOf(buffer,vert2D,len) )
532
        {
533
        correctInfo(info,buffer,len,vert2D,sin,cos,inverted);
534
        return true;
535
        }
536
      }
537 55f20739 Leszek Koltunski
538 33647db9 Leszek Koltunski
    return false;
539 7edab735 Leszek Koltunski
    }
540
541
///////////////////////////////////////////////////////////////////////////////////////////////////
542
543 33647db9 Leszek Koltunski
  private boolean tryFindingRotation(final FaceInfo info, final float[] vert2D)
544 7edab735 Leszek Koltunski
    {
545 33647db9 Leszek Koltunski
    int len = vert2D.length/2;
546 7edab735 Leszek Koltunski
547 33647db9 Leszek Koltunski
    if( len == info.vertices.length/2 )
548
      {
549
      float[] tmp1 = new float[2*len];
550
      float lenVert = (float)Math.sqrt(vert2D[0]*vert2D[0] + vert2D[1]*vert2D[1]);
551
      if( foundVertex(info,tmp1,len,false,info.vertices,vert2D,lenVert) ) return true;
552
      float[] tmp2 = new float[2*len];
553
      mirrorAllVertices(tmp2,len,info.vertices);
554
      if( foundVertex(info,tmp1,len,true ,tmp2         ,vert2D,lenVert) ) return true;
555
      }
556 55f20739 Leszek Koltunski
557 33647db9 Leszek Koltunski
    return false;
558 7edab735 Leszek Koltunski
    }
559
560
///////////////////////////////////////////////////////////////////////////////////////////////////
561
562 33647db9 Leszek Koltunski
  private float[][] constructVert(float[][] vertices, int[] index)
563 7edab735 Leszek Koltunski
    {
564 33647db9 Leszek Koltunski
    int len = index.length;
565
    float[][] ret = new float[len][4];
566 7edab735 Leszek Koltunski
567 33647db9 Leszek Koltunski
    for(int i=0; i<len; i++)
568
      {
569
      ret[i][0] = vertices[index[i]][0];
570
      ret[i][1] = vertices[index[i]][1];
571
      ret[i][2] = vertices[index[i]][2];
572
      ret[i][3] = 1.0f;
573
      }
574 7edab735 Leszek Koltunski
575 33647db9 Leszek Koltunski
    return ret;
576 7edab735 Leszek Koltunski
    }
577
578
///////////////////////////////////////////////////////////////////////////////////////////////////
579
580 33647db9 Leszek Koltunski
  private void prepareFaceInfo( final float[][] vertices, final int[][] indexes)
581 7edab735 Leszek Koltunski
    {
582 33647db9 Leszek Koltunski
    mFaceInfo.clear();
583 7edab735 Leszek Koltunski
584 33647db9 Leszek Koltunski
    int numFaces = indexes.length;
585
    FaceInfo info;
586 7edab735 Leszek Koltunski
587 33647db9 Leszek Koltunski
    for(int face=0; face<numFaces; face++)
588
      {
589
      FaceInfo newInfo = new FaceInfo();
590
      int[] index = indexes[face];
591
      float[][] vert = constructVert(vertices,index);
592
      constructNew(newInfo,vert);
593 55f20739 Leszek Koltunski
594 33647db9 Leszek Koltunski
      for(int previous=0; previous<face; previous++)
595
        {
596
        info = mFaceInfo.get(previous);
597
        if( tryFindingRotation(info,newInfo.vertices) ) break;
598
        }
599 7edab735 Leszek Koltunski
600 33647db9 Leszek Koltunski
      mFaceInfo.add(newInfo);
601
      }
602 7edab735 Leszek Koltunski
    }
603
604 ef231eba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
605
606
  private void printInfo(FaceInfo info)
607
    {
608
    android.util.Log.e("D", "vx="+info.vx+" vy="+info.vy+" vz="+info.vz);
609
    android.util.Log.e("D", "qx="+info.qx+" qy="+info.qy+" qz="+info.qz+" qw="+info.qw);
610
    android.util.Log.e("D", "scale="+info.scale);
611
612
    String ver="";
613
614
    int len = info.vertices.length/2;
615
616
    for(int i =0; i<len; i++)
617
      {
618
      ver += ("("+info.vertices[2*i]+","+info.vertices[2*i+1]+") ");
619
      }
620
621
    android.util.Log.e("D", "vertices= "+ver);
622
    }
623
624 7edab735 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
625
626 33647db9 Leszek Koltunski
  MeshBase createRoundedSolid(final float[][] vertices, final int[][] vertIndexes, final float[][] bands, final int[] bandIndexes)
627 7edab735 Leszek Koltunski
    {
628 33647db9 Leszek Koltunski
    int EFFECTS_PER_FACE = 3;
629 7edab735 Leszek Koltunski
630 33647db9 Leszek Koltunski
    prepareFaceInfo(vertices,vertIndexes);
631 7edab735 Leszek Koltunski
632 33647db9 Leszek Koltunski
    int numFaces = vertIndexes.length;
633
    float[] band, bandsComputed;
634
    MeshBase[] meshes = new MeshBase[numFaces];
635
    FaceInfo info;
636 55f20739 Leszek Koltunski
637 33647db9 Leszek Koltunski
    for(int face=0; face<numFaces; face++)
638
      {
639
      info = mFaceInfo.get(face);
640
      band = bands[bandIndexes[face]];
641
      bandsComputed = computeBands( band[0], (int)band[1], band[2], band[3], (int)band[4]);
642
      meshes[face] = new MeshPolygon(info.vertices,bandsComputed,(int)band[5],(int)band[6]);
643
      meshes[face].setEffectAssociation(0,(1<<face),0);
644
      }
645 7edab735 Leszek Koltunski
646 33647db9 Leszek Koltunski
    MeshBase mesh = new MeshJoined(meshes);
647
    VertexEffect[] effects = new VertexEffect[EFFECTS_PER_FACE*numFaces];
648 7edab735 Leszek Koltunski
    Static3D center = new Static3D(0,0,0);
649 fe032f52 Leszek Koltunski
650 33647db9 Leszek Koltunski
    for(int face=0; face<numFaces; face++)
651
      {
652
      int assoc = (1<<face);
653
      info = mFaceInfo.get(face);
654 6d020cb6 Leszek Koltunski
655 33647db9 Leszek Koltunski
      Static3D move3D= new Static3D(info.vx,info.vy,info.vz);
656
      Static3D scale = new Static3D(info.scale,info.scale, info.flip ? -info.scale : info.scale);
657
      Static4D quat  = new Static4D(info.qx,info.qy,info.qz,info.qw);
658 6d020cb6 Leszek Koltunski
659 33647db9 Leszek Koltunski
      effects[EFFECTS_PER_FACE*face  ] = new VertexEffectScale(scale);
660
      effects[EFFECTS_PER_FACE*face+1] = new VertexEffectQuaternion(quat,center);
661
      effects[EFFECTS_PER_FACE*face+2] = new VertexEffectMove(move3D);
662 a65604a7 Leszek Koltunski
663 33647db9 Leszek Koltunski
      effects[EFFECTS_PER_FACE*face  ].setMeshAssociation(assoc,-1);
664
      effects[EFFECTS_PER_FACE*face+1].setMeshAssociation(assoc,-1);
665
      effects[EFFECTS_PER_FACE*face+2].setMeshAssociation(assoc,-1);
666
      }
667 a65604a7 Leszek Koltunski
668
    for( VertexEffect effect : effects ) mesh.apply(effect);
669
670 7edab735 Leszek Koltunski
    return mesh;
671
    }
672
  }