Project

General

Profile

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

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

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.Static4D;
36

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

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

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89

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

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

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

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

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

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

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

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

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

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

    
252
///////////////////////////////////////////////////////////////////////////////////////////////////
253
// move, scale
254

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

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

    
271
      return addBase(eln);
272
      }
273

    
274
    return -1;
275
    }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278
// rotate - static axis
279

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

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

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

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

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

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

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

    
341
      return addBase(eln);
342
      }
343

    
344
    return -1;
345
    }
346

    
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348
// shear
349

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

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

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