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