Project

General

Profile

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

library / src / main / java / org / distorted / library / mesh / MeshPolygon.java @ 97b6c85e

1 808ef3aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 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.mesh;
21
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23
/**
24
 * Create a polygon of any shape and varying elevations from the edges towards the center.
25
 * <p>
26
 * Specify a list of vertices. Any two adjacent vertices + the center (0,0,0) form a triangle. The
27
 * polygon is going to be split into such triangles, and each triange is split into adjustable number
28
 * of 'bands' form the outer edge towards the center. Edges of each band can can at any elevation.
29
 */
30
public class MeshPolygon extends MeshBase
31
  {
32
  private float[] mPolygonVertices;
33
  private int mNumPolygonVertices;
34
  private float[] mPolygonBands;
35
  private int mNumPolygonBands;
36
37
  private int remainingVert;
38
  private int numVertices;
39 d456b075 Leszek Koltunski
  private int extraIndex, extraVertices;
40 808ef3aa Leszek Koltunski
41 eeb5d115 Leszek Koltunski
  private float[] mBandQuot;
42
43 808ef3aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
44
// polygonVertices>=3 , polygonBands>=2
45
46 d456b075 Leszek Koltunski
  private void computeNumberOfVertices()
47 808ef3aa Leszek Koltunski
     {
48 d456b075 Leszek Koltunski
     numVertices = (mNumPolygonVertices*mNumPolygonBands+2)*(mNumPolygonBands-1) - 1;
49
     numVertices+= 2*mNumPolygonVertices*(2*extraIndex*extraVertices);
50
51 ac6a08e7 Leszek Koltunski
     remainingVert = numVertices;
52 808ef3aa Leszek Koltunski
     }
53
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55
56 eeb5d115 Leszek Koltunski
  private void computeCache()
57 808ef3aa Leszek Koltunski
    {
58 eeb5d115 Leszek Koltunski
    mBandQuot = new float[mNumPolygonBands];
59 ac6a08e7 Leszek Koltunski
60 eeb5d115 Leszek Koltunski
    int next, prev;
61 ac6a08e7 Leszek Koltunski
62 eeb5d115 Leszek Koltunski
    for(int band=0; band<mNumPolygonBands; band++)
63
      {
64
      next = (band==mNumPolygonBands-1 ? band : band+1);
65
      prev = (band==                 0 ? band : band-1);
66 ac6a08e7 Leszek Koltunski
67 eeb5d115 Leszek Koltunski
      mBandQuot[band] = (mPolygonBands[2*prev+1]-mPolygonBands[2*next+1]) / (mPolygonBands[2*next]-mPolygonBands[2*prev]);
68
      }
69
    }
70 808ef3aa Leszek Koltunski
71 eeb5d115 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
72 808ef3aa Leszek Koltunski
73 d456b075 Leszek Koltunski
  private float getQuot(int index, int band, boolean isExtra)
74 eeb5d115 Leszek Koltunski
    {
75 d456b075 Leszek Koltunski
    int num = mNumPolygonBands-1-band;
76 808ef3aa Leszek Koltunski
77 d456b075 Leszek Koltunski
    if( num>0 )
78
      {
79
      if( isExtra )
80
        {
81
        int extra = extraIndex-band+extraVertices;
82
83
        if( index < extra )
84
          {
85
          float quot = ((float)extraIndex-band)/(extra*num);
86
          return index*quot;
87
          }
88
        else if( index > num+2*extraVertices-extra )
89
          {
90
          float quot = ((float)extraIndex-band)/(extra*num);
91
          return (1.0f-((float)extraIndex-band)/num) + (index-num-2*extraVertices+extra)*quot;
92
          }
93
        else
94
          {
95
          return ((float)(index-extraVertices))/num;
96
          }
97
        }
98 808ef3aa Leszek Koltunski
99 d456b075 Leszek Koltunski
      return (float)index/num;
100
      }
101 808ef3aa Leszek Koltunski
102 d456b075 Leszek Koltunski
    return 1.0f;
103
    }
104
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106
107
  private int addVertex(int vertex, int polyBand, int polyVertex, int polyEndVer, float quot, float[] attribs1, float[] attribs2)
108
    {
109
    remainingVert--;
110
111
    float vx,vy,vz;
112 eeb5d115 Leszek Koltunski
    float Xfirst= mPolygonVertices[2*polyVertex  ];
113
    float Yfirst= mPolygonVertices[2*polyVertex+1];
114
    float Xlast = mPolygonVertices[2*polyEndVer  ];
115
    float Ylast = mPolygonVertices[2*polyEndVer+1];
116 808ef3aa Leszek Koltunski
117 eeb5d115 Leszek Koltunski
    float xEdge = Xfirst + quot*(Xlast-Xfirst);
118
    float yEdge = Yfirst + quot*(Ylast-Yfirst);
119 808ef3aa Leszek Koltunski
120 eeb5d115 Leszek Koltunski
    float x = mPolygonBands[2*polyBand]*xEdge;
121
    float y = mPolygonBands[2*polyBand]*yEdge;
122 808ef3aa Leszek Koltunski
123 eeb5d115 Leszek Koltunski
    if( quot==0.0f || quot==1.0f )
124
      {
125
      vx = mBandQuot[polyBand]*xEdge;
126
      vy = mBandQuot[polyBand]*yEdge;
127
      vz = xEdge*xEdge + yEdge*yEdge;
128 ac6a08e7 Leszek Koltunski
      }
129
    else
130
      {
131 eeb5d115 Leszek Koltunski
      vx = mBandQuot[polyBand]*(Ylast-Yfirst);
132
      vy = mBandQuot[polyBand]*(Xfirst-Xlast);
133
      float tmp = Xfirst*Ylast - Xlast*Yfirst;
134
      vz = (tmp<0 ? -tmp:tmp);
135
      }
136 ac6a08e7 Leszek Koltunski
137 eeb5d115 Leszek Koltunski
    float len = (float)Math.sqrt(vx*vx + vy*vy + vz*vz);
138 ac6a08e7 Leszek Koltunski
139 eeb5d115 Leszek Koltunski
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB  ] = x;
140
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+1] = y;
141
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = mPolygonBands[2*polyBand+1];
142
143
    attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB  ] = vx/len;
144
    attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB+1] = vy/len;
145
    attribs1[VERT1_ATTRIBS*vertex + NOR_ATTRIB+2] = vz/len;
146
147
    attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB  ] = x+0.5f;
148
    attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB+1] = y+0.5f;
149 808ef3aa Leszek Koltunski
150
    return vertex+1;
151
    }
152
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154
155
  private int createBandStrip(int vertex, int polyBand, int polyVertex, float[] attribs1, float[] attribs2)
156
    {
157
    if( polyVertex==0 )
158
      {
159 eeb5d115 Leszek Koltunski
      vertex = addVertex(vertex,polyBand,0,1,0,attribs1,attribs2);
160 808ef3aa Leszek Koltunski
161
      if( polyBand>0 )
162
        {
163 eeb5d115 Leszek Koltunski
        vertex = addVertex(vertex,polyBand,0,1,0,attribs1,attribs2);
164 808ef3aa Leszek Koltunski
        }
165
      }
166
167
    int numPairs = mNumPolygonBands-1-polyBand;
168 d456b075 Leszek Koltunski
    boolean isExtra = polyBand<extraIndex;
169
170
    if( isExtra )
171
      {
172
      numPairs += 2*extraVertices;
173
      }
174
175 eeb5d115 Leszek Koltunski
    int polyEndVer = polyVertex==mNumPolygonVertices-1 ? 0 : polyVertex+1;
176 d456b075 Leszek Koltunski
    float quot1, quot2;
177 808ef3aa Leszek Koltunski
178 eeb5d115 Leszek Koltunski
    for(int index=0; index<numPairs; index++)
179 808ef3aa Leszek Koltunski
      {
180 d456b075 Leszek Koltunski
      quot1 = getQuot(index  ,polyBand+1, isExtra);
181
      quot2 = getQuot(index+1,polyBand  , isExtra);
182
183
      vertex = addVertex(vertex,polyBand+1,polyVertex,polyEndVer,quot1,attribs1,attribs2);
184
      vertex = addVertex(vertex,polyBand  ,polyVertex,polyEndVer,quot2,attribs1,attribs2);
185 808ef3aa Leszek Koltunski
      }
186
187
    return vertex;
188
    }
189
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
192
  private void buildGrid(float[] attribs1, float[] attribs2)
193
    {
194
    int vertex=0;
195
196 ac6a08e7 Leszek Koltunski
    for(int polyBand=0; polyBand<mNumPolygonBands-1; polyBand++)
197 808ef3aa Leszek Koltunski
      for(int polyVertex=0; polyVertex<mNumPolygonVertices; polyVertex++)
198
        {
199 ac6a08e7 Leszek Koltunski
        vertex = createBandStrip(vertex,polyBand,polyVertex,attribs1,attribs2);
200 808ef3aa Leszek Koltunski
        }
201
    }
202
203
///////////////////////////////////////////////////////////////////////////////////////////////////
204
// PUBLIC API
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206
/**
207
 * Create a polygon of any shape and varying elevations from the edges towards the center.
208 d456b075 Leszek Koltunski
 * Optionally make it more dense at the vertices.
209 808ef3aa Leszek Koltunski
 *
210
 * @param verticesXY 2N floats - packed description of polygon vertices. N pairs (x,y).
211 8b082b9f Leszek Koltunski
 *                   Vertices HAVE TO be specified in a COUNTERCLOCKWISE order (starting from any).
212 808ef3aa Leszek Koltunski
 * @param bands      2K floats; K pairs of two floats each describing a single band.
213
 *                   From (1.0,Z[0]) (outer edge, its Z elevation) to (0.0,Z[K]) (the center,
214
 *                   its elevation). The polygon is split into such concentric bands.
215 ac6a08e7 Leszek Koltunski
 *                   Must be band[2*i] > band[2*(i+1)] !
216 d456b075 Leszek Koltunski
 * @param exIndex    This and the next parameter describe how to make the mesh denser at the
217
 *                   polyVertices. If e.g. exIndex=3 and exVertices=2, then 3 triangles of the
218 c8484d73 Leszek Koltunski
 *                   outermost band (and 2 triangles of the next band, and 1 triange of the third
219 d456b075 Leszek Koltunski
 *                   band) get denser - the 3 triangles become 3+2 = 5.
220
 * @param exVertices See above.
221 808ef3aa Leszek Koltunski
 */
222 d456b075 Leszek Koltunski
  public MeshPolygon(float[] verticesXY, float[] bands, int exIndex, int exVertices)
223 808ef3aa Leszek Koltunski
    {
224
    super();
225
226 d456b075 Leszek Koltunski
    mPolygonVertices   = verticesXY;
227
    mPolygonBands      = bands;
228
    mNumPolygonVertices= mPolygonVertices.length /2;
229
    mNumPolygonBands   = mPolygonBands.length /2;
230
    extraIndex         = exIndex;
231
    extraVertices      = exVertices;
232 808ef3aa Leszek Koltunski
233 d456b075 Leszek Koltunski
    computeNumberOfVertices();
234 eeb5d115 Leszek Koltunski
    computeCache();
235 808ef3aa Leszek Koltunski
236
    float[] attribs1= new float[VERT1_ATTRIBS*numVertices];
237
    float[] attribs2= new float[VERT2_ATTRIBS*numVertices];
238
239
    buildGrid(attribs1,attribs2);
240
241
    if( remainingVert!=0 )
242
      android.util.Log.d("MeshPolygon", "remainingVert " +remainingVert );
243
244
    setAttribs(attribs1,attribs2);
245
    }
246
247 d456b075 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
248
/**
249
 * Create a polygon of any shape and varying elevations from the edges towards the center.
250
 * Equivalent of the previous with exIndex=0 or exVertices=0.
251
 */
252
  public MeshPolygon(float[] verticesXY, float[] bands)
253
    {
254
    this(verticesXY,bands,0,0);
255
    }
256
257 808ef3aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
258
/**
259
 * Copy constructor.
260
 */
261
  public MeshPolygon(MeshPolygon mesh, boolean deep)
262
    {
263
    super(mesh,deep);
264
    }
265
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267
/**
268
 * Copy the Mesh.
269
 *
270
 * @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices,
271
 *             normals and inflates (the rest, in particular the mVertAttribs2 containing texture
272
 *             coordinates and effect associations, is always deep copied)
273
 */
274
  public MeshPolygon copy(boolean deep)
275
    {
276
    return new MeshPolygon(this,deep);
277
    }
278
 }