Project

General

Profile

« Previous | Next » 

Revision 94690c11

Added by Leszek Koltunski 2 days ago

Rename .java to .kt

View differences:

src/main/java/org/distorted/library/mesh/DeferredJobs.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.mesh;
22

  
23
import org.distorted.library.effect.MatrixEffect;
24
import org.distorted.library.effect.VertexEffect;
25
import org.distorted.library.effectqueue.EffectQueueVertex;
26
import org.distorted.library.main.DistortedLibrary;
27
import org.distorted.library.type.Static4D;
28

  
29
import java.util.ArrayList;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32
/**
33
 * Not part of public API, do not document (public only because has to be cleaned from the main package)
34
 *
35
 * @y.exclude
36
 */
37
public class DeferredJobs
38
  {
39
  private static final int JOB_TYPE_VERTEX       = 0;
40
  private static final int JOB_TYPE_MATRIX       = 1;
41
  private static final int JOB_TYPE_MERGE_TEX    = 2;
42
  private static final int JOB_TYPE_MERGE_EFF    = 3;
43
  private static final int JOB_TYPE_JOIN         = 4;
44
  private static final int JOB_TYPE_COPY         = 5;
45
  private static final int JOB_TYPE_TEXTURE      = 6;
46
  private static final int JOB_TYPE_ASSOC        = 7;
47
  private static final int JOB_TYPE_CENTER       = 8;
48
  private static final int JOB_TYPE_ADD_EMPTY_TEX= 9;
49
  private static final int JOB_TYPE_NOT_AFFECTED = 10;
50

  
51
  private static final ArrayList<JobNode> mJobs = new ArrayList<>();
52

  
53
  //////////////////////////////////////////////////////////////////////////
54

  
55
  private static class Job
56
    {
57
    private final int mType;
58
    private final MeshBase mTarget;
59
    private final MeshBase[] mSource;
60
    private final MatrixEffect mMatrixEffect;
61
    private final Static4D[] mMaps;
62
    private final int mComp, mAndAssoc, mEquAssoc;
63
    private final float mX,mY,mZ;
64
    private final int[] mComps;
65

  
66
    private EffectQueueVertex mVertexEffects;
67

  
68
    Job(int type, MeshBase target, MeshBase[] source, VertexEffect vEff, MatrixEffect mEff,
69
        Static4D[] maps, int comp, int and, int equ, float x, float y, float z, int[] comps)
70
      {
71
      mType     = type;
72
      mTarget   = target;
73
      mSource   = source;
74
      mMaps     = maps;
75
      mComp     = comp;
76
      mAndAssoc = and;
77
      mEquAssoc = equ;
78
      mX        = x;
79
      mY        = y;
80
      mZ        = z;
81
      mComps    = comps;
82

  
83
      if( vEff!=null )
84
        {
85
        mVertexEffects= new EffectQueueVertex();
86
        mVertexEffects.add(vEff);
87
        }
88

  
89
      mMatrixEffect = mEff;
90
      }
91

  
92
    void addEffect(VertexEffect effect)
93
      {
94
      mVertexEffects.add(effect);
95
      }
96

  
97
    void execute()
98
      {
99
      switch(mType)
100
        {
101
        case JOB_TYPE_VERTEX       : DistortedLibrary.adjustVertices(mTarget, mVertexEffects);
102
                                     break;
103
        case JOB_TYPE_MATRIX       : mTarget.applyMatrix(mMatrixEffect,mAndAssoc,mEquAssoc);
104
                                     break;
105
        case JOB_TYPE_MERGE_TEX    : mTarget.mergeTexComponentsNow();
106
                                     break;
107
        case JOB_TYPE_MERGE_EFF    : mTarget.mergeEffComponentsNow();
108
                                     break;
109
        case JOB_TYPE_JOIN         : mTarget.joinAttribs(mSource);
110
                                     break;
111
        case JOB_TYPE_COPY         : mTarget.copy(mSource[0]);
112
                                     break;
113
        case JOB_TYPE_TEXTURE      : mTarget.textureMap(mMaps,mComp);
114
                                     break;
115
        case JOB_TYPE_ASSOC        : mTarget.setEffectAssociationNow(mComp,mAndAssoc,mEquAssoc);
116
                                     break;
117
        case JOB_TYPE_CENTER       : mTarget.setComponentCenterNow(mComp,mX,mY,mZ);
118
                                     break;
119
        case JOB_TYPE_ADD_EMPTY_TEX: mTarget.addEmptyTexComponentNow();
120
                                     break;
121
        case JOB_TYPE_NOT_AFFECTED:  mTarget.setNotAffectedComponentsNow(mComps);
122
        }
123
      }
124

  
125
    void clear()
126
      {
127
      if( mVertexEffects!=null ) mVertexEffects.removeAll(false);
128
      }
129

  
130
    String print()
131
      {
132
      switch(mType)
133
        {
134
        case JOB_TYPE_VERTEX       : return "VERTEX";
135
        case JOB_TYPE_MATRIX       : return "MATRIX";
136
        case JOB_TYPE_MERGE_TEX    : return "MERGE_TEX";
137
        case JOB_TYPE_MERGE_EFF    : return "MERGE_EFF";
138
        case JOB_TYPE_JOIN         : return "JOIN";
139
        case JOB_TYPE_COPY         : return "COPY";
140
        case JOB_TYPE_TEXTURE      : return "TEXTURE";
141
        case JOB_TYPE_ASSOC        : return "ASSOC";
142
        case JOB_TYPE_CENTER       : return "CENTER";
143
        case JOB_TYPE_ADD_EMPTY_TEX: return "ADD_EMPTY_TEX";
144
        case JOB_TYPE_NOT_AFFECTED : return "POSTPROC COMPS";
145
        }
146

  
147
      return null;
148
      }
149
    }
150

  
151
  //////////////////////////////////////////////////////////////////////////
152

  
153
  static class JobNode
154
    {
155
    private ArrayList<JobNode> mPrevJobs;
156
    private ArrayList<JobNode> mNextJobs;
157
    private Job mJob;
158

  
159
    JobNode(Job job)
160
      {
161
      mPrevJobs = new ArrayList<>();
162
      mNextJobs = new ArrayList<>();
163
      mJob      = job;
164
      }
165

  
166
    synchronized void execute()
167
      {
168
      if( mPrevJobs!=null )
169
        {
170
        JobNode node;
171
        int numPrev = mPrevJobs.size();
172

  
173
        for(int i=0; i<numPrev; i++)
174
          {
175
          node = mPrevJobs.get(0);  // removeNode() rips the executed job out, thus the 0
176
          node.execute();
177
          }
178

  
179
        removeNode(this);
180
        mJob.execute();
181
        }
182
      }
183

  
184
    synchronized void clear()
185
      {
186
      mPrevJobs.clear();
187
      mPrevJobs = null;
188
      mNextJobs.clear();
189
      mNextJobs = null;
190

  
191
      mJob.clear();
192
      mJob = null;
193
      }
194

  
195
    void print(int level)
196
      {
197
      int numPrev = mPrevJobs.size();
198
      int numNext = mNextJobs.size();
199

  
200
      String str = "";
201
      for(int i=0; i<level; i++) str+=" ";
202

  
203
      str += mJob.print();
204

  
205
      str += (" next: "+numNext+" prev: "+numPrev);
206

  
207
      DistortedLibrary.logMessage("DeferredJobs: "+str);
208

  
209
      for(int i=0; i<numPrev; i++)
210
        {
211
        JobNode node = mPrevJobs.get(i);
212
        node.print(level+1);
213
        }
214
      }
215
    }
216

  
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

  
219
  private static void removeNode(JobNode node)
220
    {
221
    mJobs.remove(node);
222
    JobNode jn;
223

  
224
    int numPrev = node.mPrevJobs.size();
225

  
226
    for(int i=0; i<numPrev; i++)
227
      {
228
      jn = node.mPrevJobs.get(i);
229
      jn.mNextJobs.remove(node);
230
      }
231

  
232
    int numNext = node.mNextJobs.size();
233

  
234
    for(int i=0; i<numNext; i++)
235
      {
236
      jn = node.mNextJobs.get(i);
237
      jn.mPrevJobs.remove(node);
238
      }
239

  
240
    node.mJob.mTarget.mJobNode[0] = null;
241
    }
242

  
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

  
245
  static JobNode vertex(MeshBase target, VertexEffect effect)
246
    {
247
    JobNode jn = target.mJobNode[0];
248

  
249
    if( jn==null )
250
      {
251
      Job job = new Job(JOB_TYPE_VERTEX,target,null,effect,null,null,0,0,0,0,0,0,null);
252
      JobNode node = new JobNode(job);
253
      mJobs.add(node);
254
      return node;
255
      }
256
    else
257
      {
258
      if( jn.mJob.mType==JOB_TYPE_VERTEX )
259
        {
260
        jn.mJob.addEffect(effect);
261
        return jn;
262
        }
263
      else
264
        {
265
        Job job = new Job(JOB_TYPE_VERTEX,target,null,effect,null,null,0,0,0,0,0,0,null);
266
        JobNode node = new JobNode(job);
267
        node.mPrevJobs.add(jn);
268
        jn.mNextJobs.add(node);
269
        mJobs.add(node);
270
        return node;
271
        }
272
      }
273
    }
274

  
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

  
277
  static JobNode matrix(MeshBase target, MatrixEffect effect, int andAssoc, int ecuAssoc)
278
    {
279
    JobNode jn = target.mJobNode[0];
280
    Job job = new Job(JOB_TYPE_MATRIX,target,null,null,effect,null,0,andAssoc,ecuAssoc,0,0,0,null);
281
    JobNode node = new JobNode(job);
282
    node.mPrevJobs.add(jn);
283
    jn.mNextJobs.add(node);
284
    mJobs.add(node);
285
    return node;
286
    }
287

  
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

  
290
  static JobNode mergeTex(MeshBase target)
291
    {
292
    JobNode jn = target.mJobNode[0];
293
    Job job = new Job(JOB_TYPE_MERGE_TEX,target,null,null,null,null,0,0,0,0,0,0,null);
294
    JobNode node = new JobNode(job);
295
    node.mPrevJobs.add(jn);
296
    jn.mNextJobs.add(node);
297
    mJobs.add(node);
298
    return node;
299
    }
300

  
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

  
303
  static JobNode addEmptyTex(MeshBase target)
304
    {
305
    JobNode jn = target.mJobNode[0];
306
    Job job = new Job(JOB_TYPE_ADD_EMPTY_TEX,target,null,null,null,null,0,0,0,0,0,0,null);
307
    JobNode node = new JobNode(job);
308
    node.mPrevJobs.add(jn);
309
    jn.mNextJobs.add(node);
310
    mJobs.add(node);
311
    return node;
312
    }
313

  
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315

  
316
  static JobNode mergeEff(MeshBase target)
317
    {
318
    JobNode jn = target.mJobNode[0];
319
    Job job = new Job(JOB_TYPE_MERGE_EFF,target,null,null,null,null,0,0,0,0,0,0,null);
320
    JobNode node = new JobNode(job);
321
    node.mPrevJobs.add(jn);
322
    jn.mNextJobs.add(node);
323
    mJobs.add(node);
324
    return node;
325
    }
326

  
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

  
329
  static JobNode join(MeshBase target, MeshBase[] meshes)
330
    {
331
    JobNode jn;
332

  
333
    Job job = new Job(JOB_TYPE_JOIN,target,meshes,null,null,null,0,0,0,0,0,0,null);
334
    JobNode node = new JobNode(job);
335

  
336
    for (MeshBase mesh : meshes)
337
      {
338
      jn = mesh.mJobNode[0];
339

  
340
      if( jn!=null )
341
        {
342
        node.mPrevJobs.add(jn);
343
        jn.mNextJobs.add(node);
344
        }
345
      }
346

  
347
    mJobs.add(node);
348
    return node;
349
    }
350

  
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

  
353
  static JobNode copy(MeshBase target, MeshBase mesh)
354
    {
355
    JobNode jn = mesh.mJobNode[0];
356
    MeshBase[] meshes = new MeshBase[1];
357
    meshes[0] = mesh;
358
    Job job = new Job(JOB_TYPE_COPY,target,meshes,null,null,null,0,0,0,0,0,0,null);
359
    JobNode node = new JobNode(job);
360
    node.mPrevJobs.add(jn);
361
    jn.mNextJobs.add(node);
362
    mJobs.add(node);
363
    return node;
364
    }
365

  
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367

  
368
  static JobNode textureMap(MeshBase target, Static4D[] maps, int comp)
369
    {
370
    JobNode jn = target.mJobNode[0];
371
    Job job = new Job(JOB_TYPE_TEXTURE,target,null,null,null,maps,comp,0,0,0,0,0,null);
372
    JobNode node = new JobNode(job);
373
    node.mPrevJobs.add(jn);
374
    jn.mNextJobs.add(node);
375
    mJobs.add(node);
376
    return node;
377
    }
378

  
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

  
381
  static JobNode effectAssoc(MeshBase target, int comp, int andAssoc, int equAssoc)
382
    {
383
    JobNode jn = target.mJobNode[0];
384
    Job job = new Job(JOB_TYPE_ASSOC,target,null,null,null,null,comp,andAssoc,equAssoc,0,0,0,null);
385
    JobNode node = new JobNode(job);
386
    node.mPrevJobs.add(jn);
387
    jn.mNextJobs.add(node);
388
    mJobs.add(node);
389
    return node;
390
    }
391

  
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

  
394
  static JobNode componentCenter(MeshBase target, int comp, float x, float y, float z)
395
    {
396
    JobNode jn = target.mJobNode[0];
397
    Job job = new Job(JOB_TYPE_CENTER,target,null,null,null,null,comp,0,0,x,y,z,null);
398
    JobNode node = new JobNode(job);
399
    node.mPrevJobs.add(jn);
400
    jn.mNextJobs.add(node);
401
    mJobs.add(node);
402
    return node;
403
    }
404

  
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406

  
407
  static JobNode setNotAffected(MeshBase target, int[] comps)
408
    {
409
    JobNode jn = target.mJobNode[0];
410
    Job job = new Job(JOB_TYPE_NOT_AFFECTED,target,null,null,null,null,0,0,0,0,0,0,comps);
411
    JobNode node = new JobNode(job);
412
    node.mPrevJobs.add(jn);
413
    jn.mNextJobs.add(node);
414
    mJobs.add(node);
415
    return node;
416
    }
417

  
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419
/**
420
 * Only for use by the library itself.
421
 *
422
 * @y.exclude
423
 */
424
  public static void onPause()
425
    {
426
    int num = mJobs.size();
427

  
428
    for(int i=0; i<num; i++)
429
      {
430
      mJobs.get(i).clear();
431
      }
432

  
433
    mJobs.clear();
434
    }
435
  }
src/main/java/org/distorted/library/mesh/DeferredJobs.kt
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.mesh;
22

  
23
import org.distorted.library.effect.MatrixEffect;
24
import org.distorted.library.effect.VertexEffect;
25
import org.distorted.library.effectqueue.EffectQueueVertex;
26
import org.distorted.library.main.DistortedLibrary;
27
import org.distorted.library.type.Static4D;
28

  
29
import java.util.ArrayList;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32
/**
33
 * Not part of public API, do not document (public only because has to be cleaned from the main package)
34
 *
35
 * @y.exclude
36
 */
37
public class DeferredJobs
38
  {
39
  private static final int JOB_TYPE_VERTEX       = 0;
40
  private static final int JOB_TYPE_MATRIX       = 1;
41
  private static final int JOB_TYPE_MERGE_TEX    = 2;
42
  private static final int JOB_TYPE_MERGE_EFF    = 3;
43
  private static final int JOB_TYPE_JOIN         = 4;
44
  private static final int JOB_TYPE_COPY         = 5;
45
  private static final int JOB_TYPE_TEXTURE      = 6;
46
  private static final int JOB_TYPE_ASSOC        = 7;
47
  private static final int JOB_TYPE_CENTER       = 8;
48
  private static final int JOB_TYPE_ADD_EMPTY_TEX= 9;
49
  private static final int JOB_TYPE_NOT_AFFECTED = 10;
50

  
51
  private static final ArrayList<JobNode> mJobs = new ArrayList<>();
52

  
53
  //////////////////////////////////////////////////////////////////////////
54

  
55
  private static class Job
56
    {
57
    private final int mType;
58
    private final MeshBase mTarget;
59
    private final MeshBase[] mSource;
60
    private final MatrixEffect mMatrixEffect;
61
    private final Static4D[] mMaps;
62
    private final int mComp, mAndAssoc, mEquAssoc;
63
    private final float mX,mY,mZ;
64
    private final int[] mComps;
65

  
66
    private EffectQueueVertex mVertexEffects;
67

  
68
    Job(int type, MeshBase target, MeshBase[] source, VertexEffect vEff, MatrixEffect mEff,
69
        Static4D[] maps, int comp, int and, int equ, float x, float y, float z, int[] comps)
70
      {
71
      mType     = type;
72
      mTarget   = target;
73
      mSource   = source;
74
      mMaps     = maps;
75
      mComp     = comp;
76
      mAndAssoc = and;
77
      mEquAssoc = equ;
78
      mX        = x;
79
      mY        = y;
80
      mZ        = z;
81
      mComps    = comps;
82

  
83
      if( vEff!=null )
84
        {
85
        mVertexEffects= new EffectQueueVertex();
86
        mVertexEffects.add(vEff);
87
        }
88

  
89
      mMatrixEffect = mEff;
90
      }
91

  
92
    void addEffect(VertexEffect effect)
93
      {
94
      mVertexEffects.add(effect);
95
      }
96

  
97
    void execute()
98
      {
99
      switch(mType)
100
        {
101
        case JOB_TYPE_VERTEX       : DistortedLibrary.adjustVertices(mTarget, mVertexEffects);
102
                                     break;
103
        case JOB_TYPE_MATRIX       : mTarget.applyMatrix(mMatrixEffect,mAndAssoc,mEquAssoc);
104
                                     break;
105
        case JOB_TYPE_MERGE_TEX    : mTarget.mergeTexComponentsNow();
106
                                     break;
107
        case JOB_TYPE_MERGE_EFF    : mTarget.mergeEffComponentsNow();
108
                                     break;
109
        case JOB_TYPE_JOIN         : mTarget.joinAttribs(mSource);
110
                                     break;
111
        case JOB_TYPE_COPY         : mTarget.copy(mSource[0]);
112
                                     break;
113
        case JOB_TYPE_TEXTURE      : mTarget.textureMap(mMaps,mComp);
114
                                     break;
115
        case JOB_TYPE_ASSOC        : mTarget.setEffectAssociationNow(mComp,mAndAssoc,mEquAssoc);
116
                                     break;
117
        case JOB_TYPE_CENTER       : mTarget.setComponentCenterNow(mComp,mX,mY,mZ);
118
                                     break;
119
        case JOB_TYPE_ADD_EMPTY_TEX: mTarget.addEmptyTexComponentNow();
120
                                     break;
121
        case JOB_TYPE_NOT_AFFECTED:  mTarget.setNotAffectedComponentsNow(mComps);
122
        }
123
      }
124

  
125
    void clear()
126
      {
127
      if( mVertexEffects!=null ) mVertexEffects.removeAll(false);
128
      }
129

  
130
    String print()
131
      {
132
      switch(mType)
133
        {
134
        case JOB_TYPE_VERTEX       : return "VERTEX";
135
        case JOB_TYPE_MATRIX       : return "MATRIX";
136
        case JOB_TYPE_MERGE_TEX    : return "MERGE_TEX";
137
        case JOB_TYPE_MERGE_EFF    : return "MERGE_EFF";
138
        case JOB_TYPE_JOIN         : return "JOIN";
139
        case JOB_TYPE_COPY         : return "COPY";
140
        case JOB_TYPE_TEXTURE      : return "TEXTURE";
141
        case JOB_TYPE_ASSOC        : return "ASSOC";
142
        case JOB_TYPE_CENTER       : return "CENTER";
143
        case JOB_TYPE_ADD_EMPTY_TEX: return "ADD_EMPTY_TEX";
144
        case JOB_TYPE_NOT_AFFECTED : return "POSTPROC COMPS";
145
        }
146

  
147
      return null;
148
      }
149
    }
150

  
151
  //////////////////////////////////////////////////////////////////////////
152

  
153
  static class JobNode
154
    {
155
    private ArrayList<JobNode> mPrevJobs;
156
    private ArrayList<JobNode> mNextJobs;
157
    private Job mJob;
158

  
159
    JobNode(Job job)
160
      {
161
      mPrevJobs = new ArrayList<>();
162
      mNextJobs = new ArrayList<>();
163
      mJob      = job;
164
      }
165

  
166
    synchronized void execute()
167
      {
168
      if( mPrevJobs!=null )
169
        {
170
        JobNode node;
171
        int numPrev = mPrevJobs.size();
172

  
173
        for(int i=0; i<numPrev; i++)
174
          {
175
          node = mPrevJobs.get(0);  // removeNode() rips the executed job out, thus the 0
176
          node.execute();
177
          }
178

  
179
        removeNode(this);
180
        mJob.execute();
181
        }
182
      }
183

  
184
    synchronized void clear()
185
      {
186
      mPrevJobs.clear();
187
      mPrevJobs = null;
188
      mNextJobs.clear();
189
      mNextJobs = null;
190

  
191
      mJob.clear();
192
      mJob = null;
193
      }
194

  
195
    void print(int level)
196
      {
197
      int numPrev = mPrevJobs.size();
198
      int numNext = mNextJobs.size();
199

  
200
      String str = "";
201
      for(int i=0; i<level; i++) str+=" ";
202

  
203
      str += mJob.print();
204

  
205
      str += (" next: "+numNext+" prev: "+numPrev);
206

  
207
      DistortedLibrary.logMessage("DeferredJobs: "+str);
208

  
209
      for(int i=0; i<numPrev; i++)
210
        {
211
        JobNode node = mPrevJobs.get(i);
212
        node.print(level+1);
213
        }
214
      }
215
    }
216

  
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

  
219
  private static void removeNode(JobNode node)
220
    {
221
    mJobs.remove(node);
222
    JobNode jn;
223

  
224
    int numPrev = node.mPrevJobs.size();
225

  
226
    for(int i=0; i<numPrev; i++)
227
      {
228
      jn = node.mPrevJobs.get(i);
229
      jn.mNextJobs.remove(node);
230
      }
231

  
232
    int numNext = node.mNextJobs.size();
233

  
234
    for(int i=0; i<numNext; i++)
235
      {
236
      jn = node.mNextJobs.get(i);
237
      jn.mPrevJobs.remove(node);
238
      }
239

  
240
    node.mJob.mTarget.mJobNode[0] = null;
241
    }
242

  
243
///////////////////////////////////////////////////////////////////////////////////////////////////
244

  
245
  static JobNode vertex(MeshBase target, VertexEffect effect)
246
    {
247
    JobNode jn = target.mJobNode[0];
248

  
249
    if( jn==null )
250
      {
251
      Job job = new Job(JOB_TYPE_VERTEX,target,null,effect,null,null,0,0,0,0,0,0,null);
252
      JobNode node = new JobNode(job);
253
      mJobs.add(node);
254
      return node;
255
      }
256
    else
257
      {
258
      if( jn.mJob.mType==JOB_TYPE_VERTEX )
259
        {
260
        jn.mJob.addEffect(effect);
261
        return jn;
262
        }
263
      else
264
        {
265
        Job job = new Job(JOB_TYPE_VERTEX,target,null,effect,null,null,0,0,0,0,0,0,null);
266
        JobNode node = new JobNode(job);
267
        node.mPrevJobs.add(jn);
268
        jn.mNextJobs.add(node);
269
        mJobs.add(node);
270
        return node;
271
        }
272
      }
273
    }
274

  
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

  
277
  static JobNode matrix(MeshBase target, MatrixEffect effect, int andAssoc, int ecuAssoc)
278
    {
279
    JobNode jn = target.mJobNode[0];
280
    Job job = new Job(JOB_TYPE_MATRIX,target,null,null,effect,null,0,andAssoc,ecuAssoc,0,0,0,null);
281
    JobNode node = new JobNode(job);
282
    node.mPrevJobs.add(jn);
283
    jn.mNextJobs.add(node);
284
    mJobs.add(node);
285
    return node;
286
    }
287

  
288
///////////////////////////////////////////////////////////////////////////////////////////////////
289

  
290
  static JobNode mergeTex(MeshBase target)
291
    {
292
    JobNode jn = target.mJobNode[0];
293
    Job job = new Job(JOB_TYPE_MERGE_TEX,target,null,null,null,null,0,0,0,0,0,0,null);
294
    JobNode node = new JobNode(job);
295
    node.mPrevJobs.add(jn);
296
    jn.mNextJobs.add(node);
297
    mJobs.add(node);
298
    return node;
299
    }
300

  
301
///////////////////////////////////////////////////////////////////////////////////////////////////
302

  
303
  static JobNode addEmptyTex(MeshBase target)
304
    {
305
    JobNode jn = target.mJobNode[0];
306
    Job job = new Job(JOB_TYPE_ADD_EMPTY_TEX,target,null,null,null,null,0,0,0,0,0,0,null);
307
    JobNode node = new JobNode(job);
308
    node.mPrevJobs.add(jn);
309
    jn.mNextJobs.add(node);
310
    mJobs.add(node);
311
    return node;
312
    }
313

  
314
///////////////////////////////////////////////////////////////////////////////////////////////////
315

  
316
  static JobNode mergeEff(MeshBase target)
317
    {
318
    JobNode jn = target.mJobNode[0];
319
    Job job = new Job(JOB_TYPE_MERGE_EFF,target,null,null,null,null,0,0,0,0,0,0,null);
320
    JobNode node = new JobNode(job);
321
    node.mPrevJobs.add(jn);
322
    jn.mNextJobs.add(node);
323
    mJobs.add(node);
324
    return node;
325
    }
326

  
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

  
329
  static JobNode join(MeshBase target, MeshBase[] meshes)
330
    {
331
    JobNode jn;
332

  
333
    Job job = new Job(JOB_TYPE_JOIN,target,meshes,null,null,null,0,0,0,0,0,0,null);
334
    JobNode node = new JobNode(job);
335

  
336
    for (MeshBase mesh : meshes)
337
      {
338
      jn = mesh.mJobNode[0];
339

  
340
      if( jn!=null )
341
        {
342
        node.mPrevJobs.add(jn);
343
        jn.mNextJobs.add(node);
344
        }
345
      }
346

  
347
    mJobs.add(node);
348
    return node;
349
    }
350

  
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352

  
353
  static JobNode copy(MeshBase target, MeshBase mesh)
354
    {
355
    JobNode jn = mesh.mJobNode[0];
356
    MeshBase[] meshes = new MeshBase[1];
357
    meshes[0] = mesh;
358
    Job job = new Job(JOB_TYPE_COPY,target,meshes,null,null,null,0,0,0,0,0,0,null);
359
    JobNode node = new JobNode(job);
360
    node.mPrevJobs.add(jn);
361
    jn.mNextJobs.add(node);
362
    mJobs.add(node);
363
    return node;
364
    }
365

  
366
///////////////////////////////////////////////////////////////////////////////////////////////////
367

  
368
  static JobNode textureMap(MeshBase target, Static4D[] maps, int comp)
369
    {
370
    JobNode jn = target.mJobNode[0];
371
    Job job = new Job(JOB_TYPE_TEXTURE,target,null,null,null,maps,comp,0,0,0,0,0,null);
372
    JobNode node = new JobNode(job);
373
    node.mPrevJobs.add(jn);
374
    jn.mNextJobs.add(node);
375
    mJobs.add(node);
376
    return node;
377
    }
378

  
379
///////////////////////////////////////////////////////////////////////////////////////////////////
380

  
381
  static JobNode effectAssoc(MeshBase target, int comp, int andAssoc, int equAssoc)
382
    {
383
    JobNode jn = target.mJobNode[0];
384
    Job job = new Job(JOB_TYPE_ASSOC,target,null,null,null,null,comp,andAssoc,equAssoc,0,0,0,null);
385
    JobNode node = new JobNode(job);
386
    node.mPrevJobs.add(jn);
387
    jn.mNextJobs.add(node);
388
    mJobs.add(node);
389
    return node;
390
    }
391

  
392
///////////////////////////////////////////////////////////////////////////////////////////////////
393

  
394
  static JobNode componentCenter(MeshBase target, int comp, float x, float y, float z)
395
    {
396
    JobNode jn = target.mJobNode[0];
397
    Job job = new Job(JOB_TYPE_CENTER,target,null,null,null,null,comp,0,0,x,y,z,null);
398
    JobNode node = new JobNode(job);
399
    node.mPrevJobs.add(jn);
400
    jn.mNextJobs.add(node);
401
    mJobs.add(node);
402
    return node;
403
    }
404

  
405
///////////////////////////////////////////////////////////////////////////////////////////////////
406

  
407
  static JobNode setNotAffected(MeshBase target, int[] comps)
408
    {
409
    JobNode jn = target.mJobNode[0];
410
    Job job = new Job(JOB_TYPE_NOT_AFFECTED,target,null,null,null,null,0,0,0,0,0,0,comps);
411
    JobNode node = new JobNode(job);
412
    node.mPrevJobs.add(jn);
413
    jn.mNextJobs.add(node);
414
    mJobs.add(node);
415
    return node;
416
    }
417

  
418
///////////////////////////////////////////////////////////////////////////////////////////////////
419
/**
420
 * Only for use by the library itself.
421
 *
422
 * @y.exclude
423
 */
424
  public static void onPause()
425
    {
426
    int num = mJobs.size();
427

  
428
    for(int i=0; i<num; i++)
429
      {
430
      mJobs.get(i).clear();
431
      }
432

  
433
    mJobs.clear();
434
    }
435
  }
src/main/java/org/distorted/library/mesh/MeshBandedTriangle.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.mesh;
22

  
23
///////////////////////////////////////////////////////////////////////////////////////////////////
24

  
25
import org.distorted.library.main.DistortedLibrary;
26

  
27
/**
28
 * Creator a triangular mesh divided into 'bands' i.e. strips parallel to one of the sides and
29
 * and of different elevations.
30
 * <p>
31
 * This is a building block for MeshMultigon.
32
 */
33
public class MeshBandedTriangle extends MeshBase
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

  
39
  private static final int NUM_CACHE = 20;
40

  
41
  private float mLeftX, mLeftY;
42
  private float mRightX, mRightY;
43
  private float mTopX, mTopY;
44

  
45
  private float[] mNormL, mNormR;
46
  private int mMode;
47

  
48
  private float[] mBands;
49
  private int mNumBands;
50

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

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

  
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

  
60
  private void computeNumberOfVertices()
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
    }
77

  
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

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

  
86
    for(int i=1; i<mNumBands; i++)
87
      {
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;
90
      }
91

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

  
97
    int prev = 0;
98
    int next = 0;
99

  
100
    for(int i=0; i<NUM_CACHE-1; i++)
101
      {
102
      float x = i/(NUM_CACHE-1.0f);
103

  
104
      if( x>=tmpX[next] )
105
        {
106
        prev = next;
107
        while( next<=mNumBands && x>=tmpX[next] ) next++;
108
        }
109

  
110
      if( next>prev )
111
        {
112
        float t = (x-tmpX[prev]) / (tmpX[next]-tmpX[prev]);
113
        mCurveCache[i] = t*(tmpD[next]-tmpD[prev]) + tmpD[prev];
114
        }
115
      else
116
        {
117
        mCurveCache[i] = tmpD[next];
118
        }
119
      }
120

  
121
    mCurveCache[NUM_CACHE-1] = tmpD[mNumBands];
122
    }
123

  
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

  
126
  private float derivative(float x)
127
    {
128
    if( x>=1.0f )
129
      {
130
      return 0.0f;
131
      }
132
    else
133
      {
134
      float tmp = x*(NUM_CACHE-1);
135
      int i1 = (int)tmp;
136
      int i2 = i1+1;
137

  
138
      // why 0.5? Arbitrarily; this way the cubit faces of Twisty Puzzles
139
      // [the main and only user of this class] look better.
140
      return 0.5f*((tmp-i1)*(mCurveCache[i2]-mCurveCache[i1]) + mCurveCache[i1]);
141
      }
142
    }
143

  
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

  
146
  private void figureOutNormalVector2D(float qx)
147
    {
148
    mVecX = mNormL[0] + qx*(mNormR[0]-mNormL[0]);
149
    mVecY = mNormL[1] + qx*(mNormR[1]-mNormL[1]);
150
    }
151

  
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

  
154
  private float figureOutDerivative(float qy)
155
    {
156
    switch(mMode)
157
      {
158
      case MODE_NORMAL  : return derivative(1-qy);
159
      case MODE_INVERTED: return -derivative(qy);
160
      default           : return 0;
161
      }
162
    }
163

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

  
166
  private float computeElevation(int band)
167
    {
168
    switch(mMode)
169
      {
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];
173
      }
174
    }
175

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

  
178
  private int addStripVertex(int vertex, float qx, float qy, int band, float[] attribs1, float[] attribs2)
179
    {
180
    remainingVert--;
181

  
182
    float bx = mLeftX + qx*(mRightX-mLeftX);
183
    float by = mLeftY + qx*(mRightY-mLeftY);
184

  
185
    float q = 1-qy;
186
    float x = bx + q*(mTopX-bx);
187
    float y = by + q*(mTopY-by);
188
    float z = computeElevation(band);
189

  
190
    figureOutNormalVector2D(band<mNumBands ? qx : 0.5f);
191
    float d = figureOutDerivative(qy);
192

  
193
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB  ] = x;
194
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+1] = y;
195
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = z;
196

  
197
    float vx = d*mVecX;
198
    float vy = d*mVecY;
199
    float vz = mVecX*mVecX + mVecY*mVecY;
200
    float len = (float)Math.sqrt(vx*vx + vy*vy + vz*vz);
201

  
202
    int index = VERT1_ATTRIBS*vertex + NOR_ATTRIB;
203
    attribs1[index  ] = vx/len;
204
    attribs1[index+1] = vy/len;
205
    attribs1[index+2] = vz/len;
206

  
207
    attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB  ] = x+0.5f;
208
    attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB+1] = y+0.5f;
209

  
210
    return vertex+1;
211
    }
212

  
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

  
215
  private int createBand(int vertex, int band, float[] attribs1, float[] attribs2)
216
    {
217
    boolean fromLeft = (band%2 == 0);
218
    int extra = ((band<extraBands && mMode==MODE_NORMAL) ? extraVertices : 0);
219
    int n = mNumBands-band-1;
220

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

  
225
    float qx = fromLeft ? 0.0f : 1.0f;
226

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

  
230
    float qyb = mBands[2*bb];
231
    float qyt = mBands[2*bt];
232

  
233
    if( mMode!=MODE_NORMAL )
234
      {
235
      qyb = 1-qyb;
236
      qyt = 1-qyt;
237
      }
238

  
239
    vertex = addStripVertex(vertex, qx, qyb, band, attribs1,attribs2);
240

  
241
    for(int v=0; v<extra; v++)
242
      {
243
      vertex = addStripVertex(vertex, qx          , qyt, band+1, attribs1,attribs2);
244
      vertex = addStripVertex(vertex, qx+(v+1)*sdx, qyb, band  , attribs1,attribs2);
245
      }
246

  
247
    if( n>0 )
248
      {
249
      float t = 1.0f/n;
250
      float dxt = fromLeft ? t : -t;
251

  
252
      for(int v=0; v<n; v++)
253
        {
254
        vertex=addStripVertex(vertex, qx+ v   *dxt, qyt, band+1, attribs1, attribs2);
255
        vertex=addStripVertex(vertex, qx+(v+1)*dxb, qyb, band  , attribs1, attribs2);
256
        }
257
      }
258

  
259
    qx = 1-qx;
260

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

  
267
    return vertex;
268
    }
269

  
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

  
272
  private void buildGrid(float[] attribs1, float[] attribs2)
273
    {
274
    if( mMode==MODE_FLAT )
275
      {
276
      addStripVertex(0, 0, 1, 0, attribs1,attribs2);
277
      addStripVertex(1, 0, 0, 0, attribs1,attribs2);
278
      addStripVertex(2, 1, 1, 0, attribs1,attribs2);
279
      }
280
    else
281
      {
282
      int vertex=0;
283
      for(int b=0; b<mNumBands; b++) vertex=createBand(vertex, b, attribs1, attribs2);
284
      }
285
    }
286

  
287
///////////////////////////////////////////////////////////////////////////////////////////////////
288
// PUBLIC API
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290
/**
291
 * Create a triangular mesh split into 'bands' - i.e. strips of triangles - which are parallel to
292
 * a given edge.
293
 *
294
 * @param vL         A pair of floats (x,y) which defines the 'left' vertex of the triangle.
295
 * @param vR         A pair of floats (x,y) which defines the 'right' vertex of the triangle.
296
 * @param vT         A pair of floats (x,y) which defines the 'top' vertex of the triangle.
297
 * @param bands      2K floats; K pairs of two floats each describing a single band.
298
 *                   From (1.0,Z[0]) (the 'left-right' edge, its Z elevation) to (0.0,Z[K])
299
 *                   (the 'top' vertex, its elevation). The polygon is split into such strips.
300
 *                   Must be band[2*i] > band[2*(i+1)] !
301
 *                   The way the bands get interpreted also depends on the 'mode' param.
302
 * @param normL      A pair of floats which define a 2D vector - which is the normal vector of each
303
 *                   mesh vertex which lies on the 'left-top' edge casted to the XY plane.
304
 * @param normR      Same as above but about the vertices which belong to the 'right-top' triangle
305
 *                   edge. This and the previous param define the vector field of normals, as seen
306
 *                   from above, of the whole mesh.
307
 * @param mode       MODE_UP, MODE_DOWN or MODE_FLAT.
308
 *                   This defines how we interpret the bands.
309
 *                   If UP, we interpret them the same as in MeshPolygon - i.e. the first band is
310
 *                   about the 'left-right' edge, then progressively towards the 'top'.
311
 *                   If DOWN, we turn the interpretation of the bands upside-down: it is the last
312
 *                   band which defines the strip aong the 'left-right' edge.
313
 *                   If FLAT, everything is flat anyway, so we disregard the bands and return a mesh
314
 *                   with 3 vertices.
315
 * @param exBands    This and the next parameter describe how to make the mesh denser at the
316
 *                   'left' and 'right' vertices. If e.g. exBands=3 and exVertices=2, then 3 triangles
317
 *                   of the outermost band (and 2 triangles of the next band, and 1 triangle of the
318
 *                   third band) get denser - the 3 triangles become 3+2 = 5.
319
 * @param exVertices See above.
320
 */
321
  public MeshBandedTriangle(float[] vL, float[] vR, float[] vT, float[] bands, float[] normL, float[] normR, int mode, int exBands, int exVertices)
322
    {
323
    super();
324

  
325
    mLeftX   = vL[0];
326
    mLeftY   = vL[1];
327
    mRightX  = vR[0];
328
    mRightY  = vR[1];
329
    mTopX    = vT[0];
330
    mTopY    = vT[1];
331

  
332
    mMode = mode;
333
    mNormL= new float[] { normL[0],normL[1] };
334
    mNormR= new float[] { normR[0],normR[1] };
335

  
336
    mBands        = bands;
337
    mNumBands     = mBands.length/2 -1;
338
    extraBands    = exBands;
339
    extraVertices = exVertices;
340

  
341
    computeNumberOfVertices();
342
    computeCache();
343

  
344
    float[] attribs1= new float[VERT1_ATTRIBS*numVertices];
345
    float[] attribs2= new float[VERT2_ATTRIBS*numVertices];
346

  
347
    buildGrid(attribs1,attribs2);
348

  
349
    if( remainingVert!=0 )
350
      DistortedLibrary.logMessage("MeshBandedTriangle: remainingVert " +remainingVert );
351

  
352
    setAttribs(attribs1,attribs2);
353
    }
354

  
355
///////////////////////////////////////////////////////////////////////////////////////////////////
356
/**
357
 * Copy constructor.
358
 */
359
  public MeshBandedTriangle(MeshBandedTriangle mesh, boolean deep)
360
    {
361
    super(mesh,deep);
362
    }
363

  
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365
/**
366
 * Copy the Mesh.
367
 *
368
 * @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices,
369
 *             normals and inflates (the rest, in particular the mVertAttribs2 containing texture
370
 *             coordinates and effect associations, is always deep copied)
371
 */
372
  public MeshBandedTriangle copy(boolean deep)
373
    {
374
    return new MeshBandedTriangle(this,deep);
375
    }
376
 }
src/main/java/org/distorted/library/mesh/MeshBandedTriangle.kt
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2020 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library 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 GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

  
21
package org.distorted.library.mesh;
22

  
23
///////////////////////////////////////////////////////////////////////////////////////////////////
24

  
25
import org.distorted.library.main.DistortedLibrary;
26

  
27
/**
28
 * Creator a triangular mesh divided into 'bands' i.e. strips parallel to one of the sides and
29
 * and of different elevations.
30
 * <p>
31
 * This is a building block for MeshMultigon.
32
 */
33
public class MeshBandedTriangle extends MeshBase
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

  
39
  private static final int NUM_CACHE = 20;
40

  
41
  private float mLeftX, mLeftY;
42
  private float mRightX, mRightY;
43
  private float mTopX, mTopY;
44

  
45
  private float[] mNormL, mNormR;
46
  private int mMode;
47

  
48
  private float[] mBands;
49
  private int mNumBands;
50

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

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

  
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

  
60
  private void computeNumberOfVertices()
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
    }
77

  
78
///////////////////////////////////////////////////////////////////////////////////////////////////
79

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

  
86
    for(int i=1; i<mNumBands; i++)
87
      {
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;
90
      }
91

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

  
97
    int prev = 0;
98
    int next = 0;
99

  
100
    for(int i=0; i<NUM_CACHE-1; i++)
101
      {
102
      float x = i/(NUM_CACHE-1.0f);
103

  
104
      if( x>=tmpX[next] )
105
        {
106
        prev = next;
107
        while( next<=mNumBands && x>=tmpX[next] ) next++;
108
        }
109

  
110
      if( next>prev )
111
        {
112
        float t = (x-tmpX[prev]) / (tmpX[next]-tmpX[prev]);
113
        mCurveCache[i] = t*(tmpD[next]-tmpD[prev]) + tmpD[prev];
114
        }
115
      else
116
        {
117
        mCurveCache[i] = tmpD[next];
118
        }
119
      }
120

  
121
    mCurveCache[NUM_CACHE-1] = tmpD[mNumBands];
122
    }
123

  
124
///////////////////////////////////////////////////////////////////////////////////////////////////
125

  
126
  private float derivative(float x)
127
    {
128
    if( x>=1.0f )
129
      {
130
      return 0.0f;
131
      }
132
    else
133
      {
134
      float tmp = x*(NUM_CACHE-1);
135
      int i1 = (int)tmp;
136
      int i2 = i1+1;
137

  
138
      // why 0.5? Arbitrarily; this way the cubit faces of Twisty Puzzles
139
      // [the main and only user of this class] look better.
140
      return 0.5f*((tmp-i1)*(mCurveCache[i2]-mCurveCache[i1]) + mCurveCache[i1]);
141
      }
142
    }
143

  
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

  
146
  private void figureOutNormalVector2D(float qx)
147
    {
148
    mVecX = mNormL[0] + qx*(mNormR[0]-mNormL[0]);
149
    mVecY = mNormL[1] + qx*(mNormR[1]-mNormL[1]);
150
    }
151

  
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

  
154
  private float figureOutDerivative(float qy)
155
    {
156
    switch(mMode)
157
      {
158
      case MODE_NORMAL  : return derivative(1-qy);
159
      case MODE_INVERTED: return -derivative(qy);
160
      default           : return 0;
161
      }
162
    }
163

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

  
166
  private float computeElevation(int band)
167
    {
168
    switch(mMode)
169
      {
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];
173
      }
174
    }
175

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

  
178
  private int addStripVertex(int vertex, float qx, float qy, int band, float[] attribs1, float[] attribs2)
179
    {
180
    remainingVert--;
181

  
182
    float bx = mLeftX + qx*(mRightX-mLeftX);
183
    float by = mLeftY + qx*(mRightY-mLeftY);
184

  
185
    float q = 1-qy;
186
    float x = bx + q*(mTopX-bx);
187
    float y = by + q*(mTopY-by);
188
    float z = computeElevation(band);
189

  
190
    figureOutNormalVector2D(band<mNumBands ? qx : 0.5f);
191
    float d = figureOutDerivative(qy);
192

  
193
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB  ] = x;
194
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+1] = y;
195
    attribs1[VERT1_ATTRIBS*vertex + POS_ATTRIB+2] = z;
196

  
197
    float vx = d*mVecX;
198
    float vy = d*mVecY;
199
    float vz = mVecX*mVecX + mVecY*mVecY;
200
    float len = (float)Math.sqrt(vx*vx + vy*vy + vz*vz);
201

  
202
    int index = VERT1_ATTRIBS*vertex + NOR_ATTRIB;
203
    attribs1[index  ] = vx/len;
204
    attribs1[index+1] = vy/len;
205
    attribs1[index+2] = vz/len;
206

  
207
    attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB  ] = x+0.5f;
208
    attribs2[VERT2_ATTRIBS*vertex + TEX_ATTRIB+1] = y+0.5f;
209

  
210
    return vertex+1;
211
    }
212

  
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214

  
215
  private int createBand(int vertex, int band, float[] attribs1, float[] attribs2)
216
    {
217
    boolean fromLeft = (band%2 == 0);
218
    int extra = ((band<extraBands && mMode==MODE_NORMAL) ? extraVertices : 0);
219
    int n = mNumBands-band-1;
220

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

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff