Project

General

Profile

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

library / src / main / java / org / distorted / library / EffectQueueMatrix.java @ a15631bc

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 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.library;
21

    
22
import android.opengl.GLES30;
23
import android.opengl.Matrix;
24

    
25
import org.distorted.library.message.EffectMessage;
26
import org.distorted.library.type.Data1D;
27
import org.distorted.library.type.Data3D;
28
import org.distorted.library.type.Data4D;
29
import org.distorted.library.type.Dynamic1D;
30
import org.distorted.library.type.Dynamic3D;
31
import org.distorted.library.type.Dynamic4D;
32
import org.distorted.library.type.DynamicQuat;
33
import org.distorted.library.type.Static1D;
34
import org.distorted.library.type.Static3D;
35
import org.distorted.library.type.Static4D;
36

    
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38

    
39
class EffectQueueMatrix extends EffectQueue
40
  {   
41
  private static final int NUM_UNIFORMS = 7;
42
  private static final int NUM_CACHE    = 0;
43
  private static final int INDEX = EffectTypes.MATRIX.ordinal();
44

    
45
  private static float[] mMVPMatrix = new float[16];
46
  private static float[] mTmpMatrix = new float[16];
47
  private static float[] mViewMatrix= new float[16];
48

    
49
  private static int mObjDH;      // This is a handle to half a Object dimensions
50
  private static int mMVPMatrixH; // pass in the transformation matrix
51
  private static int mMVMatrixH;  // pass in the modelview matrix.
52
  
53
///////////////////////////////////////////////////////////////////////////////////////////////////
54
   
55
  EffectQueueMatrix(long id)
56
    { 
57
    super(id,NUM_UNIFORMS,NUM_CACHE,INDEX );
58
    }
59

    
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

    
62
  private static void multiplyByQuat(float[] matrix, float X, float Y, float Z, float W)
63
    {
64
    float xx= X * X;
65
    float xy= X * Y;
66
    float xz= X * Z;
67
    float xw= X * W;
68
    float yy= Y * Y;
69
    float yz= Y * Z;
70
    float yw= Y * W;
71
    float zz= Z * Z;
72
    float zw= Z * W;
73

    
74
    mTmpMatrix[0]  = 1 - 2 * ( yy + zz );
75
    mTmpMatrix[1]  =     2 * ( xy - zw );
76
    mTmpMatrix[2]  =     2 * ( xz + yw );
77
    mTmpMatrix[4]  =     2 * ( xy + zw );
78
    mTmpMatrix[5]  = 1 - 2 * ( xx + zz );
79
    mTmpMatrix[6]  =     2 * ( yz - xw );
80
    mTmpMatrix[8]  =     2 * ( xz - yw );
81
    mTmpMatrix[9]  =     2 * ( yz + xw );
82
    mTmpMatrix[10] = 1 - 2 * ( xx + yy );
83
    mTmpMatrix[3]  = mTmpMatrix[7] = mTmpMatrix[11] = mTmpMatrix[12] = mTmpMatrix[13] = mTmpMatrix[14] = 0;
84
    mTmpMatrix[15] = 1;
85
    
86
    Matrix.multiplyMM(mMVPMatrix, 0, matrix, 0, mTmpMatrix, 0);  
87

    
88
    matrix[ 0] = mMVPMatrix[ 0];
89
    matrix[ 1] = mMVPMatrix[ 1];
90
    matrix[ 2] = mMVPMatrix[ 2];
91
    matrix[ 3] = mMVPMatrix[ 3];
92
    matrix[ 4] = mMVPMatrix[ 4];
93
    matrix[ 5] = mMVPMatrix[ 5];
94
    matrix[ 6] = mMVPMatrix[ 6];
95
    matrix[ 7] = mMVPMatrix[ 7];
96
    matrix[ 8] = mMVPMatrix[ 8];
97
    matrix[ 9] = mMVPMatrix[ 9];
98
    matrix[10] = mMVPMatrix[10];
99
    matrix[11] = mMVPMatrix[11];
100
    matrix[12] = mMVPMatrix[12];
101
    matrix[13] = mMVPMatrix[13];
102
    matrix[14] = mMVPMatrix[14];
103
    matrix[15] = mMVPMatrix[15];
104
    }
105

    
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

    
108
  private void magnify(float halfX, float halfY, float halfZ, DistortedOutputSurface projection)
109
    {
110
    float scale;
111
    float[] result= new float[4];
112
    float[] point = new float[4];
113
    float[] matrix= new float[16];
114
    double d1, d2, d3, d4, d5, d6, d7, d8;
115
    float nx, ny;
116
    float w = projection.mWidth/2;
117
    float h = projection.mHeight/2;
118
    double sum = 0.0;
119
    point[3] = 0.0f;
120

    
121
    Matrix.multiplyMM(matrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
122

    
123
    point[0] = +halfX; point[1] = +halfY; point[2] = +halfZ;
124
    Matrix.multiplyMV(result,0,matrix,0,point,0);
125
    nx = w*result[0]/result[3];
126
    ny = h*result[1]/result[3];
127
    d1 = Math.sqrt(nx*nx+ny*ny);
128

    
129
    point[0] = +halfX; point[1] = +halfY; point[2] = -halfZ;
130
    Matrix.multiplyMV(result,0,matrix,0,point,0);
131
    nx = w*result[0]/result[3];
132
    ny = h*result[1]/result[3];
133
    d2 = Math.sqrt(nx*nx+ny*ny);
134

    
135
    point[0] = +halfX; point[1] = -halfY; point[2] = +halfZ;
136
    Matrix.multiplyMV(result,0,matrix,0,point,0);
137
    nx = w*result[0]/result[3];
138
    ny = h*result[1]/result[3];
139
    d3 = Math.sqrt(nx*nx+ny*ny);
140

    
141
    point[0] = +halfX; point[1] = -halfY; point[2] = -halfZ;
142
    Matrix.multiplyMV(result,0,matrix,0,point,0);
143
    nx = w*result[0]/result[3];
144
    ny = h*result[1]/result[3];
145
    d4 = Math.sqrt(nx*nx+ny*ny);
146

    
147
    point[0] = -halfX; point[1] = +halfY; point[2] = +halfZ;
148
    Matrix.multiplyMV(result,0,matrix,0,point,0);
149
    nx = w*result[0]/result[3];
150
    ny = h*result[1]/result[3];
151
    d5 = Math.sqrt(nx*nx+ny*ny);
152

    
153
    point[0] = -halfX; point[1] = +halfY; point[2] = -halfZ;
154
    Matrix.multiplyMV(result,0,matrix,0,point,0);
155
    nx = w*result[0]/result[3];
156
    ny = h*result[1]/result[3];
157
    d6 = Math.sqrt(nx*nx+ny*ny);
158

    
159
    point[0] = -halfX; point[1] = -halfY; point[2] = +halfZ;
160
    Matrix.multiplyMV(result,0,matrix,0,point,0);
161
    nx = w*result[0]/result[3];
162
    ny = h*result[1]/result[3];
163
    d7 = Math.sqrt(nx*nx+ny*ny);
164

    
165
    point[0] = -halfX; point[1] = -halfY; point[2] = -halfZ;
166
    Matrix.multiplyMV(result,0,matrix,0,point,0);
167
    nx = w*result[0]/result[3];
168
    ny = h*result[1]/result[3];
169
    d8 = Math.sqrt(nx*nx+ny*ny);
170

    
171
    sum = (d1+d2+d3+d4+d5+d6+d7+d8)/8;
172

    
173
    scale = 1.0f + (float)(Distorted.mMargin/sum);
174

    
175
    android.util.Log.d("scale", "scale="+scale+" sum="+sum+" "+d1+" "+d2+" "+d3+" "+d4+" "+d5+" "+d6+" "+d7+" "+d8);
176

    
177
    Matrix.scaleM(mViewMatrix, 0, scale, scale, scale);
178
    }
179

    
180
///////////////////////////////////////////////////////////////////////////////////////////////////
181
// here construct the ModelView and the ModelViewProjection Matrices
182

    
183
  private void constructMatrices(DistortedOutputSurface projection, float halfX, float halfY, float halfZ)
184
    {
185
    Matrix.setIdentityM(mViewMatrix, 0);
186
    Matrix.translateM(mViewMatrix, 0, -projection.mWidth/2, projection.mHeight/2, -projection.mDistance);
187

    
188
    float x,y,z, sx,sy,sz;
189
    float mipmap = projection.mMipmap;
190

    
191
    if( mipmap!=1 ) Matrix.scaleM(mViewMatrix, 0, mipmap, mipmap, mipmap);
192

    
193
    for(int i=0; i<mNumEffects; i++)
194
      {
195
      if (mName[i] == EffectNames.ROTATE.ordinal() )
196
        {
197
        x = mUniforms[NUM_UNIFORMS*i+4];
198
        y = mUniforms[NUM_UNIFORMS*i+5];
199
        z = mUniforms[NUM_UNIFORMS*i+6];
200

    
201
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
202
        Matrix.rotateM( mViewMatrix, 0, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]);
203
        Matrix.translateM(mViewMatrix, 0,-x, y,-z);
204
        }
205
      else if(mName[i] == EffectNames.QUATERNION.ordinal() )
206
        {
207
        x = mUniforms[NUM_UNIFORMS*i+4];
208
        y = mUniforms[NUM_UNIFORMS*i+5];
209
        z = mUniforms[NUM_UNIFORMS*i+6];
210

    
211
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
212
        multiplyByQuat(mViewMatrix, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]);
213
        Matrix.translateM(mViewMatrix, 0,-x, y,-z);
214
        }
215
      else if(mName[i] == EffectNames.MOVE.ordinal() )
216
        {
217
        sx = mUniforms[NUM_UNIFORMS*i  ];
218
        sy = mUniforms[NUM_UNIFORMS*i+1];
219
        sz = mUniforms[NUM_UNIFORMS*i+2];
220

    
221
        Matrix.translateM(mViewMatrix, 0, sx,-sy, sz);
222
        }
223
      else if(mName[i] == EffectNames.SCALE.ordinal() )
224
        {
225
        sx = mUniforms[NUM_UNIFORMS*i  ];
226
        sy = mUniforms[NUM_UNIFORMS*i+1];
227
        sz = mUniforms[NUM_UNIFORMS*i+2];
228

    
229
        Matrix.scaleM(mViewMatrix, 0, sx, sy, sz);
230
        }
231
      else if(mName[i] == EffectNames.SHEAR.ordinal() )
232
        {
233
        sx = mUniforms[NUM_UNIFORMS*i  ];
234
        sy = mUniforms[NUM_UNIFORMS*i+1];
235
        sz = mUniforms[NUM_UNIFORMS*i+2];
236

    
237
        x  = mUniforms[NUM_UNIFORMS*i+4];
238
        y  = mUniforms[NUM_UNIFORMS*i+5];
239
        z  = mUniforms[NUM_UNIFORMS*i+6];
240

    
241
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
242

    
243
        mViewMatrix[4] += sx*mViewMatrix[0]; // Multiply viewMatrix by 1 x 0 0 , i.e. X-shear.
244
        mViewMatrix[5] += sx*mViewMatrix[1]; //                        0 1 0 0
245
        mViewMatrix[6] += sx*mViewMatrix[2]; //                        0 0 1 0
246
        mViewMatrix[7] += sx*mViewMatrix[3]; //                        0 0 0 1
247

    
248
        mViewMatrix[0] += sy*mViewMatrix[4]; // Multiply viewMatrix by 1 0 0 0 , i.e. Y-shear.
249
        mViewMatrix[1] += sy*mViewMatrix[5]; //                        y 1 0 0
250
        mViewMatrix[2] += sy*mViewMatrix[6]; //                        0 0 1 0
251
        mViewMatrix[3] += sy*mViewMatrix[7]; //                        0 0 0 1
252

    
253
        mViewMatrix[4] += sz*mViewMatrix[8]; // Multiply viewMatrix by 1 0 0 0 , i.e. Z-shear.
254
        mViewMatrix[5] += sz*mViewMatrix[9]; //                        0 1 0 0
255
        mViewMatrix[6] += sz*mViewMatrix[10];//                        0 z 1 0
256
        mViewMatrix[7] += sz*mViewMatrix[11];//                        0 0 0 1
257

    
258
        Matrix.translateM(mViewMatrix, 0,-x, y, -z);
259
        }
260
      }
261

    
262
    Matrix.translateM(mViewMatrix, 0, halfX,-halfY,-halfZ);
263

    
264
    if( Distorted.mMargin!=0 ) magnify(halfX,halfY,halfZ,projection);
265

    
266
    Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
267
    }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

    
271
  static void getUniforms(int mProgramH)
272
    {
273
    mObjDH     = GLES30.glGetUniformLocation(mProgramH, "u_objD");
274
    mMVPMatrixH= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
275
    mMVMatrixH = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  synchronized void compute(long currTime) 
281
    {
282
    if( currTime==mTime ) return;
283
    if( mTime==0 ) mTime = currTime;
284
    long step = (currTime-mTime);
285
   
286
    for(int i=0; i<mNumEffects; i++)
287
      {
288
      mCurrentDuration[i] += step;
289

    
290
      if( mInter[0][i]!=null && mInter[0][i].interpolateMain(mUniforms ,NUM_UNIFORMS*i, mCurrentDuration[i], step) )
291
        {
292
        for(int j=0; j<mNumListeners; j++)
293
          EffectMessageSender.newMessage( mListeners.elementAt(j),
294
                                          EffectMessage.EFFECT_FINISHED,
295
                                         (mID[i]<<EffectTypes.LENGTH)+EffectTypes.MATRIX.type,
296
                                          mName[i],
297
                                          mObjectID);
298

    
299
        if( EffectNames.isUnity(mName[i], mUniforms, NUM_UNIFORMS*i) )
300
          {
301
          remove(i);
302
          i--;
303
          continue;
304
          }
305
        else mInter[0][i] = null;
306
        }
307

    
308
      if( mInter[1][i]!=null )
309
        {
310
        mInter[1][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+4, mCurrentDuration[i], step);
311
        }
312
      }
313
     
314
    mTime = currTime;  
315
    }  
316

    
317
///////////////////////////////////////////////////////////////////////////////////////////////////
318

    
319
  protected void moveEffect(int index)
320
    {
321
    mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
322
    mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
323
    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];
324
    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];
325
    mUniforms[NUM_UNIFORMS*index+4] = mUniforms[NUM_UNIFORMS*(index+1)+4];
326
    mUniforms[NUM_UNIFORMS*index+5] = mUniforms[NUM_UNIFORMS*(index+1)+5];
327
    mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
328
    }
329

    
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331

    
332
  float[] getMVP()
333
    {
334
    return mMVPMatrix;
335
    }
336

    
337
///////////////////////////////////////////////////////////////////////////////////////////////////
338

    
339
  synchronized void send(DistortedOutputSurface projection, float halfX, float halfY, float halfZ)
340
    {
341
    constructMatrices(projection,halfX,halfY,halfZ);
342

    
343
    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
344
    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
345
    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349
// move, scale
350

    
351
  synchronized long add(EffectNames eln, Data3D vector)
352
    {
353
    if( mMax[INDEX]>mNumEffects )
354
      {
355
      mInter[1][mNumEffects] = null;
356

    
357
      if( vector instanceof Dynamic3D)
358
        {
359
        mInter[0][mNumEffects] = (Dynamic3D)vector;
360
        }
361
      else if( vector instanceof Static3D )
362
        {
363
        mInter[0][mNumEffects] = null;
364
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static3D)vector).getX();
365
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)vector).getY();
366
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)vector).getZ();
367
        }
368
      else return -1;
369

    
370
      return addBase(eln);
371
      }
372

    
373
    return -1;
374
    }
375

    
376
///////////////////////////////////////////////////////////////////////////////////////////////////
377
// rotate - static axis
378

    
379
  synchronized long add(EffectNames eln, Data1D angle, Static3D axis, Data3D center)
380
    {
381
    if( mMax[INDEX]>mNumEffects )
382
      {
383
      if( angle instanceof Dynamic1D)
384
        {
385
        mInter[0][mNumEffects] = (Dynamic1D)angle;
386
        }
387
      else if( angle instanceof Static1D)
388
        {
389
        mInter[0][mNumEffects] = null;
390
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)angle).getX();
391
        }
392
      else return -1;
393

    
394
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = axis.getX();
395
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = axis.getY();
396
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = axis.getZ();
397

    
398
      if( center instanceof Dynamic3D)
399
        {
400
        mInter[1][mNumEffects] = (Dynamic3D)center;
401
        }
402
      else if( center instanceof Static3D )
403
        {
404
        mInter[1][mNumEffects] = null;
405
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static3D)center).getX();
406
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static3D)center).getY();
407
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static3D)center).getZ();
408
        }
409
      else return -1;
410

    
411
      return addBase(eln);
412
      }
413
      
414
    return -1;
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418
// quaternion or rotate - dynamic axis
419

    
420
  synchronized long add(EffectNames eln, Data4D data, Data3D center)
421
    {
422
    if( mMax[INDEX]>mNumEffects )
423
      {
424
      if( data instanceof Dynamic4D  )
425
        {
426
        mInter[0][mNumEffects] = (Dynamic4D)data;
427
        }
428
      else if( data instanceof DynamicQuat)
429
        {
430
        mInter[0][mNumEffects] = (DynamicQuat)data;
431
        }
432
      else if( data instanceof Static4D   )
433
        {
434
        mInter[0][mNumEffects] = null;
435
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static4D)data).getX();
436
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static4D)data).getY();
437
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static4D)data).getZ();
438
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static4D)data).getW();
439
        }
440
      else return -1;
441

    
442
      if( center instanceof Dynamic3D)
443
        {
444
        mInter[1][mNumEffects] = (Dynamic3D)center;
445
        }
446
      else if( center instanceof Static3D )
447
        {
448
        mInter[1][mNumEffects] = null;
449
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static3D)center).getX();
450
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static3D)center).getY();
451
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static3D)center).getZ();
452
        }
453
      else return -1;
454

    
455
      return addBase(eln);
456
      }
457

    
458
    return -1;
459
    }
460

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462
// shear
463

    
464
  synchronized long add(EffectNames eln, Data3D shear, Data3D center)
465
    {
466
    if( mMax[INDEX]>mNumEffects )
467
      {
468
      if( shear instanceof Dynamic3D)
469
        {
470
        mInter[0][mNumEffects] = (Dynamic3D)shear;
471
        }
472
      else if( shear instanceof Static3D )
473
        {
474
        mInter[0][mNumEffects] = null;
475
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static3D)shear).getX();
476
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)shear).getY();
477
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)shear).getZ();
478
        }
479
      else return -1;
480

    
481
      if( center instanceof Dynamic3D)
482
        {
483
        mInter[1][mNumEffects] = (Dynamic3D)center;
484
        }
485
      else if( center instanceof Static3D )
486
        {
487
        mInter[1][mNumEffects] = null;
488
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static3D)center).getX();
489
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static3D)center).getY();
490
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static3D)center).getZ();
491
        }
492
      else return -1;
493

    
494
      return addBase(eln);
495
      }
496
      
497
    return -1;
498
    }
499
  }
(20-20/26)