1 /*
2  * Copyright (C) 2008-2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.renderscript;
18 
19 import java.util.Vector;
20 
21 /**
22  * @hide
23  * @deprecated in API 16
24  * <p>This class is a container for geometric data displayed with
25  * RenderScript. Internally, a mesh is a collection of allocations that
26  * represent vertex data (positions, normals, texture
27  * coordinates) and index data such as triangles and lines. </p>
28  * <p>
29  * Vertex data could either be interleaved within one
30  * allocation that is provided separately, as multiple allocation
31  * objects, or done as a combination of both. When a
32  * vertex channel name matches an input in the vertex program,
33  * RenderScript automatically connects the two together.
34  * </p>
35  * <p>
36  *  Parts of the mesh can be rendered with either explicit
37  *  index sets or primitive types.
38  * </p>
39  **/
40 public class Mesh extends BaseObj {
41 
42     /**
43     * @deprecated in API 16
44     * Describes the way mesh vertex data is interpreted when rendering
45     *
46     **/
47     public enum Primitive {
48         /**
49         * @deprecated in API 16
50         * Vertex data will be rendered as a series of points
51         */
52         POINT (0),
53         /**
54         * @deprecated in API 16
55         * Vertex pairs will be rendered as lines
56         */
57         LINE (1),
58         /**
59         * @deprecated in API 16
60         * Vertex data will be rendered as a connected line strip
61         */
62         LINE_STRIP (2),
63         /**
64         * @deprecated in API 16
65         * Vertices will be rendered as individual triangles
66         */
67         TRIANGLE (3),
68         /**
69         * @deprecated in API 16
70         * Vertices will be rendered as a connected triangle strip
71         * defined by the first three vertices with each additional
72         * triangle defined by a new vertex
73         */
74         TRIANGLE_STRIP (4),
75         /**
76         * @deprecated in API 16
77         * Vertices will be rendered as a sequence of triangles that all
78         * share first vertex as the origin
79         */
80         TRIANGLE_FAN (5);
81 
82         int mID;
Primitive(int id)83         Primitive(int id) {
84             mID = id;
85         }
86     }
87 
88     Allocation[] mVertexBuffers;
89     Allocation[] mIndexBuffers;
90     Primitive[] mPrimitives;
91 
Mesh(long id, RenderScript rs)92     Mesh(long id, RenderScript rs) {
93         super(id, rs);
94     }
95 
96     /**
97     * @deprecated in API 16
98     * @return number of allocations containing vertex data
99     *
100     **/
getVertexAllocationCount()101     public int getVertexAllocationCount() {
102         if(mVertexBuffers == null) {
103             return 0;
104         }
105         return mVertexBuffers.length;
106     }
107     /**
108     * @deprecated in API 16
109     * @param slot index in the list of allocations to return
110     * @return vertex data allocation at the given index
111     *
112     **/
getVertexAllocation(int slot)113     public Allocation getVertexAllocation(int slot) {
114         return mVertexBuffers[slot];
115     }
116 
117     /**
118     * @deprecated in API 16
119     * @return number of primitives or index sets in the mesh
120     *
121     **/
getPrimitiveCount()122     public int getPrimitiveCount() {
123         if(mIndexBuffers == null) {
124             return 0;
125         }
126         return mIndexBuffers.length;
127     }
128 
129     /**
130     * @deprecated in API 16
131     * @param slot locaton within the list of index set allocation
132     * @return allocation containing primtive index data or null if
133     *         the index data is not specified explicitly
134     *
135     **/
getIndexSetAllocation(int slot)136     public Allocation getIndexSetAllocation(int slot) {
137         return mIndexBuffers[slot];
138     }
139     /**
140     * @deprecated in API 16
141     * @param slot locaiton within the list of index set primitives
142     * @return index set primitive type
143     *
144     **/
getPrimitive(int slot)145     public Primitive getPrimitive(int slot) {
146         return mPrimitives[slot];
147     }
148 
149     @Override
updateFromNative()150     void updateFromNative() {
151         super.updateFromNative();
152         int vtxCount = mRS.nMeshGetVertexBufferCount(getID(mRS));
153         int idxCount = mRS.nMeshGetIndexCount(getID(mRS));
154 
155         long[] vtxIDs = new long[vtxCount];
156         long[] idxIDs = new long[idxCount];
157         int[] primitives = new int[idxCount];
158 
159         mRS.nMeshGetVertices(getID(mRS), vtxIDs, vtxCount);
160         mRS.nMeshGetIndices(getID(mRS), idxIDs, primitives, idxCount);
161 
162         mVertexBuffers = new Allocation[vtxCount];
163         mIndexBuffers = new Allocation[idxCount];
164         mPrimitives = new Primitive[idxCount];
165 
166         for(int i = 0; i < vtxCount; i ++) {
167             if(vtxIDs[i] != 0) {
168                 mVertexBuffers[i] = new Allocation(vtxIDs[i], mRS, null, Allocation.USAGE_SCRIPT);
169                 mVertexBuffers[i].updateFromNative();
170             }
171         }
172 
173         for(int i = 0; i < idxCount; i ++) {
174             if(idxIDs[i] != 0) {
175                 mIndexBuffers[i] = new Allocation(idxIDs[i], mRS, null, Allocation.USAGE_SCRIPT);
176                 mIndexBuffers[i].updateFromNative();
177             }
178             mPrimitives[i] = Primitive.values()[primitives[i]];
179         }
180     }
181 
182     /**
183     * @deprecated in API 16
184     * Mesh builder object. It starts empty and requires you to
185     * add the types necessary to create vertex and index
186     * allocations.
187     *
188     */
189     public static class Builder {
190         RenderScript mRS;
191         int mUsage;
192 
193         class Entry {
194             Type t;
195             Element e;
196             int size;
197             Primitive prim;
198             int usage;
199         }
200 
201         int mVertexTypeCount;
202         Entry[] mVertexTypes;
203         Vector mIndexTypes;
204 
205         /**
206         * @deprecated in API 16
207         * Creates builder object
208         * @param rs Context to which the mesh will belong.
209         * @param usage specifies how the mesh allocations are to be
210         *              handled, whether they need to be uploaded to a
211         *              buffer on the gpu, maintain a cpu copy, etc
212         */
Builder(RenderScript rs, int usage)213         public Builder(RenderScript rs, int usage) {
214             mRS = rs;
215             mUsage = usage;
216             mVertexTypeCount = 0;
217             mVertexTypes = new Entry[16];
218             mIndexTypes = new Vector();
219         }
220 
221         /**
222         * @deprecated in API 16
223         * @return internal index of the last vertex buffer type added to
224         *         builder
225         **/
getCurrentVertexTypeIndex()226         public int getCurrentVertexTypeIndex() {
227             return mVertexTypeCount - 1;
228         }
229 
230         /**
231         * @deprecated in API 16
232         * @return internal index of the last index set added to the
233         *         builder
234         **/
getCurrentIndexSetIndex()235         public int getCurrentIndexSetIndex() {
236             return mIndexTypes.size() - 1;
237         }
238 
239         /**
240         * @deprecated in API 16
241         * Adds a vertex data type to the builder object
242         *
243         * @param t type of the vertex data allocation to be created
244         *
245         * @return this
246         **/
addVertexType(Type t)247         public Builder addVertexType(Type t) throws IllegalStateException {
248             if (mVertexTypeCount >= mVertexTypes.length) {
249                 throw new IllegalStateException("Max vertex types exceeded.");
250             }
251 
252             mVertexTypes[mVertexTypeCount] = new Entry();
253             mVertexTypes[mVertexTypeCount].t = t;
254             mVertexTypes[mVertexTypeCount].e = null;
255             mVertexTypeCount++;
256             return this;
257         }
258 
259         /**
260         * @deprecated in API 16
261         * Adds a vertex data type to the builder object
262         *
263         * @param e element describing the vertex data layout
264         * @param size number of elements in the buffer
265         *
266         * @return this
267         **/
addVertexType(Element e, int size)268         public Builder addVertexType(Element e, int size) throws IllegalStateException {
269             if (mVertexTypeCount >= mVertexTypes.length) {
270                 throw new IllegalStateException("Max vertex types exceeded.");
271             }
272 
273             mVertexTypes[mVertexTypeCount] = new Entry();
274             mVertexTypes[mVertexTypeCount].t = null;
275             mVertexTypes[mVertexTypeCount].e = e;
276             mVertexTypes[mVertexTypeCount].size = size;
277             mVertexTypeCount++;
278             return this;
279         }
280 
281         /**
282         * @deprecated in API 16
283         * Adds an index set data type to the builder object
284         *
285         * @param t type of the index set data, could be null
286         * @param p primitive type
287         *
288         * @return this
289         **/
addIndexSetType(Type t, Primitive p)290         public Builder addIndexSetType(Type t, Primitive p) {
291             Entry indexType = new Entry();
292             indexType.t = t;
293             indexType.e = null;
294             indexType.size = 0;
295             indexType.prim = p;
296             mIndexTypes.addElement(indexType);
297             return this;
298         }
299 
300         /**
301         * @deprecated in API 16
302         * Adds an index set primitive type to the builder object
303         *
304         * @param p primitive type
305         *
306         * @return this
307         **/
addIndexSetType(Primitive p)308         public Builder addIndexSetType(Primitive p) {
309             Entry indexType = new Entry();
310             indexType.t = null;
311             indexType.e = null;
312             indexType.size = 0;
313             indexType.prim = p;
314             mIndexTypes.addElement(indexType);
315             return this;
316         }
317 
318         /**
319         * @deprecated in API 16
320         * Adds an index set data type to the builder object
321         *
322         * @param e element describing the index set data layout
323         * @param size number of elements in the buffer
324         * @param p primitive type
325         *
326         * @return this
327         **/
addIndexSetType(Element e, int size, Primitive p)328         public Builder addIndexSetType(Element e, int size, Primitive p) {
329             Entry indexType = new Entry();
330             indexType.t = null;
331             indexType.e = e;
332             indexType.size = size;
333             indexType.prim = p;
334             mIndexTypes.addElement(indexType);
335             return this;
336         }
337 
newType(Element e, int size)338         Type newType(Element e, int size) {
339             Type.Builder tb = new Type.Builder(mRS, e);
340             tb.setX(size);
341             return tb.create();
342         }
343 
344         /**
345         * @deprecated in API 16
346         * Create a Mesh object from the current state of the builder
347         *
348         **/
create()349         public Mesh create() {
350             mRS.validate();
351             long[] vtx = new long[mVertexTypeCount];
352             long[] idx = new long[mIndexTypes.size()];
353             int[] prim = new int[mIndexTypes.size()];
354 
355             Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
356             Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
357             Primitive[] primitives = new Primitive[mIndexTypes.size()];
358 
359             for(int ct = 0; ct < mVertexTypeCount; ct ++) {
360                 Allocation alloc = null;
361                 Entry entry = mVertexTypes[ct];
362                 if (entry.t != null) {
363                     alloc = Allocation.createTyped(mRS, entry.t, mUsage);
364                 } else if(entry.e != null) {
365                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
366                 } else {
367                     // Should never happen because the builder will always set one
368                     throw new IllegalStateException("Builder corrupt, no valid element in entry.");
369                 }
370                 vertexBuffers[ct] = alloc;
371                 vtx[ct] = alloc.getID(mRS);
372             }
373 
374             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
375                 Allocation alloc = null;
376                 Entry entry = (Entry)mIndexTypes.elementAt(ct);
377                 if (entry.t != null) {
378                     alloc = Allocation.createTyped(mRS, entry.t, mUsage);
379                 } else if(entry.e != null) {
380                     alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage);
381                 } else {
382                     // Should never happen because the builder will always set one
383                     throw new IllegalStateException("Builder corrupt, no valid element in entry.");
384                 }
385                 long allocID = (alloc == null) ? 0 : alloc.getID(mRS);
386                 indexBuffers[ct] = alloc;
387                 primitives[ct] = entry.prim;
388 
389                 idx[ct] = allocID;
390                 prim[ct] = entry.prim.mID;
391             }
392 
393             long id = mRS.nMeshCreate(vtx, idx, prim);
394             Mesh newMesh = new Mesh(id, mRS);
395             newMesh.mVertexBuffers = vertexBuffers;
396             newMesh.mIndexBuffers = indexBuffers;
397             newMesh.mPrimitives = primitives;
398 
399             return newMesh;
400         }
401     }
402 
403     /**
404     * @deprecated in API 16
405     * Mesh builder object. It starts empty and requires the user to
406     * add all the vertex and index allocations that comprise the
407     * mesh
408     *
409     */
410     public static class AllocationBuilder {
411         RenderScript mRS;
412 
413         class Entry {
414             Allocation a;
415             Primitive prim;
416         }
417 
418         int mVertexTypeCount;
419         Entry[] mVertexTypes;
420 
421         Vector mIndexTypes;
422 
423         /**
424         * @deprecated in API 16
425         **/
AllocationBuilder(RenderScript rs)426         public AllocationBuilder(RenderScript rs) {
427             mRS = rs;
428             mVertexTypeCount = 0;
429             mVertexTypes = new Entry[16];
430             mIndexTypes = new Vector();
431         }
432 
433         /**
434         * @deprecated in API 16
435         * @return internal index of the last vertex buffer type added to
436         *         builder
437         **/
getCurrentVertexTypeIndex()438         public int getCurrentVertexTypeIndex() {
439             return mVertexTypeCount - 1;
440         }
441 
442         /**
443         * @deprecated in API 16
444         * @return internal index of the last index set added to the
445         *         builder
446         **/
getCurrentIndexSetIndex()447         public int getCurrentIndexSetIndex() {
448             return mIndexTypes.size() - 1;
449         }
450 
451         /**
452         * @deprecated in API 16
453         * Adds an allocation containing vertex buffer data to the
454         * builder
455         *
456         * @param a vertex data allocation
457         *
458         * @return this
459         **/
addVertexAllocation(Allocation a)460         public AllocationBuilder addVertexAllocation(Allocation a) throws IllegalStateException {
461             if (mVertexTypeCount >= mVertexTypes.length) {
462                 throw new IllegalStateException("Max vertex types exceeded.");
463             }
464 
465             mVertexTypes[mVertexTypeCount] = new Entry();
466             mVertexTypes[mVertexTypeCount].a = a;
467             mVertexTypeCount++;
468             return this;
469         }
470 
471         /**
472         * @deprecated in API 16
473         * Adds an allocation containing index buffer data and index type
474         * to the builder
475         *
476         * @param a index set data allocation, could be null
477         * @param p index set primitive type
478         *
479         * @return this
480         **/
addIndexSetAllocation(Allocation a, Primitive p)481         public AllocationBuilder addIndexSetAllocation(Allocation a, Primitive p) {
482             Entry indexType = new Entry();
483             indexType.a = a;
484             indexType.prim = p;
485             mIndexTypes.addElement(indexType);
486             return this;
487         }
488 
489         /**
490         * @deprecated in API 16
491         * Adds an index set type to the builder
492         *
493         * @param p index set primitive type
494         *
495         * @return this
496         **/
addIndexSetType(Primitive p)497         public AllocationBuilder addIndexSetType(Primitive p) {
498             Entry indexType = new Entry();
499             indexType.a = null;
500             indexType.prim = p;
501             mIndexTypes.addElement(indexType);
502             return this;
503         }
504 
505         /**
506         * @deprecated in API 16
507         * Create a Mesh object from the current state of the builder
508         *
509         **/
create()510         public Mesh create() {
511             mRS.validate();
512 
513             long[] vtx = new long[mVertexTypeCount];
514             long[] idx = new long[mIndexTypes.size()];
515             int[] prim = new int[mIndexTypes.size()];
516 
517             Allocation[] indexBuffers = new Allocation[mIndexTypes.size()];
518             Primitive[] primitives = new Primitive[mIndexTypes.size()];
519             Allocation[] vertexBuffers = new Allocation[mVertexTypeCount];
520 
521             for(int ct = 0; ct < mVertexTypeCount; ct ++) {
522                 Entry entry = mVertexTypes[ct];
523                 vertexBuffers[ct] = entry.a;
524                 vtx[ct] = entry.a.getID(mRS);
525             }
526 
527             for(int ct = 0; ct < mIndexTypes.size(); ct ++) {
528                 Entry entry = (Entry)mIndexTypes.elementAt(ct);
529                 long allocID = (entry.a == null) ? 0 : entry.a.getID(mRS);
530                 indexBuffers[ct] = entry.a;
531                 primitives[ct] = entry.prim;
532 
533                 idx[ct] = allocID;
534                 prim[ct] = entry.prim.mID;
535             }
536 
537             long id = mRS.nMeshCreate(vtx, idx, prim);
538             Mesh newMesh = new Mesh(id, mRS);
539             newMesh.mVertexBuffers = vertexBuffers;
540             newMesh.mIndexBuffers = indexBuffers;
541             newMesh.mPrimitives = primitives;
542 
543             return newMesh;
544         }
545     }
546 
547     /**
548     * @deprecated in API 16
549     * Builder that allows creation of a mesh object point by point
550     * and triangle by triangle
551     *
552     **/
553     public static class TriangleMeshBuilder {
554         float mVtxData[];
555         int mVtxCount;
556         int mMaxIndex;
557         short mIndexData[];
558         int mIndexCount;
559         RenderScript mRS;
560         Element mElement;
561 
562         float mNX = 0;
563         float mNY = 0;
564         float mNZ = -1;
565         float mS0 = 0;
566         float mT0 = 0;
567         float mR = 1;
568         float mG = 1;
569         float mB = 1;
570         float mA = 1;
571 
572         int mVtxSize;
573         int mFlags;
574 
575         /**
576         * @deprecated in API 16
577         **/
578         public static final int COLOR = 0x0001;
579         /**
580         * @deprecated in API 16
581         **/
582         public static final int NORMAL = 0x0002;
583         /**
584         * @deprecated in API 16
585         **/
586         public static final int TEXTURE_0 = 0x0100;
587 
588         /**
589         * @deprecated in API 16
590         * @param rs Context to which the mesh will belong.
591         * @param vtxSize specifies whether the vertex is a float2 or
592         *                float3
593         * @param flags bitfield that is a combination of COLOR, NORMAL,
594         *              and TEXTURE_0 that specifies what vertex data
595         *              channels are present in the mesh
596         *
597         **/
TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags)598         public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) {
599             mRS = rs;
600             mVtxCount = 0;
601             mMaxIndex = 0;
602             mIndexCount = 0;
603             mVtxData = new float[128];
604             mIndexData = new short[128];
605             mVtxSize = vtxSize;
606             mFlags = flags;
607 
608             if (vtxSize < 2 || vtxSize > 3) {
609                 throw new IllegalArgumentException("Vertex size out of range.");
610             }
611         }
612 
makeSpace(int count)613         private void makeSpace(int count) {
614             if ((mVtxCount + count) >= mVtxData.length) {
615                 float t[] = new float[mVtxData.length * 2];
616                 System.arraycopy(mVtxData, 0, t, 0, mVtxData.length);
617                 mVtxData = t;
618             }
619         }
620 
latch()621         private void latch() {
622             if ((mFlags & COLOR) != 0) {
623                 makeSpace(4);
624                 mVtxData[mVtxCount++] = mR;
625                 mVtxData[mVtxCount++] = mG;
626                 mVtxData[mVtxCount++] = mB;
627                 mVtxData[mVtxCount++] = mA;
628             }
629             if ((mFlags & TEXTURE_0) != 0) {
630                 makeSpace(2);
631                 mVtxData[mVtxCount++] = mS0;
632                 mVtxData[mVtxCount++] = mT0;
633             }
634             if ((mFlags & NORMAL) != 0) {
635                 makeSpace(4);
636                 mVtxData[mVtxCount++] = mNX;
637                 mVtxData[mVtxCount++] = mNY;
638                 mVtxData[mVtxCount++] = mNZ;
639                 mVtxData[mVtxCount++] = 0.0f;
640             }
641             mMaxIndex ++;
642         }
643 
644         /**
645         * @deprecated in API 16
646         * Adds a float2 vertex to the mesh
647         *
648         * @param x position x
649         * @param y position y
650         *
651         * @return this
652         *
653         **/
addVertex(float x, float y)654         public TriangleMeshBuilder addVertex(float x, float y) {
655             if (mVtxSize != 2) {
656                 throw new IllegalStateException("add mistmatch with declared components.");
657             }
658             makeSpace(2);
659             mVtxData[mVtxCount++] = x;
660             mVtxData[mVtxCount++] = y;
661             latch();
662             return this;
663         }
664 
665         /**
666         * @deprecated in API 16
667         * Adds a float3 vertex to the mesh
668         *
669         * @param x position x
670         * @param y position y
671         * @param z position z
672         *
673         * @return this
674         *
675         **/
addVertex(float x, float y, float z)676         public TriangleMeshBuilder addVertex(float x, float y, float z) {
677             if (mVtxSize != 3) {
678                 throw new IllegalStateException("add mistmatch with declared components.");
679             }
680             makeSpace(4);
681             mVtxData[mVtxCount++] = x;
682             mVtxData[mVtxCount++] = y;
683             mVtxData[mVtxCount++] = z;
684             mVtxData[mVtxCount++] = 1.0f;
685             latch();
686             return this;
687         }
688 
689         /**
690         * @deprecated in API 16
691         * Sets the texture coordinate for the vertices that are added after this method call.
692         *
693         * @param s texture coordinate s
694         * @param t texture coordinate t
695         *
696         * @return this
697         **/
setTexture(float s, float t)698         public TriangleMeshBuilder setTexture(float s, float t) {
699             if ((mFlags & TEXTURE_0) == 0) {
700                 throw new IllegalStateException("add mistmatch with declared components.");
701             }
702             mS0 = s;
703             mT0 = t;
704             return this;
705         }
706 
707         /**
708         * @deprecated in API 16
709         * Sets the normal vector for the vertices that are added after this method call.
710         *
711         * @param x normal vector x
712         * @param y normal vector y
713         * @param z normal vector z
714         *
715         * @return this
716         **/
setNormal(float x, float y, float z)717         public TriangleMeshBuilder setNormal(float x, float y, float z) {
718             if ((mFlags & NORMAL) == 0) {
719                 throw new IllegalStateException("add mistmatch with declared components.");
720             }
721             mNX = x;
722             mNY = y;
723             mNZ = z;
724             return this;
725         }
726 
727         /**
728         * @deprecated in API 16
729         * Sets the color for the vertices that are added after this method call.
730         *
731         * @param r red component
732         * @param g green component
733         * @param b blue component
734         * @param a alpha component
735         *
736         * @return this
737         **/
setColor(float r, float g, float b, float a)738         public TriangleMeshBuilder setColor(float r, float g, float b, float a) {
739             if ((mFlags & COLOR) == 0) {
740                 throw new IllegalStateException("add mistmatch with declared components.");
741             }
742             mR = r;
743             mG = g;
744             mB = b;
745             mA = a;
746             return this;
747         }
748 
749         /**
750         * @deprecated in API 16
751         * Adds a new triangle to the mesh builder
752         *
753         * @param idx1 index of the first vertex in the triangle
754         * @param idx2 index of the second vertex in the triangle
755         * @param idx3 index of the third vertex in the triangle
756         *
757         * @return this
758         **/
addTriangle(int idx1, int idx2, int idx3)759         public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) {
760             if((idx1 >= mMaxIndex) || (idx1 < 0) ||
761                (idx2 >= mMaxIndex) || (idx2 < 0) ||
762                (idx3 >= mMaxIndex) || (idx3 < 0)) {
763                throw new IllegalStateException("Index provided greater than vertex count.");
764             }
765             if ((mIndexCount + 3) >= mIndexData.length) {
766                 short t[] = new short[mIndexData.length * 2];
767                 System.arraycopy(mIndexData, 0, t, 0, mIndexData.length);
768                 mIndexData = t;
769             }
770             mIndexData[mIndexCount++] = (short)idx1;
771             mIndexData[mIndexCount++] = (short)idx2;
772             mIndexData[mIndexCount++] = (short)idx3;
773             return this;
774         }
775 
776         /**
777         * @deprecated in API 16
778         * Creates the mesh object from the current state of the builder
779         *
780         * @param uploadToBufferObject specifies whether the vertex data
781         *                             is to be uploaded into the buffer
782         *                             object indicating that it's likely
783         *                             not going to be modified and
784         *                             rendered many times.
785         *                             Alternatively, it indicates the
786         *                             mesh data will be updated
787         *                             frequently and remain in script
788         *                             accessible memory
789         *
790         **/
create(boolean uploadToBufferObject)791         public Mesh create(boolean uploadToBufferObject) {
792             Element.Builder b = new Element.Builder(mRS);
793             b.add(Element.createVector(mRS,
794                                        Element.DataType.FLOAT_32,
795                                        mVtxSize), "position");
796             if ((mFlags & COLOR) != 0) {
797                 b.add(Element.F32_4(mRS), "color");
798             }
799             if ((mFlags & TEXTURE_0) != 0) {
800                 b.add(Element.F32_2(mRS), "texture0");
801             }
802             if ((mFlags & NORMAL) != 0) {
803                 b.add(Element.F32_3(mRS), "normal");
804             }
805             mElement = b.create();
806 
807             int usage = Allocation.USAGE_SCRIPT;
808             if (uploadToBufferObject) {
809                 usage |= Allocation.USAGE_GRAPHICS_VERTEX;
810             }
811 
812             Builder smb = new Builder(mRS, usage);
813             smb.addVertexType(mElement, mMaxIndex);
814             smb.addIndexSetType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE);
815 
816             Mesh sm = smb.create();
817 
818             sm.getVertexAllocation(0).copy1DRangeFromUnchecked(0, mMaxIndex, mVtxData);
819             if(uploadToBufferObject) {
820                 sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
821             }
822 
823             sm.getIndexSetAllocation(0).copy1DRangeFromUnchecked(0, mIndexCount, mIndexData);
824             if (uploadToBufferObject) {
825                 sm.getIndexSetAllocation(0).syncAll(Allocation.USAGE_SCRIPT);
826             }
827 
828             return sm;
829         }
830     }
831 }
832 
833