Project

General

Profile

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

examples / src / main / java / org / distorted / examples / meshfile / FactoryCubit.java @ 140f2c4e

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 140f2c4e Leszek Koltunski
    float len = mBuffer[0]*mBuffer[0] + mBuffer[1]*mBuffer[1] + mBuffer[2]*mBuffer[2];
267
    len = (float)Math.sqrt(len);
268
    mBuffer[0] /= len;
269
    mBuffer[1] /= len;
270
    mBuffer[2] /= len;
271 ef231eba Leszek Koltunski
272 140f2c4e Leszek Koltunski
//android.util.Log.e("D", " normal: "+mBuffer[0]+" "+mBuffer[1]+" "+mBuffer[2]);
273 7edab735 Leszek Koltunski
    }
274
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276 33647db9 Leszek Koltunski
// return quat1*quat2
277 7edab735 Leszek Koltunski
278 33647db9 Leszek Koltunski
  private static void quatMultiply( float[] quat1, float[] quat2, float[] result )
279 7edab735 Leszek Koltunski
    {
280 33647db9 Leszek Koltunski
    float qx = quat1[0];
281
    float qy = quat1[1];
282
    float qz = quat1[2];
283
    float qw = quat1[3];
284 7edab735 Leszek Koltunski
285 33647db9 Leszek Koltunski
    float rx = quat2[0];
286
    float ry = quat2[1];
287
    float rz = quat2[2];
288
    float rw = quat2[3];
289 7edab735 Leszek Koltunski
290 33647db9 Leszek Koltunski
    result[0] = rw*qx - rz*qy + ry*qz + rx*qw;
291
    result[1] = rw*qy + rz*qx + ry*qw - rx*qz;
292
    result[2] = rw*qz + rz*qw - ry*qx + rx*qy;
293
    result[3] = rw*qw - rz*qz - ry*qy - rx*qx;
294 7edab735 Leszek Koltunski
    }
295
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297
298 33647db9 Leszek Koltunski
  private void fitInSquare(FaceInfo info, float[][] vert3D)
299 7edab735 Leszek Koltunski
    {
300 33647db9 Leszek Koltunski
    float minX = Float.MAX_VALUE;
301
    float maxX =-Float.MAX_VALUE;
302
    float minY = Float.MAX_VALUE;
303
    float maxY =-Float.MAX_VALUE;
304 55f20739 Leszek Koltunski
305 33647db9 Leszek Koltunski
    for (float[] vert : vert3D)
306
      {
307
      float x = vert[0];
308
      float y = vert[1];
309 55f20739 Leszek Koltunski
310 33647db9 Leszek Koltunski
      if (x > maxX) maxX = x;
311
      if (x < minX) minX = x;
312
      if (y > maxY) maxY = y;
313
      if (y < minY) minY = y;
314
      }
315 55f20739 Leszek Koltunski
316 33647db9 Leszek Koltunski
    info.scale = Math.max(maxX-minX,maxY-minY);
317 ef231eba Leszek Koltunski
318 33647db9 Leszek Koltunski
    int len = vert3D.length;
319
    info.vertices = new float[2*len];
320 55f20739 Leszek Koltunski
321 33647db9 Leszek Koltunski
    for( int vertex=0; vertex<len; vertex++ )
322 55f20739 Leszek Koltunski
      {
323 33647db9 Leszek Koltunski
      info.vertices[2*vertex  ] = vert3D[vertex][0] / info.scale;
324
      info.vertices[2*vertex+1] = vert3D[vertex][1] / info.scale;
325 55f20739 Leszek Koltunski
      }
326
327 33647db9 Leszek Koltunski
    info.flip = false;
328 55f20739 Leszek Koltunski
    }
329
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331
332 33647db9 Leszek Koltunski
  private void constructNew(FaceInfo info, final float[][] vert3D)
333 55f20739 Leszek Koltunski
    {
334 33647db9 Leszek Koltunski
    // compute center of gravity
335
    info.vx = 0.0f;
336
    info.vy = 0.0f;
337
    info.vz = 0.0f;
338
    int len = vert3D.length;
339 55f20739 Leszek Koltunski
340 33647db9 Leszek Koltunski
    for (float[] vert : vert3D)
341 55f20739 Leszek Koltunski
      {
342 33647db9 Leszek Koltunski
      info.vx += vert[0];
343
      info.vy += vert[1];
344
      info.vz += vert[2];
345 55f20739 Leszek Koltunski
      }
346
347 33647db9 Leszek Koltunski
    info.vx /= len;
348
    info.vy /= len;
349
    info.vz /= len;
350 55f20739 Leszek Koltunski
351 33647db9 Leszek Koltunski
    // move all vertices so that their center of gravity is at (0,0,0)
352
    for (int i=0; i<len; i++)
353 7cd30f7c Leszek Koltunski
      {
354 33647db9 Leszek Koltunski
      vert3D[i][0] -= info.vx;
355
      vert3D[i][1] -= info.vy;
356
      vert3D[i][2] -= info.vz;
357 7cd30f7c Leszek Koltunski
      }
358
359 33647db9 Leszek Koltunski
    // find 3 non-colinear vertices
360
    int foundIndex = -1;
361 7cd30f7c Leszek Koltunski
362 33647db9 Leszek Koltunski
    for(int vertex=2; vertex<len; vertex++)
363 7cd30f7c Leszek Koltunski
      {
364 33647db9 Leszek Koltunski
      if( !areColinear(vert3D,0,1,vertex) )
365
        {
366
        foundIndex = vertex;
367
        break;
368
        }
369 7cd30f7c Leszek Koltunski
      }
370
371 33647db9 Leszek Koltunski
    // compute the normal vector
372
    if( foundIndex==-1 )
373
      {
374
      throw new RuntimeException("all vertices colinear");
375
      }
376 7cd30f7c Leszek Koltunski
377 33647db9 Leszek Koltunski
    computeNormalVector(vert3D,0,1,foundIndex);
378
379 140f2c4e Leszek Koltunski
    // rotate so that the normal vector becomes (0,0,1)
380
    float axisX, axisY, axisZ;
381
382 ef231eba Leszek Koltunski
    if( mBuffer[0]!=0.0f || mBuffer[1]!=0.0f )
383 33647db9 Leszek Koltunski
      {
384 140f2c4e Leszek Koltunski
      axisX = -mBuffer[1];
385
      axisY =  mBuffer[0];
386
      axisZ = 0.0f;
387 ef231eba Leszek Koltunski
388
      float axiLen = axisX*axisX + axisY*axisY + axisZ*axisZ;
389
      axiLen = (float)Math.sqrt(axiLen);
390
      axisX /= axiLen;
391
      axisY /= axiLen;
392
      axisZ /= axiLen;
393 140f2c4e Leszek Koltunski
      }
394
    else
395
      {
396
      axisX = 0.0f;
397
      axisY = 1.0f;
398
      axisZ = 0.0f;
399
      }
400 ef231eba Leszek Koltunski
401 140f2c4e Leszek Koltunski
    float cosTheta = mBuffer[2];
402
  //float sinTheta = axiLen / vecLen;
403 ef231eba Leszek Koltunski
404 140f2c4e Leszek Koltunski
    float sinHalfTheta = (float)Math.sqrt(0.5f*(1-cosTheta));
405
    float cosHalfTheta = (float)Math.sqrt(0.5f*(1+cosTheta));
406 ef231eba Leszek Koltunski
407 140f2c4e Leszek Koltunski
    mQuat1[0] = axisX*sinHalfTheta;
408
    mQuat1[1] = axisY*sinHalfTheta;
409
    mQuat1[2] = axisZ*sinHalfTheta;
410
    mQuat1[3] = cosHalfTheta;
411
    mQuat2[0] = axisX*sinHalfTheta;
412
    mQuat2[1] = axisY*sinHalfTheta;
413
    mQuat2[2] = axisZ*sinHalfTheta;
414
    mQuat2[3] = -cosHalfTheta;
415 ef231eba Leszek Koltunski
416 140f2c4e Leszek Koltunski
    for (float[] vert : vert3D)
417
      {
418
      quatMultiply(mQuat1, vert, mQuat3);
419
      quatMultiply(mQuat3, mQuat2, vert);
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 140f2c4e Leszek Koltunski
        if( tryFindingRotation(newInfo,info.vertices) )
598
          {
599
          android.util.Log.e("D", "comparing face "+face+" to "+previous+" SUCCESS!!");
600
          break;
601
          }
602 33647db9 Leszek Koltunski
        }
603 7edab735 Leszek Koltunski
604 33647db9 Leszek Koltunski
      mFaceInfo.add(newInfo);
605
      }
606 7edab735 Leszek Koltunski
    }
607
608 ef231eba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
609
610
  private void printInfo(FaceInfo info)
611
    {
612
    android.util.Log.e("D", "vx="+info.vx+" vy="+info.vy+" vz="+info.vz);
613
    android.util.Log.e("D", "qx="+info.qx+" qy="+info.qy+" qz="+info.qz+" qw="+info.qw);
614
    android.util.Log.e("D", "scale="+info.scale);
615
616
    String ver="";
617
618
    int len = info.vertices.length/2;
619
620
    for(int i =0; i<len; i++)
621
      {
622
      ver += ("("+info.vertices[2*i]+","+info.vertices[2*i+1]+") ");
623
      }
624
625
    android.util.Log.e("D", "vertices= "+ver);
626
    }
627
628 7edab735 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
629
630 33647db9 Leszek Koltunski
  MeshBase createRoundedSolid(final float[][] vertices, final int[][] vertIndexes, final float[][] bands, final int[] bandIndexes)
631 7edab735 Leszek Koltunski
    {
632 33647db9 Leszek Koltunski
    int EFFECTS_PER_FACE = 3;
633 7edab735 Leszek Koltunski
634 33647db9 Leszek Koltunski
    prepareFaceInfo(vertices,vertIndexes);
635 7edab735 Leszek Koltunski
636 33647db9 Leszek Koltunski
    int numFaces = vertIndexes.length;
637
    float[] band, bandsComputed;
638
    MeshBase[] meshes = new MeshBase[numFaces];
639
    FaceInfo info;
640 55f20739 Leszek Koltunski
641 33647db9 Leszek Koltunski
    for(int face=0; face<numFaces; face++)
642
      {
643
      info = mFaceInfo.get(face);
644 140f2c4e Leszek Koltunski
645
      android.util.Log.d("D", "--------------");
646
      printInfo(info);
647
648 33647db9 Leszek Koltunski
      band = bands[bandIndexes[face]];
649
      bandsComputed = computeBands( band[0], (int)band[1], band[2], band[3], (int)band[4]);
650
      meshes[face] = new MeshPolygon(info.vertices,bandsComputed,(int)band[5],(int)band[6]);
651
      meshes[face].setEffectAssociation(0,(1<<face),0);
652
      }
653 7edab735 Leszek Koltunski
654 33647db9 Leszek Koltunski
    MeshBase mesh = new MeshJoined(meshes);
655
    VertexEffect[] effects = new VertexEffect[EFFECTS_PER_FACE*numFaces];
656 7edab735 Leszek Koltunski
    Static3D center = new Static3D(0,0,0);
657 fe032f52 Leszek Koltunski
658 33647db9 Leszek Koltunski
    for(int face=0; face<numFaces; face++)
659
      {
660
      int assoc = (1<<face);
661
      info = mFaceInfo.get(face);
662 6d020cb6 Leszek Koltunski
663 33647db9 Leszek Koltunski
      Static3D move3D= new Static3D(info.vx,info.vy,info.vz);
664
      Static3D scale = new Static3D(info.scale,info.scale, info.flip ? -info.scale : info.scale);
665
      Static4D quat  = new Static4D(info.qx,info.qy,info.qz,info.qw);
666 6d020cb6 Leszek Koltunski
667 33647db9 Leszek Koltunski
      effects[EFFECTS_PER_FACE*face  ] = new VertexEffectScale(scale);
668
      effects[EFFECTS_PER_FACE*face+1] = new VertexEffectQuaternion(quat,center);
669
      effects[EFFECTS_PER_FACE*face+2] = new VertexEffectMove(move3D);
670 a65604a7 Leszek Koltunski
671 33647db9 Leszek Koltunski
      effects[EFFECTS_PER_FACE*face  ].setMeshAssociation(assoc,-1);
672
      effects[EFFECTS_PER_FACE*face+1].setMeshAssociation(assoc,-1);
673
      effects[EFFECTS_PER_FACE*face+2].setMeshAssociation(assoc,-1);
674
      }
675 a65604a7 Leszek Koltunski
676
    for( VertexEffect effect : effects ) mesh.apply(effect);
677
678 7edab735 Leszek Koltunski
    return mesh;
679
    }
680
  }