Project

General

Profile

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

library / src / main / java / org / distorted / library / EffectQueueMatrix.java @ 568b29d8

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.GLES20;
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.Dynamic;
36
import org.distorted.library.type.Static4D;
37

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

    
40
class EffectQueueMatrix extends EffectQueue
41
  {   
42
  private static final int NUM_UNIFORMS = 7;
43
  private static final int INDEX = EffectTypes.MATRIX.ordinal();
44
  private static float[] mMVPMatrix= new float[16];
45
  private static float[] mTmpMatrix= new float[16];
46
  
47
  private static int mBmpDH;      // This is a handle to half a bitmap dimensions
48
  private static int mDepthH;     // Handle to the max Depth, i.e (farplane-nearplane)/2
49
  private static int mMVPMatrixH; // pass in the transformation matrix
50
  private static int mMVMatrixH;  // pass in the modelview matrix.
51
  
52
///////////////////////////////////////////////////////////////////////////////////////////////////
53
   
54
  public EffectQueueMatrix(DistortedObject obj)
55
    { 
56
    super(obj,NUM_UNIFORMS, 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
    for(int j=0; j<16; j++) matrix[j] = mMVPMatrix[j];   
87
    }
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

    
91
  static void getUniforms(int mProgramH)
92
    {
93
    mBmpDH     = GLES20.glGetUniformLocation(mProgramH, "u_bmpD");
94
    mDepthH    = GLES20.glGetUniformLocation(mProgramH, "u_Depth");
95
    mMVPMatrixH= GLES20.glGetUniformLocation(mProgramH, "u_MVPMatrix");
96
    mMVMatrixH = GLES20.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
97
    }
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100
  
101
  synchronized void compute(long currTime) 
102
    {
103
    if( currTime==mTime ) return;
104
    if( mTime==0 ) mTime = currTime;
105
    long step = (currTime-mTime);
106
   
107
    for(int i=0; i<mNumEffects; i++)
108
      {
109
      if( mInterI[i]==null ) continue;    
110
           
111
      if( mInterP[i]!=null ) 
112
        {
113
        mInterP[i].interpolateMain(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i]);
114
        }
115
        
116
      if( mInterI[i].interpolateMain(mUniforms ,NUM_UNIFORMS*i+3, mCurrentDuration[i], step) )      
117
        {   
118
        for(int j=0; j<mNumListeners; j++)   
119
          EffectMessageSender.newMessage( mListeners.elementAt(j),
120
                                          EffectMessage.EFFECT_FINISHED,
121
                                         (mID[i]<<EffectTypes.LENGTH)+EffectTypes.MATRIX.type,
122
                                          mType[i], 
123
                                          mBitmapID,
124
                                          null);
125
       
126
        if( EffectNames.isUnity(mType[i], mUniforms, NUM_UNIFORMS*i+3) )
127
          {  
128
          remove(i);
129
          i--;
130
          continue;
131
          }
132
        }
133
    
134
      mCurrentDuration[i] += step;
135
      }
136
     
137
    mTime = currTime;  
138
    }  
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
  protected void moveEffect(int index)
143
    {
144
    mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
145
    mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
146
    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];
147
    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];
148
    mUniforms[NUM_UNIFORMS*index+4] = mUniforms[NUM_UNIFORMS*(index+1)+4];
149
    mUniforms[NUM_UNIFORMS*index+5] = mUniforms[NUM_UNIFORMS*(index+1)+5];
150
    mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
// here construct the ModelView Matrix
155

    
156
  synchronized void send(float[] viewMatrix, DistortedProjection dp) 
157
    {
158
    Matrix.setIdentityM(viewMatrix, 0);
159
    Matrix.translateM(viewMatrix, 0, -dp.width/2, dp.height/2, -dp.distance);
160
    
161
    float x,y,z, sx,sy,sz=1.0f;
162
   
163
    for(int i=0; i<mNumEffects; i++)
164
      {
165
      if (mType[i] == EffectNames.ROTATE.ordinal() )
166
        {
167
        x = mUniforms[NUM_UNIFORMS*i  ];
168
        y = mUniforms[NUM_UNIFORMS*i+1];
169
        z = mUniforms[NUM_UNIFORMS*i+2];
170

    
171
        Matrix.translateM(viewMatrix, 0, x,-y, z); 
172
        Matrix.rotateM( viewMatrix, 0, mUniforms[NUM_UNIFORMS*i+3], mUniforms[NUM_UNIFORMS*i+4], mUniforms[NUM_UNIFORMS*i+5], mUniforms[NUM_UNIFORMS*i+6]);  
173
        Matrix.translateM(viewMatrix, 0,-x, y,-z);  
174
        }
175
      else if(mType[i] == EffectNames.QUATERNION.ordinal() )
176
        {
177
        x = mUniforms[NUM_UNIFORMS*i  ];
178
        y = mUniforms[NUM_UNIFORMS*i+1];
179
        z = mUniforms[NUM_UNIFORMS*i+2];
180
     	
181
        Matrix.translateM(viewMatrix, 0, x,-y, z); 
182
        multiplyByQuat(viewMatrix, mUniforms[NUM_UNIFORMS*i+3], mUniforms[NUM_UNIFORMS*i+4], mUniforms[NUM_UNIFORMS*i+5], mUniforms[NUM_UNIFORMS*i+6]);
183
        Matrix.translateM(viewMatrix, 0,-x, y,-z);  
184
        }
185
      else if(mType[i] == EffectNames.MOVE.ordinal() )
186
        {
187
        sx = mUniforms[NUM_UNIFORMS*i+3];   
188
        sy = mUniforms[NUM_UNIFORMS*i+4];   
189
        sz = mUniforms[NUM_UNIFORMS*i+5];   
190
        
191
        Matrix.translateM(viewMatrix, 0, sx,-sy, sz);   
192
        }
193
      else if(mType[i] == EffectNames.SCALE.ordinal() )
194
        {
195
        sx = mUniforms[NUM_UNIFORMS*i+3];   
196
        sy = mUniforms[NUM_UNIFORMS*i+4];   
197
        sz = mUniforms[NUM_UNIFORMS*i+5];   
198

    
199
        Matrix.scaleM(viewMatrix, 0, sx, sy, sz);  
200
        }
201
      else if(mType[i] == EffectNames.SHEAR.ordinal() )
202
        {
203
        x  = mUniforms[NUM_UNIFORMS*i  ];
204
        y  = mUniforms[NUM_UNIFORMS*i+1];
205
        z  = mUniforms[NUM_UNIFORMS*i+2];
206
        
207
        sx = mUniforms[NUM_UNIFORMS*i+3];   
208
        sy = mUniforms[NUM_UNIFORMS*i+4];   
209
        sz = mUniforms[NUM_UNIFORMS*i+5];   
210
        
211
        Matrix.translateM(viewMatrix, 0, x,-y, z); 
212
      
213
        viewMatrix[4] += sx*viewMatrix[0]; // Multiply viewMatrix by 1 x 0 0 , i.e. X-shear. TODO: change this so it is symmetric w respect to all the axis.
214
        viewMatrix[5] += sx*viewMatrix[1]; //                        0 1 0 0 
215
        viewMatrix[6] += sx*viewMatrix[2]; //                        0 0 1 0
216
        viewMatrix[7] += sx*viewMatrix[3]; //                        0 0 0 1
217
      
218
        viewMatrix[0] += sy*viewMatrix[4]; // Multiply viewMatrix by 1 0 0 0 , i.e. Y-shear. TODO: change this so it is symmetric w respect to all the axis.
219
        viewMatrix[1] += sy*viewMatrix[5]; //                        y 1 0 0
220
        viewMatrix[2] += sy*viewMatrix[6]; //                        0 0 1 0
221
        viewMatrix[3] += sy*viewMatrix[7]; //                        0 0 0 1      
222
      
223
        // TODO: implement Z-shear.
224
        
225
        Matrix.translateM(viewMatrix, 0,-x, y, -z);
226
        }
227
      }
228
   
229
    Matrix.translateM(viewMatrix, 0, mObjHalfX,-mObjHalfY, -mObjHalfZ);
230
    Matrix.multiplyMM(mMVPMatrix, 0, dp.projectionMatrix, 0, viewMatrix, 0);
231
    
232
    GLES20.glUniform3f( mBmpDH , mObjHalfX, mObjHalfY, mObjHalfZ);
233
    GLES20.glUniform1f( mDepthH, dp.depth);   
234
    GLES20.glUniformMatrix4fv(mMVMatrixH , 1, false, viewMatrix, 0);
235
    GLES20.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix, 0);
236
    }
237

    
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239
// here construct the ModelView Matrix, but without any effects
240

    
241
  synchronized void sendNoEffects(DistortedProjection dp) 
242
    {
243
    Matrix.setIdentityM(mTmpMatrix, 0);
244
    Matrix.translateM(mTmpMatrix, 0, mObjHalfX-dp.width/2, dp.height/2-mObjHalfY, mObjHalfZ-dp.distance);
245
    Matrix.multiplyMM(mMVPMatrix, 0, dp.projectionMatrix, 0, mTmpMatrix, 0);
246
    
247
    GLES20.glUniform3f( mBmpDH , mObjHalfX, mObjHalfY, mObjHalfZ);
248
    GLES20.glUniform1f( mDepthH, dp.depth);  
249
    GLES20.glUniformMatrix4fv(mMVMatrixH , 1, false, mTmpMatrix, 0);
250
    GLES20.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix, 0);
251
    }
252

    
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254
// move, scale
255

    
256
  synchronized long add(EffectNames eln, Data3D vector)
257
    {
258
    if( mMax[INDEX]>mNumEffects )
259
      {
260
      mInterP[mNumEffects] = null;
261

    
262
           if( vector instanceof Dynamic3D) mInterI[mNumEffects] = (Dynamic3D)vector;
263
      else if( vector instanceof Static3D )
264
        {
265
        mInterI[mNumEffects] = null;
266
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static3D)vector).getX();
267
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static3D)vector).getY();
268
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static3D)vector).getZ();
269
        }
270
      else return -1;
271

    
272
      return addBase(eln);
273
      }
274

    
275
    return -1;
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279
// rotate - static axis
280

    
281
  synchronized long add(EffectNames eln, Data3D center, Data1D angle, Static3D axis)
282
    {
283
    if( mMax[INDEX]>mNumEffects )
284
      {
285
           if( center instanceof Dynamic3D) mInterP[mNumEffects] = (Dynamic3D)center;
286
      else if( center instanceof Static3D )
287
        {
288
        mInterP[mNumEffects] = null;
289
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static3D)center).getX();
290
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)center).getY();
291
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)center).getZ();
292
        }
293
      else return -1;
294

    
295
           if( angle instanceof Dynamic1D) mInterI[mNumEffects] = (Dynamic1D)angle;
296
      else if( angle instanceof Static1D)
297
        {
298
        mInterI[mNumEffects] = null;
299
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static1D)angle).getX();
300
        }
301
      else return -1;
302

    
303
      mUniforms[NUM_UNIFORMS*mNumEffects+4] = axis.getX();
304
      mUniforms[NUM_UNIFORMS*mNumEffects+5] = axis.getY();
305
      mUniforms[NUM_UNIFORMS*mNumEffects+6] = axis.getZ();
306

    
307
      return addBase(eln);
308
      }
309
      
310
    return -1;
311
    }
312

    
313
///////////////////////////////////////////////////////////////////////////////////////////////////
314
// quaternion or rotate - dynamic axis
315

    
316
  synchronized long add(EffectNames eln, Data3D center, Data4D data)
317
    {
318
    if( mMax[INDEX]>mNumEffects )
319
      {
320
           if( center instanceof Dynamic3D) mInterP[mNumEffects] = (Dynamic3D)center;
321
      else if( center instanceof Static3D )
322
        {
323
        mInterP[mNumEffects] = null;
324
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static3D)center).getX();
325
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)center).getY();
326
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)center).getZ();
327
        }
328
      else return -1;
329

    
330
           if( data instanceof Dynamic4D  ) mInterI[mNumEffects] = (Dynamic4D)data;
331
      else if( data instanceof DynamicQuat) mInterI[mNumEffects] = (DynamicQuat)data;
332
      else if( data instanceof Static4D   )
333
        {
334
        mInterI[mNumEffects] = null;
335
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static4D)data).getX();
336
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static4D)data).getY();
337
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static4D)data).getZ();
338
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static4D)data).getW();
339
        }
340
      else return -1;
341

    
342
      return addBase(eln);
343
      }
344

    
345
    return -1;
346
    }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349
// shear
350

    
351
  synchronized long add(EffectNames eln, Data3D center, Data3D shear)
352
    {
353
    if( mMax[INDEX]>mNumEffects )
354
      {
355
           if( center instanceof Dynamic3D) mInterP[mNumEffects] = (Dynamic3D)center;
356
      else if( center instanceof Static3D )
357
        {
358
        mInterP[mNumEffects] = null;
359
        mUniforms[NUM_UNIFORMS*mNumEffects  ] = ((Static3D)center).getX();
360
        mUniforms[NUM_UNIFORMS*mNumEffects+1] = ((Static3D)center).getY();
361
        mUniforms[NUM_UNIFORMS*mNumEffects+2] = ((Static3D)center).getZ();
362
        }
363
      else return -1;
364

    
365
           if( shear instanceof Dynamic3D) mInterI[mNumEffects] = (Dynamic3D)shear;
366
      else if( shear instanceof Static3D )
367
        {
368
        mInterI[mNumEffects] = null;
369
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = ((Static3D)shear).getX();
370
        mUniforms[NUM_UNIFORMS*mNumEffects+4] = ((Static3D)shear).getY();
371
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = ((Static3D)shear).getZ();
372
        }
373
      else return -1;
374

    
375
      return addBase(eln);
376
      }
377
      
378
    return -1;
379
    }
380
  }
(15-15/17)