Project

General

Profile

« Previous | Next » 

Revision a60f7acf

Added by Leszek Koltunski 11 months ago

MeshMultigon finished.

View differences:

src/main/java/org/distorted/library/mesh/MeshMultigon.java
20 20

  
21 21
package org.distorted.library.mesh;
22 22

  
23
import java.util.ArrayList;
24

  
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26

  
23 27
/**
24 28
 * Create a 'multigon' mesh - a union of several polygons.
25 29
 *
......
31 35
public class MeshMultigon extends MeshBase
32 36
  {
33 37
  private static final float MAX_ERROR = 0.0001f;
38
  private float[][] mOuterVertices;
34 39

  
35
  private boolean isSame(float[] v1, float[] v2)
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41

  
42
  private boolean isSame(float dx, float dy)
36 43
    {
37
    float dx = v1[0]-v2[0];
38
    float dy = v1[1]-v2[1];
39 44
    return (dx*dx + dy*dy < MAX_ERROR);
40 45
    }
41 46

  
42 47
///////////////////////////////////////////////////////////////////////////////////////////////////
43 48

  
44
  private boolean isUp(float[][][] vertices, int polygon, int edge)
49
  private boolean isUp(float[][] vertices, int polygon, int edge)
45 50
    {
46
    float[][] p = vertices[polygon];
47
    int lenP = p.length;
51
    //android.util.Log.e("D", "checking polygon "+polygon+" edge "+edge);
52

  
53
    float[] p= vertices[polygon];
54
    int lenP = p.length/2;
48 55
    int len  = vertices.length;
49 56
    int next = (edge==lenP-1 ? 0 : edge+1);
50 57

  
51
    float[] v1 = p[edge];
52
    float[] v2 = p[next];
58
    float v1x = p[2*edge  ];
59
    float v1y = p[2*edge+1];
60
    float v2x = p[2*next  ];
61
    float v2y = p[2*next+1];
62

  
63
    //android.util.Log.e("D", " v1="+v1x+" "+v1y+"  v2="+v2x+" "+v2y);
53 64

  
54 65
    for(int i=0; i<len; i++)
55 66
      if( i!=polygon )
56 67
        {
57
        int num = vertices[i].length;
68
        int num = vertices[i].length/2;
58 69

  
59 70
        for(int j=0; j<num; j++)
60 71
          {
61 72
          int n = (j==num-1 ? 0 : j+1);
62
          if( isSame(v2,vertices[i][j]) && isSame(v1,vertices[i][n]) ) return true;
73
          float[] v = vertices[i];
74
          float x1 = v[2*j  ];
75
          float y1 = v[2*j+1];
76
          float x2 = v[2*n  ];
77
          float y2 = v[2*n+1];
78

  
79
          //android.util.Log.e("D", "comparing v2 to "+x1+" "+y1);
80
          //android.util.Log.e("D", "comparing v1 to "+x2+" "+y2);
81

  
82
          if( isSame(v2x-x1,v2y-y1) && isSame(v1x-x2,v1y-y2) ) return true;
63 83
          }
64 84
        }
65 85

  
86
    //android.util.Log.e("D", "FALSE");
87

  
66 88
    return false;
67 89
    }
68 90

  
69 91
///////////////////////////////////////////////////////////////////////////////////////////////////
70 92

  
71
  private boolean[][] computeUp(float[][] vertices, float[][] centers)
93
  private boolean[][] computeEdgesUp(float[][] vertices)
72 94
    {
73 95
    int num = vertices.length;
74 96
    boolean[][] up = new boolean[num][];
75
    float[][][] v = new float[num][][];
76 97

  
77 98
    for(int i=0; i<num; i++)
78 99
      {
79 100
      int len = vertices[i].length/2;
80
      v[i] = new float[len][2];
81

  
101
      up[i] = new boolean[len];
82 102
      for(int j=0; j<len; j++)
83 103
        {
84
        v[i][j][0] = vertices[i][2*j  ] + centers[i][0];
85
        v[i][j][1] = vertices[i][2*j+1] + centers[i][1];
104
        up[i][j] = isUp(vertices,i,j);
105
        //android.util.Log.e("D", "polygon "+i+" edge "+j+" up: "+up[i][j]);
86 106
        }
87 107
      }
88 108

  
89
    for(int i=0; i<num; i++)
109
    return up;
110
    }
111

  
112
///////////////////////////////////////////////////////////////////////////////////////////////////
113

  
114
  private float[] detectFirstOuterVertex(float[][] vertices)
115
    {
116
    float X = -Float.MAX_VALUE;
117
    int I=0,J=0, len = vertices.length;
118

  
119
    for(int i=0; i<len; i++ )
90 120
      {
91
      int len = vertices[i].length/2;
92
      up[i] = new boolean[len];
93
      for(int j=0; j<len; j++)
121
      float[] v = vertices[i];
122
      int num = v.length/2;
123

  
124
      for(int j=0; j<num; j++)
125
        if(v[2*j]>X)
126
          {
127
          X = v[2*j];
128
          I = i;
129
          J = j;
130
          }
131
      }
132

  
133
    float[] v = vertices[I];
134
    return new float[] {v[2*J],v[2*J+1]};
135
    }
136

  
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

  
139
  private double computeAngle(float x1,float y1, float x2, float y2)
140
    {
141
    double diff = Math.atan2(y2,x2)-Math.atan2(y1,x1);
142
    return diff<0 ? diff+(2*Math.PI) : diff;
143
    }
144

  
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

  
147
  private float[] detectNextOuterVertex(float[][] vertices, float[] curr, float[] vect)
148
    {
149
    double minAngle = 2*Math.PI;
150
    float x=0, y=0;
151

  
152
    for( float[] v : vertices )
153
      {
154
      int num = v.length/2;
155

  
156
      for( int j=0; j<num; j++)
94 157
        {
95
        up[i][j] = isUp(v,i,j);
158
        float xc = v[2*j];
159
        float yc = v[2*j+1];
160

  
161
        if( xc==curr[0] && yc==curr[1])
162
          {
163
          int n = (j==num-1 ? 0 : j+1);
164
          float xn = v[2*n];
165
          float yn = v[2*n+1];
166

  
167
          double angle = computeAngle(vect[0], vect[1], xn-xc, yn-yc);
168

  
169
          if (angle < minAngle)
170
            {
171
            minAngle = angle;
172
            x = xn;
173
            y = yn;
174
            }
96 175

  
97
        android.util.Log.e("D", "polygon "+i+" edge "+j+" up: "+up[i][j]);
176
          break;
177
          }
98 178
        }
99 179
      }
100 180

  
181
    return new float[] {x,y};
182
    }
183

  
184
///////////////////////////////////////////////////////////////////////////////////////////////////
185

  
186
  private void computeOuter(float[][] vertices)
187
    {
188
    ArrayList<float[]> tmp = new ArrayList<>();
189

  
190
    float[] vect = new float[] {1,0};
191
    float[] first= detectFirstOuterVertex(vertices);
192
    float[] next = first;
193

  
194
    do
195
      {
196
      float[] prev = next;
197
      next = detectNextOuterVertex(vertices,next,vect);
198
      vect[0] = prev[0]-next[0];
199
      vect[1] = prev[1]-next[1];
200
      tmp.add(next);
201
      }
202
    while( next[0]!=first[0] || next[1]!=first[1] );
203

  
204
    int num = tmp.size();
205
    mOuterVertices = new float[num][];
206
    for(int i=0; i<num; i++) mOuterVertices[i] = tmp.remove(0);
207
    }
208

  
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210

  
211
  private boolean doesntBelongToOuter(float x, float y)
212
    {
213
    for( float[] v : mOuterVertices )
214
      if( x==v[0] && y==v[1] ) return false;
215

  
216
    return true;
217
    }
218

  
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

  
221
  private boolean[][] computeVertsUp(float[][] vertices)
222
    {
223
    computeOuter(vertices);
224

  
225
    int num = vertices.length;
226
    boolean[][] up = new boolean[num][];
227

  
228
    for(int i=0; i<num; i++)
229
      {
230
      float[] v = vertices[i];
231
      int len = v.length/2;
232
      up[i] = new boolean[len];
233
      for(int j=0; j<len; j++) up[i][j] = doesntBelongToOuter(v[2*j],v[2*j+1]);
234
      }
235

  
101 236
    return up;
102 237
    }
103 238

  
......
121 256

  
122 257
    int numPolygons = vertices.length;
123 258
    MeshPolygon[] meshes = new MeshPolygon[numPolygons];
124
    boolean[][] up = computeUp(vertices,centers);
259
    boolean[][] edgesUp = computeEdgesUp(vertices);
260
    boolean[][] vertsUp = computeVertsUp(vertices);
261

  
262
    for(int i=0; i<numPolygons; i++)
263
      meshes[i] = new MeshPolygon(vertices[i],band,edgesUp[i],vertsUp[i],exIndex,exVertices,centers[i][0],centers[i][1]);
264

  
265
    join(meshes);
266
    }
267

  
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269
/**
270
 * Auto-create the centers to be the centers of gravity of each polygon.
271
 */
272

  
273
  public MeshMultigon(float[][] vertices, float[] band, int exIndex, int exVertices)
274
    {
275
    super();
276

  
277
    int numPolygons = vertices.length;
278
    MeshPolygon[] meshes = new MeshPolygon[numPolygons];
279
    boolean[][] edgesUp = computeEdgesUp(vertices);
280
    boolean[][] vertsUp = computeVertsUp(vertices);
125 281

  
126 282
    for(int i=0; i<numPolygons; i++)
127
      meshes[i] = new MeshPolygon(vertices[i],band,up[i],exIndex,exVertices,centers[i][0],centers[i][1]);
283
      {
284
      float[] v = vertices[i];
285
      int num = v.length/2;
286
      float xsum=0, ysum = 0;
287

  
288
      for(int j=0; j<num; j++)
289
        {
290
        xsum += v[2*j];
291
        ysum += v[2*j+1];
292
        }
293

  
294
      meshes[i] = new MeshPolygon(v,band,edgesUp[i],vertsUp[i],exIndex,exVertices,xsum/num,ysum/num);
295
      }
128 296

  
129 297
    join(meshes);
130 298
    }
src/main/java/org/distorted/library/mesh/MeshPolygon.java
45 45
  private float[] mPolygonBands;
46 46
  private int mNumPolygonBands;
47 47
  private boolean[] mEdgeUp;
48
  private boolean[] mVertUp;
48 49

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

  
53 54
  private float[] mCurveCache;
55
  private float[] mEdgeQuots;
54 56

  
55 57
///////////////////////////////////////////////////////////////////////////////////////////////////
56 58
// polygonVertices>=3 , polygonBands>=2
......
116 118
    mCurveCache[NUM_CACHE-1] = tmpD[mNumPolygonBands];
117 119
    }
118 120

  
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

  
123
  private void computeQuots()
124
    {
125
    mEdgeQuots = new float[mNumPolygonVertices];
126

  
127
    for(int i=0; i<mNumPolygonVertices; i++)
128
      {
129
      int n = (i==mNumPolygonVertices-1 ? 0:i+1);
130

  
131
      float x1 = mPolygonVertices[2*i];
132
      float y1 = mPolygonVertices[2*i+1];
133
      float x2 = mPolygonVertices[2*n];
134
      float y2 = mPolygonVertices[2*n+1];
135
      float A = x1-x2;
136
      float B = y1-y2;
137
      float C = A*A+B*B;
138

  
139
      float x = (B*B*x1-A*B*y1)/C;
140
      float y = (A*A*y1-A*B*x1)/C;
141

  
142
      float dx = x1-x;
143
      float dy = y1-y;
144

  
145
      mEdgeQuots[i] = (float)Math.sqrt((dx*dx+dy*dy)/C);
146
      }
147
    }
148

  
119 149
///////////////////////////////////////////////////////////////////////////////////////////////////
120 150

  
121 151
  private float getSpecialQuot(int index)
......
209 239
///////////////////////////////////////////////////////////////////////////////////////////////////
210 240

  
211 241
  private void doNormals(float[] attribs1, int index, float quot, int edgeShape,
212
                         float xEdge, float yEdge, float zEdge, int polyBand)
242
                         float xEdge, float yEdge, float zEdge, int polyVertex, int polyBand)
213 243
    {
214 244
    if( ( quot<=0.5f && (edgeShape==SHAPE_UD || edgeShape==SHAPE_UU) ) ||
215 245
        ( quot> 0.5f && (edgeShape==SHAPE_DU || edgeShape==SHAPE_UU) )  )
......
220 250
      }
221 251
    else
222 252
      {
223
      float t = mPolygonBands[2*mNumPolygonBands-1];
224
      float x = 1.0f - mPolygonBands[2*polyBand];
225
      float d = derivative(x);
253
      float d,x = 1-mPolygonBands[2*polyBand];
226 254

  
227
      d *= ((t-zEdge)/t);
255
      if( /*quot==0.0f || quot==1.0f ||*/ edgeShape==SHAPE_DD )
256
        {
257
        float t = mPolygonBands[2*mNumPolygonBands-1];
258
        d = ((t-zEdge)/t)*derivative(x);
259
        }
260
      else
261
        {
262
        float q = quot + x*(mEdgeQuots[polyVertex]-quot);
263
        d = (q<0.5f ? derivative(2*q) : -derivative(2-2*q));
264
        int nextVertex = polyVertex==mNumPolygonVertices-1 ? 0:polyVertex+1;
265
        xEdge = mPolygonVertices[2*polyVertex  ] - mPolygonVertices[2*nextVertex  ];
266
        yEdge = mPolygonVertices[2*polyVertex+1] - mPolygonVertices[2*nextVertex+1];
267

  
268
        //android.util.Log.e("D", "normals: edgeQuot="+mEdgeQuots[polyVertex]+" vertex="+polyVertex+" d="+d+" xEdge="+xEdge+" yEdge="+yEdge+" q="+q+" quot="+quot);
269
        }
228 270

  
229 271
      float vx = d*xEdge;
230 272
      float vy = d*yEdge;
......
275 317
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = z;
276 318

  
277 319
    int index = VERT1_ATTRIBS*vertex + NOR_ATTRIB;
278
    doNormals(attribs1,index, quot, edgeShape, xEdge, yEdge, zEdge, polyBand);
320
    doNormals(attribs1,index, quot, edgeShape, xEdge, yEdge, zEdge, polyVertex, polyBand);
279 321

  
280 322
    attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB  ] = x+0.5f;
281 323
    attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB+1] = y+0.5f;
......
330 372
    int prev = (curr==0 ? mNumPolygonVertices-1 : curr-1);
331 373
    int next = (curr==mNumPolygonVertices-1 ? 0 : curr+1);
332 374

  
333
    boolean l = mEdgeUp[prev];
334
    boolean r = mEdgeUp[next];
375
    boolean rd = ( !mEdgeUp[next] || mVertUp==null || !mVertUp[next] );
376
    boolean ld = ( !mEdgeUp[prev] || mVertUp==null || !mVertUp[curr] );
335 377

  
336
    return l ? (r ? SHAPE_UU : SHAPE_UD) : (r ? SHAPE_DU : SHAPE_DUD);
378
    return rd ? (ld ? SHAPE_DUD : SHAPE_UD) : (ld ? SHAPE_DU : SHAPE_UU);
337 379
    }
338 380

  
339 381
///////////////////////////////////////////////////////////////////////////////////////////////////
......
377 419
 *                   If the 'previous' edge is also up, then the Z is up horizontally from its middle
378 420
 *                   to the left vertex; else it goes down along the same function it goes along the bands.
379 421
 *                   Same with the right half of the edge.
422
 * @param vertUp     N booleans - one for each vertex. The first is about vertex 0, then vertex 1, etc.
423
 *                   If this is null or false, the vertex is down; otheerwise - it is 'up'.
424
 *                   This is taken into account only in one case: if both edges the vertex is the end of
425
 *                   are 'up', then the vertex can be 'up' or 'down'; otherwise - if at least one of
426
 *                   those edges is 'down' - then the vertex must be 'down' as well and this is ignored.
380 427
 * @param exIndex    This and the next parameter describe how to make the mesh denser at the
381 428
 *                   polyVertices. If e.g. exIndex=3 and exVertices=2, then 3 triangles of the
382 429
 *                   outermost band (and 2 triangles of the next band, and 1 triangle of the third
......
386 433
 *                   all bands go to.
387 434
 * @param centerY    Y coordinate of the center.
388 435
 */
389
  public MeshPolygon(float[] verticesXY, float[] bands, boolean[] edgeUp, int exIndex, int exVertices, float centerX, float centerY)
436
  public MeshPolygon(float[] verticesXY, float[] bands, boolean[] edgeUp, boolean[] vertUp, int exIndex, int exVertices, float centerX, float centerY)
390 437
    {
391 438
    super();
392 439

  
......
395 442
    mNumPolygonVertices= mPolygonVertices.length /2;
396 443
    mNumPolygonBands   = mPolygonBands.length /2;
397 444
    mEdgeUp            = edgeUp;
445
    mVertUp            = vertUp;
398 446
    extraIndex         = exIndex;
399 447
    extraVertices      = exVertices;
400 448

  
......
409 457

  
410 458
    computeNumberOfVertices();
411 459
    computeCache();
460
    computeQuots();
412 461

  
413 462
    float[] attribs1= new float[VERT1_ATTRIBS*numVertices];
414 463
    float[] attribs2= new float[VERT2_ATTRIBS*numVertices];
......
436 485

  
437 486
  public MeshPolygon(float[] verticesXY, float[] bands, int exIndex, int exVertices)
438 487
    {
439
    this(verticesXY,bands,null,exIndex,exVertices,0.0f,0.0f);
488
    this(verticesXY,bands,null,null,exIndex,exVertices,0.0f,0.0f);
440 489
    }
441 490

  
442 491
///////////////////////////////////////////////////////////////////////////////////////////////////
......
446 495
 */
447 496
  public MeshPolygon(float[] verticesXY, float[] bands)
448 497
    {
449
    this(verticesXY,bands,null,0,0,0.0f,0.0f);
498
    this(verticesXY,bands,null,null,0,0,0.0f,0.0f);
450 499
    }
451 500

  
452 501
///////////////////////////////////////////////////////////////////////////////////////////////////

Also available in: Unified diff