Project

General

Profile

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

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

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, float[] projection)
109
    {
110
    float scale = Distorted.mMagnify;
111
    float[] point = new float[4];
112
    point[3] = 0.0f;
113

    
114
    Matrix.scaleM(mViewMatrix, 0, scale, scale, scale);
115
    }
116

    
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118
// here construct the ModelView and the ModelViewProjection Matrices
119

    
120
  private void constructMatrices(DistortedOutputSurface projection, float halfX, float halfY, float halfZ)
121
    {
122
    Matrix.setIdentityM(mViewMatrix, 0);
123
    Matrix.translateM(mViewMatrix, 0, -projection.mWidth/2, projection.mHeight/2, -projection.mDistance);
124

    
125
    float x,y,z, sx,sy,sz;
126
    float mipmap = projection.mMipmap;
127

    
128
    if( mipmap!=1 ) Matrix.scaleM(mViewMatrix, 0, mipmap, mipmap, mipmap);
129

    
130
    for(int i=0; i<mNumEffects; i++)
131
      {
132
      if (mName[i] == EffectNames.ROTATE.ordinal() )
133
        {
134
        x = mUniforms[NUM_UNIFORMS*i+4];
135
        y = mUniforms[NUM_UNIFORMS*i+5];
136
        z = mUniforms[NUM_UNIFORMS*i+6];
137

    
138
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
139
        Matrix.rotateM( mViewMatrix, 0, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]);
140
        Matrix.translateM(mViewMatrix, 0,-x, y,-z);
141
        }
142
      else if(mName[i] == EffectNames.QUATERNION.ordinal() )
143
        {
144
        x = mUniforms[NUM_UNIFORMS*i+4];
145
        y = mUniforms[NUM_UNIFORMS*i+5];
146
        z = mUniforms[NUM_UNIFORMS*i+6];
147

    
148
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
149
        multiplyByQuat(mViewMatrix, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]);
150
        Matrix.translateM(mViewMatrix, 0,-x, y,-z);
151
        }
152
      else if(mName[i] == EffectNames.MOVE.ordinal() )
153
        {
154
        sx = mUniforms[NUM_UNIFORMS*i  ];
155
        sy = mUniforms[NUM_UNIFORMS*i+1];
156
        sz = mUniforms[NUM_UNIFORMS*i+2];
157

    
158
        Matrix.translateM(mViewMatrix, 0, sx,-sy, sz);
159
        }
160
      else if(mName[i] == EffectNames.SCALE.ordinal() )
161
        {
162
        sx = mUniforms[NUM_UNIFORMS*i  ];
163
        sy = mUniforms[NUM_UNIFORMS*i+1];
164
        sz = mUniforms[NUM_UNIFORMS*i+2];
165

    
166
        Matrix.scaleM(mViewMatrix, 0, sx, sy, sz);
167
        }
168
      else if(mName[i] == EffectNames.SHEAR.ordinal() )
169
        {
170
        sx = mUniforms[NUM_UNIFORMS*i  ];
171
        sy = mUniforms[NUM_UNIFORMS*i+1];
172
        sz = mUniforms[NUM_UNIFORMS*i+2];
173

    
174
        x  = mUniforms[NUM_UNIFORMS*i+4];
175
        y  = mUniforms[NUM_UNIFORMS*i+5];
176
        z  = mUniforms[NUM_UNIFORMS*i+6];
177

    
178
        Matrix.translateM(mViewMatrix, 0, x,-y, z);
179

    
180
        mViewMatrix[4] += sx*mViewMatrix[0]; // Multiply viewMatrix by 1 x 0 0 , i.e. X-shear.
181
        mViewMatrix[5] += sx*mViewMatrix[1]; //                        0 1 0 0
182
        mViewMatrix[6] += sx*mViewMatrix[2]; //                        0 0 1 0
183
        mViewMatrix[7] += sx*mViewMatrix[3]; //                        0 0 0 1
184

    
185
        mViewMatrix[0] += sy*mViewMatrix[4]; // Multiply viewMatrix by 1 0 0 0 , i.e. Y-shear.
186
        mViewMatrix[1] += sy*mViewMatrix[5]; //                        y 1 0 0
187
        mViewMatrix[2] += sy*mViewMatrix[6]; //                        0 0 1 0
188
        mViewMatrix[3] += sy*mViewMatrix[7]; //                        0 0 0 1
189

    
190
        mViewMatrix[4] += sz*mViewMatrix[8]; // Multiply viewMatrix by 1 0 0 0 , i.e. Z-shear.
191
        mViewMatrix[5] += sz*mViewMatrix[9]; //                        0 1 0 0
192
        mViewMatrix[6] += sz*mViewMatrix[10];//                        0 z 1 0
193
        mViewMatrix[7] += sz*mViewMatrix[11];//                        0 0 0 1
194

    
195
        Matrix.translateM(mViewMatrix, 0,-x, y, -z);
196
        }
197
      }
198

    
199
    Matrix.translateM(mViewMatrix, 0, halfX,-halfY,-halfZ);
200

    
201
    if( Distorted.mMagnify!=1.0f ) magnify(halfX,halfY,halfZ, projection.mProjectionMatrix);
202

    
203
    Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
204
    }
205

    
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

    
208
  static void getUniforms(int mProgramH)
209
    {
210
    mObjDH     = GLES30.glGetUniformLocation(mProgramH, "u_objD");
211
    mMVPMatrixH= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
212
    mMVMatrixH = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
213
    }
214

    
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

    
217
  synchronized void compute(long currTime) 
218
    {
219
    if( currTime==mTime ) return;
220
    if( mTime==0 ) mTime = currTime;
221
    long step = (currTime-mTime);
222
   
223
    for(int i=0; i<mNumEffects; i++)
224
      {
225
      mCurrentDuration[i] += step;
226

    
227
      if( mInter[0][i]!=null && mInter[0][i].interpolateMain(mUniforms ,NUM_UNIFORMS*i, mCurrentDuration[i], step) )
228
        {
229
        for(int j=0; j<mNumListeners; j++)
230
          EffectMessageSender.newMessage( mListeners.elementAt(j),
231
                                          EffectMessage.EFFECT_FINISHED,
232
                                         (mID[i]<<EffectTypes.LENGTH)+EffectTypes.MATRIX.type,
233
                                          mName[i],
234
                                          mObjectID);
235

    
236
        if( EffectNames.isUnity(mName[i], mUniforms, NUM_UNIFORMS*i) )
237
          {
238
          remove(i);
239
          i--;
240
          continue;
241
          }
242
        else mInter[0][i] = null;
243
        }
244

    
245
      if( mInter[1][i]!=null )
246
        {
247
        mInter[1][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+4, mCurrentDuration[i], step);
248
        }
249
      }
250
     
251
    mTime = currTime;  
252
    }  
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
  protected void moveEffect(int index)
257
    {
258
    mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
259
    mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
260
    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];
261
    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];
262
    mUniforms[NUM_UNIFORMS*index+4] = mUniforms[NUM_UNIFORMS*(index+1)+4];
263
    mUniforms[NUM_UNIFORMS*index+5] = mUniforms[NUM_UNIFORMS*(index+1)+5];
264
    mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
265
    }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
  float[] getMVP()
270
    {
271
    return mMVPMatrix;
272
    }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
  synchronized void send(DistortedOutputSurface projection, float halfX, float halfY, float halfZ)
277
    {
278
    constructMatrices(projection,halfX,halfY,halfZ);
279

    
280
    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
281
    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
282
    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
283
    }
284

    
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286
// move, scale
287

    
288
  synchronized long add(EffectNames eln, Data3D vector)
289
    {
290
    if( mMax[INDEX]>mNumEffects )
291
      {
292
      mInter[1][mNumEffects] = null;
293

    
294
      if( vector instanceof Dynamic3D)
295
        {
296
        mInter[0][mNumEffects] = (Dynamic3D)vector;
297
        }
298
      else if( vector instanceof Static3D )
299
        {
300
        mInter[0][mNumEffects] = null;
301
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static3D)vector).getX();
302
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)vector).getY();
303
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)vector).getZ();
304
        }
305
      else return -1;
306

    
307
      return addBase(eln);
308
      }
309

    
310
    return -1;
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314
// rotate - static axis
315

    
316
  synchronized long add(EffectNames eln, Data1D angle, Static3D axis, Data3D center)
317
    {
318
    if( mMax[INDEX]>mNumEffects )
319
      {
320
      if( angle instanceof Dynamic1D)
321
        {
322
        mInter[0][mNumEffects] = (Dynamic1D)angle;
323
        }
324
      else if( angle instanceof Static1D)
325
        {
326
        mInter[0][mNumEffects] = null;
327
        mUniforms[NUM_UNIFORMS*mNumEffects] = ((Static1D)angle).getX();
328
        }
329
      else return -1;
330

    
331
      mUniforms[NUM_UNIFORMS*mNumEffects+1] = axis.getX();
332
      mUniforms[NUM_UNIFORMS*mNumEffects+2] = axis.getY();
333
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = axis.getZ();
334

    
335
      if( center instanceof Dynamic3D)
336
        {
337
        mInter[1][mNumEffects] = (Dynamic3D)center;
338
        }
339
      else if( center instanceof Static3D )
340
        {
341
        mInter[1][mNumEffects] = null;
342
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static3D)center).getX();
343
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static3D)center).getY();
344
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static3D)center).getZ();
345
        }
346
      else return -1;
347

    
348
      return addBase(eln);
349
      }
350
      
351
    return -1;
352
    }
353

    
354
///////////////////////////////////////////////////////////////////////////////////////////////////
355
// quaternion or rotate - dynamic axis
356

    
357
  synchronized long add(EffectNames eln, Data4D data, Data3D center)
358
    {
359
    if( mMax[INDEX]>mNumEffects )
360
      {
361
      if( data instanceof Dynamic4D  )
362
        {
363
        mInter[0][mNumEffects] = (Dynamic4D)data;
364
        }
365
      else if( data instanceof DynamicQuat)
366
        {
367
        mInter[0][mNumEffects] = (DynamicQuat)data;
368
        }
369
      else if( data instanceof Static4D   )
370
        {
371
        mInter[0][mNumEffects] = null;
372
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static4D)data).getX();
373
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static4D)data).getY();
374
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static4D)data).getZ();
375
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static4D)data).getW();
376
        }
377
      else return -1;
378

    
379
      if( center instanceof Dynamic3D)
380
        {
381
        mInter[1][mNumEffects] = (Dynamic3D)center;
382
        }
383
      else if( center instanceof Static3D )
384
        {
385
        mInter[1][mNumEffects] = null;
386
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static3D)center).getX();
387
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static3D)center).getY();
388
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static3D)center).getZ();
389
        }
390
      else return -1;
391

    
392
      return addBase(eln);
393
      }
394

    
395
    return -1;
396
    }
397

    
398
///////////////////////////////////////////////////////////////////////////////////////////////////
399
// shear
400

    
401
  synchronized long add(EffectNames eln, Data3D shear, Data3D center)
402
    {
403
    if( mMax[INDEX]>mNumEffects )
404
      {
405
      if( shear instanceof Dynamic3D)
406
        {
407
        mInter[0][mNumEffects] = (Dynamic3D)shear;
408
        }
409
      else if( shear instanceof Static3D )
410
        {
411
        mInter[0][mNumEffects] = null;
412
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static3D)shear).getX();
413
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)shear).getY();
414
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)shear).getZ();
415
        }
416
      else return -1;
417

    
418
      if( center instanceof Dynamic3D)
419
        {
420
        mInter[1][mNumEffects] = (Dynamic3D)center;
421
        }
422
      else if( center instanceof Static3D )
423
        {
424
        mInter[1][mNumEffects] = null;
425
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static3D)center).getX();
426
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static3D)center).getY();
427
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static3D)center).getZ();
428
        }
429
      else return -1;
430

    
431
      return addBase(eln);
432
      }
433
      
434
    return -1;
435
    }
436
  }
(20-20/26)