Project

General

Profile

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

library / src / main / java / org / distorted / library / mesh / MeshBase.java @ 22422a76

1 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4 46b572b5 Leszek Koltunski
// This file is part of Distorted.                                                               //
5 d333eb6b Leszek Koltunski
//                                                                                               //
6 46b572b5 Leszek Koltunski
// Distorted is free software: you can redistribute it and/or modify                             //
7 d333eb6b Leszek Koltunski
// 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 46b572b5 Leszek Koltunski
// Distorted is distributed in the hope that it will be useful,                                  //
12 d333eb6b Leszek Koltunski
// 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 46b572b5 Leszek Koltunski
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18 d333eb6b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 6c00149d Leszek Koltunski
package org.distorted.library.mesh;
21 6a06a912 Leszek Koltunski
22 b7074bc6 Leszek Koltunski
import android.opengl.GLES30;
23 e8925fcd Leszek Koltunski
import android.opengl.Matrix;
24 f046b159 Leszek Koltunski
import android.util.Log;
25 6c00149d Leszek Koltunski
26 e8925fcd Leszek Koltunski
import org.distorted.library.effect.MatrixEffect;
27 f046b159 Leszek Koltunski
import org.distorted.library.effect.VertexEffect;
28 36d65d88 Leszek Koltunski
import org.distorted.library.effectqueue.EffectQueue;
29 7602a827 Leszek Koltunski
import org.distorted.library.main.InternalBuffer;
30 da681e7e Leszek Koltunski
import org.distorted.library.program.DistortedProgram;
31 a3a05347 Leszek Koltunski
import org.distorted.library.type.Static4D;
32 6c00149d Leszek Koltunski
33 22422a76 Leszek Koltunski
import java.io.IOException;
34 f046b159 Leszek Koltunski
import java.nio.ByteBuffer;
35
import java.nio.ByteOrder;
36
import java.nio.FloatBuffer;
37 22422a76 Leszek Koltunski
import java.nio.channels.FileChannel;
38 c90aca24 Leszek Koltunski
import java.util.ArrayList;
39 6a06a912 Leszek Koltunski
40
///////////////////////////////////////////////////////////////////////////////////////////////////
41 e0b6c593 Leszek Koltunski
/**
42 e5ba319d Leszek Koltunski
 * Abstract class which represents a Mesh, ie an array of vertices (rendered as a TRIANGLE_STRIP).
43 e0b6c593 Leszek Koltunski
 * <p>
44 da681e7e Leszek Koltunski
 * If you want to render to a particular shape, extend from here, construct a float array
45 7a5e538a Leszek Koltunski
 * containing per-vertex attributes, and call back setAttribs().
46 e0b6c593 Leszek Koltunski
 */
47 715e7726 Leszek Koltunski
public abstract class MeshBase
48 6a06a912 Leszek Koltunski
   {
49 e8925fcd Leszek Koltunski
   private static final int MAX_EFFECT_COMPONENTS= 100;
50 07206c71 Leszek Koltunski
   private static final int DEFAULT_ASSOCIATION = 0xffffffff;
51 bc208a9c Leszek Koltunski
52 227b9bca Leszek Koltunski
   // sizes of attributes of an individual vertex.
53
   private static final int POS_DATA_SIZE= 3; // vertex coordinates: x,y,z
54
   private static final int NOR_DATA_SIZE= 3; // normal vector: x,y,z
55
   private static final int INF_DATA_SIZE= 3; // 'inflate' vector: x,y,z
56 7a5e538a Leszek Koltunski
   private static final int TEX_DATA_SIZE= 2; // texture coordinates: s,t
57 36d65d88 Leszek Koltunski
   private static final int COM_DATA_SIZE= 1; // component number, a single float
58 6f2d931d Leszek Koltunski
59
   static final int POS_ATTRIB   = 0;
60
   static final int NOR_ATTRIB   = POS_DATA_SIZE;
61
   static final int INF_ATTRIB   = POS_DATA_SIZE + NOR_DATA_SIZE;
62 e54bfada Leszek Koltunski
   static final int TEX_ATTRIB   = 0;
63 36d65d88 Leszek Koltunski
   static final int COM_ATTRIB   = TEX_DATA_SIZE;
64 bc208a9c Leszek Koltunski
65 e54bfada Leszek Koltunski
   static final int VERT1_ATTRIBS= POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE;  // number of attributes of a vertex (the part changed by preapply)
66 36d65d88 Leszek Koltunski
   static final int VERT2_ATTRIBS= TEX_DATA_SIZE + COM_DATA_SIZE;                  // number of attributes of a vertex (the 'preapply invariant' part)
67 e54bfada Leszek Koltunski
   static final int TRAN_ATTRIBS = POS_DATA_SIZE + NOR_DATA_SIZE + INF_DATA_SIZE;  // number of attributes of a transform feedback vertex
68 6a06a912 Leszek Koltunski
69 da681e7e Leszek Koltunski
   private static final int BYTES_PER_FLOAT = 4;
70 3ef3364d Leszek Koltunski
71 6f2d931d Leszek Koltunski
   private static final int OFFSET_POS = POS_ATTRIB*BYTES_PER_FLOAT;
72
   private static final int OFFSET_NOR = NOR_ATTRIB*BYTES_PER_FLOAT;
73
   private static final int OFFSET_INF = INF_ATTRIB*BYTES_PER_FLOAT;
74
   private static final int OFFSET_TEX = TEX_ATTRIB*BYTES_PER_FLOAT;
75 36d65d88 Leszek Koltunski
   private static final int OFFSET_COM = COM_ATTRIB*BYTES_PER_FLOAT;
76 bc208a9c Leszek Koltunski
77 227b9bca Leszek Koltunski
   private static final int TRAN_SIZE  = TRAN_ATTRIBS*BYTES_PER_FLOAT;
78 e54bfada Leszek Koltunski
   private static final int VERT1_SIZE = VERT1_ATTRIBS*BYTES_PER_FLOAT;
79
   private static final int VERT2_SIZE = VERT2_ATTRIBS*BYTES_PER_FLOAT;
80 a51fe521 Leszek Koltunski
81 e54bfada Leszek Koltunski
   private boolean mShowNormals;              // when rendering this mesh, draw normal vectors?
82
   private InternalBuffer mVBO1, mVBO2, mTFO; // main vertex buffer and transform feedback buffer
83 da681e7e Leszek Koltunski
   private int mNumVertices;
84 e54bfada Leszek Koltunski
   private float[] mVertAttribs1;             // packed: PosX,PosY,PosZ, NorX,NorY,NorZ, InfX,InfY,InfZ
85 36d65d88 Leszek Koltunski
   private float[] mVertAttribs2;             // packed: TexS,TexT, Component
86 7a5e538a Leszek Koltunski
   private float mInflate;
87 2aeb75aa Leszek Koltunski
   private int[] mEquAssociation;
88
   private int[] mAndAssociation;
89 36d65d88 Leszek Koltunski
90 71d8aba1 Leszek Koltunski
   DeferredJobs.JobNode[] mJobNode;
91 07206c71 Leszek Koltunski
92 2aeb75aa Leszek Koltunski
   private static int[] mEquAssociationH = new int[EffectQueue.MAIN_VARIANTS];
93
   private static int[] mAndAssociationH = new int[EffectQueue.MAIN_VARIANTS];
94 3ef3364d Leszek Koltunski
95 22422a76 Leszek Koltunski
   private static final int TEX_COMP_SIZE = 5; // 5 four-bytes entities inside the component
96
97 e8925fcd Leszek Koltunski
   private static class TexComponent
98 c90aca24 Leszek Koltunski
     {
99
     private int mEndIndex;
100 a3a05347 Leszek Koltunski
     private Static4D mTextureMap;
101 c90aca24 Leszek Koltunski
102 e8925fcd Leszek Koltunski
     TexComponent(int end)
103 c90aca24 Leszek Koltunski
       {
104 a3a05347 Leszek Koltunski
       mEndIndex  = end;
105
       mTextureMap= new Static4D(0,0,1,1);
106 c90aca24 Leszek Koltunski
       }
107 e8925fcd Leszek Koltunski
     TexComponent(TexComponent original)
108 c90aca24 Leszek Koltunski
       {
109
       mEndIndex = original.mEndIndex;
110 a3a05347 Leszek Koltunski
111
       float x = original.mTextureMap.get0();
112
       float y = original.mTextureMap.get1();
113
       float z = original.mTextureMap.get2();
114
       float w = original.mTextureMap.get3();
115
       mTextureMap = new Static4D(x,y,z,w);
116 0d4aae88 Leszek Koltunski
       }
117
118 a3a05347 Leszek Koltunski
     void setMap(Static4D map)
119 0d4aae88 Leszek Koltunski
       {
120 a3a05347 Leszek Koltunski
       mTextureMap.set(map.get0(),map.get1(),map.get2(),map.get3());
121 c90aca24 Leszek Koltunski
       }
122
     }
123
124 e8925fcd Leszek Koltunski
   private ArrayList<TexComponent> mTexComponent;
125
   private ArrayList<Integer> mEffComponent;
126 c90aca24 Leszek Koltunski
127 6a06a912 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
128 3ef3364d Leszek Koltunski
129 0f10a0b6 Leszek Koltunski
   MeshBase()
130 3ef3364d Leszek Koltunski
     {
131 e8925fcd Leszek Koltunski
     mShowNormals  = false;
132
     mInflate      = 0.0f;
133
     mTexComponent = new ArrayList<>();
134
     mEffComponent = new ArrayList<>();
135
136
     mEquAssociation= new int[MAX_EFFECT_COMPONENTS];
137
     mAndAssociation= new int[MAX_EFFECT_COMPONENTS];
138 36d65d88 Leszek Koltunski
139 71d8aba1 Leszek Koltunski
     mJobNode = new DeferredJobs.JobNode[1];
140
141 e8925fcd Leszek Koltunski
     for(int i=0; i<MAX_EFFECT_COMPONENTS; i++)
142 2aeb75aa Leszek Koltunski
       {
143
       mAndAssociation[i] = DEFAULT_ASSOCIATION;
144
       mEquAssociation[i] = i;
145
       }
146 4f81e0c8 Leszek Koltunski
147 e54bfada Leszek Koltunski
     mVBO1= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
148
     mVBO2= new InternalBuffer(GLES30.GL_ARRAY_BUFFER             , GLES30.GL_STATIC_READ);
149 b7074bc6 Leszek Koltunski
     mTFO = new InternalBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, GLES30.GL_STATIC_READ);
150 c90aca24 Leszek Koltunski
     }
151
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
// copy constructor
154
155 4f81e0c8 Leszek Koltunski
   MeshBase(MeshBase original, boolean deep)
156 c90aca24 Leszek Koltunski
     {
157 1fad573e Leszek Koltunski
     mShowNormals= original.mShowNormals;
158
     mInflate    = original.mInflate;
159
     mNumVertices= original.mNumVertices;
160 42571056 Leszek Koltunski
161 e8925fcd Leszek Koltunski
     mAndAssociation= new int[MAX_EFFECT_COMPONENTS];
162
     System.arraycopy(original.mAndAssociation, 0, mAndAssociation, 0, MAX_EFFECT_COMPONENTS);
163
     mEquAssociation= new int[MAX_EFFECT_COMPONENTS];
164
     System.arraycopy(original.mEquAssociation, 0, mEquAssociation, 0, MAX_EFFECT_COMPONENTS);
165 36d65d88 Leszek Koltunski
166 4f81e0c8 Leszek Koltunski
     if( deep )
167
       {
168 71d8aba1 Leszek Koltunski
       mJobNode = new DeferredJobs.JobNode[1];
169 1fad573e Leszek Koltunski
       if( original.mJobNode[0]==null ) copy(original);
170
       else mJobNode[0] = DeferredJobs.copy(this,original);
171 4f81e0c8 Leszek Koltunski
       }
172
     else
173
       {
174 71d8aba1 Leszek Koltunski
       mJobNode      = original.mJobNode;
175
       mVBO1         = original.mVBO1;
176
       mVertAttribs1 = original.mVertAttribs1;
177 1fad573e Leszek Koltunski
       shallowCopy(original);
178 4f81e0c8 Leszek Koltunski
       }
179 cbd502ec Leszek Koltunski
180 4f81e0c8 Leszek Koltunski
     mTFO = new InternalBuffer(GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, GLES30.GL_STATIC_READ);
181 cbd502ec Leszek Koltunski
     mTFO.invalidate();
182 42571056 Leszek Koltunski
     }
183
184 36d65d88 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
185
186 1fad573e Leszek Koltunski
   void copy(MeshBase original)
187 36d65d88 Leszek Koltunski
     {
188 1fad573e Leszek Koltunski
     shallowCopy(original);
189
190
     mVBO1= new InternalBuffer(GLES30.GL_ARRAY_BUFFER, GLES30.GL_STATIC_READ);
191
     mVertAttribs1= new float[mNumVertices*VERT1_ATTRIBS];
192
     System.arraycopy(original.mVertAttribs1,0,mVertAttribs1,0,mNumVertices*VERT1_ATTRIBS);
193
     mVBO1.invalidate();
194 36d65d88 Leszek Koltunski
     }
195
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197
198 1fad573e Leszek Koltunski
   private void shallowCopy(MeshBase original)
199 36d65d88 Leszek Koltunski
     {
200 e8925fcd Leszek Koltunski
     int texComSize = original.mTexComponent.size();
201
     mTexComponent = new ArrayList<>();
202 36d65d88 Leszek Koltunski
203 e8925fcd Leszek Koltunski
     for(int i=0; i<texComSize; i++)
204 1fad573e Leszek Koltunski
       {
205 e8925fcd Leszek Koltunski
       TexComponent comp = new TexComponent(original.mTexComponent.get(i));
206
       mTexComponent.add(comp);
207 1fad573e Leszek Koltunski
       }
208 f4c5a46e Leszek Koltunski
209 e8925fcd Leszek Koltunski
     mEffComponent = new ArrayList<>();
210
     mEffComponent.addAll(original.mEffComponent);
211
212 1fad573e Leszek Koltunski
     mVBO2= new InternalBuffer(GLES30.GL_ARRAY_BUFFER, GLES30.GL_STATIC_READ);
213
     mVertAttribs2= new float[mNumVertices*VERT2_ATTRIBS];
214
     System.arraycopy(original.mVertAttribs2,0,mVertAttribs2,0,mNumVertices*VERT2_ATTRIBS);
215
     mVBO2.invalidate();
216 f4c5a46e Leszek Koltunski
     }
217
218 a8dfedcc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
219
220 e8925fcd Leszek Koltunski
   void mergeTexComponentsNow()
221 a8dfedcc Leszek Koltunski
     {
222 e8925fcd Leszek Koltunski
     int num = mTexComponent.size();
223 a8dfedcc Leszek Koltunski
224
     if( num>1 )
225
       {
226 e8925fcd Leszek Koltunski
       mTexComponent.clear();
227
       mTexComponent.add(new TexComponent(mNumVertices-1));
228
229
       mVBO2.invalidate();
230
       }
231
     }
232
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234
235
   void mergeEffComponentsNow()
236
     {
237
     int num = mEffComponent.size();
238
239
     if( num>1 )
240
       {
241
       mEffComponent.clear();
242
       mEffComponent.add(mNumVertices-1);
243 a8dfedcc Leszek Koltunski
244
       for(int index=0; index<mNumVertices; index++)
245
         {
246
         mVertAttribs2[VERT2_ATTRIBS*index+COM_ATTRIB] = 0;
247
         }
248
249
       mVBO2.invalidate();
250
       }
251
     }
252
253 0d4aae88 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
254
255 e8925fcd Leszek Koltunski
   void applyMatrix(MatrixEffect effect, int andAssoc, int equAssoc)
256
     {
257
     float[] matrix   = new float[16];
258
     float[] uniforms = new float[7];
259
     int start, end=-1, numComp = mEffComponent.size();
260
261
     Matrix.setIdentityM(matrix,0);
262
     effect.compute(uniforms,0,0,0);
263
     effect.apply(matrix, uniforms, 0);
264
265
     for(int i=0; i<numComp; i++)
266
       {
267 f45e4279 Leszek Koltunski
       start = end+1;
268 e8925fcd Leszek Koltunski
       end   = mEffComponent.get(i);
269
270
       if( (andAssoc & mAndAssociation[i]) != 0 || (equAssoc == mEquAssociation[i]) )
271
         {
272 f45e4279 Leszek Koltunski
         applyMatrixToComponent(matrix,start,end);
273 e8925fcd Leszek Koltunski
         }
274
       }
275
276
     mVBO1.invalidate();
277
     }
278
279
///////////////////////////////////////////////////////////////////////////////////////////////////
280
281
   private void applyMatrixToComponent(float[] matrix, int start, int end)
282
     {
283
     float x,y,z;
284
285 f45e4279 Leszek Koltunski
     for(int index=start*VERT1_ATTRIBS; index<=end*VERT1_ATTRIBS; index+=VERT1_ATTRIBS )
286 e8925fcd Leszek Koltunski
       {
287
       x = mVertAttribs1[index+POS_ATTRIB  ];
288
       y = mVertAttribs1[index+POS_ATTRIB+1];
289
       z = mVertAttribs1[index+POS_ATTRIB+2];
290
291
       mVertAttribs1[index+POS_ATTRIB  ] = matrix[0]*x + matrix[4]*y + matrix[ 8]*z + matrix[12];
292
       mVertAttribs1[index+POS_ATTRIB+1] = matrix[1]*x + matrix[5]*y + matrix[ 9]*z + matrix[13];
293
       mVertAttribs1[index+POS_ATTRIB+2] = matrix[2]*x + matrix[6]*y + matrix[10]*z + matrix[14];
294
295
       x = mVertAttribs1[index+NOR_ATTRIB  ];
296
       y = mVertAttribs1[index+NOR_ATTRIB+1];
297
       z = mVertAttribs1[index+NOR_ATTRIB+2];
298
299
       mVertAttribs1[index+NOR_ATTRIB  ] = matrix[0]*x + matrix[4]*y + matrix[ 8]*z;
300
       mVertAttribs1[index+NOR_ATTRIB+1] = matrix[1]*x + matrix[5]*y + matrix[ 9]*z;
301
       mVertAttribs1[index+NOR_ATTRIB+2] = matrix[2]*x + matrix[6]*y + matrix[10]*z;
302
303
       x = mVertAttribs1[index+INF_ATTRIB  ];
304
       y = mVertAttribs1[index+INF_ATTRIB+1];
305
       z = mVertAttribs1[index+INF_ATTRIB+2];
306
307
       mVertAttribs1[index+INF_ATTRIB  ] = matrix[0]*x + matrix[4]*y + matrix[ 8]*z;
308
       mVertAttribs1[index+INF_ATTRIB+1] = matrix[1]*x + matrix[5]*y + matrix[ 9]*z;
309
       mVertAttribs1[index+INF_ATTRIB+2] = matrix[2]*x + matrix[6]*y + matrix[10]*z;
310
       }
311
     }
312
313 26671ef8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
314
315
   void setEffectAssociationNow(int component, int andAssociation, int equAssociation)
316
     {
317
     mAndAssociation[component] = andAssociation;
318
     mEquAssociation[component] = equAssociation;
319
     }
320
321 e8925fcd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
322
323
   int numTexComponents()
324
     {
325
     return mTexComponent.size();
326
     }
327
328
///////////////////////////////////////////////////////////////////////////////////////////////////
329
330
   int numEffComponents()
331 0d4aae88 Leszek Koltunski
     {
332 e8925fcd Leszek Koltunski
     return mEffComponent.size();
333 0d4aae88 Leszek Koltunski
     }
334
335 42571056 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
336 6c00149d Leszek Koltunski
// when a derived class is done computing its mesh, it has to call this method.
337 42571056 Leszek Koltunski
338 e54bfada Leszek Koltunski
   void setAttribs(float[] vert1Attribs, float[] vert2Attribs)
339 42571056 Leszek Koltunski
     {
340 e54bfada Leszek Koltunski
     mNumVertices = vert1Attribs.length/VERT1_ATTRIBS;
341
     mVertAttribs1= vert1Attribs;
342
     mVertAttribs2= vert2Attribs;
343 da681e7e Leszek Koltunski
344 e8925fcd Leszek Koltunski
     mTexComponent.add(new TexComponent(mNumVertices-1));
345
     mEffComponent.add(mNumVertices-1);
346 c90aca24 Leszek Koltunski
347 e54bfada Leszek Koltunski
     mVBO1.invalidate();
348
     mVBO2.invalidate();
349 42571056 Leszek Koltunski
     }
350
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352
353 1fad573e Leszek Koltunski
   void joinAttribs(MeshBase[] meshes)
354 226144d0 leszek
     {
355 0d4aae88 Leszek Koltunski
     MeshBase mesh;
356 e8925fcd Leszek Koltunski
     TexComponent comp;
357 a8dfedcc Leszek Koltunski
     int numMeshes = meshes.length;
358 e8925fcd Leszek Koltunski
     int numVertices,origVertices = mNumVertices;
359 26671ef8 Leszek Koltunski
     int origTexComponents,numTexComponents;
360 e8925fcd Leszek Koltunski
     int origEffComponents=0,numEffComponents;
361 044b5494 Leszek Koltunski
362 0d4aae88 Leszek Koltunski
     if( origVertices>0 )
363
       {
364 e8925fcd Leszek Koltunski
       origTexComponents = mTexComponent.size();
365 1fad573e Leszek Koltunski
       mNumVertices+= ( mNumVertices%2==1 ? 2:1 );
366 e8925fcd Leszek Koltunski
       mTexComponent.get(origTexComponents-1).mEndIndex = mNumVertices-1;
367
       origEffComponents = mEffComponent.size();
368
       mEffComponent.set(origEffComponents-1,mNumVertices-1);
369 0d4aae88 Leszek Koltunski
       }
370 044b5494 Leszek Koltunski
371 e7f85322 Leszek Koltunski
     for(int i=0; i<numMeshes; i++)
372 0d4aae88 Leszek Koltunski
       {
373
       mesh = meshes[i];
374 e8925fcd Leszek Koltunski
       numTexComponents = mesh.mTexComponent.size();
375
       numEffComponents = mesh.mEffComponent.size();
376 36d65d88 Leszek Koltunski
       numVertices = mesh.mNumVertices;
377
378 1fad573e Leszek Koltunski
       int extraVerticesBefore = mNumVertices==0 ? 0:1;
379
       int extraVerticesAfter  = (i==numMeshes-1) ? 0 : (numVertices%2==1 ? 2:1);
380 36d65d88 Leszek Koltunski
381 e8925fcd Leszek Koltunski
       for(int j=0; j<numTexComponents; j++)
382 0d4aae88 Leszek Koltunski
         {
383 e8925fcd Leszek Koltunski
         comp = new TexComponent(mesh.mTexComponent.get(j));
384 e0343804 Leszek Koltunski
         comp.mEndIndex += (extraVerticesBefore+mNumVertices);
385
         if( j==numTexComponents-1) comp.mEndIndex += extraVerticesAfter;
386 e8925fcd Leszek Koltunski
         mTexComponent.add(comp);
387
         }
388 23b733db Leszek Koltunski
389 e8925fcd Leszek Koltunski
       for(int j=0; j<numEffComponents; j++)
390
         {
391
         int index = mesh.mEffComponent.get(j);
392 e0343804 Leszek Koltunski
         index += (extraVerticesBefore+mNumVertices);
393
         if( j==numEffComponents-1 ) index += extraVerticesAfter;
394 e8925fcd Leszek Koltunski
         mEffComponent.add(index);
395
396
         if( origEffComponents<MAX_EFFECT_COMPONENTS )
397 36d65d88 Leszek Koltunski
           {
398 e8925fcd Leszek Koltunski
           mAndAssociation[origEffComponents] = mesh.mAndAssociation[j];
399
           mEquAssociation[origEffComponents] = mesh.mEquAssociation[j];
400
           origEffComponents++;
401 36d65d88 Leszek Koltunski
           }
402 e7f85322 Leszek Koltunski
         }
403 a8dfedcc Leszek Koltunski
404 1fad573e Leszek Koltunski
       mNumVertices += (extraVerticesBefore+numVertices+extraVerticesAfter);
405
       }
406 a8dfedcc Leszek Koltunski
407 1fad573e Leszek Koltunski
     float[] newAttribs1 = new float[VERT1_ATTRIBS*mNumVertices];
408 e54bfada Leszek Koltunski
     float[] newAttribs2 = new float[VERT2_ATTRIBS*mNumVertices];
409 1fad573e Leszek Koltunski
     numVertices = origVertices;
410 0d4aae88 Leszek Koltunski
411
     if( origVertices>0 )
412
       {
413 e8925fcd Leszek Koltunski
       System.arraycopy(mVertAttribs1,                              0, newAttribs1,                          0, VERT1_ATTRIBS*numVertices);
414
       System.arraycopy(mVertAttribs1, VERT1_ATTRIBS*(origVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS            );
415
       System.arraycopy(mVertAttribs2,                              0, newAttribs2,                          0, VERT2_ATTRIBS*numVertices);
416
       System.arraycopy(mVertAttribs2, VERT2_ATTRIBS*(origVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS            );
417 0d4aae88 Leszek Koltunski
       origVertices++;
418
419 e7f85322 Leszek Koltunski
       if( numVertices%2==1 )
420 0d4aae88 Leszek Koltunski
         {
421 1fad573e Leszek Koltunski
         System.arraycopy(mVertAttribs1, VERT1_ATTRIBS*(origVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
422 e54bfada Leszek Koltunski
         System.arraycopy(mVertAttribs2, VERT2_ATTRIBS*(origVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
423 0d4aae88 Leszek Koltunski
         origVertices++;
424
         }
425
       }
426
427 e7f85322 Leszek Koltunski
     for(int i=0; i<numMeshes; i++)
428 0d4aae88 Leszek Koltunski
       {
429
       mesh = meshes[i];
430 e7f85322 Leszek Koltunski
       numVertices = mesh.mNumVertices;
431 0d4aae88 Leszek Koltunski
432 22e60fba Leszek Koltunski
       if( origVertices>0 )
433
         {
434 e8925fcd Leszek Koltunski
         System.arraycopy(mesh.mVertAttribs1, 0, newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
435
         System.arraycopy(mesh.mVertAttribs2, 0, newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
436 22e60fba Leszek Koltunski
         origVertices++;
437
         }
438 1fad573e Leszek Koltunski
       System.arraycopy(mesh.mVertAttribs1, 0, newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS*numVertices);
439 e54bfada Leszek Koltunski
       System.arraycopy(mesh.mVertAttribs2, 0, newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS*numVertices);
440 e7f85322 Leszek Koltunski
       origVertices+=numVertices;
441 0d4aae88 Leszek Koltunski
442 e7f85322 Leszek Koltunski
       if( i<numMeshes-1 )
443 0d4aae88 Leszek Koltunski
         {
444 1fad573e Leszek Koltunski
         System.arraycopy(mesh.mVertAttribs1, VERT1_ATTRIBS*(numVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
445 e54bfada Leszek Koltunski
         System.arraycopy(mesh.mVertAttribs2, VERT2_ATTRIBS*(numVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
446 0d4aae88 Leszek Koltunski
         origVertices++;
447
448 e7f85322 Leszek Koltunski
         if( numVertices%2==1 )
449 0d4aae88 Leszek Koltunski
           {
450 1fad573e Leszek Koltunski
           System.arraycopy(mesh.mVertAttribs1, VERT1_ATTRIBS*(numVertices-1), newAttribs1, VERT1_ATTRIBS*origVertices, VERT1_ATTRIBS);
451 e54bfada Leszek Koltunski
           System.arraycopy(mesh.mVertAttribs2, VERT2_ATTRIBS*(numVertices-1), newAttribs2, VERT2_ATTRIBS*origVertices, VERT2_ATTRIBS);
452 0d4aae88 Leszek Koltunski
           origVertices++;
453
           }
454
         }
455
       }
456
457
     if( origVertices!=mNumVertices )
458
       {
459
       android.util.Log.e("mesh", "join: origVertices: "+origVertices+" numVertices: "+mNumVertices);
460
       }
461
462 e8925fcd Leszek Koltunski
     int endIndex, index=0, numEffComp = mEffComponent.size();
463 36d65d88 Leszek Koltunski
464 e8925fcd Leszek Koltunski
     for(int component=0; component<numEffComp; component++)
465 36d65d88 Leszek Koltunski
       {
466 e8925fcd Leszek Koltunski
       endIndex = mEffComponent.get(component);
467 36d65d88 Leszek Koltunski
468
       for( ; index<=endIndex; index++) newAttribs2[VERT2_ATTRIBS*index+COM_ATTRIB] = component;
469
       }
470
471 1fad573e Leszek Koltunski
     mVertAttribs1 = newAttribs1;
472 e54bfada Leszek Koltunski
     mVertAttribs2 = newAttribs2;
473 1fad573e Leszek Koltunski
     mVBO1.invalidate();
474 e54bfada Leszek Koltunski
     mVBO2.invalidate();
475 23b733db Leszek Koltunski
     }
476
477 a8dfedcc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
478
// called from MeshJoined
479
480
   void join(MeshBase[] meshes)
481
     {
482 1fad573e Leszek Koltunski
     boolean immediateJoin = true;
483 a8dfedcc Leszek Koltunski
484 1fad573e Leszek Koltunski
     for (MeshBase mesh : meshes)
485 a8dfedcc Leszek Koltunski
       {
486 1fad573e Leszek Koltunski
       if (mesh.mJobNode[0] != null)
487
         {
488
         immediateJoin = false;
489
         break;
490
         }
491 a8dfedcc Leszek Koltunski
       }
492
493 1fad573e Leszek Koltunski
     if( immediateJoin ) joinAttribs(meshes);
494
     else                mJobNode[0] = DeferredJobs.join(this,meshes);
495
     }
496 a8dfedcc Leszek Koltunski
497 1fad573e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
498 a8dfedcc Leszek Koltunski
499 dbe3079d Leszek Koltunski
   void textureMap(Static4D[] maps, int startComponent)
500 1fad573e Leszek Koltunski
     {
501 e8925fcd Leszek Koltunski
     int num_comp = mTexComponent.size();
502 1fad573e Leszek Koltunski
     int num_maps = maps.length;
503 dbe3079d Leszek Koltunski
     int min = Math.min(num_comp-startComponent, num_maps);
504 96877ab4 Leszek Koltunski
     int vertex = startComponent>0 ? mTexComponent.get(startComponent-1).mEndIndex+1 : 0;
505 1fad573e Leszek Koltunski
     Static4D newMap, oldMap;
506 e8925fcd Leszek Koltunski
     TexComponent comp;
507 1fad573e Leszek Koltunski
     float newW, newH, ratW, ratH, movX, movY;
508 a8dfedcc Leszek Koltunski
509 1fad573e Leszek Koltunski
     for(int i=0; i<min; i++)
510
       {
511
       newMap = maps[i];
512 dbe3079d Leszek Koltunski
       comp = mTexComponent.get(i+startComponent);
513 1fad573e Leszek Koltunski
514
       if( newMap!=null )
515 a8dfedcc Leszek Koltunski
         {
516 1fad573e Leszek Koltunski
         newW = newMap.get2();
517
         newH = newMap.get3();
518 a8dfedcc Leszek Koltunski
519 1fad573e Leszek Koltunski
         if( newW!=0.0f && newH!=0.0f )
520 a8dfedcc Leszek Koltunski
           {
521 1fad573e Leszek Koltunski
           oldMap = comp.mTextureMap;
522
           ratW = newW/oldMap.get2();
523
           ratH = newH/oldMap.get3();
524
           movX = newMap.get0() - ratW*oldMap.get0();
525
           movY = newMap.get1() - ratH*oldMap.get1();
526
527
           for( int index=vertex*VERT2_ATTRIBS+TEX_ATTRIB ; vertex<=comp.mEndIndex; vertex++, index+=VERT2_ATTRIBS)
528
             {
529
             mVertAttribs2[index  ] = ratW*mVertAttribs2[index  ] + movX;
530
             mVertAttribs2[index+1] = ratH*mVertAttribs2[index+1] + movY;
531
             }
532
           comp.setMap(newMap);
533 a8dfedcc Leszek Koltunski
           }
534
         }
535
536 1fad573e Leszek Koltunski
       vertex= comp.mEndIndex+1;
537 a8dfedcc Leszek Koltunski
       }
538
539 1fad573e Leszek Koltunski
     mVBO2.invalidate();
540
     }
541
542
///////////////////////////////////////////////////////////////////////////////////////////////////
543 a8dfedcc Leszek Koltunski
544 e8925fcd Leszek Koltunski
   public static int getMaxEffComponents()
545 1fad573e Leszek Koltunski
     {
546 e8925fcd Leszek Koltunski
     return MAX_EFFECT_COMPONENTS;
547 1fad573e Leszek Koltunski
     }
548
549
///////////////////////////////////////////////////////////////////////////////////////////////////
550
551
   public static void getUniforms(int mProgramH, int variant)
552
     {
553 2aeb75aa Leszek Koltunski
     mEquAssociationH[variant] = GLES30.glGetUniformLocation( mProgramH, "vComEquAssoc");
554
     mAndAssociationH[variant] = GLES30.glGetUniformLocation( mProgramH, "vComAndAssoc");
555 a8dfedcc Leszek Koltunski
     }
556
557 f046b159 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
558
/**
559
 * Not part of public API, do not document (public only because has to be used from the main package)
560
 *
561
 * @y.exclude
562
 */
563
   public void copyTransformToVertex()
564
     {
565 e54bfada Leszek Koltunski
     ByteBuffer buffer = (ByteBuffer)GLES30.glMapBufferRange( GLES30.GL_TRANSFORM_FEEDBACK_BUFFER, 0,
566
                                                              TRAN_SIZE*mNumVertices, GLES30.GL_MAP_READ_BIT);
567 f046b159 Leszek Koltunski
     if( buffer!=null )
568
       {
569 e54bfada Leszek Koltunski
       FloatBuffer feedback = buffer.order(ByteOrder.nativeOrder()).asFloatBuffer();
570
       feedback.get(mVertAttribs1,0,VERT1_ATTRIBS*mNumVertices);
571
       mVBO1.update(mVertAttribs1);
572 f046b159 Leszek Koltunski
       }
573
     else
574
       {
575 b5be333a Leszek Koltunski
       int error = GLES30.glGetError();
576
       Log.e("mesh", "failed to map tf buffer, error="+error);
577 f046b159 Leszek Koltunski
       }
578
579 b5be333a Leszek Koltunski
     GLES30.glUnmapBuffer(GLES30.GL_TRANSFORM_FEEDBACK);
580 f046b159 Leszek Koltunski
     }
581
582 1fad573e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
583
/**
584
 * Not part of public API, do not document (public only because has to be used from the main package)
585
 *
586
 * @y.exclude
587
 */
588
   public void debug()
589
     {
590
     if( mJobNode[0]!=null )
591
       {
592
       mJobNode[0].print(0);
593
       }
594
     else
595
       {
596
       android.util.Log.e("mesh", "JobNode null");
597
       }
598
     }
599
600
///////////////////////////////////////////////////////////////////////////////////////////////////
601
/**
602
 * Not part of public API, do not document (public only because has to be used from the main package)
603
 *
604
 * @y.exclude
605
 */
606 e0343804 Leszek Koltunski
   public void printPos()
607 1fad573e Leszek Koltunski
     {
608 26671ef8 Leszek Koltunski
     StringBuilder sb = new StringBuilder();
609 1fad573e Leszek Koltunski
610
     for(int i=0; i<mNumVertices; i++)
611
       {
612
       sb.append('(');
613
       sb.append(mVertAttribs1[VERT1_ATTRIBS*i+POS_ATTRIB  ]);
614
       sb.append(',');
615
       sb.append(mVertAttribs1[VERT1_ATTRIBS*i+POS_ATTRIB+1]);
616
       sb.append(',');
617
       sb.append(mVertAttribs1[VERT1_ATTRIBS*i+POS_ATTRIB+2]);
618
       sb.append(") ");
619
       }
620 e0343804 Leszek Koltunski
     Log.d("mesh", sb.toString());
621
     }
622 1fad573e Leszek Koltunski
623 e0343804 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
624
/**
625
 * Not part of public API, do not document (public only because has to be used from the main package)
626
 *
627
 * @y.exclude
628
 */
629
   public void printCom()
630
     {
631
     StringBuilder sb = new StringBuilder();
632 1fad573e Leszek Koltunski
633
     for(int i=0; i<mNumVertices; i++)
634
       {
635 e0343804 Leszek Koltunski
       sb.append(mVertAttribs2[VERT2_ATTRIBS*i+COM_ATTRIB]);
636
       sb.append(' ');
637
       }
638
639
     Log.d("mesh", sb.toString());
640
     }
641
642
///////////////////////////////////////////////////////////////////////////////////////////////////
643
/**
644
 * Not part of public API, do not document (public only because has to be used from the main package)
645
 *
646
 * @y.exclude
647
 */
648
   public void printTex()
649
     {
650
     int vert=0;
651
     int num = numTexComponents();
652
     StringBuilder sb = new StringBuilder();
653
     sb.append("tex components: ").append(num);
654
655
     for(int i=0; i<num; i++)
656
       {
657
       int end = mTexComponent.get(i).mEndIndex;
658
       sb.append("\n");
659
660
       for( ; vert<=end; vert++)
661
         {
662
         sb.append(' ');
663
         sb.append('(');
664
         sb.append(mVertAttribs2[VERT2_ATTRIBS*vert+TEX_ATTRIB]);
665
         sb.append(',');
666
         sb.append(mVertAttribs2[VERT2_ATTRIBS*vert+TEX_ATTRIB+1]);
667
         sb.append(')');
668
         }
669 1fad573e Leszek Koltunski
       }
670
671 e0343804 Leszek Koltunski
     Log.d("mesh", sb.toString());
672 1fad573e Leszek Koltunski
     }
673
674 23b733db Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
675
/**
676 0d4aae88 Leszek Koltunski
 * Not part of public API, do not document (public only because has to be used from the main package)
677
 *
678
 * @y.exclude
679 23b733db Leszek Koltunski
 */
680 0d4aae88 Leszek Koltunski
   public int getTFO()
681 23b733db Leszek Koltunski
     {
682 b5be333a Leszek Koltunski
     return mTFO.createImmediately(mNumVertices*TRAN_SIZE, null);
683 23b733db Leszek Koltunski
     }
684
685
///////////////////////////////////////////////////////////////////////////////////////////////////
686
/**
687 0d4aae88 Leszek Koltunski
 * Not part of public API, do not document (public only because has to be used from the main package)
688
 *
689
 * @y.exclude
690 23b733db Leszek Koltunski
 */
691 0d4aae88 Leszek Koltunski
   public int getNumVertices()
692 23b733db Leszek Koltunski
     {
693 0d4aae88 Leszek Koltunski
     return mNumVertices;
694 23b733db Leszek Koltunski
     }
695
696 36d65d88 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
697
/**
698
 * Not part of public API, do not document (public only because has to be used from the main package)
699
 *
700
 * @y.exclude
701
 */
702
   public void send(int variant)
703
     {
704 e8925fcd Leszek Koltunski
     GLES30.glUniform1iv( mEquAssociationH[variant], MAX_EFFECT_COMPONENTS, mEquAssociation, 0);
705
     GLES30.glUniform1iv( mAndAssociationH[variant], MAX_EFFECT_COMPONENTS, mAndAssociation, 0);
706 36d65d88 Leszek Koltunski
     }
707
708 044b5494 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
709 6c00149d Leszek Koltunski
/**
710
 * Not part of public API, do not document (public only because has to be used from the main package)
711
 *
712
 * @y.exclude
713
 */
714 da681e7e Leszek Koltunski
   public void bindVertexAttribs(DistortedProgram program)
715 6c00149d Leszek Koltunski
     {
716 71d8aba1 Leszek Koltunski
     if( mJobNode[0]!=null )
717 f046b159 Leszek Koltunski
       {
718 71d8aba1 Leszek Koltunski
       mJobNode[0].execute();  // this will set itself to null
719 f046b159 Leszek Koltunski
       }
720
721 e54bfada Leszek Koltunski
     int index1 = mVBO1.createImmediately(mNumVertices*VERT1_SIZE, mVertAttribs1);
722
     int index2 = mVBO2.createImmediately(mNumVertices*VERT2_SIZE, mVertAttribs2);
723 22e60fba Leszek Koltunski
724 e54bfada Leszek Koltunski
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index1 );
725
     GLES30.glVertexAttribPointer(program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_POS);
726
     GLES30.glVertexAttribPointer(program.mAttribute[1], NOR_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_NOR);
727
     GLES30.glVertexAttribPointer(program.mAttribute[2], INF_DATA_SIZE, GLES30.GL_FLOAT, false, VERT1_SIZE, OFFSET_INF);
728
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index2 );
729
     GLES30.glVertexAttribPointer(program.mAttribute[3], TEX_DATA_SIZE, GLES30.GL_FLOAT, false, VERT2_SIZE, OFFSET_TEX);
730 36d65d88 Leszek Koltunski
     GLES30.glVertexAttribPointer(program.mAttribute[4], COM_DATA_SIZE, GLES30.GL_FLOAT, false, VERT2_SIZE, OFFSET_COM);
731 b7074bc6 Leszek Koltunski
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
732 da681e7e Leszek Koltunski
     }
733
734
///////////////////////////////////////////////////////////////////////////////////////////////////
735
/**
736
 * Not part of public API, do not document (public only because has to be used from the main package)
737
 *
738
 * @y.exclude
739
 */
740
   public void bindTransformAttribs(DistortedProgram program)
741
     {
742 7e53a35f Leszek Koltunski
     int index = mTFO.createImmediately(mNumVertices*TRAN_SIZE, null);
743 22e60fba Leszek Koltunski
744 b7074bc6 Leszek Koltunski
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, index );
745
     GLES30.glVertexAttribPointer(program.mAttribute[0], POS_DATA_SIZE, GLES30.GL_FLOAT, false, 0, 0);
746
     GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
747 6c00149d Leszek Koltunski
     }
748
749 7a5e538a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
750
/**
751
 * Not part of public API, do not document (public only because has to be used from the main package)
752
 *
753
 * @y.exclude
754
 */
755
   public void setInflate(float inflate)
756
     {
757
     mInflate = inflate;
758
     }
759
760
///////////////////////////////////////////////////////////////////////////////////////////////////
761
/**
762
 * Not part of public API, do not document (public only because has to be used from the main package)
763
 *
764
 * @y.exclude
765
 */
766
   public float getInflate()
767
     {
768
     return mInflate;
769
     }
770
771 466450b5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
772 22422a76 Leszek Koltunski
773
   void read(FileChannel file) throws IOException
774 10836924 Leszek Koltunski
     {
775 22422a76 Leszek Koltunski
     ByteBuffer buffer = ByteBuffer.allocate(BYTES_PER_FLOAT*4);
776
     int version, numVertices=0, numEff=0, numTex=0;
777
778
     try
779
       {
780
       file.read(buffer);
781
782
       version = buffer.getInt(0);
783
784
       if( version==1 )
785
         {
786
         numVertices = buffer.getInt(4);
787
         numTex      = buffer.getInt(8);
788
         numEff      = buffer.getInt(12);
789
         }
790
       else
791
         {
792
         android.util.Log.e("mesh", "Error: unknown mesh file version "+version);
793
         file.close();
794
         return;
795
         }
796
       }
797
     catch(IOException e)
798
       {
799
       file.close();
800
       throw e;
801
       }
802
803
     if( numVertices>0 && numEff>0 && numTex>0 )
804
       {
805
       int size = numEff+TEX_COMP_SIZE*numTex;
806
       float[] tmp = new float[size];
807
       mVertAttribs1 = new float[VERT1_SIZE*mNumVertices];
808
       mVertAttribs2 = new float[VERT2_SIZE*mNumVertices];
809
810
       buffer = ByteBuffer.allocate(BYTES_PER_FLOAT*size + mNumVertices*(VERT1_SIZE+VERT2_SIZE));
811
812
       file.read(buffer);
813
814
       buffer.asFloatBuffer().get(tmp,0,size);
815
       buffer.asFloatBuffer().get(mVertAttribs1, 0, VERT1_SIZE*mNumVertices);
816
       buffer.asFloatBuffer().get(mVertAttribs2, 0, VERT2_SIZE*mNumVertices);
817
818
       TexComponent tex;
819
       int index, texComp;
820
       float x, y, z, w;
821
822
       for(texComp=0; texComp<numTex; texComp++)
823
         {
824
         index = (int)tmp[TEX_COMP_SIZE*texComp];
825
826
         x= tmp[TEX_COMP_SIZE*texComp+1];
827
         y= tmp[TEX_COMP_SIZE*texComp+2];
828
         z= tmp[TEX_COMP_SIZE*texComp+3];
829
         w= tmp[TEX_COMP_SIZE*texComp+4];
830
831
         tex = new TexComponent(index);
832
         tex.setMap(new Static4D(x,y,z,w));
833 10836924 Leszek Koltunski
834 22422a76 Leszek Koltunski
         mTexComponent.add(tex);
835
         }
836
837
       for(int effComp=0; effComp<numEff; effComp++)
838
         {
839
         index = (int)tmp[TEX_COMP_SIZE*texComp + effComp ];
840
         mEffComponent.add(index);
841
         }
842
       }
843
844
     file.close();
845 10836924 Leszek Koltunski
     }
846
847 22422a76 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
848
// PUBLIC API
849 10836924 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
850
/**
851 22422a76 Leszek Koltunski
 * Write the Mesh to a File.
852 10836924 Leszek Koltunski
 */
853 22422a76 Leszek Koltunski
   public void write(FileChannel file) throws IOException
854 10836924 Leszek Koltunski
     {
855 22422a76 Leszek Koltunski
     TexComponent tex;
856
857
     int numTex = mTexComponent.size();
858
     int numEff = mEffComponent.size();
859
860
     ByteBuffer buffer = ByteBuffer.allocate(BYTES_PER_FLOAT*(numEff+TEX_COMP_SIZE*numTex+4));
861
     FloatBuffer buf  = buffer.asFloatBuffer();
862
863
     buf.put(1);             // version
864
     buf.put(mNumVertices);
865
     buf.put(numTex);
866
     buf.put(numEff);
867
868
     for(int i=0; i<numTex; i++)
869
       {
870
       tex = mTexComponent.get(i);
871
872
       buf.put(tex.mEndIndex);
873
       buf.put(tex.mTextureMap.get0());
874
       buf.put(tex.mTextureMap.get1());
875
       buf.put(tex.mTextureMap.get2());
876
       buf.put(tex.mTextureMap.get3());
877
       }
878
879
     for(int i=0; i<numEff; i++)
880
       {
881
       buf.put(mEffComponent.get(i));
882
       }
883
884
     ByteBuffer vertBuf1 = ByteBuffer.allocate(VERT1_SIZE*mNumVertices);
885
     vertBuf1.asFloatBuffer().put(mVertAttribs1);
886
     ByteBuffer vertBuf2 = ByteBuffer.allocate(VERT2_SIZE*mNumVertices);
887
     vertBuf2.asFloatBuffer().put(mVertAttribs2);
888 10836924 Leszek Koltunski
889 22422a76 Leszek Koltunski
     try
890
       {
891
       file.write(buffer);
892
       file.write(vertBuf1);
893
       file.write(vertBuf2);
894
       }
895
     catch(IOException e)
896
       {
897
       file.close();
898
       throw e;
899
       }
900
901
     file.close();
902 10836924 Leszek Koltunski
     }
903
904
///////////////////////////////////////////////////////////////////////////////////////////////////
905 3fc9327a Leszek Koltunski
/**
906
 * When rendering this Mesh, do we want to render the Normal vectors as well?
907 420836fc leszek
 * <p>
908
 * Will work only on OpenGL ES >= 3.0 devices.
909 3fc9327a Leszek Koltunski
 *
910
 * @param show Controls if we render the Normal vectors or not.
911
 */
912
   public void setShowNormals(boolean show)
913
     {
914 b7074bc6 Leszek Koltunski
     mShowNormals = show;
915 3fc9327a Leszek Koltunski
     }
916 466450b5 Leszek Koltunski
917 6c00149d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
918
/**
919
 * When rendering this mesh, should we also draw the normal vectors?
920
 *
921
 * @return <i>true</i> if we do render normal vectors
922
 */
923
   public boolean getShowNormals()
924
     {
925
     return mShowNormals;
926
     }
927
928 a8dfedcc Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
929
/**
930 e8925fcd Leszek Koltunski
 * Merge all texture components of this Mesh into a single one.
931 a8dfedcc Leszek Koltunski
 */
932 e8925fcd Leszek Koltunski
   public void mergeTexComponents()
933 a8dfedcc Leszek Koltunski
     {
934 1fad573e Leszek Koltunski
     if( mJobNode[0]==null )
935 a8dfedcc Leszek Koltunski
       {
936 e8925fcd Leszek Koltunski
       mergeTexComponentsNow();
937 a8dfedcc Leszek Koltunski
       }
938
     else
939
       {
940 e8925fcd Leszek Koltunski
       mJobNode[0] = DeferredJobs.mergeTex(this);
941
       }
942
     }
943
944
///////////////////////////////////////////////////////////////////////////////////////////////////
945
/**
946
 * Merge all effect components of this Mesh into a single one.
947
 */
948
   public void mergeEffComponents()
949
     {
950
     if( mJobNode[0]==null )
951
       {
952
       mergeEffComponentsNow();
953
       }
954
     else
955
       {
956
       mJobNode[0] = DeferredJobs.mergeEff(this);
957 a8dfedcc Leszek Koltunski
       }
958
     }
959
960 466450b5 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
961
/**
962
 * Release all internal resources.
963
 */
964
   public void markForDeletion()
965
     {
966 e54bfada Leszek Koltunski
     mVertAttribs1 = null;
967
     mVertAttribs2 = null;
968 466450b5 Leszek Koltunski
969 e54bfada Leszek Koltunski
     mVBO1.markForDeletion();
970
     mVBO2.markForDeletion();
971 466450b5 Leszek Koltunski
     mTFO.markForDeletion();
972
     }
973 fa8bc998 Leszek Koltunski
974 e8925fcd Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
975
/**
976
 * Apply a Matrix Effect to the components which match the (addAssoc,equAssoc) association.
977
 * <p>
978
 * This is a static, permanent modification of the vertices contained in this Mesh. If the effect
979
 * contains any Dynamics, they will be evaluated at 0.
980
 *
981
 * @param effect List of Matrix Effects to apply to the Mesh.
982
 * @param andAssoc 'Logical AND' association which defines which components will be affected.
983
 * @param equAssoc 'equality' association which defines which components will be affected.
984
 */
985
   public void apply(MatrixEffect effect, int andAssoc, int equAssoc)
986
     {
987
     if( mJobNode[0]==null )
988
       {
989
       applyMatrix(effect,andAssoc,equAssoc);
990
       }
991
     else
992
       {
993
       mJobNode[0] = DeferredJobs.matrix(this,effect,andAssoc,equAssoc);
994
       }
995
     }
996
997 fa8bc998 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
998
/**
999 f046b159 Leszek Koltunski
 * Apply a Vertex Effect to the vertex mesh.
1000 fa8bc998 Leszek Koltunski
 * <p>
1001 c90aca24 Leszek Koltunski
 * This is a static, permanent modification of the vertices contained in this Mesh. If the effects
1002 f046b159 Leszek Koltunski
 * contain any Dynamics, the Dynamics will be evaluated at 0.
1003 fa8bc998 Leszek Koltunski
 *
1004 f046b159 Leszek Koltunski
 * We would call this several times building up a list of Effects to do. This list of effects gets
1005
 * lazily executed only when the Mesh is used for rendering for the first time.
1006 e172985c Leszek Koltunski
 *
1007 f046b159 Leszek Koltunski
 * @param effect Vertex Effect to apply to the Mesh.
1008 fa8bc998 Leszek Koltunski
 */
1009 f046b159 Leszek Koltunski
   public void apply(VertexEffect effect)
1010 fa8bc998 Leszek Koltunski
     {
1011 71d8aba1 Leszek Koltunski
     mJobNode[0] = DeferredJobs.vertex(this,effect);
1012 c90aca24 Leszek Koltunski
     }
1013
1014
///////////////////////////////////////////////////////////////////////////////////////////////////
1015
/**
1016 a3a05347 Leszek Koltunski
 * Sets texture maps for (some of) the components of this mesh.
1017 c90aca24 Leszek Koltunski
 * <p>
1018 a3a05347 Leszek Koltunski
 * Format: ( x of lower-left corner, y of lower-left corner, width, height ).
1019
 * For example maps[0] = new Static4D( 0.0, 0.5, 0.5, 0.5 ) sets the 0th component texture map to the
1020 0d4aae88 Leszek Koltunski
 * upper-left quadrant of the texture.
1021 a3a05347 Leszek Koltunski
 * <p>
1022
 * Probably the most common user case would be sending as many maps as there are components in this
1023
 * Mesh. One can also send less, or more (the extraneous ones will be ignored) and set some of them
1024
 * to null (those will be ignored as well). So if there are 5 components, and we want to set the map
1025
 * of the 2nd and 4rd one, call this with
1026
 * maps = new Static4D[4]
1027
 * maps[0] = null
1028
 * maps[1] = the map for the 2nd component
1029
 * maps[2] = null
1030
 * maps[3] = the map for the 4th component
1031
 *
1032
 * A map's width and height have to be non-zero (but can be negative!)
1033 e172985c Leszek Koltunski
 *
1034 dbe3079d Leszek Koltunski
 * @param maps            List of texture maps to apply to the texture's components.
1035
 * @param startComponent  the component the first of the maps refers to.
1036 c90aca24 Leszek Koltunski
 */
1037 dbe3079d Leszek Koltunski
   public void setTextureMap(Static4D[] maps, int startComponent)
1038 c90aca24 Leszek Koltunski
     {
1039 1fad573e Leszek Koltunski
     if( mJobNode[0]==null )
1040 ea88d502 Leszek Koltunski
       {
1041 dbe3079d Leszek Koltunski
       textureMap(maps,startComponent);
1042 1fad573e Leszek Koltunski
       }
1043
     else
1044
       {
1045 dbe3079d Leszek Koltunski
       mJobNode[0] = DeferredJobs.textureMap(this,maps,startComponent);
1046 ea88d502 Leszek Koltunski
       }
1047 fa8bc998 Leszek Koltunski
     }
1048 9099e567 Leszek Koltunski
1049 e172985c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1050
/**
1051
 * Return the texture map of one of the components.
1052
 *
1053
 * @param component The component number whose texture map we want to retrieve.
1054
 */
1055
   public Static4D getTextureMap(int component)
1056
     {
1057 e8925fcd Leszek Koltunski
     return (component>=0 && component<mTexComponent.size()) ? mTexComponent.get(component).mTextureMap : null;
1058 e172985c Leszek Koltunski
     }
1059 cbd502ec Leszek Koltunski
1060
///////////////////////////////////////////////////////////////////////////////////////////////////
1061
/**
1062 1e672c1d Leszek Koltunski
 * Set Effect association.
1063 bc208a9c Leszek Koltunski
 *
1064 1e672c1d Leszek Koltunski
 * This creates an association between a Component of this Mesh and a Vertex Effect.
1065 2aeb75aa Leszek Koltunski
 * One can set two types of associations - an 'logical and' and a 'equal' associations and the Effect
1066
 * will only be active on vertices of Components such that
1067 36d65d88 Leszek Koltunski
 *
1068 2aeb75aa Leszek Koltunski
 * (effect andAssoc) & (component andAssoc) != 0 || (effect equAssoc) == (mesh equAssoc)
1069 36d65d88 Leszek Koltunski
 *
1070
 * (see main_vertex_shader)
1071 bc208a9c Leszek Koltunski
 *
1072
 * The point: this way we can configure the system so that each Vertex Effect acts only on a certain
1073 1e672c1d Leszek Koltunski
 * subset of a Mesh, thus potentially significantly reducing the number of render calls.
1074 cbd502ec Leszek Koltunski
 */
1075 26671ef8 Leszek Koltunski
   public void setEffectAssociation(int component, int andAssociation, int equAssociation)
1076
     {
1077
     if( component>=0 && component<MAX_EFFECT_COMPONENTS )
1078
       {
1079
       if( mJobNode[0]==null )
1080
         {
1081
         setEffectAssociationNow(component, andAssociation, equAssociation);
1082
         }
1083
       else
1084
         {
1085
         mJobNode[0] = DeferredJobs.effectAssoc(this,component,andAssociation,equAssociation);
1086
         }
1087
       }
1088
     }
1089 bc208a9c Leszek Koltunski
1090
///////////////////////////////////////////////////////////////////////////////////////////////////
1091
/**
1092 4f81e0c8 Leszek Koltunski
 * Copy the Mesh.
1093
 *
1094
 * @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices,
1095
 *             normals and inflates (the rest, in particular the mVertAttribs2 containing texture
1096 36d65d88 Leszek Koltunski
 *             coordinates and effect associations, is always deep copied)
1097 bc208a9c Leszek Koltunski
 */
1098 4f81e0c8 Leszek Koltunski
   public abstract MeshBase copy(boolean deep);
1099 bc208a9c Leszek Koltunski
   }