Project

General

Profile

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

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

1 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
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 fe82a979 Leszek Koltunski
package org.distorted.library.main;
21 6a06a912 Leszek Koltunski
22 194ab46f Leszek Koltunski
import android.opengl.GLES30;
23 6a06a912 Leszek Koltunski
import android.opengl.Matrix;
24
25 da9b3f07 Leszek Koltunski
import org.distorted.library.effect.EffectType;
26 fe82a979 Leszek Koltunski
import org.distorted.library.effect.MatrixEffect;
27 e458a4ba Leszek Koltunski
import org.distorted.library.message.EffectMessage;
28 a4835695 Leszek Koltunski
29 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
30
31 d07f2950 Leszek Koltunski
class EffectQueueMatrix extends EffectQueue
32 6a06a912 Leszek Koltunski
  {   
33 15aa7d94 Leszek Koltunski
  private static final int NUM_UNIFORMS = MatrixEffect.NUM_UNIFORMS;
34 da9b3f07 Leszek Koltunski
  private static final int INDEX = EffectType.MATRIX.ordinal();
35 1a940548 Leszek Koltunski
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 1aedf874 leszek
  private static int mObjDH;      // This is a handle to half a Object dimensions
41 8eccf334 Leszek Koltunski
  private static int mMVPMatrixH; // the transformation matrix
42
  private static int mMVMatrixH;  // the modelview matrix.
43 6a06a912 Leszek Koltunski
  
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45
   
46 0a046359 Leszek Koltunski
  EffectQueueMatrix(long id)
47 6a06a912 Leszek Koltunski
    { 
48 15aa7d94 Leszek Koltunski
    super(id,NUM_UNIFORMS,INDEX );
49 6a06a912 Leszek Koltunski
    }
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 ab12f06b Leszek Koltunski
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 6a06a912 Leszek Koltunski
    }
96
97 a8162df9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
98
99 270c27bc Leszek Koltunski
  private void magnify(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
100 a8162df9 Leszek Koltunski
    {
101 270c27bc Leszek Koltunski
    float scale, nx, ny;
102 a15631bc leszek
    float[] result= new float[4];
103 a8162df9 Leszek Koltunski
    float[] point = new float[4];
104 a15631bc leszek
    float[] matrix= new float[16];
105 270c27bc Leszek Koltunski
    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 a8162df9 Leszek Koltunski
112 a15631bc leszek
    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 270c27bc Leszek Koltunski
    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 a15631bc leszek
123
    point[0] = +halfX; point[1] = +halfY; point[2] = -halfZ;
124
    Matrix.multiplyMV(result,0,matrix,0,point,0);
125 270c27bc Leszek Koltunski
    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 a15631bc leszek
132
    point[0] = +halfX; point[1] = -halfY; point[2] = +halfZ;
133
    Matrix.multiplyMV(result,0,matrix,0,point,0);
134 270c27bc Leszek Koltunski
    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 a15631bc leszek
141
    point[0] = +halfX; point[1] = -halfY; point[2] = -halfZ;
142
    Matrix.multiplyMV(result,0,matrix,0,point,0);
143 270c27bc Leszek Koltunski
    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 a15631bc leszek
150
    point[0] = -halfX; point[1] = +halfY; point[2] = +halfZ;
151
    Matrix.multiplyMV(result,0,matrix,0,point,0);
152 270c27bc Leszek Koltunski
    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 a15631bc leszek
159
    point[0] = -halfX; point[1] = +halfY; point[2] = -halfZ;
160
    Matrix.multiplyMV(result,0,matrix,0,point,0);
161 270c27bc Leszek Koltunski
    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 a15631bc leszek
168
    point[0] = -halfX; point[1] = -halfY; point[2] = +halfZ;
169
    Matrix.multiplyMV(result,0,matrix,0,point,0);
170 270c27bc Leszek Koltunski
    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 a15631bc leszek
177
    point[0] = -halfX; point[1] = -halfY; point[2] = -halfZ;
178
    Matrix.multiplyMV(result,0,matrix,0,point,0);
179 270c27bc Leszek Koltunski
    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 a15631bc leszek
186 270c27bc Leszek Koltunski
    float xlen = projection.mWidth *(maxx-minx)/2;
187
    float ylen = projection.mHeight*(maxy-miny)/2;
188 a15631bc leszek
189 270c27bc Leszek Koltunski
    scale = 1.0f + marginInPixels/( xlen>ylen ? ylen:xlen );
190 a15631bc leszek
191 b3120b1b leszek
    //android.util.Log.d("scale", ""+marginInPixels+" scale= "+scale+" xlen="+xlen+" ylen="+ylen);
192 a15631bc leszek
193 a8162df9 Leszek Koltunski
    Matrix.scaleM(mViewMatrix, 0, scale, scale, scale);
194
    }
195
196 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
197 02de77c9 Leszek Koltunski
// here construct the ModelView and the ModelViewProjection Matrices
198 6a06a912 Leszek Koltunski
199 270c27bc Leszek Koltunski
  private void constructMatrices(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
200 6a06a912 Leszek Koltunski
    {
201 1a940548 Leszek Koltunski
    Matrix.setIdentityM(mViewMatrix, 0);
202 a2594090 leszek
    Matrix.translateM(mViewMatrix, 0, -projection.mWidth/2, projection.mHeight/2, -projection.mDistance);
203 02de77c9 Leszek Koltunski
204 a595ee16 Leszek Koltunski
    float x,y,z, sx,sy,sz;
205 78db8663 Leszek Koltunski
    float mipmap = projection.mMipmap;
206 02de77c9 Leszek Koltunski
207 638b5b5c leszek
    if( mipmap!=1 ) Matrix.scaleM(mViewMatrix, 0, mipmap, mipmap, mipmap);
208
209 6a06a912 Leszek Koltunski
    for(int i=0; i<mNumEffects; i++)
210
      {
211 15aa7d94 Leszek Koltunski
      switch( mEffects[i].getName() )
212 6a06a912 Leszek Koltunski
        {
213 da9b3f07 Leszek Koltunski
        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 6a06a912 Leszek Koltunski
        }
269
      }
270 02de77c9 Leszek Koltunski
271 eb80a7e8 Leszek Koltunski
    Matrix.translateM(mViewMatrix, 0, halfX,-halfY,-halfZ);
272 a8162df9 Leszek Koltunski
273 270c27bc Leszek Koltunski
    if( marginInPixels!=0 ) magnify(projection,halfX,halfY,halfZ, marginInPixels);
274 a8162df9 Leszek Koltunski
275 c5369f1b leszek
    Matrix.multiplyMM(mMVPMatrix, 0, projection.mProjectionMatrix, 0, mViewMatrix, 0);
276 02de77c9 Leszek Koltunski
    }
277
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279
280 1aedf874 leszek
  static void getUniforms(int mProgramH)
281 02de77c9 Leszek Koltunski
    {
282 1aedf874 leszek
    mObjDH     = GLES30.glGetUniformLocation(mProgramH, "u_objD");
283
    mMVPMatrixH= GLES30.glGetUniformLocation(mProgramH, "u_MVPMatrix");
284
    mMVMatrixH = GLES30.glGetUniformLocation(mProgramH, "u_MVMatrix"); 
285 02de77c9 Leszek Koltunski
    }
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 15aa7d94 Leszek Koltunski
295 02de77c9 Leszek Koltunski
    for(int i=0; i<mNumEffects; i++)
296
      {
297 3a70bd6d leszek
      mCurrentDuration[i] += step;
298
299 15aa7d94 Leszek Koltunski
      if( mEffects[i].compute(mUniforms, NUM_UNIFORMS*i, mCurrentDuration[i], step) )
300 02de77c9 Leszek Koltunski
        {
301
        for(int j=0; j<mNumListeners; j++)
302 15aa7d94 Leszek Koltunski
          EffectMessageSender.newMessage( mListeners.elementAt(j), EffectMessage.EFFECT_FINISHED, mEffects[i].getID(), mID);
303 02de77c9 Leszek Koltunski
304 da9b3f07 Leszek Koltunski
        if( mEffects[i].isUnity( mUniforms, NUM_UNIFORMS*i) )
305 15aa7d94 Leszek Koltunski
          remove(i--);
306 02de77c9 Leszek Koltunski
        }
307
      }
308
     
309
    mTime = currTime;  
310
    }  
311
312 3fc9327a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
313
314
  float[] getMVP()
315
    {
316
    return mMVPMatrix;
317
    }
318
319 02de77c9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
320
321 270c27bc Leszek Koltunski
  synchronized void send(DistortedOutputSurface projection, float halfX, float halfY, float halfZ, float marginInPixels)
322 02de77c9 Leszek Koltunski
    {
323 270c27bc Leszek Koltunski
    constructMatrices(projection,halfX,halfY,halfZ, marginInPixels);
324 02de77c9 Leszek Koltunski
325 1aedf874 leszek
    GLES30.glUniform3f( mObjDH , halfX, halfY, halfZ);
326
    GLES30.glUniformMatrix4fv(mMVMatrixH , 1, false, mViewMatrix, 0);
327
    GLES30.glUniformMatrix4fv(mMVPMatrixH, 1, false, mMVPMatrix , 0);
328 6a06a912 Leszek Koltunski
    }
329
  }