|  | /* | 
|  | * Copyright (C) 2008-2012 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | package android.renderscript; | 
|  |  | 
|  | import android.compat.annotation.UnsupportedAppUsage; | 
|  | import android.os.Build; | 
|  |  | 
|  | import java.util.Vector; | 
|  |  | 
|  | /** | 
|  | * @hide | 
|  | * @deprecated in API 16 | 
|  | * <p>This class is a container for geometric data displayed with | 
|  | * RenderScript. Internally, a mesh is a collection of allocations that | 
|  | * represent vertex data (positions, normals, texture | 
|  | * coordinates) and index data such as triangles and lines. </p> | 
|  | * <p> | 
|  | * Vertex data could either be interleaved within one | 
|  | * allocation that is provided separately, as multiple allocation | 
|  | * objects, or done as a combination of both. When a | 
|  | * vertex channel name matches an input in the vertex program, | 
|  | * RenderScript automatically connects the two together. | 
|  | * </p> | 
|  | * <p> | 
|  | *  Parts of the mesh can be rendered with either explicit | 
|  | *  index sets or primitive types. | 
|  | * </p> | 
|  | **/ | 
|  | @Deprecated | 
|  | public class Mesh extends BaseObj { | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Describes the way mesh vertex data is interpreted when rendering | 
|  | * | 
|  | **/ | 
|  | public enum Primitive { | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Vertex data will be rendered as a series of points | 
|  | */ | 
|  | @UnsupportedAppUsage | 
|  | POINT (0), | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Vertex pairs will be rendered as lines | 
|  | */ | 
|  | LINE (1), | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Vertex data will be rendered as a connected line strip | 
|  | */ | 
|  | LINE_STRIP (2), | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Vertices will be rendered as individual triangles | 
|  | */ | 
|  | @UnsupportedAppUsage | 
|  | TRIANGLE (3), | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Vertices will be rendered as a connected triangle strip | 
|  | * defined by the first three vertices with each additional | 
|  | * triangle defined by a new vertex | 
|  | */ | 
|  | TRIANGLE_STRIP (4), | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Vertices will be rendered as a sequence of triangles that all | 
|  | * share first vertex as the origin | 
|  | */ | 
|  | TRIANGLE_FAN (5); | 
|  |  | 
|  | int mID; | 
|  | Primitive(int id) { | 
|  | mID = id; | 
|  | } | 
|  | } | 
|  |  | 
|  | Allocation[] mVertexBuffers; | 
|  | Allocation[] mIndexBuffers; | 
|  | Primitive[] mPrimitives; | 
|  |  | 
|  | Mesh(long id, RenderScript rs) { | 
|  | super(id, rs); | 
|  | guard.open("destroy"); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @return number of allocations containing vertex data | 
|  | * | 
|  | **/ | 
|  | public int getVertexAllocationCount() { | 
|  | if(mVertexBuffers == null) { | 
|  | return 0; | 
|  | } | 
|  | return mVertexBuffers.length; | 
|  | } | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @param slot index in the list of allocations to return | 
|  | * @return vertex data allocation at the given index | 
|  | * | 
|  | **/ | 
|  | @UnsupportedAppUsage | 
|  | public Allocation getVertexAllocation(int slot) { | 
|  | return mVertexBuffers[slot]; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @return number of primitives or index sets in the mesh | 
|  | * | 
|  | **/ | 
|  | public int getPrimitiveCount() { | 
|  | if(mIndexBuffers == null) { | 
|  | return 0; | 
|  | } | 
|  | return mIndexBuffers.length; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @param slot locaton within the list of index set allocation | 
|  | * @return allocation containing primtive index data or null if | 
|  | *         the index data is not specified explicitly | 
|  | * | 
|  | **/ | 
|  | public Allocation getIndexSetAllocation(int slot) { | 
|  | return mIndexBuffers[slot]; | 
|  | } | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @param slot locaiton within the list of index set primitives | 
|  | * @return index set primitive type | 
|  | * | 
|  | **/ | 
|  | public Primitive getPrimitive(int slot) { | 
|  | return mPrimitives[slot]; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | void updateFromNative() { | 
|  | super.updateFromNative(); | 
|  | int vtxCount = mRS.nMeshGetVertexBufferCount(getID(mRS)); | 
|  | int idxCount = mRS.nMeshGetIndexCount(getID(mRS)); | 
|  |  | 
|  | long[] vtxIDs = new long[vtxCount]; | 
|  | long[] idxIDs = new long[idxCount]; | 
|  | int[] primitives = new int[idxCount]; | 
|  |  | 
|  | mRS.nMeshGetVertices(getID(mRS), vtxIDs, vtxCount); | 
|  | mRS.nMeshGetIndices(getID(mRS), idxIDs, primitives, idxCount); | 
|  |  | 
|  | mVertexBuffers = new Allocation[vtxCount]; | 
|  | mIndexBuffers = new Allocation[idxCount]; | 
|  | mPrimitives = new Primitive[idxCount]; | 
|  |  | 
|  | for(int i = 0; i < vtxCount; i ++) { | 
|  | if(vtxIDs[i] != 0) { | 
|  | mVertexBuffers[i] = new Allocation(vtxIDs[i], mRS, null, Allocation.USAGE_SCRIPT); | 
|  | mVertexBuffers[i].updateFromNative(); | 
|  | } | 
|  | } | 
|  |  | 
|  | for(int i = 0; i < idxCount; i ++) { | 
|  | if(idxIDs[i] != 0) { | 
|  | mIndexBuffers[i] = new Allocation(idxIDs[i], mRS, null, Allocation.USAGE_SCRIPT); | 
|  | mIndexBuffers[i].updateFromNative(); | 
|  | } | 
|  | mPrimitives[i] = Primitive.values()[primitives[i]]; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Mesh builder object. It starts empty and requires you to | 
|  | * add the types necessary to create vertex and index | 
|  | * allocations. | 
|  | * | 
|  | */ | 
|  | public static class Builder { | 
|  | RenderScript mRS; | 
|  | int mUsage; | 
|  |  | 
|  | class Entry { | 
|  | Type t; | 
|  | Element e; | 
|  | int size; | 
|  | Primitive prim; | 
|  | int usage; | 
|  | } | 
|  |  | 
|  | int mVertexTypeCount; | 
|  | Entry[] mVertexTypes; | 
|  | Vector mIndexTypes; | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Creates builder object | 
|  | * @param rs Context to which the mesh will belong. | 
|  | * @param usage specifies how the mesh allocations are to be | 
|  | *              handled, whether they need to be uploaded to a | 
|  | *              buffer on the gpu, maintain a cpu copy, etc | 
|  | */ | 
|  | public Builder(RenderScript rs, int usage) { | 
|  | mRS = rs; | 
|  | mUsage = usage; | 
|  | mVertexTypeCount = 0; | 
|  | mVertexTypes = new Entry[16]; | 
|  | mIndexTypes = new Vector(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @return internal index of the last vertex buffer type added to | 
|  | *         builder | 
|  | **/ | 
|  | public int getCurrentVertexTypeIndex() { | 
|  | return mVertexTypeCount - 1; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @return internal index of the last index set added to the | 
|  | *         builder | 
|  | **/ | 
|  | public int getCurrentIndexSetIndex() { | 
|  | return mIndexTypes.size() - 1; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds a vertex data type to the builder object | 
|  | * | 
|  | * @param t type of the vertex data allocation to be created | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | public Builder addVertexType(Type t) throws IllegalStateException { | 
|  | if (mVertexTypeCount >= mVertexTypes.length) { | 
|  | throw new IllegalStateException("Max vertex types exceeded."); | 
|  | } | 
|  |  | 
|  | mVertexTypes[mVertexTypeCount] = new Entry(); | 
|  | mVertexTypes[mVertexTypeCount].t = t; | 
|  | mVertexTypes[mVertexTypeCount].e = null; | 
|  | mVertexTypeCount++; | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds a vertex data type to the builder object | 
|  | * | 
|  | * @param e element describing the vertex data layout | 
|  | * @param size number of elements in the buffer | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | public Builder addVertexType(Element e, int size) throws IllegalStateException { | 
|  | if (mVertexTypeCount >= mVertexTypes.length) { | 
|  | throw new IllegalStateException("Max vertex types exceeded."); | 
|  | } | 
|  |  | 
|  | mVertexTypes[mVertexTypeCount] = new Entry(); | 
|  | mVertexTypes[mVertexTypeCount].t = null; | 
|  | mVertexTypes[mVertexTypeCount].e = e; | 
|  | mVertexTypes[mVertexTypeCount].size = size; | 
|  | mVertexTypeCount++; | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds an index set data type to the builder object | 
|  | * | 
|  | * @param t type of the index set data, could be null | 
|  | * @param p primitive type | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | public Builder addIndexSetType(Type t, Primitive p) { | 
|  | Entry indexType = new Entry(); | 
|  | indexType.t = t; | 
|  | indexType.e = null; | 
|  | indexType.size = 0; | 
|  | indexType.prim = p; | 
|  | mIndexTypes.addElement(indexType); | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds an index set primitive type to the builder object | 
|  | * | 
|  | * @param p primitive type | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | public Builder addIndexSetType(Primitive p) { | 
|  | Entry indexType = new Entry(); | 
|  | indexType.t = null; | 
|  | indexType.e = null; | 
|  | indexType.size = 0; | 
|  | indexType.prim = p; | 
|  | mIndexTypes.addElement(indexType); | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds an index set data type to the builder object | 
|  | * | 
|  | * @param e element describing the index set data layout | 
|  | * @param size number of elements in the buffer | 
|  | * @param p primitive type | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | public Builder addIndexSetType(Element e, int size, Primitive p) { | 
|  | Entry indexType = new Entry(); | 
|  | indexType.t = null; | 
|  | indexType.e = e; | 
|  | indexType.size = size; | 
|  | indexType.prim = p; | 
|  | mIndexTypes.addElement(indexType); | 
|  | return this; | 
|  | } | 
|  |  | 
|  | Type newType(Element e, int size) { | 
|  | Type.Builder tb = new Type.Builder(mRS, e); | 
|  | tb.setX(size); | 
|  | return tb.create(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Create a Mesh object from the current state of the builder | 
|  | * | 
|  | **/ | 
|  | public Mesh create() { | 
|  | mRS.validate(); | 
|  | long[] vtx = new long[mVertexTypeCount]; | 
|  | long[] idx = new long[mIndexTypes.size()]; | 
|  | int[] prim = new int[mIndexTypes.size()]; | 
|  |  | 
|  | Allocation[] vertexBuffers = new Allocation[mVertexTypeCount]; | 
|  | Allocation[] indexBuffers = new Allocation[mIndexTypes.size()]; | 
|  | Primitive[] primitives = new Primitive[mIndexTypes.size()]; | 
|  |  | 
|  | for(int ct = 0; ct < mVertexTypeCount; ct ++) { | 
|  | Allocation alloc = null; | 
|  | Entry entry = mVertexTypes[ct]; | 
|  | if (entry.t != null) { | 
|  | alloc = Allocation.createTyped(mRS, entry.t, mUsage); | 
|  | } else if(entry.e != null) { | 
|  | alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage); | 
|  | } else { | 
|  | // Should never happen because the builder will always set one | 
|  | throw new IllegalStateException("Builder corrupt, no valid element in entry."); | 
|  | } | 
|  | vertexBuffers[ct] = alloc; | 
|  | vtx[ct] = alloc.getID(mRS); | 
|  | } | 
|  |  | 
|  | for(int ct = 0; ct < mIndexTypes.size(); ct ++) { | 
|  | Allocation alloc = null; | 
|  | Entry entry = (Entry)mIndexTypes.elementAt(ct); | 
|  | if (entry.t != null) { | 
|  | alloc = Allocation.createTyped(mRS, entry.t, mUsage); | 
|  | } else if(entry.e != null) { | 
|  | alloc = Allocation.createSized(mRS, entry.e, entry.size, mUsage); | 
|  | } else { | 
|  | // Should never happen because the builder will always set one | 
|  | throw new IllegalStateException("Builder corrupt, no valid element in entry."); | 
|  | } | 
|  | long allocID = (alloc == null) ? 0 : alloc.getID(mRS); | 
|  | indexBuffers[ct] = alloc; | 
|  | primitives[ct] = entry.prim; | 
|  |  | 
|  | idx[ct] = allocID; | 
|  | prim[ct] = entry.prim.mID; | 
|  | } | 
|  |  | 
|  | long id = mRS.nMeshCreate(vtx, idx, prim); | 
|  | Mesh newMesh = new Mesh(id, mRS); | 
|  | newMesh.mVertexBuffers = vertexBuffers; | 
|  | newMesh.mIndexBuffers = indexBuffers; | 
|  | newMesh.mPrimitives = primitives; | 
|  |  | 
|  | return newMesh; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Mesh builder object. It starts empty and requires the user to | 
|  | * add all the vertex and index allocations that comprise the | 
|  | * mesh | 
|  | * | 
|  | */ | 
|  | public static class AllocationBuilder { | 
|  | RenderScript mRS; | 
|  |  | 
|  | class Entry { | 
|  | Allocation a; | 
|  | Primitive prim; | 
|  | } | 
|  |  | 
|  | int mVertexTypeCount; | 
|  | Entry[] mVertexTypes; | 
|  |  | 
|  | Vector mIndexTypes; | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | **/ | 
|  | @UnsupportedAppUsage | 
|  | public AllocationBuilder(RenderScript rs) { | 
|  | mRS = rs; | 
|  | mVertexTypeCount = 0; | 
|  | mVertexTypes = new Entry[16]; | 
|  | mIndexTypes = new Vector(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @return internal index of the last vertex buffer type added to | 
|  | *         builder | 
|  | **/ | 
|  | public int getCurrentVertexTypeIndex() { | 
|  | return mVertexTypeCount - 1; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @return internal index of the last index set added to the | 
|  | *         builder | 
|  | **/ | 
|  | public int getCurrentIndexSetIndex() { | 
|  | return mIndexTypes.size() - 1; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds an allocation containing vertex buffer data to the | 
|  | * builder | 
|  | * | 
|  | * @param a vertex data allocation | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | @UnsupportedAppUsage | 
|  | public AllocationBuilder addVertexAllocation(Allocation a) throws IllegalStateException { | 
|  | if (mVertexTypeCount >= mVertexTypes.length) { | 
|  | throw new IllegalStateException("Max vertex types exceeded."); | 
|  | } | 
|  |  | 
|  | mVertexTypes[mVertexTypeCount] = new Entry(); | 
|  | mVertexTypes[mVertexTypeCount].a = a; | 
|  | mVertexTypeCount++; | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds an allocation containing index buffer data and index type | 
|  | * to the builder | 
|  | * | 
|  | * @param a index set data allocation, could be null | 
|  | * @param p index set primitive type | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | @UnsupportedAppUsage | 
|  | public AllocationBuilder addIndexSetAllocation(Allocation a, Primitive p) { | 
|  | Entry indexType = new Entry(); | 
|  | indexType.a = a; | 
|  | indexType.prim = p; | 
|  | mIndexTypes.addElement(indexType); | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds an index set type to the builder | 
|  | * | 
|  | * @param p index set primitive type | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | @UnsupportedAppUsage | 
|  | public AllocationBuilder addIndexSetType(Primitive p) { | 
|  | Entry indexType = new Entry(); | 
|  | indexType.a = null; | 
|  | indexType.prim = p; | 
|  | mIndexTypes.addElement(indexType); | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Create a Mesh object from the current state of the builder | 
|  | * | 
|  | **/ | 
|  | @UnsupportedAppUsage | 
|  | public Mesh create() { | 
|  | mRS.validate(); | 
|  |  | 
|  | long[] vtx = new long[mVertexTypeCount]; | 
|  | long[] idx = new long[mIndexTypes.size()]; | 
|  | int[] prim = new int[mIndexTypes.size()]; | 
|  |  | 
|  | Allocation[] indexBuffers = new Allocation[mIndexTypes.size()]; | 
|  | Primitive[] primitives = new Primitive[mIndexTypes.size()]; | 
|  | Allocation[] vertexBuffers = new Allocation[mVertexTypeCount]; | 
|  |  | 
|  | for(int ct = 0; ct < mVertexTypeCount; ct ++) { | 
|  | Entry entry = mVertexTypes[ct]; | 
|  | vertexBuffers[ct] = entry.a; | 
|  | vtx[ct] = entry.a.getID(mRS); | 
|  | } | 
|  |  | 
|  | for(int ct = 0; ct < mIndexTypes.size(); ct ++) { | 
|  | Entry entry = (Entry)mIndexTypes.elementAt(ct); | 
|  | long allocID = (entry.a == null) ? 0 : entry.a.getID(mRS); | 
|  | indexBuffers[ct] = entry.a; | 
|  | primitives[ct] = entry.prim; | 
|  |  | 
|  | idx[ct] = allocID; | 
|  | prim[ct] = entry.prim.mID; | 
|  | } | 
|  |  | 
|  | long id = mRS.nMeshCreate(vtx, idx, prim); | 
|  | Mesh newMesh = new Mesh(id, mRS); | 
|  | newMesh.mVertexBuffers = vertexBuffers; | 
|  | newMesh.mIndexBuffers = indexBuffers; | 
|  | newMesh.mPrimitives = primitives; | 
|  |  | 
|  | return newMesh; | 
|  | } | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Builder that allows creation of a mesh object point by point | 
|  | * and triangle by triangle | 
|  | * | 
|  | **/ | 
|  | public static class TriangleMeshBuilder { | 
|  | float mVtxData[]; | 
|  | int mVtxCount; | 
|  | int mMaxIndex; | 
|  | short mIndexData[]; | 
|  | int mIndexCount; | 
|  | RenderScript mRS; | 
|  | Element mElement; | 
|  |  | 
|  | float mNX = 0; | 
|  | float mNY = 0; | 
|  | float mNZ = -1; | 
|  | float mS0 = 0; | 
|  | float mT0 = 0; | 
|  | float mR = 1; | 
|  | float mG = 1; | 
|  | float mB = 1; | 
|  | float mA = 1; | 
|  |  | 
|  | int mVtxSize; | 
|  | int mFlags; | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | **/ | 
|  | public static final int COLOR = 0x0001; | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | **/ | 
|  | public static final int NORMAL = 0x0002; | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | **/ | 
|  | public static final int TEXTURE_0 = 0x0100; | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * @param rs Context to which the mesh will belong. | 
|  | * @param vtxSize specifies whether the vertex is a float2 or | 
|  | *                float3 | 
|  | * @param flags bitfield that is a combination of COLOR, NORMAL, | 
|  | *              and TEXTURE_0 that specifies what vertex data | 
|  | *              channels are present in the mesh | 
|  | * | 
|  | **/ | 
|  | @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) | 
|  | public TriangleMeshBuilder(RenderScript rs, int vtxSize, int flags) { | 
|  | mRS = rs; | 
|  | mVtxCount = 0; | 
|  | mMaxIndex = 0; | 
|  | mIndexCount = 0; | 
|  | mVtxData = new float[128]; | 
|  | mIndexData = new short[128]; | 
|  | mVtxSize = vtxSize; | 
|  | mFlags = flags; | 
|  |  | 
|  | if (vtxSize < 2 || vtxSize > 3) { | 
|  | throw new IllegalArgumentException("Vertex size out of range."); | 
|  | } | 
|  | } | 
|  |  | 
|  | private void makeSpace(int count) { | 
|  | if ((mVtxCount + count) >= mVtxData.length) { | 
|  | float t[] = new float[mVtxData.length * 2]; | 
|  | System.arraycopy(mVtxData, 0, t, 0, mVtxData.length); | 
|  | mVtxData = t; | 
|  | } | 
|  | } | 
|  |  | 
|  | private void latch() { | 
|  | if ((mFlags & COLOR) != 0) { | 
|  | makeSpace(4); | 
|  | mVtxData[mVtxCount++] = mR; | 
|  | mVtxData[mVtxCount++] = mG; | 
|  | mVtxData[mVtxCount++] = mB; | 
|  | mVtxData[mVtxCount++] = mA; | 
|  | } | 
|  | if ((mFlags & TEXTURE_0) != 0) { | 
|  | makeSpace(2); | 
|  | mVtxData[mVtxCount++] = mS0; | 
|  | mVtxData[mVtxCount++] = mT0; | 
|  | } | 
|  | if ((mFlags & NORMAL) != 0) { | 
|  | makeSpace(4); | 
|  | mVtxData[mVtxCount++] = mNX; | 
|  | mVtxData[mVtxCount++] = mNY; | 
|  | mVtxData[mVtxCount++] = mNZ; | 
|  | mVtxData[mVtxCount++] = 0.0f; | 
|  | } | 
|  | mMaxIndex ++; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds a float2 vertex to the mesh | 
|  | * | 
|  | * @param x position x | 
|  | * @param y position y | 
|  | * | 
|  | * @return this | 
|  | * | 
|  | **/ | 
|  | @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) | 
|  | public TriangleMeshBuilder addVertex(float x, float y) { | 
|  | if (mVtxSize != 2) { | 
|  | throw new IllegalStateException("add mistmatch with declared components."); | 
|  | } | 
|  | makeSpace(2); | 
|  | mVtxData[mVtxCount++] = x; | 
|  | mVtxData[mVtxCount++] = y; | 
|  | latch(); | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds a float3 vertex to the mesh | 
|  | * | 
|  | * @param x position x | 
|  | * @param y position y | 
|  | * @param z position z | 
|  | * | 
|  | * @return this | 
|  | * | 
|  | **/ | 
|  | public TriangleMeshBuilder addVertex(float x, float y, float z) { | 
|  | if (mVtxSize != 3) { | 
|  | throw new IllegalStateException("add mistmatch with declared components."); | 
|  | } | 
|  | makeSpace(4); | 
|  | mVtxData[mVtxCount++] = x; | 
|  | mVtxData[mVtxCount++] = y; | 
|  | mVtxData[mVtxCount++] = z; | 
|  | mVtxData[mVtxCount++] = 1.0f; | 
|  | latch(); | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Sets the texture coordinate for the vertices that are added after this method call. | 
|  | * | 
|  | * @param s texture coordinate s | 
|  | * @param t texture coordinate t | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | public TriangleMeshBuilder setTexture(float s, float t) { | 
|  | if ((mFlags & TEXTURE_0) == 0) { | 
|  | throw new IllegalStateException("add mistmatch with declared components."); | 
|  | } | 
|  | mS0 = s; | 
|  | mT0 = t; | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Sets the normal vector for the vertices that are added after this method call. | 
|  | * | 
|  | * @param x normal vector x | 
|  | * @param y normal vector y | 
|  | * @param z normal vector z | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | public TriangleMeshBuilder setNormal(float x, float y, float z) { | 
|  | if ((mFlags & NORMAL) == 0) { | 
|  | throw new IllegalStateException("add mistmatch with declared components."); | 
|  | } | 
|  | mNX = x; | 
|  | mNY = y; | 
|  | mNZ = z; | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Sets the color for the vertices that are added after this method call. | 
|  | * | 
|  | * @param r red component | 
|  | * @param g green component | 
|  | * @param b blue component | 
|  | * @param a alpha component | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | public TriangleMeshBuilder setColor(float r, float g, float b, float a) { | 
|  | if ((mFlags & COLOR) == 0) { | 
|  | throw new IllegalStateException("add mistmatch with declared components."); | 
|  | } | 
|  | mR = r; | 
|  | mG = g; | 
|  | mB = b; | 
|  | mA = a; | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Adds a new triangle to the mesh builder | 
|  | * | 
|  | * @param idx1 index of the first vertex in the triangle | 
|  | * @param idx2 index of the second vertex in the triangle | 
|  | * @param idx3 index of the third vertex in the triangle | 
|  | * | 
|  | * @return this | 
|  | **/ | 
|  | @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) | 
|  | public TriangleMeshBuilder addTriangle(int idx1, int idx2, int idx3) { | 
|  | if((idx1 >= mMaxIndex) || (idx1 < 0) || | 
|  | (idx2 >= mMaxIndex) || (idx2 < 0) || | 
|  | (idx3 >= mMaxIndex) || (idx3 < 0)) { | 
|  | throw new IllegalStateException("Index provided greater than vertex count."); | 
|  | } | 
|  | if ((mIndexCount + 3) >= mIndexData.length) { | 
|  | short t[] = new short[mIndexData.length * 2]; | 
|  | System.arraycopy(mIndexData, 0, t, 0, mIndexData.length); | 
|  | mIndexData = t; | 
|  | } | 
|  | mIndexData[mIndexCount++] = (short)idx1; | 
|  | mIndexData[mIndexCount++] = (short)idx2; | 
|  | mIndexData[mIndexCount++] = (short)idx3; | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * @deprecated in API 16 | 
|  | * Creates the mesh object from the current state of the builder | 
|  | * | 
|  | * @param uploadToBufferObject specifies whether the vertex data | 
|  | *                             is to be uploaded into the buffer | 
|  | *                             object indicating that it's likely | 
|  | *                             not going to be modified and | 
|  | *                             rendered many times. | 
|  | *                             Alternatively, it indicates the | 
|  | *                             mesh data will be updated | 
|  | *                             frequently and remain in script | 
|  | *                             accessible memory | 
|  | * | 
|  | **/ | 
|  | @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) | 
|  | public Mesh create(boolean uploadToBufferObject) { | 
|  | Element.Builder b = new Element.Builder(mRS); | 
|  | b.add(Element.createVector(mRS, | 
|  | Element.DataType.FLOAT_32, | 
|  | mVtxSize), "position"); | 
|  | if ((mFlags & COLOR) != 0) { | 
|  | b.add(Element.F32_4(mRS), "color"); | 
|  | } | 
|  | if ((mFlags & TEXTURE_0) != 0) { | 
|  | b.add(Element.F32_2(mRS), "texture0"); | 
|  | } | 
|  | if ((mFlags & NORMAL) != 0) { | 
|  | b.add(Element.F32_3(mRS), "normal"); | 
|  | } | 
|  | mElement = b.create(); | 
|  |  | 
|  | int usage = Allocation.USAGE_SCRIPT; | 
|  | if (uploadToBufferObject) { | 
|  | usage |= Allocation.USAGE_GRAPHICS_VERTEX; | 
|  | } | 
|  |  | 
|  | Builder smb = new Builder(mRS, usage); | 
|  | smb.addVertexType(mElement, mMaxIndex); | 
|  | smb.addIndexSetType(Element.U16(mRS), mIndexCount, Primitive.TRIANGLE); | 
|  |  | 
|  | Mesh sm = smb.create(); | 
|  |  | 
|  | sm.getVertexAllocation(0).copy1DRangeFromUnchecked(0, mMaxIndex, mVtxData); | 
|  | if(uploadToBufferObject) { | 
|  | sm.getVertexAllocation(0).syncAll(Allocation.USAGE_SCRIPT); | 
|  | } | 
|  |  | 
|  | sm.getIndexSetAllocation(0).copy1DRangeFromUnchecked(0, mIndexCount, mIndexData); | 
|  | if (uploadToBufferObject) { | 
|  | sm.getIndexSetAllocation(0).syncAll(Allocation.USAGE_SCRIPT); | 
|  | } | 
|  |  | 
|  | return sm; | 
|  | } | 
|  | } | 
|  | } | 
|  |  |