Project

General

Profile

« Previous | Next » 

Revision f19d533d

Added by Leszek Koltunski 11 months ago

MeshBandedTriangle implemented

View differences:

src/main/java/org/distorted/library/mesh/MeshBandedTriangle.java
32 32
 */
33 33
public class MeshBandedTriangle extends MeshBase
34 34
  {
35
  public static final int MODE_NORMAL  = 0;
36
  public static final int MODE_INVERTED= 1;
37
  public static final int MODE_FLAT    = 2;
38

  
35 39
  private static final int NUM_CACHE = 20;
36
  private static final int MODE_UP   = 0;
37
  private static final int MODE_DOWN = 1;
38
  private static final int MODE_FLAT = 2;
39 40

  
40 41
  private float mLeftX, mLeftY;
41 42
  private float mRightX, mRightY;
......
49 50

  
50 51
  private int remainingVert;
51 52
  private int numVertices;
52
  private int extraIndex, extraVertices;
53
  private int extraBands, extraVertices;
53 54

  
54 55
  private float[] mCurveCache;
55 56
  private float mVecX, mVecY;
56
  private int[] mEdgeShape;
57 57

  
58 58
///////////////////////////////////////////////////////////////////////////////////////////////////
59
// mNumBands>=2
60 59

  
61 60
  private void computeNumberOfVertices()
62
     {
63
     /*
64
     if( mNumBands==2 && extraIndex>0 )
65
       {
66
       numVertices = 1 + 2*mNumPolygonVertices*(1+extraIndex+2*extraVertices);
67
       }
68
     else
69
       {
70
       numVertices = (mNumPolygonVertices*mNumPolygonBands+2)*(mNumPolygonBands-1) - 1;
71
       numVertices+= 2*mNumPolygonVertices*(2*extraIndex*extraVertices);
72
       }
73

  
74
     remainingVert = numVertices;
75

  
76
      */
77
     }
61
    {
62
    if( mMode==MODE_FLAT )
63
      {
64
      numVertices = 3;
65
      }
66
    else if( mMode==MODE_NORMAL )
67
      {
68
      numVertices = mNumBands*(mNumBands+2) + 4*extraVertices*extraBands;
69
      }
70
    else
71
      {
72
      numVertices = mNumBands*(mNumBands+2);
73
      }
74

  
75
    remainingVert = numVertices;
76
    }
78 77

  
79 78
///////////////////////////////////////////////////////////////////////////////////////////////////
80 79

  
81 80
  private void computeCache()
82 81
    {
83
    /*
84 82
    mCurveCache = new float[NUM_CACHE];
85
    float[] tmpD = new float[mNumPolygonBands+1];
86
    float[] tmpX = new float[mNumPolygonBands+1];
83
    float[] tmpD = new float[mNumBands+1];
84
    float[] tmpX = new float[mNumBands+1];
87 85

  
88
    for(int i=1; i<mNumPolygonBands; i++)
86
    for(int i=1; i<mNumBands; i++)
89 87
      {
90
      tmpD[i] = (mPolygonBands[2*i-1]-mPolygonBands[2*i+1]) / (mPolygonBands[2*i]-mPolygonBands[2*i-2]);
91
      tmpX[i] = 1.0f - (mPolygonBands[2*i]+mPolygonBands[2*i-2])/2;
88
      tmpD[i] = (mBands[2*i-1]-mBands[2*i+1]) / (mBands[2*i]-mBands[2*i-2]);
89
      tmpX[i] = 1.0f - (mBands[2*i]+mBands[2*i-2])/2;
92 90
      }
93 91

  
94 92
    tmpD[0] = tmpD[1];
95
    tmpD[mNumPolygonBands] = tmpD[mNumPolygonBands-1];
93
    tmpD[mNumBands] = tmpD[mNumBands-1];
96 94
    tmpX[0] = 0.0f;
97
    tmpX[mNumPolygonBands] = 1.0f;
95
    tmpX[mNumBands] = 1.0f;
98 96

  
99 97
    int prev = 0;
100 98
    int next = 0;
......
106 104
      if( x>=tmpX[next] )
107 105
        {
108 106
        prev = next;
109
        while( next<=mNumPolygonBands && x>=tmpX[next] ) next++;
107
        while( next<=mNumBands && x>=tmpX[next] ) next++;
110 108
        }
111 109

  
112 110
      if( next>prev )
......
120 118
        }
121 119
      }
122 120

  
123
    mCurveCache[NUM_CACHE-1] = tmpD[mNumPolygonBands];
124

  
125
     */
126
    }
127
/*
128
///////////////////////////////////////////////////////////////////////////////////////////////////
129

  
130
  private float getSpecialQuot(int index)
131
    {
132
    int num = 1 + extraIndex + 2*extraVertices;
133
    int change1 = extraVertices+1;
134
    int change2 = num-change1;
135
    float quot = 1.0f/(extraIndex+1);
136

  
137
    if( index<change1 )      return index*quot/change1;
138
    else if( index>change2 ) return 1-quot + (index-change2)*quot/change1;
139
    else                     return (index-change1+1)*quot;
140
    }
141

  
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143

  
144
  private float getQuot(int index, int band, boolean isExtra)
145
    {
146
    int num = mNumPolygonBands-1-band;
147

  
148
    if( num>0 )
149
      {
150
      if( isExtra )
151
        {
152
        int extra = extraIndex-band+extraVertices;
153

  
154
        if( index < extra )
155
          {
156
          float quot = ((float)extraIndex-band)/(extra*num);
157
          return index*quot;
158
          }
159
        else if( index > num+2*extraVertices-extra )
160
          {
161
          float quot = ((float)extraIndex-band)/(extra*num);
162
          return (1.0f-((float)extraIndex-band)/num) + (index-num-2*extraVertices+extra)*quot;
163
          }
164
        else
165
          {
166
          return ((float)(index-extraVertices))/num;
167
          }
168
        }
169

  
170
      return (float)index/num;
171
      }
172

  
173
    return 1.0f;
174
    }
175

  
176
///////////////////////////////////////////////////////////////////////////////////////////////////
177

  
178
  private float computeZEdge(float quot)
179
    {
180
    if( quot>=1.0f ) return 0.0f;
181

  
182
    for(int band=1; band<mNumPolygonBands; band++)
183
      {
184
      float curr = mPolygonBands[2*band];
185

  
186
      if( curr<=quot )
187
        {
188
        float prev = mPolygonBands[2*band-2];
189
        float prevH= mPolygonBands[2*band-1];
190
        float currH= mPolygonBands[2*band+1];
191

  
192
        float A = (prev-quot)/(prev-curr);
193

  
194
        return A*currH + (1-A)*prevH;
195
        }
196
      }
197

  
198
    return 0.0f;
121
    mCurveCache[NUM_CACHE-1] = tmpD[mNumBands];
199 122
    }
200 123

  
201 124
///////////////////////////////////////////////////////////////////////////////////////////////////
......
220 143

  
221 144
///////////////////////////////////////////////////////////////////////////////////////////////////
222 145

  
223
  private void figureOutNormalVector2D(int edgeShape, int polyVertex, int polyEndVer, float quot, float xEdge, float yEdge )
146
  private void figureOutNormalVector2D(float qx)
224 147
    {
225
    if( edgeShape==SHAPE_DD )
226
      {
227
      if( quot<0.5f )
228
        {
229
        int p = polyVertex>0 ? polyVertex-1 : mNumPolygonVertices-1;
230
        int prvShape = mEdgeShape[p];
231

  
232
        switch(prvShape)
233
          {
234
          case SHAPE_DD : mVecX = xEdge;
235
                          mVecY = yEdge;
236
                          break;
237
          case SHAPE_UD :
238
          case SHAPE_DUD: float a = 2*quot;
239
                          float xCurr= mPolygonVertices[2*polyVertex  ];
240
                          float yCurr= mPolygonVertices[2*polyVertex+1];
241
                          float xPrev= mPolygonVertices[2*p  ];
242
                          float yPrev= mPolygonVertices[2*p+1];
243
                          float xVec = xCurr-xPrev;
244
                          float yVec = yCurr-yPrev;
245

  
246
                          mVecX = a*xEdge + (1-a)*xVec;
247
                          mVecY = a*yEdge + (1-a)*yVec;
248

  
249
                          break;
250
          default: throw new RuntimeException("figureOutNormalVector2D: impossible1: "+prvShape);
251
          }
252
        }
253
      else
254
        {
255
        int n = polyEndVer==mNumPolygonVertices-1 ? 0 : polyEndVer+1;
256
        int nxtShape = mEdgeShape[polyEndVer];
257

  
258
        switch(nxtShape)
259
          {
260
          case SHAPE_DD : mVecX = xEdge;
261
                          mVecY = yEdge;
262
                          break;
263
          case SHAPE_DU :
264
          case SHAPE_DUD: float a = 2-2*quot;
265
                          float xCurr= mPolygonVertices[2*polyEndVer  ];
266
                          float yCurr= mPolygonVertices[2*polyEndVer+1];
267
                          float xNext= mPolygonVertices[2*n  ];
268
                          float yNext= mPolygonVertices[2*n+1];
269
                          float xVec = xCurr-xNext;
270
                          float yVec = yCurr-yNext;
271

  
272
                          mVecX = a*xEdge + (1-a)*xVec;
273
                          mVecY = a*yEdge + (1-a)*yVec;
274
                          break;
275
          default: throw new RuntimeException("figureOutNormalVector2D: impossible2: "+nxtShape);
276
          }
277
        }
278
      }
279
    else if( edgeShape==SHAPE_UU || (quot>=0.5f && edgeShape==SHAPE_DU) || (quot<0.5f && edgeShape==SHAPE_UD) )
280
      {
281
      mVecX = 1;
282
      mVecY = 0;
283
      }
284
    else
285
      {
286
      float dx = mPolygonVertices[2*polyVertex  ] - mPolygonVertices[2*polyEndVer  ];
287
      float dy = mPolygonVertices[2*polyVertex+1] - mPolygonVertices[2*polyEndVer+1];
288

  
289
      if( quot<0.5 )
290
        {
291
        mVecX = dx;
292
        mVecY = dy;
293
        }
294
      else
295
        {
296
        mVecX = -dx;
297
        mVecY = -dy;
298
        }
299
      }
148
    mVecX = mNormL[0] + qx*(mNormR[0]-mNormL[0]);
149
    mVecY = mNormL[1] + qx*(mNormR[1]-mNormL[1]);
300 150
    }
301 151

  
302 152
///////////////////////////////////////////////////////////////////////////////////////////////////
303 153

  
304
  private float figureOutDerivative(int edgeShape, int polyBand, float quot)
154
  private float figureOutDerivative(float qy)
305 155
    {
306
    if( edgeShape==SHAPE_DD )
156
    switch(mMode)
307 157
      {
308
      return derivative(1-mPolygonBands[2*polyBand]);
158
      case MODE_NORMAL  : return derivative(1-qy);
159
      case MODE_INVERTED: return -derivative(qy);
160
      default           : return 0;
309 161
      }
310
    if( edgeShape==SHAPE_UU || (quot>=0.5f && edgeShape==SHAPE_DU) || (quot<0.5f && edgeShape==SHAPE_UD) )
162
    }
163

  
164
///////////////////////////////////////////////////////////////////////////////////////////////////
165

  
166
  private float computeElevation(int band)
167
    {
168
    switch(mMode)
311 169
      {
312
      return 0;
170
      case MODE_NORMAL  : return mBands[2*band+1];
171
      case MODE_INVERTED: return mBands[2*(mNumBands-band)+1];
172
      default           : return mBands[2*mNumBands+1];
313 173
      }
314

  
315
    float x = 1-mPolygonBands[2*polyBand];
316
    float q = quot>=0.5f ? 2-2*quot : 2*quot;
317
    return derivative((1-x)*q+x);
318 174
    }
319 175

  
320 176
///////////////////////////////////////////////////////////////////////////////////////////////////
321 177

  
322
  private int addVertex(int vertex, int polyBand, int polyVertex, int polyEndVer, float quot,
323
                        float[] attribs1, float[] attribs2)
178
  private int addStripVertex(int vertex, float qx, float qy, int band, float[] attribs1, float[] attribs2)
324 179
    {
325 180
    remainingVert--;
326 181

  
327
    float Xfirst= mPolygonVertices[2*polyVertex  ];
328
    float Yfirst= mPolygonVertices[2*polyVertex+1];
329
    float Xlast = mPolygonVertices[2*polyEndVer  ];
330
    float Ylast = mPolygonVertices[2*polyEndVer+1];
331

  
332
    float xEdge = Xfirst + quot*(Xlast-Xfirst);
333
    float yEdge = Yfirst + quot*(Ylast-Yfirst);
334
    float zEdge;
182
    // android.util.Log.e("D", "new v: qx="+qx+" band="+band);
335 183

  
336
    float q = mPolygonBands[2*polyBand];
337
    float o = mPolygonBands[2*polyBand+1];
338
    float t = mPolygonBands[2*mNumPolygonBands-1];
184
    float bx = mLeftX + qx*(mRightX-mLeftX);
185
    float by = mLeftY + qx*(mRightY-mLeftY);
339 186

  
340
    int shape = mEdgeShape[polyVertex];
341

  
342
    switch(shape)
343
      {
344
      case SHAPE_DD : zEdge = 0.0f; break;
345
      case SHAPE_UU : zEdge = t;    break;
346
      case SHAPE_DU : zEdge = quot>=0.5f ? t : computeZEdge(1-2*quot); break;
347
      case SHAPE_UD : zEdge = quot<=0.5f ? t : computeZEdge(2*quot-1); break;
348
      default       : zEdge = quot<=0.5f ? computeZEdge(1-2*quot) : computeZEdge(2*quot-1); break;
349
      }
187
    float q = 1-qy;
188
    float x = bx + q*(mTopX-bx);
189
    float y = by + q*(mTopY-by);
190
    float z = computeElevation(band);
350 191

  
351
    float x = q*xEdge;
352
    float y = q*yEdge;
353
    float z = o + (t-o)*(zEdge/t);
192
    figureOutNormalVector2D(band<mNumBands ? qx : 0.5f);
193
    float d = figureOutDerivative(qy);
354 194

  
355 195
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB  ] = x;
356 196
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+1] = y;
357 197
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = z;
358 198

  
359
    figureOutNormalVector2D(shape, polyVertex, polyEndVer, quot, xEdge, yEdge);
360
    float d = figureOutDerivative(shape,polyBand,quot);
361

  
362 199
    float vx = d*mVecX;
363 200
    float vy = d*mVecY;
364 201
    float vz = mVecX*mVecX + mVecY*mVecY;
......
377 214

  
378 215
///////////////////////////////////////////////////////////////////////////////////////////////////
379 216

  
380
  private int createBandStrip(int vertex, int polyBand, int polyVertex, float[] attribs1, float[] attribs2)
217
  private int createBand(int vertex, int band, float[] attribs1, float[] attribs2)
381 218
    {
382
    if( polyVertex==0 )
219
    boolean fromLeft = (band%2 == 0);
220
    int extra = ((band<extraBands && mMode==MODE_NORMAL) ? extraVertices : 0);
221
    int n = mNumBands-band-1;
222

  
223
    float b = 1.0f/(mNumBands-band);
224
    float dxb = fromLeft ? b : -b;
225
    float sdx = dxb/(extra+1);
226

  
227
    float qx = fromLeft ? 0.0f : 1.0f;
228

  
229
    int bb = mMode==MODE_NORMAL ? band   : mNumBands-band;
230
    int bt = mMode==MODE_NORMAL ? band+1 : mNumBands-(band+1);
231

  
232
    float qyb = mBands[2*bb];
233
    float qyt = mBands[2*bt];
234

  
235
    if( mMode!=MODE_NORMAL )
383 236
      {
384
      vertex = addVertex(vertex,polyBand,0,1,0,attribs1,attribs2);
385
      if( polyBand>0 ) vertex = addVertex(vertex,polyBand,0,1,0,attribs1,attribs2);
237
      qyb = 1-qyb;
238
      qyt = 1-qyt;
386 239
      }
387 240

  
388
    boolean specialCase = mNumPolygonBands==2 && polyBand==0 && extraIndex>0;
389
    boolean isExtra = polyBand<extraIndex;
390
    int numPairs = specialCase ? extraIndex+1 : mNumPolygonBands-1-polyBand;
391
    if( isExtra ) numPairs += 2*extraVertices;
241
    vertex = addStripVertex(vertex, qx, qyb, band, attribs1,attribs2);
392 242

  
393
    int polyEndVer = polyVertex==mNumPolygonVertices-1 ? 0 : polyVertex+1;
394
    float quot1, quot2;
243
    for(int v=0; v<extra; v++)
244
      {
245
      vertex = addStripVertex(vertex, qx          , qyt, band+1, attribs1,attribs2);
246
      vertex = addStripVertex(vertex, qx+(v+1)*sdx, qyb, band  , attribs1,attribs2);
247
      }
395 248

  
396
    for(int index=0; index<numPairs; index++)
249
    if( n>0 )
397 250
      {
398
      if( specialCase )
399
        {
400
        quot1 = 1.0f;
401
        quot2 = getSpecialQuot(index+1);
402
        }
403
      else
251
      float t = 1.0f/n;
252
      float dxt = fromLeft ? t : -t;
253

  
254
      for(int v=0; v<n; v++)
404 255
        {
405
        quot1 = getQuot(index  ,polyBand+1, isExtra);
406
        quot2 = getQuot(index+1,polyBand  , isExtra);
256
        vertex=addStripVertex(vertex, qx+ v   *dxt, qyt, band+1, attribs1, attribs2);
257
        vertex=addStripVertex(vertex, qx+(v+1)*dxb, qyb, band  , attribs1, attribs2);
407 258
        }
259
      }
408 260

  
409
      vertex = addVertex(vertex,polyBand+1,polyVertex,polyEndVer,quot1,attribs1,attribs2);
410
      vertex = addVertex(vertex,polyBand  ,polyVertex,polyEndVer,quot2,attribs1,attribs2);
261
    qx = 1-qx;
262

  
263
    for(int v=0; v<=extra; v++)
264
      {
265
      vertex = addStripVertex(vertex, qx              , qyt, band+1, attribs1,attribs2);
266
      vertex = addStripVertex(vertex, qx-dxb+(v+1)*sdx, qyb, band  , attribs1,attribs2);
411 267
      }
412 268

  
413 269
    return vertex;
414 270
    }
415 271

  
416
///////////////////////////////////////////////////////////////////////////////////////////////////
417

  
418
  private int computeEdgeShape(int curr)
419
    {
420
    if( mEdgeUp==null || !mEdgeUp[curr] ) return SHAPE_DD;
421

  
422
    int prev = (curr==0 ? mNumPolygonVertices-1 : curr-1);
423
    int next = (curr==mNumPolygonVertices-1 ? 0 : curr+1);
424

  
425
    boolean rd = ( !mEdgeUp[next] || mVertUp==null || !mVertUp[next] );
426
    boolean ld = ( !mEdgeUp[prev] || mVertUp==null || !mVertUp[curr] );
427

  
428
    return rd ? (ld ? SHAPE_DUD : SHAPE_UD) : (ld ? SHAPE_DU : SHAPE_UU);
429
    }
430
*/
431 272
///////////////////////////////////////////////////////////////////////////////////////////////////
432 273

  
433 274
  private void buildGrid(float[] attribs1, float[] attribs2)
434 275
    {
435
    /*
436
    int vertex=0;
437

  
438
    mEdgeShape = new int[mNumPolygonVertices];
439

  
440
    for(int polyVertex=0; polyVertex<mNumPolygonVertices; polyVertex++)
441
      mEdgeShape[polyVertex] = computeEdgeShape(polyVertex);
442

  
443
    for(int polyBand=0; polyBand<mNumPolygonBands-1; polyBand++)
444
      for(int polyVertex=0; polyVertex<mNumPolygonVertices; polyVertex++)
445
        vertex = createBandStrip(vertex,polyBand,polyVertex,attribs1,attribs2);
446

  
447
     */
276
    if( mMode==MODE_FLAT )
277
      {
278
      addStripVertex(0, 0, 1, 0, attribs1,attribs2);
279
      addStripVertex(1, 0, 0, 0, attribs1,attribs2);
280
      addStripVertex(2, 1, 1, 0, attribs1,attribs2);
281
      }
282
    else
283
      {
284
      int vertex=0;
285
      for(int b=0; b<mNumBands; b++) vertex=createBand(vertex, b, attribs1, attribs2);
286
      }
448 287
    }
449 288

  
450 289
///////////////////////////////////////////////////////////////////////////////////////////////////
......
475 314
 *                   band which defines the strip aong the 'left-right' edge.
476 315
 *                   If FLAT, everything is flat anyway, so we disregard the bands and return a mesh
477 316
 *                   with 3 vertices.
478
 * @param exIndex    This and the next parameter describe how to make the mesh denser at the
479
 *                   'left' and 'right' vertices. If e.g. exIndex=3 and exVertices=2, then 3 triangles
317
 * @param exBands    This and the next parameter describe how to make the mesh denser at the
318
 *                   'left' and 'right' vertices. If e.g. exBands=3 and exVertices=2, then 3 triangles
480 319
 *                   of the outermost band (and 2 triangles of the next band, and 1 triangle of the
481 320
 *                   third band) get denser - the 3 triangles become 3+2 = 5.
482 321
 * @param exVertices See above.
483 322
 */
484
  public MeshBandedTriangle(float[] vL, float[] vR, float[] vT, float[] bands, float[] normL, float[] normR, int mode, int exIndex, int exVertices)
323
  public MeshBandedTriangle(float[] vL, float[] vR, float[] vT, float[] bands, float[] normL, float[] normR, int mode, int exBands, int exVertices)
485 324
    {
486 325
    super();
487 326

  
......
497 336
    mNormR= normR;
498 337

  
499 338
    mBands        = bands;
500
    mNumBands     = mBands.length /2;
501
    extraIndex    = exIndex;
339
    mNumBands     = mBands.length/2 -1;
340
    extraBands    = exBands;
502 341
    extraVertices = exVertices;
503 342

  
504 343
    computeNumberOfVertices();

Also available in: Unified diff