Project

General

Profile

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

library / src / main / java / org / distorted / library / effect / EffectQueueMatrix.java @ 310e14fb

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

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

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

    
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

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

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

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

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

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

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

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

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

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

    
117
    point[3] = 1.0f;
118

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
292
///////////////////////////////////////////////////////////////////////////////////////////////////
293

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

    
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

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

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

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

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

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

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

    
353
///////////////////////////////////////////////////////////////////////////////////////////////////
354

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

    
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

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

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

    
371
///////////////////////////////////////////////////////////////////////////////////////////////////
372

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

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

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

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

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

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

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

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

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

    
436
      return addBase(me);
437
      }
438
      
439
    return -1;
440
    }
441
  }
(5-5/29)