Project

General

Profile

Download (21.6 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / magic / RubikCube.java @ ffd48105

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted 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
// Distorted 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 Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.magic;
21

    
22
import android.graphics.Bitmap;
23
import android.graphics.Canvas;
24
import android.graphics.Paint;
25

    
26
import org.distorted.library.effect.Effect;
27
import org.distorted.library.effect.EffectType;
28
import org.distorted.library.effect.MatrixEffectMove;
29
import org.distorted.library.effect.MatrixEffectQuaternion;
30
import org.distorted.library.effect.MatrixEffectRotate;
31
import org.distorted.library.effect.MatrixEffectScale;
32
import org.distorted.library.effect.VertexEffectSink;
33
import org.distorted.library.effectqueue.EffectQueue;
34
import org.distorted.library.main.DistortedEffects;
35
import org.distorted.library.main.DistortedNode;
36
import org.distorted.library.main.DistortedTexture;
37
import org.distorted.library.mesh.MeshCubes;
38
import org.distorted.library.mesh.MeshFlat;
39
import org.distorted.library.message.EffectListener;
40
import org.distorted.library.type.Dynamic1D;
41
import org.distorted.library.type.Static1D;
42
import org.distorted.library.type.Static3D;
43
import org.distorted.library.type.Static4D;
44

    
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

    
47
public class RubikCube extends DistortedNode
48
{
49
    private static final int POST_ROTATION_MILLISEC = 500;
50
    private static final int TEXTURE_SIZE = 100;
51

    
52
    private static final Static3D VectX = new Static3D(1,0,0);
53
    private static final Static3D VectY = new Static3D(0,1,0);
54
    private static final Static3D VectZ = new Static3D(0,0,1);
55

    
56
    private DistortedNode[][][] mNodes;
57
    private MeshCubes[][][] mCubes;
58
    private DistortedEffects[][][] mEffects;
59
    private Static4D[][][] mQuatScramble;
60
    private Static3D[][][] mRotationAxis;
61
    private Dynamic1D[][][] mRotationAngle;
62
    private Static3D[][][] mCurrentPosition;
63
    private MatrixEffectRotate[][][] mRotateEffect;
64
    private Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
65
    private Static3D mMove, mScale, mNodeMove, mNodeScale;
66
    private DistortedTexture mTexture;
67

    
68
    private int mRotAxis, mRotRow;
69
    private int mSize;
70

    
71
    private DistortedTexture mNodeTexture;
72

    
73
///////////////////////////////////////////////////////////////////////////////////////////////////
74

    
75
    RubikCube(int size, Static4D quatCur, Static4D quatAcc, DistortedTexture texture, MeshFlat mesh, DistortedEffects effects)
76
      {
77
      super(texture,effects,mesh);
78

    
79
      mNodeTexture = texture;
80

    
81
      mSize = size;
82

    
83
      mRotationAngleStatic = new Static1D(0);
84
      mRotationAngleMiddle = new Static1D(0);
85
      mRotationAngleFinal  = new Static1D(0);
86

    
87
      mMove     = new Static3D(0,0,0);
88
      mScale    = new Static3D(1,1,1);
89
      mNodeMove = new Static3D(0,0,0);
90
      mNodeScale= new Static3D(1,1,1);
91

    
92
      mRotAxis= RubikSurfaceView.VECTX;
93
      mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
94

    
95
      mNodes          = new DistortedNode[mSize][mSize][mSize];
96
      mCubes          = new MeshCubes[mSize][mSize][mSize];
97
      mEffects        = new DistortedEffects[mSize][mSize][mSize];
98
      mQuatScramble   = new Static4D[mSize][mSize][mSize];
99
      mRotationAxis   = new Static3D[mSize][mSize][mSize];
100
      mRotationAngle  = new Dynamic1D[mSize][mSize][mSize];
101
      mCurrentPosition= new Static3D[mSize][mSize][mSize];
102
      mRotateEffect   = new MatrixEffectRotate[mSize][mSize][mSize];
103

    
104
      Static3D[][][] cubeVectors = new Static3D[mSize][mSize][mSize];
105

    
106
      Static3D sinkCenter = new Static3D(TEXTURE_SIZE*0.5f, TEXTURE_SIZE*0.5f, TEXTURE_SIZE*0.5f);
107
      Static3D matrCenter = new Static3D(0,0,0);
108
      Static4D region = new Static4D(0,0,0, TEXTURE_SIZE*0.72f);
109

    
110
      VertexEffectSink        sinkEffect = new VertexEffectSink( new Static1D(getSinkStrength()), sinkCenter, region );
111
      MatrixEffectMove        moveEffect = new MatrixEffectMove(mMove);
112
      MatrixEffectScale      scaleEffect = new MatrixEffectScale(mScale);
113
      MatrixEffectQuaternion quatCEffect = new MatrixEffectQuaternion(quatCur, matrCenter);
114
      MatrixEffectQuaternion quatAEffect = new MatrixEffectQuaternion(quatAcc, matrCenter);
115

    
116
      MatrixEffectMove       nodeMoveEffect  = new MatrixEffectMove(mNodeMove);
117
      MatrixEffectScale      nodeScaleEffect = new MatrixEffectScale(mNodeScale);
118

    
119
      effects.apply(nodeScaleEffect);
120
      effects.apply(nodeMoveEffect);
121

    
122
      // 3x2 bitmap = 6 squares:
123
      //
124
      // RED     GREEN   BLUE
125
      // YELLOW  WHITE   BROWN
126

    
127
      final float ze = 0.0f;
128
      final float ot = 1.0f/3.0f;
129
      final float tt = 2.0f/3.0f;
130
      final float oh = 1.0f/2.0f;
131
      final float of = 1.0f/40.0f;
132

    
133
      final Static4D mapFront = new Static4D(ze,oh, ze+ot,oh+oh);
134
      final Static4D mapBack  = new Static4D(tt,ze, tt+ot,ze+oh);
135
      final Static4D mapLeft  = new Static4D(ot,ze, ot+ot,ze+oh);
136
      final Static4D mapRight = new Static4D(ze,ze, ze+ot,ze+oh);
137
      final Static4D mapTop   = new Static4D(tt,oh, tt+ot,oh+oh);
138
      final Static4D mapBottom= new Static4D(ot,oh, ot+ot,oh+oh);
139

    
140
      final Static4D mapBlack = new Static4D(ze,ze, ze+of,ze+of);
141

    
142
      Static4D tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom;
143
      float nc = 0.5f*mSize;
144
      int vertices = (int)(24.0f/mSize + 2.0f);
145

    
146
      for(int x = 0; x< mSize; x++)
147
        for(int y = 0; y< mSize; y++)
148
          for(int z = 0; z< mSize; z++)
149
            {
150
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) // only the external walls
151
              {
152
              tmpLeft  = (x==       0 ? mapLeft  :mapBlack);
153
              tmpRight = (x== mSize-1 ? mapRight :mapBlack);
154
              tmpFront = (z== mSize-1 ? mapFront :mapBlack);
155
              tmpBack  = (z==       0 ? mapBack  :mapBlack);
156
              tmpTop   = (y== mSize-1 ? mapTop   :mapBlack);
157
              tmpBottom= (y==       0 ? mapBottom:mapBlack);
158

    
159
              mCubes[x][y][z]           = new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
160
              cubeVectors[x][y][z]      = new Static3D( TEXTURE_SIZE*(x-nc), TEXTURE_SIZE*(y-nc), TEXTURE_SIZE*(z-nc) );
161
              mQuatScramble[x][y][z]    = new Static4D(0,0,0,1);
162
              mRotationAngle[x][y][z]   = new Dynamic1D();
163
              mRotationAxis[x][y][z]    = new Static3D(1,0,0);
164
              mCurrentPosition[x][y][z] = new Static3D(x,y,z);
165
              mRotateEffect[x][y][z]    = new MatrixEffectRotate(mRotationAngle[x][y][z], mRotationAxis[x][y][z], matrCenter);
166

    
167
              mEffects[x][y][z] = new DistortedEffects();
168
              mEffects[x][y][z].apply(sinkEffect);
169
              mEffects[x][y][z].apply( new MatrixEffectMove(cubeVectors[x][y][z]) );
170
              mEffects[x][y][z].apply( new MatrixEffectQuaternion(mQuatScramble[x][y][z], matrCenter));
171
              mEffects[x][y][z].apply(mRotateEffect[x][y][z]);
172
              mEffects[x][y][z].apply(quatAEffect);
173
              mEffects[x][y][z].apply(quatCEffect);
174
              mEffects[x][y][z].apply(scaleEffect);
175
              mEffects[x][y][z].apply(moveEffect);
176

    
177
              mNodes[x][y][z] = new DistortedNode(mTexture,mEffects[x][y][z],mCubes[x][y][z]);
178

    
179
              attach(mNodes[x][y][z]);
180
              }
181
            }
182
      }
183

    
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

    
186
    public void apply(Effect effect, int position)
187
      {
188
      for(int x=0; x<mSize; x++)
189
        for(int y=0; y<mSize; y++)
190
          for(int z=0; z<mSize; z++)
191
            {
192
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
193
              {
194
              mEffects[x][y][z].apply(effect, position);
195
              }
196
            }
197
      }
198

    
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200

    
201
    public void remove(long effectID)
202
      {
203
      for(int x=0; x<mSize; x++)
204
        for(int y=0; y<mSize; y++)
205
          for(int z=0; z<mSize; z++)
206
            {
207
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
208
              {
209
              mEffects[x][y][z].abortById(effectID);
210
              }
211
            }
212
      }
213

    
214
///////////////////////////////////////////////////////////////////////////////////////////////////
215

    
216
    public void unscramble()
217
      {
218
      for(int x=0; x<mSize; x++)
219
        for(int y=0; y<mSize; y++)
220
          for(int z=0; z<mSize; z++)
221
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
222
              {
223
              mQuatScramble[x][y][z].set(0,0,0,1);
224
              mCurrentPosition[x][y][z].set(x,y,z);
225
              }
226
      }
227

    
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

    
230
    public String print_effects()
231
      {
232
      String str="";
233

    
234
      EffectQueue[] effects = mEffects[0][0][0].getQueues();
235
      EffectQueue matrix      = effects[0];
236
      EffectQueue vertex      = effects[1];
237
      EffectQueue fragment    = effects[2];
238
      EffectQueue postprocess = effects[3];
239

    
240
      str+="MATRIX: ";
241
      int m_len = matrix.getNumEffects();
242
      for(int i=0; i<m_len; i++)
243
        {
244
        str+=(" "+matrix.getEffect(i).getName()+"("+matrix.getEffect(i).getID()+")" );
245
        }
246
      str+='\n';
247

    
248
      str+="VERTEX: ";
249
      int v_len = vertex.getNumEffects();
250
      for(int i=0; i<v_len; i++)
251
        {
252
        str+=(" "+vertex.getEffect(i).getName()+"("+matrix.getEffect(i).getID()+")" );
253
        }
254
      str+='\n';
255

    
256
      str+="FRAGMENT: ";
257
      int f_len = fragment.getNumEffects();
258
      for(int i=0; i<f_len; i++)
259
        {
260
        str+=(" "+fragment.getEffect(i).getName()+"("+matrix.getEffect(i).getID()+")" );
261
        }
262
      str+='\n';
263

    
264
      str+="POSTPROCESS: ";
265
      int p_len = postprocess.getNumEffects();
266
      for(int i=0; i<p_len; i++)
267
        {
268
        str+=(" "+postprocess.getEffect(i).getName()+"("+matrix.getEffect(i).getID()+")" );
269
        }
270
      str+='\n';
271

    
272
      return str;
273
      }
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
    public int getNumEffects(EffectType type)
277
      {
278
      return mEffects[0][0][0].getNumEffects(type);
279
      }
280

    
281
///////////////////////////////////////////////////////////////////////////////////////////////////
282
// all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of
283
// Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major
284
// memory leak.
285

    
286
    void releaseResources()
287
      {
288
      mTexture.markForDeletion();
289

    
290
      for(int x=0; x<mSize; x++)
291
        for(int y=0; y<mSize; y++)
292
          for(int z=0; z<mSize; z++)
293
            {
294
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
295
              {
296
              mCubes[x][y][z].markForDeletion();
297
              mNodes[x][y][z].markForDeletion();
298
              }
299
            }
300
      }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
    void addNewRotation(int vector, int row )
305
      {
306
      Static3D axis = VectX;
307

    
308
      switch(vector)
309
        {
310
        case RubikSurfaceView.VECTX: axis = VectX; break;
311
        case RubikSurfaceView.VECTY: axis = VectY; break;
312
        case RubikSurfaceView.VECTZ: axis = VectZ; break;
313
        }
314

    
315
      mRotAxis = vector;
316
      mRotRow  = row;
317

    
318
      mRotationAngleStatic.set1(0.0f);
319

    
320
      for(int x=0; x<mSize; x++)
321
        for(int y=0; y<mSize; y++)
322
          for(int z=0; z<mSize; z++)
323
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
324
              {
325
              if( belongsToRotation(x,y,z,vector,mRotRow) )
326
                {
327
                mRotationAxis[x][y][z].set(axis);
328
                mRotationAngle[x][y][z].add(mRotationAngleStatic);
329
                }
330
              }
331
      }
332

    
333
///////////////////////////////////////////////////////////////////////////////////////////////////
334

    
335
    void continueRotation(float angleInDegrees)
336
      {
337
      mRotationAngleStatic.set1(angleInDegrees);
338
      }
339

    
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341

    
342
    private int computeNearestAngle(float angle)
343
      {
344
      final int NEAREST = 90;
345

    
346
      int tmp = (int)((angle+NEAREST/2)/NEAREST);
347
      if( angle< -(NEAREST/2) ) tmp-=1;
348

    
349
      return NEAREST*tmp;
350
      }
351

    
352
///////////////////////////////////////////////////////////////////////////////////////////////////
353

    
354
    long finishRotationNow(EffectListener listener)
355
      {
356
      boolean first = true;
357
      long effectID=0;
358

    
359
      for(int x=0; x<mSize; x++)
360
        for(int y=0; y<mSize; y++)
361
          for(int z=0; z<mSize; z++)
362
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
363
              {
364
              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
365
                {
366
                if( first )
367
                  {
368
                  first = false;
369
                  mRotateEffect[x][y][z].notifyWhenFinished(listener);
370
                  effectID = mRotateEffect[x][y][z].getID();
371
                  int pointNum = mRotationAngle[x][y][z].getNumPoints();
372

    
373
                  if( pointNum>=1 )
374
                    {
375
                    float startingAngle = mRotationAngle[x][y][z].getPoint(pointNum-1).get1();
376
                    int nearestAngleInDegrees = computeNearestAngle(startingAngle);
377
                    mRotationAngleStatic.set1(startingAngle);
378
                    mRotationAngleFinal.set1(nearestAngleInDegrees);
379
                    mRotationAngleMiddle.set1( nearestAngleInDegrees + (nearestAngleInDegrees-startingAngle)*0.2f );
380
                    }
381
                  else
382
                    {
383
                    android.util.Log.e("cube", "ERROR finishing rotation!");
384
                    return 0;
385
                    }
386
                  }
387

    
388
                mRotationAngle[x][y][z].setDuration(POST_ROTATION_MILLISEC);
389
                mRotationAngle[x][y][z].resetToBeginning();
390
                mRotationAngle[x][y][z].removeAll();
391
                mRotationAngle[x][y][z].add(mRotationAngleStatic);
392
                mRotationAngle[x][y][z].add(mRotationAngleMiddle);
393
                mRotationAngle[x][y][z].add(mRotationAngleFinal);
394
                }
395
              }
396

    
397
      return effectID;
398
      }
399

    
400
///////////////////////////////////////////////////////////////////////////////////////////////////
401

    
402
    void removeRotationNow()
403
      {
404
      int nearestAngleInDegrees = computeNearestAngle(mRotationAngleStatic.get1());
405
      double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
406
      float sinA =-(float)Math.sin(nearestAngleInRadians*0.5);
407
      float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
408

    
409
      mRotationAngleStatic.set1(0);
410

    
411
      float qx=0,qy=0,qz=0;
412

    
413
      switch(mRotAxis)
414
        {
415
        case RubikSurfaceView.VECTX: qx=1; break;
416
        case RubikSurfaceView.VECTY: qy=1; break;
417
        case RubikSurfaceView.VECTZ: qz=1; break;
418
        }
419

    
420
      Static4D quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
421

    
422
      for(int x=0; x<mSize; x++)
423
        for(int y=0; y<mSize; y++)
424
          for(int z=0; z<mSize; z++)
425
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
426
              {
427
              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
428
                {
429
                mRotationAngle[x][y][z].removeAll();
430
                mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z]));
431
                modifyCurrentPosition(x,y,z,quat);
432
                }
433
              }
434
      }
435

    
436
///////////////////////////////////////////////////////////////////////////////////////////////////
437

    
438
    private float getSinkStrength()
439
      {
440
      switch(mSize)
441
        {
442
        case 1 : return 1.1f;
443
        case 2 : return 1.5f;
444
        case 3 : return 1.8f;
445
        case 4 : return 2.0f;
446
        default: return 3.0f - 4.0f/mSize;
447
        }
448
      }
449

    
450
///////////////////////////////////////////////////////////////////////////////////////////////////
451

    
452
    private boolean belongsToRotation(int x, int y, int z, int vector, int row)
453
      {
454
      switch(vector)
455
        {
456
        case RubikSurfaceView.VECTX: return mCurrentPosition[x][y][z].get1()==row;
457
        case RubikSurfaceView.VECTY: return mCurrentPosition[x][y][z].get2()==row;
458
        case RubikSurfaceView.VECTZ: return mCurrentPosition[x][y][z].get3()==row;
459
        }
460

    
461
      return false;
462
      }
463

    
464
///////////////////////////////////////////////////////////////////////////////////////////////////
465

    
466
    private void modifyCurrentPosition(int x, int y, int z, Static4D quat)
467
      {
468
      Static3D current = mCurrentPosition[x][y][z];
469
      float diff = 0.5f*(mSize-1);
470
      float cubitCenterX = current.get1() - diff;
471
      float cubitCenterY = current.get2() - diff;
472
      float cubitCenterZ = current.get3() - diff;
473

    
474
      Static4D cubitCenter =  new Static4D(cubitCenterX, cubitCenterY, cubitCenterZ, 0);
475
      Static4D rotatedCenter = RubikSurfaceView.rotateVectorByQuat( cubitCenter, quat);
476

    
477
      float rotatedX = rotatedCenter.get1() + diff;
478
      float rotatedY = rotatedCenter.get2() + diff;
479
      float rotatedZ = rotatedCenter.get3() + diff;
480

    
481
      int roundedX = (int)(rotatedX+0.1f);
482
      int roundedY = (int)(rotatedY+0.1f);
483
      int roundedZ = (int)(rotatedZ+0.1f);
484

    
485
      mCurrentPosition[x][y][z].set1(roundedX);
486
      mCurrentPosition[x][y][z].set2(roundedY);
487
      mCurrentPosition[x][y][z].set3(roundedZ);
488
      }
489

    
490
///////////////////////////////////////////////////////////////////////////////////////////////////
491

    
492
    void createTexture()
493
      {
494
      Bitmap bitmap;
495

    
496
      final int S = 128;
497
      final int W = 3*S;
498
      final int H = 2*S;
499
      final int R = S/10;
500
      final int M = S/20;
501

    
502
      Paint paint = new Paint();
503
      bitmap = Bitmap.createBitmap(W,H, Bitmap.Config.ARGB_8888);
504
      Canvas canvas = new Canvas(bitmap);
505

    
506
      paint.setAntiAlias(true);
507
      paint.setTextAlign(Paint.Align.CENTER);
508
      paint.setStyle(Paint.Style.FILL);
509

    
510
      // 3x2 bitmap = 6 squares:
511
      //
512
      // RED     GREEN   BLUE
513
      // YELLOW  WHITE   BROWN
514

    
515
      paint.setColor(0xff000000);                                  // BLACK BACKGROUND
516
      canvas.drawRect(0, 0, W, H, paint);                          //
517

    
518
      paint.setColor(0xffff0000);                                  // RED
519
      canvas.drawRoundRect(    M,   M,   S-M,   S-M, R, R, paint); //
520
      paint.setColor(0xff00ff00);                                  // GREEN
521
      canvas.drawRoundRect(  S+M,   M, 2*S-M,   S-M, R, R, paint); //
522
      paint.setColor(0xff0000ff);                                  // BLUE
523
      canvas.drawRoundRect(2*S+M,   M, 3*S-M,   S-M, R, R, paint); //
524
      paint.setColor(0xffffff00);                                  // YELLOW
525
      canvas.drawRoundRect(    M, S+M,   S-M, 2*S-M, R, R, paint); //
526
      paint.setColor(0xffffffff);                                  // WHITE
527
      canvas.drawRoundRect(  S+M, S+M, 2*S-M, 2*S-M, R, R, paint); //
528
      paint.setColor(0xffb5651d);                                  // BROWN
529
      canvas.drawRoundRect(2*S+M, S+M, 3*S-M, 2*S-M, R, R, paint); //
530

    
531
      mTexture.setTexture(bitmap);
532
      }
533

    
534
///////////////////////////////////////////////////////////////////////////////////////////////////
535

    
536
   void recomputeScaleFactor(int screenWidth, int screenHeight, float size)
537
     {
538
     int texW = mNodeTexture.getWidth();
539
     int texH = mNodeTexture.getHeight();
540

    
541
     if( (float)texH/texW > (float)screenHeight/screenWidth )
542
       {
543
       int w = (screenHeight*texW)/texH;
544
       float factor = (float)screenHeight/texH;
545
       mNodeMove.set((screenWidth-w)*0.5f ,0, 0);
546
       mNodeScale.set(factor,factor,factor);
547
       }
548
     else
549
       {
550
       int h = (screenWidth*texH)/texW;
551
       float factor = (float)screenWidth/texW;
552
       mNodeMove.set(0,(screenHeight-h)*0.5f,0);
553
       mNodeScale.set(factor,factor,factor);
554
       }
555

    
556
     float scaleFactor = (size/(TEXTURE_SIZE*mSize)) * (float)texW/(screenWidth>screenHeight ? screenHeight:screenWidth);
557

    
558
     mMove.set( texW*0.5f , texH*0.5f , 0.0f );
559
     mScale.set(scaleFactor,scaleFactor,scaleFactor);
560
     }
561

    
562
///////////////////////////////////////////////////////////////////////////////////////////////////
563

    
564
    int getSize()
565
      {
566
      return mSize;
567
      }
568
}
(3-3/6)