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