Beispiel #1
0
        /**
         * Updates the plane model transform matrix and extents.
         */
        private void updatePlaneParameters(float[] planeMatrix, float extentX, float extentZ,
                                           FloatBuffer boundary)
        {
            Array.Copy(planeMatrix, 0, mModelMatrix, 0, 16);
            if (boundary == null)
            {
                mVertexBuffer.Limit(0);
                mIndexBuffer.Limit(0);
                return;
            }

            // Generate a new set of vertices and a corresponding triangle strip index set so that
            // the plane boundary polygon has a fading edge. This is done by making a copy of the
            // boundary polygon vertices and scaling it down around center to push it inwards. Then
            // the index buffer is setup accordingly.
            boundary.Rewind();
            int boundaryVertices = boundary.Limit() / 2;
            int numVertices;
            int numIndices;

            numVertices = boundaryVertices * VERTS_PER_BOUNDARY_VERT;
            // drawn as GL_TRIANGLE_STRIP with 3n-2 triangles (n-2 for fill, 2n for perimeter).
            numIndices = boundaryVertices * INDICES_PER_BOUNDARY_VERT;

            if (mVertexBuffer.Capacity() < numVertices * COORDS_PER_VERTEX)
            {
                int size = mVertexBuffer.Capacity();
                while (size < numVertices * COORDS_PER_VERTEX)
                {
                    size *= 2;
                }
                mVertexBuffer = ByteBuffer.AllocateDirect(BYTES_PER_FLOAT * size)
                                .Order(ByteOrder.NativeOrder()).AsFloatBuffer();
            }
            mVertexBuffer.Rewind();
            mVertexBuffer.Limit(numVertices * COORDS_PER_VERTEX);


            if (mIndexBuffer.Capacity() < numIndices)
            {
                int size = mIndexBuffer.Capacity();
                while (size < numIndices)
                {
                    size *= 2;
                }
                mIndexBuffer = ByteBuffer.AllocateDirect(BYTES_PER_SHORT * size)
                               .Order(ByteOrder.NativeOrder()).AsShortBuffer();
            }
            mIndexBuffer.Rewind();
            mIndexBuffer.Limit(numIndices);

            // Note: when either dimension of the bounding box is smaller than 2*FADE_RADIUS_M we
            // generate a bunch of 0-area triangles.  These don't get rendered though so it works
            // out ok.
            float xScale = Math.Max((extentX - 2 * FADE_RADIUS_M) / extentX, 0.0f);
            float zScale = Math.Max((extentZ - 2 * FADE_RADIUS_M) / extentZ, 0.0f);

            while (boundary.HasRemaining)
            {
                float x = boundary.Get();
                float z = boundary.Get();
                mVertexBuffer.Put(x);
                mVertexBuffer.Put(z);
                mVertexBuffer.Put(0.0f);
                mVertexBuffer.Put(x * xScale);
                mVertexBuffer.Put(z * zScale);
                mVertexBuffer.Put(1.0f);
            }

            // step 1, perimeter
            mIndexBuffer.Put((short)((boundaryVertices - 1) * 2));
            for (int i = 0; i < boundaryVertices; ++i)
            {
                mIndexBuffer.Put((short)(i * 2));
                mIndexBuffer.Put((short)(i * 2 + 1));
            }
            mIndexBuffer.Put((short)1);
            // This leaves us on the interior edge of the perimeter between the inset vertices
            // for boundary verts n-1 and 0.

            // step 2, interior:
            for (int i = 1; i < boundaryVertices / 2; ++i)
            {
                mIndexBuffer.Put((short)((boundaryVertices - 1 - i) * 2 + 1));
                mIndexBuffer.Put((short)(i * 2 + 1));
            }
            if (boundaryVertices % 2 != 0)
            {
                mIndexBuffer.Put((short)((boundaryVertices / 2) * 2 + 1));
            }
        }