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