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