Project

General

Profile

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

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

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.EffectType;
26
import org.distorted.library.effect.MatrixEffect;
27
import org.distorted.library.message.EffectMessage;
28

    
29
///////////////////////////////////////////////////////////////////////////////////////////////////
30

    
31
class EffectQueueMatrix extends EffectQueue
32
  {   
33
  private static final int NUM_UNIFORMS = MatrixEffect.NUM_UNIFORMS;
34
  private static final int INDEX = EffectType.MATRIX.ordinal();
35

    
36
  private static float[] mMVPMatrix = new float[16];
37
  private static float[] mTmpMatrix = new float[16];
38
  private static float[] mViewMatrix= new float[16];
39

    
40
  private static int mObjDH;      // This is a handle to half a Object dimensions
41
  private static int mMVPMatrixH; // the transformation matrix
42
  private static int mMVMatrixH;  // the modelview matrix.
43
  
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45
   
46
  EffectQueueMatrix(long id)
47
    { 
48
    super(id,NUM_UNIFORMS,INDEX );
49
    }
50

    
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

    
53
  private static void multiplyByQuat(float[] matrix, float X, float Y, float Z, float W)
54
    {
55
    float xx= X * X;
56
    float xy= X * Y;
57
    float xz= X * Z;
58
    float xw= X * W;
59
    float yy= Y * Y;
60
    float yz= Y * Z;
61
    float yw= Y * W;
62
    float zz= Z * Z;
63
    float zw= Z * W;
64

    
65
    mTmpMatrix[0]  = 1 - 2 * ( yy + zz );
66
    mTmpMatrix[1]  =     2 * ( xy - zw );
67
    mTmpMatrix[2]  =     2 * ( xz + yw );
68
    mTmpMatrix[4]  =     2 * ( xy + zw );
69
    mTmpMatrix[5]  = 1 - 2 * ( xx + zz );
70
    mTmpMatrix[6]  =     2 * ( yz - xw );
71
    mTmpMatrix[8]  =     2 * ( xz - yw );
72
    mTmpMatrix[9]  =     2 * ( yz + xw );
73
    mTmpMatrix[10] = 1 - 2 * ( xx + yy );
74
    mTmpMatrix[3]  = mTmpMatrix[7] = mTmpMatrix[11] = mTmpMatrix[12] = mTmpMatrix[13] = mTmpMatrix[14] = 0;
75
    mTmpMatrix[15] = 1;
76
    
77
    Matrix.multiplyMM(mMVPMatrix, 0, matrix, 0, mTmpMatrix, 0);  
78

    
79
    matrix[ 0] = mMVPMatrix[ 0];
80
    matrix[ 1] = mMVPMatrix[ 1];
81
    matrix[ 2] = mMVPMatrix[ 2];
82
    matrix[ 3] = mMVPMatrix[ 3];
83
    matrix[ 4] = mMVPMatrix[ 4];
84
    matrix[ 5] = mMVPMatrix[ 5];
85
    matrix[ 6] = mMVPMatrix[ 6];
86
    matrix[ 7] = mMVPMatrix[ 7];
87
    matrix[ 8] = mMVPMatrix[ 8];
88
    matrix[ 9] = mMVPMatrix[ 9];
89
    matrix[10] = mMVPMatrix[10];
90
    matrix[11] = mMVPMatrix[11];
91
    matrix[12] = mMVPMatrix[12];
92
    matrix[13] = mMVPMatrix[13];
93
    matrix[14] = mMVPMatrix[14];
94
    matrix[15] = mMVPMatrix[15];
95
    }
96

    
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

    
99
  private void magnify(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
100
    {
101
    float scale, nx, ny;
102
    float[] result= new float[4];
103
    float[] point = new float[4];
104
    float[] matrix= new float[16];
105
    float minx = Integer.MAX_VALUE;
106
    float maxx = Integer.MIN_VALUE;
107
    float miny = Integer.MAX_VALUE;
108
    float maxy = Integer.MIN_VALUE;
109

    
110
    point[3] = 1.0f;
111

    
112
    Matrix.multiplyMM(matrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
113

    
114
    point[0] = +halfX; point[1] = +halfY; point[2] = +halfZ;
115
    Matrix.multiplyMV(result,0,matrix,0,point,0);
116
    nx = result[0]/result[3];
117
    ny = result[1]/result[3];
118
    if( nx<minx ) minx = nx;
119
    if( nx>maxx ) maxx = nx;
120
    if( ny<miny ) miny = ny;
121
    if( ny>maxy ) maxy = ny;
122

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

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

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

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

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

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

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

    
186
    float xlen = projection.mWidth *(maxx-minx)/2;
187
    float ylen = projection.mHeight*(maxy-miny)/2;
188

    
189
    scale = 1.0f + marginInPixels/( xlen>ylen ? ylen:xlen );
190

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

    
193
    Matrix.scaleM(mViewMatrix, 0, scale, scale, scale);
194
    }
195

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197
// here construct the ModelView and the ModelViewProjection Matrices
198

    
199
  private void constructMatrices(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
200
    {
201
    Matrix.setIdentityM(mViewMatrix, 0);
202
    Matrix.translateM(mViewMatrix, 0, -projection.mWidth/2, projection.mHeight/2, -projection.mDistance);
203

    
204
    float x,y,z, sx,sy,sz;
205
    float mipmap = projection.mMipmap;
206

    
207
    if( mipmap!=1 ) Matrix.scaleM(mViewMatrix, 0, mipmap, mipmap, mipmap);
208

    
209
    for(int i=0; i<mNumEffects; i++)
210
      {
211
      switch( mEffects[i].getName() )
212
        {
213
        case ROTATE     : x = mUniforms[NUM_UNIFORMS*i+4];
214
                          y = mUniforms[NUM_UNIFORMS*i+5];
215
                          z = mUniforms[NUM_UNIFORMS*i+6];
216

    
217
                          Matrix.translateM(mViewMatrix, 0, x,-y, z);
218
                          Matrix.rotateM( mViewMatrix, 0, mUniforms[NUM_UNIFORMS*i], mUniforms[NUM_UNIFORMS*i+1], mUniforms[NUM_UNIFORMS*i+2], mUniforms[NUM_UNIFORMS*i+3]);
219
                          Matrix.translateM(mViewMatrix, 0,-x, y,-z);
220
                          break;
221
        case QUATERNION : 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
                          multiplyByQuat(mViewMatrix, 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
                          break;
229
        case MOVE       : sx = mUniforms[NUM_UNIFORMS*i  ];
230
                          sy = mUniforms[NUM_UNIFORMS*i+1];
231
                          sz = mUniforms[NUM_UNIFORMS*i+2];
232

    
233
                          Matrix.translateM(mViewMatrix, 0, sx,-sy, sz);
234
                          break;
235
        case SCALE      : sx = mUniforms[NUM_UNIFORMS*i  ];
236
                          sy = mUniforms[NUM_UNIFORMS*i+1];
237
                          sz = mUniforms[NUM_UNIFORMS*i+2];
238

    
239
                          Matrix.scaleM(mViewMatrix, 0, sx, sy, sz);
240
                          break;
241
        case SHEAR      : sx = mUniforms[NUM_UNIFORMS*i  ];
242
                          sy = mUniforms[NUM_UNIFORMS*i+1];
243
                          sz = mUniforms[NUM_UNIFORMS*i+2];
244

    
245
                          x  = mUniforms[NUM_UNIFORMS*i+4];
246
                          y  = mUniforms[NUM_UNIFORMS*i+5];
247
                          z  = mUniforms[NUM_UNIFORMS*i+6];
248

    
249
                          Matrix.translateM(mViewMatrix, 0, x,-y, z);
250

    
251
                          mViewMatrix[4] += sx*mViewMatrix[0]; // Multiply viewMatrix by 1 x 0 0 , i.e. X-shear.
252
                          mViewMatrix[5] += sx*mViewMatrix[1]; //                        0 1 0 0
253
                          mViewMatrix[6] += sx*mViewMatrix[2]; //                        0 0 1 0
254
                          mViewMatrix[7] += sx*mViewMatrix[3]; //                        0 0 0 1
255

    
256
                          mViewMatrix[0] += sy*mViewMatrix[4]; // Multiply viewMatrix by 1 0 0 0 , i.e. Y-shear.
257
                          mViewMatrix[1] += sy*mViewMatrix[5]; //                        y 1 0 0
258
                          mViewMatrix[2] += sy*mViewMatrix[6]; //                        0 0 1 0
259
                          mViewMatrix[3] += sy*mViewMatrix[7]; //                        0 0 0 1
260

    
261
                          mViewMatrix[4] += sz*mViewMatrix[8]; // Multiply viewMatrix by 1 0 0 0 , i.e. Z-shear.
262
                          mViewMatrix[5] += sz*mViewMatrix[9]; //                        0 1 0 0
263
                          mViewMatrix[6] += sz*mViewMatrix[10];//                        0 z 1 0
264
                          mViewMatrix[7] += sz*mViewMatrix[11];//                        0 0 0 1
265

    
266
                          Matrix.translateM(mViewMatrix, 0,-x, y, -z);
267
                          break;
268
        }
269
      }
270

    
271
    Matrix.translateM(mViewMatrix, 0, halfX,-halfY,-halfZ);
272

    
273
    if( marginInPixels!=0 ) magnify(projection,halfX,halfY,halfZ, marginInPixels);
274

    
275
    Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
276
    }
277

    
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

    
280
  static void getUniforms(int mProgramH)
281
    {
282
    mObjDH     = GLES30.glGetUniformLocation(mProgramH, "u_objD");
283
    mMVPMatrixH= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
284
    mMVMatrixH = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
285
    }
286

    
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288

    
289
  synchronized void compute(long currTime) 
290
    {
291
    if( currTime==mTime ) return;
292
    if( mTime==0 ) mTime = currTime;
293
    long step = (currTime-mTime);
294

    
295
    for(int i=0; i<mNumEffects; i++)
296
      {
297
      mCurrentDuration[i] += step;
298

    
299
      if( mEffects[i].compute(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i], step) )
300
        {
301
        for(int j=0; j<mNumListeners; j++)
302
          EffectMessageSender.newMessage( mListeners.elementAt(j), EffectMessage.EFFECT_FINISHED, mEffects[i].getID(), mDistortedEffectsID);
303

    
304
        if( mEffects[i].isUnity( mUniforms, NUM_UNIFORMS*i) )
305
          remove(i--);
306
        }
307
      }
308
     
309
    mTime = currTime;  
310
    }  
311

    
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

    
314
  float[] getMVP()
315
    {
316
    return mMVPMatrix;
317
    }
318

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320

    
321
  synchronized void send(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
322
    {
323
    constructMatrices(projection,halfX,halfY,halfZ, marginInPixels);
324

    
325
    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
326
    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
327
    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
328
    }
329
  }
(18-18/23)