Project

General

Profile

« Previous | Next » 

Revision 4fde55a0

Added by Leszek Koltunski over 7 years ago

Beginnings of the WAVE effect.

View differences:

src/main/java/org/distorted/library/DistortedObject.java
790 790
/**
791 791
 * Rotate part of the Object around the Center of the Effect by a certain angle.
792 792
 *
793
 * @param swirl  The degree of Swirl. Positive values swirl clockwise.
793
 * @param swirl  The angle of Swirl (in degrees). Positive values swirl clockwise.
794 794
 * @param center 2-dimensional Data that, at any given time, returns the Center of the Effect.
795 795
 * @param region Region that masks the Effect.
796 796
 * @return       ID of the effect added, or -1 if we failed to add one.
......
804 804
/**
805 805
 * Rotate the whole Object around the Center of the Effect by a certain angle.
806 806
 *
807
 * @param swirl  The degree of Swirl. Positive values swirl clockwise.
807
 * @param swirl  The angle of Swirl (in degrees). Positive values swirl clockwise.
808 808
 * @param center 2-dimensional Data that, at any given time, returns the Center of the Effect.
809 809
 * @return       ID of the effect added, or -1 if we failed to add one.
810 810
 */
......
812 812
    {
813 813
    return mV.add(EffectNames.SWIRL, swirl, center);
814 814
    }
815

  
816
///////////////////////////////////////////////////////////////////////////////////////////////////
817
/**
818
 * Directional, sinusoidal wave effect.
819
 *
820
 * @param wave   A 3-dimensional data structure describing the wave: first member is the amplitude,
821
 *               second is the angle (in degrees, as always) the direction of the wave forms with
822
 *               the X-axis, and the third is the wave length.
823
 * @param center 2-dimensional Data that, at any given time, returns the Center of the Effect.
824
 * @return       ID of the effect added, or -1 if we failed to add one.
825
 */
826
  public long wave(Data3D wave, Data2D center)
827
    {
828
    return mV.add(EffectNames.WAVE, wave, center);
829
    }
830

  
831
///////////////////////////////////////////////////////////////////////////////////////////////////
832
/**
833
 * Directional, sinusoidal wave effect.
834
 *
835
 * @param wave   A 3-dimensional data structure describing the wave: first member is the amplitude,
836
 *               second is the angle (in degrees, as always) the direction of the wave forms with
837
 *               the X-axis, and the third is the wave length.
838
 * @param center 2-dimensional Data that, at any given time, returns the Center of the Effect.
839
 * @param region Region that masks the Effect.
840
 * @return       ID of the effect added, or -1 if we failed to add one.
841
 */
842
  public long wave(Data3D wave, Data2D center, Data4D region)
843
    {
844
    return mV.add(EffectNames.WAVE, wave, center, region);
845
    }
815 846
  }
src/main/java/org/distorted/library/EffectNames.java
115 115
   * Unity: swirlAngle = 0
116 116
   */
117 117
  SWIRL            ( EffectTypes.VERTEX  ,   new float[] {0.0f}           ),
118
  /**
119
   * Directional sinusoidal wave effect. The direction of the wave is given by the 'angle'
120
   * parameter, which is the angle (in degrees) the direction forms with the X-axis.
121
   * <p>
122
   * Uniforms: (amplitude,angle,length,regionX,regionY,regionRX,regionRY,centerX,centerY)
123
   * Unity: amplitude  = 0
124
   */
125
  WAVE             ( EffectTypes.VERTEX  ,   new float[] {0.0f}           ),
118 126
  // add new Vertex Effects here...
119 127

  
120 128
 /////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/library/EffectQueueVertex.java
39 39

  
40 40
class EffectQueueVertex extends EffectQueue
41 41
  { 
42
  private static final int NUM_UNIFORMS = 9;
42
  private static final int NUM_UNIFORMS = 12;
43 43
  private static final int INDEX = EffectTypes.VERTEX.ordinal();
44 44
  private static int mNumEffectsH;
45 45
  private static int mTypeH;
......
90 90
        else mInter[0][i] = null;
91 91
        }
92 92

  
93
      if( mInter[1][i]!=null )
93
      if( mInter[1][i]!=null )  // region
94 94
        {
95
        mInter[1][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+3, mCurrentDuration[i]);
95
        mInter[1][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+8, mCurrentDuration[i]);
96 96
        }
97 97

  
98
      if( mInter[2][i]!=null )
98
      if( mInter[2][i]!=null )  // center
99 99
        {
100
        mInter[2][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+7, mCurrentDuration[i]);
100
        mInter[2][i].interpolateMain(mUniforms, NUM_UNIFORMS*i+6, mCurrentDuration[i]);
101 101

  
102
        mUniforms[NUM_UNIFORMS*i+7] = mUniforms[NUM_UNIFORMS*i+7]-mObjHalfX;
103
        mUniforms[NUM_UNIFORMS*i+8] =-mUniforms[NUM_UNIFORMS*i+8]+mObjHalfY;
102
        mUniforms[NUM_UNIFORMS*i+6] = mUniforms[NUM_UNIFORMS*i+6]-mObjHalfX;
103
        mUniforms[NUM_UNIFORMS*i+7] =-mUniforms[NUM_UNIFORMS*i+7]+mObjHalfY;
104 104
        }
105 105

  
106 106
      mCurrentDuration[i] += step;
......
113 113

  
114 114
  protected void moveEffect(int index)
115 115
    {
116
    mUniforms[NUM_UNIFORMS*index  ] = mUniforms[NUM_UNIFORMS*(index+1)  ];
117
    mUniforms[NUM_UNIFORMS*index+1] = mUniforms[NUM_UNIFORMS*(index+1)+1];
118
    mUniforms[NUM_UNIFORMS*index+2] = mUniforms[NUM_UNIFORMS*(index+1)+2];
119
    mUniforms[NUM_UNIFORMS*index+3] = mUniforms[NUM_UNIFORMS*(index+1)+3];
120
    mUniforms[NUM_UNIFORMS*index+4] = mUniforms[NUM_UNIFORMS*(index+1)+4];
121
    mUniforms[NUM_UNIFORMS*index+5] = mUniforms[NUM_UNIFORMS*(index+1)+5];
122
    mUniforms[NUM_UNIFORMS*index+6] = mUniforms[NUM_UNIFORMS*(index+1)+6];
123
    mUniforms[NUM_UNIFORMS*index+7] = mUniforms[NUM_UNIFORMS*(index+1)+7];
124
    mUniforms[NUM_UNIFORMS*index+8] = mUniforms[NUM_UNIFORMS*(index+1)+8];
116
    mUniforms[NUM_UNIFORMS*index   ] = mUniforms[NUM_UNIFORMS*(index+1)   ];
117
    mUniforms[NUM_UNIFORMS*index+ 1] = mUniforms[NUM_UNIFORMS*(index+1)+ 1];
118
    mUniforms[NUM_UNIFORMS*index+ 2] = mUniforms[NUM_UNIFORMS*(index+1)+ 2];
119
    mUniforms[NUM_UNIFORMS*index+ 3] = mUniforms[NUM_UNIFORMS*(index+1)+ 3];
120
    mUniforms[NUM_UNIFORMS*index+ 4] = mUniforms[NUM_UNIFORMS*(index+1)+ 4];
121
    mUniforms[NUM_UNIFORMS*index+ 5] = mUniforms[NUM_UNIFORMS*(index+1)+ 5];
122
    mUniforms[NUM_UNIFORMS*index+ 6] = mUniforms[NUM_UNIFORMS*(index+1)+ 6];
123
    mUniforms[NUM_UNIFORMS*index+ 7] = mUniforms[NUM_UNIFORMS*(index+1)+ 7];
124
    mUniforms[NUM_UNIFORMS*index+ 8] = mUniforms[NUM_UNIFORMS*(index+1)+ 8];
125
    mUniforms[NUM_UNIFORMS*index+ 9] = mUniforms[NUM_UNIFORMS*(index+1)+ 9];
126
    mUniforms[NUM_UNIFORMS*index+10] = mUniforms[NUM_UNIFORMS*(index+1)+10];
127
    mUniforms[NUM_UNIFORMS*index+11] = mUniforms[NUM_UNIFORMS*(index+1)+11];
125 128
    }
126 129
   
127 130
///////////////////////////////////////////////////////////////////////////////////////////////////
......
132 135
      
133 136
    if( mNumEffects>0 )
134 137
      {     
135
      GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mName,0);
136
      GLES20.glUniform3fv( mUniformsH,3*mNumEffects, mUniforms,0);
138
      GLES20.glUniform1iv( mTypeH    ,  mNumEffects, mName    ,0);
139
      GLES20.glUniform4fv( mUniformsH,3*mNumEffects, mUniforms,0);
137 140
      }
138 141
    }
139 142

  
......
148 151
// Do various post-processing on already computed effects.
149 152
// 1) here unlike in the fragment queue, we don't have to multiply the points by ModelView matrix because that gets done in the shader.
150 153
// 2) in case of swirl, pre-compute the sine and cosine of its rotation angle
154
// 3) likewise in case of wave
151 155
  
152 156
  void postprocess()
153 157
    {
......
158 162
      if( mName[i]==EffectNames.SWIRL.ordinal() )
159 163
        {
160 164
        d = Math.PI*mUniforms[NUM_UNIFORMS*i]/180;  
161
        mUniforms[NUM_UNIFORMS*i+1] = (float)Math.sin(d);
162
        mUniforms[NUM_UNIFORMS*i+2] = (float)Math.cos(d);
165
        mUniforms[NUM_UNIFORMS*i+4] = (float)Math.sin(d);
166
        mUniforms[NUM_UNIFORMS*i+5] = (float)Math.cos(d);
167
        }
168
      if( mName[i]==EffectNames.WAVE.ordinal() )
169
        {
170
        d = Math.PI*mUniforms[NUM_UNIFORMS*i+1]/180;
171
        mUniforms[NUM_UNIFORMS*i+4] = (float)Math.sin(d);
172
        mUniforms[NUM_UNIFORMS*i+5] = (float)Math.cos(d);
163 173
        }
164 174
      }
165 175
    }
166 176
  
167 177
///////////////////////////////////////////////////////////////////////////////////////////////////
168
// distort
178
// distort, wave
169 179

  
170 180
  synchronized long add(EffectNames eln, Data3D data, Data2D center, Data4D region)
171 181
    {
......
190 200
    }
191 201
   
192 202
///////////////////////////////////////////////////////////////////////////////////////////////////
193
// deform, distort
203
// deform, distort, wave
194 204

  
195 205
  synchronized long add(EffectNames eln, Data3D data, Data2D center)
196 206
    {
......
276 286

  
277 287
        float z = tmp.getZ();
278 288

  
279
        mUniforms[NUM_UNIFORMS*mNumEffects+3] = tmp.getX();
280
        mUniforms[NUM_UNIFORMS*mNumEffects+4] =-tmp.getY();   // invert y already
281
        mUniforms[NUM_UNIFORMS*mNumEffects+5] = z<=0.0f ? 1000*mObjHalfX : z;
282
        mUniforms[NUM_UNIFORMS*mNumEffects+6] = tmp.getW();
289
        mUniforms[NUM_UNIFORMS*mNumEffects+ 8] = tmp.getX();
290
        mUniforms[NUM_UNIFORMS*mNumEffects+ 9] =-tmp.getY();   // invert y already
291
        mUniforms[NUM_UNIFORMS*mNumEffects+10] = z<=0.0f ? 1000*mObjHalfX : z;
292
        mUniforms[NUM_UNIFORMS*mNumEffects+11] = tmp.getW();
283 293
        mInter[1][mNumEffects] = null;
284 294
        }
285 295
      else return -1;
286 296
      }
287 297
    else
288 298
      {
289
      mUniforms[NUM_UNIFORMS*mNumEffects+3] = 0.0f;
290
      mUniforms[NUM_UNIFORMS*mNumEffects+4] = 0.0f;
291
      mUniforms[NUM_UNIFORMS*mNumEffects+5] = 1000*mObjHalfX;
292
      mUniforms[NUM_UNIFORMS*mNumEffects+6] = 0.0f;
299
      mUniforms[NUM_UNIFORMS*mNumEffects+ 8] = 0.0f;
300
      mUniforms[NUM_UNIFORMS*mNumEffects+ 9] = 0.0f;
301
      mUniforms[NUM_UNIFORMS*mNumEffects+10] = 1000*mObjHalfX;
302
      mUniforms[NUM_UNIFORMS*mNumEffects+11] = 0.0f;
293 303
      mInter[1][mNumEffects] = null;
294 304
      }
295 305

  
......
298 308
    else if( center instanceof Static2D)
299 309
      {
300 310
      mInter[2][mNumEffects] = null;
301
      mUniforms[NUM_UNIFORMS*mNumEffects+7] = ((Static2D)center).getX()-mObjHalfX;
302
      mUniforms[NUM_UNIFORMS*mNumEffects+8] =-((Static2D)center).getY()+mObjHalfY;
311
      mUniforms[NUM_UNIFORMS*mNumEffects+6] = ((Static2D)center).getX()-mObjHalfX;
312
      mUniforms[NUM_UNIFORMS*mNumEffects+7] =-((Static2D)center).getY()+mObjHalfY;
303 313
      }
304 314

  
305 315
    return addBase(eln);
src/main/res/raw/main_vertex_shader.glsl
40 40

  
41 41
#if NUM_VERTEX>0
42 42
uniform int vType[NUM_VERTEX];            // their types.
43
uniform vec3 vUniforms[3*NUM_VERTEX];     // i-th effect is 3 consecutive vec3's: [3*i], [3*i+1], [3*i+2]. 
44
                                          // The first 3 floats are the Interpolated values,
45
                                          // next 4 are the Region, next 2 are the Center.
43
uniform vec4 vUniforms[3*NUM_VERTEX];     // i-th effect is 3 consecutive vec4's: [3*i], [3*i+1], [3*i+2].
44
                                          // The first vec4 is the Interpolated values,
45
                                          // next is half cache half Center, the third -  the Region.
46 46
#endif
47 47

  
48 48
#if NUM_VERTEX>0
......
93 93
// where a = PS*PO/|PS| but we are really looking for d = |PX|/(|PX|+|PS|) = 1/(1+ (|PS|/|PX|) ) and
94 94
// |PX|/|PS| = -b + sqrt(b^2 + (OX^2-PO^2)/PS^2) where b=PS*PO/|PS|^2 which can be computed with only one sqrt.
95 95

  
96
float degree_region(in vec3 region, in vec2 PS)
96
float degree_region(in vec4 region, in vec2 PS)
97 97
  {
98 98
  vec2 PO  = PS + region.xy;
99 99
  float D = region.z*region.z-dot(PO,PO);      // D = |OX|^2 - |PO|^2
......
118 118
//////////////////////////////////////////////////////////////////////////////////////////////
119 119
// return min(degree_bitmap,degree_region). Just like degree_region, currently only supports circles.
120 120

  
121
float degree(in vec3 region, in vec2 S, in vec2 PS)
121
float degree(in vec4 region, in vec2 S, in vec2 PS)
122 122
  {
123 123
  vec2 PO  = PS + region.xy;
124 124
  float D = region.z*region.z-dot(PO,PO);      // D = |OX|^2 - |PO|^2
......
205 205
  
206 206
void deform(in int effect, inout vec4 v)
207 207
  {
208
  vec2 center = vUniforms[effect+2].yz;
208
  vec2 center = vUniforms[effect+1].zw;
209 209
  vec2 force = vUniforms[effect].xy;    // force = vec(MM')
210 210
  vec2 vert_vec, horz_vec; 
211 211
  vec2 signXY = sign(center-v.xy);
......
283 283
        
284 284
void distort(in int effect, inout vec4 v, inout vec4 n)
285 285
  {
286
  vec2 point = vUniforms[effect+2].yz;
287
  vec2 ps = point-v.xy;
288
  float d = degree(vUniforms[effect+1],point,ps);
286
  vec2 center = vUniforms[effect+1].zw;
287
  vec2 ps = center-v.xy;
288
  float d = degree(vUniforms[effect+2],center,ps);
289 289
  vec2 w = vec2(vUniforms[effect].x, -vUniforms[effect].y);
290 290
  float uz = vUniforms[effect].z;                                         // height of the bubble
291 291
  float denominator = dot(ps+(1.0-d)*w,ps);
......
312 312
 
313 313
void sink(in int effect,inout vec4 v)
314 314
  {
315
  vec2 point = vUniforms[effect+2].yz;
316
  vec2 ps = point-v.xy;
315
  vec2 center = vUniforms[effect+1].zw;
316
  vec2 ps = center-v.xy;
317 317
  float h = vUniforms[effect].x;
318
  float t = degree(vUniforms[effect+1],point,ps) * (1.0-h)/max(1.0,h);                                                                        
318
  float t = degree(vUniforms[effect+2],center,ps) * (1.0-h)/max(1.0,h);
319 319
  
320 320
  v.xy += t*ps;           
321 321
  }
......
329 329

  
330 330
void swirl(in int effect, inout vec4 v)
331 331
  {
332
  vec2 S  = vUniforms[effect+2].yz;
333
  vec2 PS = S-v.xy;
334
  vec3 SO = vUniforms[effect+1];
332
  vec2 center  = vUniforms[effect+1].zw;
333
  vec2 PS = center-v.xy;
334
  vec4 SO = vUniforms[effect+2];
335 335
  float d1_circle = degree_region(SO,PS);
336
  float d1_bitmap = degree_bitmap(S,PS);
337
  float sinA = vUniforms[effect].y;                            // sin(A) precomputed in EffectListVertex.postprocess
338
  float cosA = vUniforms[effect].z;                            // cos(A) precomputed in EffectListVertex.postprocess
339
  vec2 PS2 = vec2( PS.x*cosA+PS.y*sinA,-PS.x*sinA+PS.y*cosA ); // vector PS rotated by A radians clockwise around S.
340
  vec3 SG = (1.0-d1_circle)*SO;                                // coordinates of the dilated circle P is going to get rotated around
341
  float d2 = max(0.0,degree(SG,S,PS2));                        // make it a max(0,deg) because otherwise when S=left edge of the
336
  float d1_bitmap = degree_bitmap(center,PS);
337
  float sinA = vUniforms[effect+1].x;                          // sin(A) precomputed in EffectListVertex.postprocess
338
  float cosA = vUniforms[effect+1].y;                          // cos(A) precomputed in EffectListVertex.postprocess
339
  vec2 PS2 = vec2( PS.x*cosA+PS.y*sinA,-PS.x*sinA+PS.y*cosA ); // vector PS rotated by A radians clockwise around center.
340
  vec4 SG = (1.0-d1_circle)*SO;                                // coordinates of the dilated circle P is going to get rotated around
341
  float d2 = max(0.0,degree(SG,center,PS2));                   // make it a max(0,deg) because otherwise when center=left edge of the
342 342
                                                               // bitmap some points end up with d2<0 and they disappear off view.
343
  v.xy += min(d1_circle,d1_bitmap)*(PS - PS2/(1.0-d2));        // if d2=1 (i.e P=S) we should have P unchanged. How to do it?
343
  v.xy += min(d1_circle,d1_bitmap)*(PS - PS2/(1.0-d2));        // if d2=1 (i.e P=center) we should have P unchanged. How to do it?
344
  }
345

  
346
//////////////////////////////////////////////////////////////////////////////////////////////
347
// WAVE EFFECT
348
//
349
// Directional sinusoidal wave effect.
350

  
351
void wave(in int effect, inout vec4 v)
352
  {
353
  vec2 center = vUniforms[effect+1].zw;
354
  vec2 ps = center-v.xy;
355
  float deg = degree_region(vUniforms[effect+2],ps);
356
  vec2 sincos = vUniforms[effect+1].xy;
357

  
358
  float amplitude = vUniforms[effect].x;
359
  float angle     = vUniforms[effect].y;
360
  float length    = vUniforms[effect].z;
361
  float d = dot( vec2(-ps.y,-ps.x),sincos );
362
  float num = length==0.0 ? 1.0 : d / length;
363
  float floornum = floor(num);
364
  float therest = num-floornum;
365
  float phi = mod(floornum,2.0) == 0.0 ? 1.0-therest:therest;
366

  
367
  v.xy += (phi*amplitude*deg*sincos);
344 368
  }
345 369

  
346 370
#endif
......
359 383
    else if( vType[i]==DEFORM ) deform (3*i,v);
360 384
    else if( vType[i]==SINK   ) sink   (3*i,v);
361 385
    else if( vType[i]==SWIRL  ) swirl  (3*i,v);
386
    else if( vType[i]==WAVE   ) wave   (3*i,v);
362 387
    }
363 388
 
364 389
  restrict(v.z);  

Also available in: Unified diff