Project

General

Profile

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

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

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.main;
21

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

    
25
import org.distorted.library.effect.Effect;
26
import org.distorted.library.effect.MatrixEffect;
27
import org.distorted.library.message.EffectMessage;
28
import org.distorted.library.type.Dynamic3D;
29
import org.distorted.library.type.Static;
30
import org.distorted.library.type.Static1D;
31
import org.distorted.library.type.Static2D;
32
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34
import org.distorted.library.type.Static5D;
35

    
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37

    
38
class EffectQueueMatrix extends EffectQueue
39
  {   
40
  private static final int NUM_UNIFORMS = 7;
41
  private static final int NUM_CACHE    = 0;
42
  private static final int INDEX = Effect.MATRIX;
43

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

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

    
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

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

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

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

    
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106

    
107
  private void magnify(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
108
    {
109
    float scale, nx, ny;
110
    float[] result= new float[4];
111
    float[] point = new float[4];
112
    float[] matrix= new float[16];
113
    float minx = Integer.MAX_VALUE;
114
    float maxx = Integer.MIN_VALUE;
115
    float miny = Integer.MAX_VALUE;
116
    float maxy = Integer.MIN_VALUE;
117

    
118
    point[3] = 1.0f;
119

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

    
122
    point[0] = +halfX; point[1] = +halfY; point[2] = +halfZ;
123
    Matrix.multiplyMV(result,0,matrix,0,point,0);
124
    nx = result[0]/result[3];
125
    ny = result[1]/result[3];
126
    if( nx<minx ) minx = nx;
127
    if( nx>maxx ) maxx = nx;
128
    if( ny<miny ) miny = ny;
129
    if( ny>maxy ) maxy = ny;
130

    
131
    point[0] = +halfX; point[1] = +halfY; point[2] = -halfZ;
132
    Matrix.multiplyMV(result,0,matrix,0,point,0);
133
    nx = result[0]/result[3];
134
    ny = result[1]/result[3];
135
    if( nx<minx ) minx = nx;
136
    if( nx>maxx ) maxx = nx;
137
    if( ny<miny ) miny = ny;
138
    if( ny>maxy ) maxy = ny;
139

    
140
    point[0] = +halfX; point[1] = -halfY; point[2] = +halfZ;
141
    Matrix.multiplyMV(result,0,matrix,0,point,0);
142
    nx = result[0]/result[3];
143
    ny = result[1]/result[3];
144
    if( nx<minx ) minx = nx;
145
    if( nx>maxx ) maxx = nx;
146
    if( ny<miny ) miny = ny;
147
    if( ny>maxy ) maxy = ny;
148

    
149
    point[0] = +halfX; point[1] = -halfY; point[2] = -halfZ;
150
    Matrix.multiplyMV(result,0,matrix,0,point,0);
151
    nx = result[0]/result[3];
152
    ny = result[1]/result[3];
153
    if( nx<minx ) minx = nx;
154
    if( nx>maxx ) maxx = nx;
155
    if( ny<miny ) miny = ny;
156
    if( ny>maxy ) maxy = ny;
157

    
158
    point[0] = -halfX; point[1] = +halfY; point[2] = +halfZ;
159
    Matrix.multiplyMV(result,0,matrix,0,point,0);
160
    nx = result[0]/result[3];
161
    ny = result[1]/result[3];
162
    if( nx<minx ) minx = nx;
163
    if( nx>maxx ) maxx = nx;
164
    if( ny<miny ) miny = ny;
165
    if( ny>maxy ) maxy = ny;
166

    
167
    point[0] = -halfX; point[1] = +halfY; point[2] = -halfZ;
168
    Matrix.multiplyMV(result,0,matrix,0,point,0);
169
    nx = result[0]/result[3];
170
    ny = result[1]/result[3];
171
    if( nx<minx ) minx = nx;
172
    if( nx>maxx ) maxx = nx;
173
    if( ny<miny ) miny = ny;
174
    if( ny>maxy ) maxy = ny;
175

    
176
    point[0] = -halfX; point[1] = -halfY; point[2] = +halfZ;
177
    Matrix.multiplyMV(result,0,matrix,0,point,0);
178
    nx = result[0]/result[3];
179
    ny = result[1]/result[3];
180
    if( nx<minx ) minx = nx;
181
    if( nx>maxx ) maxx = nx;
182
    if( ny<miny ) miny = ny;
183
    if( ny>maxy ) maxy = ny;
184

    
185
    point[0] = -halfX; point[1] = -halfY; point[2] = -halfZ;
186
    Matrix.multiplyMV(result,0,matrix,0,point,0);
187
    nx = result[0]/result[3];
188
    ny = result[1]/result[3];
189
    if( nx<minx ) minx = nx;
190
    if( nx>maxx ) maxx = nx;
191
    if( ny<miny ) miny = ny;
192
    if( ny>maxy ) maxy = ny;
193

    
194
    float xlen = projection.mWidth *(maxx-minx)/2;
195
    float ylen = projection.mHeight*(maxy-miny)/2;
196

    
197
    scale = 1.0f + marginInPixels/( xlen>ylen ? ylen:xlen );
198

    
199
    //android.util.Log.d("scale", ""+marginInPixels+" scale= "+scale+" xlen="+xlen+" ylen="+ylen);
200

    
201
    Matrix.scaleM(mViewMatrix, 0, scale, scale, scale);
202
    }
203

    
204
///////////////////////////////////////////////////////////////////////////////////////////////////
205
// here construct the ModelView and the ModelViewProjection Matrices
206

    
207
  private void constructMatrices(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
208
    {
209
    Matrix.setIdentityM(mViewMatrix, 0);
210
    Matrix.translateM(mViewMatrix, 0, -projection.mWidth/2, projection.mHeight/2, -projection.mDistance);
211

    
212
    float x,y,z, sx,sy,sz;
213
    float mipmap = projection.mMipmap;
214

    
215
    if( mipmap!=1 ) Matrix.scaleM(mViewMatrix, 0, mipmap, mipmap, mipmap);
216

    
217
    for(int i=0; i<mNumEffects; i++)
218
      {
219
      if (mName[i] == MatrixEffect.ROTATE )
220
        {
221
        x = mUniforms[NUM_UNIFORMS*i+4];
222
        y = mUniforms[NUM_UNIFORMS*i+5];
223
        z = mUniforms[NUM_UNIFORMS*i+6];
224

    
225
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
226
        Matrix.rotateM( mViewMatrix, 0, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]);
227
        Matrix.translateM(mViewMatrix, 0,-x, y,-z);
228
        }
229
      else if(mName[i] == MatrixEffect.QUATERNION )
230
        {
231
        x = mUniforms[NUM_UNIFORMS*i+4];
232
        y = mUniforms[NUM_UNIFORMS*i+5];
233
        z = mUniforms[NUM_UNIFORMS*i+6];
234

    
235
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
236
        multiplyByQuat(mViewMatrix, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]);
237
        Matrix.translateM(mViewMatrix, 0,-x, y,-z);
238
        }
239
      else if(mName[i] == MatrixEffect.MOVE )
240
        {
241
        sx = mUniforms[NUM_UNIFORMS*i  ];
242
        sy = mUniforms[NUM_UNIFORMS*i+1];
243
        sz = mUniforms[NUM_UNIFORMS*i+2];
244

    
245
        Matrix.translateM(mViewMatrix, 0, sx,-sy, sz);
246
        }
247
      else if(mName[i] == MatrixEffect.SCALE )
248
        {
249
        sx = mUniforms[NUM_UNIFORMS*i  ];
250
        sy = mUniforms[NUM_UNIFORMS*i+1];
251
        sz = mUniforms[NUM_UNIFORMS*i+2];
252

    
253
        Matrix.scaleM(mViewMatrix, 0, sx, sy, sz);
254
        }
255
      else if(mName[i] == MatrixEffect.SHEAR )
256
        {
257
        sx = mUniforms[NUM_UNIFORMS*i  ];
258
        sy = mUniforms[NUM_UNIFORMS*i+1];
259
        sz = mUniforms[NUM_UNIFORMS*i+2];
260

    
261
        x  = mUniforms[NUM_UNIFORMS*i+4];
262
        y  = mUniforms[NUM_UNIFORMS*i+5];
263
        z  = mUniforms[NUM_UNIFORMS*i+6];
264

    
265
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
266

    
267
        mViewMatrix[4] += sx*mViewMatrix[0]; // Multiply viewMatrix by 1 x 0 0 , i.e. X-shear.
268
        mViewMatrix[5] += sx*mViewMatrix[1]; //                        0 1 0 0
269
        mViewMatrix[6] += sx*mViewMatrix[2]; //                        0 0 1 0
270
        mViewMatrix[7] += sx*mViewMatrix[3]; //                        0 0 0 1
271

    
272
        mViewMatrix[0] += sy*mViewMatrix[4]; // Multiply viewMatrix by 1 0 0 0 , i.e. Y-shear.
273
        mViewMatrix[1] += sy*mViewMatrix[5]; //                        y 1 0 0
274
        mViewMatrix[2] += sy*mViewMatrix[6]; //                        0 0 1 0
275
        mViewMatrix[3] += sy*mViewMatrix[7]; //                        0 0 0 1
276

    
277
        mViewMatrix[4] += sz*mViewMatrix[8]; // Multiply viewMatrix by 1 0 0 0 , i.e. Z-shear.
278
        mViewMatrix[5] += sz*mViewMatrix[9]; //                        0 1 0 0
279
        mViewMatrix[6] += sz*mViewMatrix[10];//                        0 z 1 0
280
        mViewMatrix[7] += sz*mViewMatrix[11];//                        0 0 0 1
281

    
282
        Matrix.translateM(mViewMatrix, 0,-x, y, -z);
283
        }
284
      }
285

    
286
    Matrix.translateM(mViewMatrix, 0, halfX,-halfY,-halfZ);
287

    
288
    if( marginInPixels!=0 ) magnify(projection,halfX,halfY,halfZ, marginInPixels);
289

    
290
    Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
291
    }
292

    
293
///////////////////////////////////////////////////////////////////////////////////////////////////
294

    
295
  static void getUniforms(int mProgramH)
296
    {
297
    mObjDH     = GLES30.glGetUniformLocation(mProgramH, "u_objD");
298
    mMVPMatrixH= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
299
    mMVMatrixH = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
300
    }
301

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

    
304
  synchronized void compute(long currTime) 
305
    {
306
    if( currTime==mTime ) return;
307
    if( mTime==0 ) mTime = currTime;
308
    long step = (currTime-mTime);
309
   
310
    for(int i=0; i<mNumEffects; i++)
311
      {
312
      mCurrentDuration[i] += step;
313

    
314
      if( mInter[0][i]!=null && mInter[0][i].interpolateMain(mUniforms ,NUM_UNIFORMS*i, mCurrentDuration[i], step) )
315
        {
316
        for(int j=0; j<mNumListeners; j++)
317
          EffectMessageSender.newMessage( mListeners.elementAt(j),
318
                                          EffectMessage.EFFECT_FINISHED,
319
                                         (mID[i]<<Effect.LENGTH)+Effect.MATRIX,
320
                                          mName[i],
321
                                          mObjectID);
322

    
323
        if( MatrixEffect.isUnity(mName[i], mUniforms, NUM_UNIFORMS*i) )
324
          {
325
          remove(i);
326
          i--;
327
          continue;
328
          }
329
        else mInter[0][i] = null;
330
        }
331

    
332
      if( mInter[2][i]!=null )
333
        {
334
        mInter[2][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+4, mCurrentDuration[i], step);
335
        }
336
      }
337
     
338
    mTime = currTime;  
339
    }  
340

    
341
///////////////////////////////////////////////////////////////////////////////////////////////////
342

    
343
  protected void moveEffect(int index)
344
    {
345
    mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
346
    mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
347
    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];
348
    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];
349
    mUniforms[NUM_UNIFORMS*index+4] = mUniforms[NUM_UNIFORMS*(index+1)+4];
350
    mUniforms[NUM_UNIFORMS*index+5] = mUniforms[NUM_UNIFORMS*(index+1)+5];
351
    mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355

    
356
  float[] getMVP()
357
    {
358
    return mMVPMatrix;
359
    }
360

    
361
///////////////////////////////////////////////////////////////////////////////////////////////////
362

    
363
  synchronized void send(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
364
    {
365
    constructMatrices(projection,halfX,halfY,halfZ, marginInPixels);
366

    
367
    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
368
    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
369
    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
370
    }
371

    
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373

    
374
  synchronized long add(MatrixEffect me)
375
    {
376
    if( mMax[INDEX]>mNumEffects )
377
      {
378
      int dim0 = 0;
379

    
380
      if( me.mDynamic0 != null )
381
        {
382
        mInter[0][mNumEffects] = me.mDynamic0;
383
        dim0 = me.mDynamic0.getDimension();
384
        }
385
      else
386
        {
387
        mInter[0][mNumEffects] = null;
388

    
389
        if( me.mStatic0 != null )
390
          {
391
          Static s = me.mStatic0;
392
          dim0 = s.getDimension();
393

    
394
          switch( dim0 )
395
            {
396
            case 5 : mUniforms[NUM_UNIFORMS*mNumEffects + 4] = ((Static5D)s).getV();
397
            case 4 : mUniforms[NUM_UNIFORMS*mNumEffects + 3] = ((Static4D)s).getW();
398
            case 3 : mUniforms[NUM_UNIFORMS*mNumEffects + 2] = ((Static3D)s).getZ();
399
            case 2 : mUniforms[NUM_UNIFORMS*mNumEffects + 1] = ((Static2D)s).getY();
400
            case 1 : mUniforms[NUM_UNIFORMS*mNumEffects    ] = ((Static1D)s).getX();
401
            }
402
          }
403
        }
404

    
405
      mInter[1][mNumEffects] = null;
406

    
407
      if( me.mStatic1 != null )
408
        {
409
        Static s = me.mStatic1;
410
        int dim1 = s.getDimension();
411

    
412
        switch( dim1 )
413
          {
414
          case 5 : mUniforms[NUM_UNIFORMS*mNumEffects + dim0 + 4] = ((Static5D)s).getV();
415
          case 4 : mUniforms[NUM_UNIFORMS*mNumEffects + dim0 + 3] = ((Static4D)s).getW();
416
          case 3 : mUniforms[NUM_UNIFORMS*mNumEffects + dim0 + 2] = ((Static3D)s).getZ();
417
          case 2 : mUniforms[NUM_UNIFORMS*mNumEffects + dim0 + 1] = ((Static2D)s).getY();
418
          case 1 : mUniforms[NUM_UNIFORMS*mNumEffects + dim0    ] = ((Static1D)s).getX();
419
          }
420
        }
421

    
422
      if( me.mCenter instanceof Dynamic3D)
423
        {
424
        mInter[2][mNumEffects] = (Dynamic3D)me.mCenter;
425
        }
426
      else if( me.mCenter instanceof Static3D )
427
        {
428
        mInter[2][mNumEffects] = null;
429

    
430
        Static3D s = (Static3D)me.mCenter;
431
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = s.getX();
432
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = s.getY();
433
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = s.getZ();
434
        }
435
      else return -1;
436

    
437
      return addBase(me);
438
      }
439
      
440
    return -1;
441
    }
442
  }
(19-19/24)