/// <summary> /// Update the coordinates of hand skeleton points. /// </summary> private void UpdateHandSkeletonsData(float[] handSkeletons) { ShaderUtil.CheckGlError(TAG, "Update hand skeletons data start."); // Each point has a 3D coordinate. The total number of coordinates // is three times the number of skeleton points. int mPointsNum = handSkeletons.Length / 3; Log.Debug(TAG, "ARHand HandSkeletonNumber = " + mPointsNum); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo); mNumPoints = mPointsNum; if (mVboSize < mNumPoints * BYTES_PER_POINT) { while (mVboSize < mNumPoints * BYTES_PER_POINT) { // If the size of VBO is insufficient to accommodate the new point cloud, resize the VBO. mVboSize *= 2; } GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw); } FloatBuffer mSkeletonPoints = FloatBuffer.Wrap(handSkeletons); GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mNumPoints * BYTES_PER_POINT, mSkeletonPoints); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); ShaderUtil.CheckGlError(TAG, "Update hand skeletons data end."); }
/// <summary> /// Update the coordinates of the hand bounding box. /// </summary> /// <param name="gesturePoints">Gesture hand box data.</param> private void UpdateHandBoxData(float[] gesturePoints) { ShaderUtil.CheckGlError(TAG, "Update hand box data start."); float[] glGesturePoints = { // Get the four coordinates of a rectangular box bounding the hand. gesturePoints[0], gesturePoints[1], gesturePoints[2], gesturePoints[3], gesturePoints[1], gesturePoints[2], gesturePoints[3], gesturePoints[4], gesturePoints[5], gesturePoints[0], gesturePoints[4], gesturePoints[5], }; int gesturePointsNum = glGesturePoints.Length / COORDINATE_DIMENSION; GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo); mNumPoints = gesturePointsNum; if (mVboSize < mNumPoints * BYTES_PER_POINT) { while (mVboSize < mNumPoints * BYTES_PER_POINT) { // If the size of VBO is insufficient to accommodate the new point cloud, resize the VBO. mVboSize *= 2; } GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw); } Log.Debug(TAG, "gesture.getGestureHandPointsNum()" + mNumPoints); FloatBuffer mVertices = FloatBuffer.Wrap(glGesturePoints); GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mNumPoints * BYTES_PER_POINT, mVertices); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); ShaderUtil.CheckGlError(TAG, "Update hand box data end."); }
/// <summary> /// This method updates the connection data of skeleton points and is called when any frame is updated. /// </summary> /// <param name="handSkeletons">Bone point data of hand.</param> /// <param name="handSkeletonConnection">Data of connection between bone points of hand.</param> private void UpdateHandSkeletonLinesData(float[] handSkeletons, int[] handSkeletonConnection) { ShaderUtil.CheckGlError(TAG, "Update hand skeleton lines data start."); int pointsLineNum = 0; // Each point is a set of 3D coordinate. Each connection line consists of two points. float[] linePoint = new float[handSkeletonConnection.Length * 3 * 2]; // The format of HandSkeletonConnection data is [p0,p1;p0,p3;p0,p5;p1,p2]. // handSkeletonConnection saves the node indexes. Two indexes obtain a set // of connection point data. Therefore, j = j + 2. This loop obtains related // coordinates and saves them in linePoint. for (int j = 0; j < handSkeletonConnection.Length; j += 2) { linePoint[pointsLineNum * 3] = handSkeletons[3 * handSkeletonConnection[j]]; linePoint[pointsLineNum * 3 + 1] = handSkeletons[3 * handSkeletonConnection[j] + 1]; linePoint[pointsLineNum * 3 + 2] = handSkeletons[3 * handSkeletonConnection[j] + 2]; linePoint[pointsLineNum * 3 + 3] = handSkeletons[3 * handSkeletonConnection[j + 1]]; linePoint[pointsLineNum * 3 + 4] = handSkeletons[3 * handSkeletonConnection[j + 1] + 1]; linePoint[pointsLineNum * 3 + 5] = handSkeletons[3 * handSkeletonConnection[j + 1] + 2]; pointsLineNum += 2; } GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo); mPointsNum = pointsLineNum; // If the storage space is insufficient, apply for twice the memory each time. if (mVboSize < mPointsNum * BYTES_PER_POINT) { while (mVboSize < mPointsNum * BYTES_PER_POINT) { mVboSize *= 2; } GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw); } FloatBuffer linePoints = FloatBuffer.Wrap(linePoint); Log.Debug(TAG, "Skeleton skeleton line points num: " + mPointsNum); Log.Debug(TAG, "Skeleton line points: " + linePoints.ToString()); GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mPointsNum * BYTES_PER_POINT, linePoints); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); ShaderUtil.CheckGlError(TAG, "Update hand skeleton lines data end."); }
private void FindValidSkeletonPoints(ARBody arBody) { int index = 0; int[] isExists; int validPointNum = 0; float[] points; float[] skeletonPoints; // Determine whether the data returned by the algorithm is 3D human // skeleton data or 2D human skeleton data, and obtain valid skeleton points. if (arBody.CoordinateSystemType == ARCoordinateSystemType.CoordinateSystemType3dCamera) { isExists = arBody.GetSkeletonPointIsExist3D(); points = new float[isExists.Length * 3]; skeletonPoints = arBody.GetSkeletonPoint3D(); } else { isExists = arBody.GetSkeletonPointIsExist2D(); points = new float[isExists.Length * 3]; skeletonPoints = arBody.GetSkeletonPoint2D(); } // Save the three coordinates of each joint point(each point has three coordinates). for (int i = 0; i < isExists.Length; i++) { if (isExists[i] != 0) { points[index++] = skeletonPoints[3 * i]; points[index++] = skeletonPoints[3 * i + 1]; points[index++] = skeletonPoints[3 * i + 2]; validPointNum++; } } mSkeletonPoints = FloatBuffer.Wrap(points); mPointsNum = validPointNum; }
private void FindValidConnectionSkeletonLines(ARBody arBody) { mPointsLineNum = 0; int[] connections = arBody.GetBodySkeletonConnection(); float[] linePoints = new float[LINE_POINT_RATIO * connections.Length]; float[] coors; int[] isExists; if (arBody.CoordinateSystemType == ARCoordinateSystemType.CoordinateSystemType3dCamera) { coors = arBody.GetSkeletonPoint3D(); isExists = arBody.GetSkeletonPointIsExist3D(); } else { coors = arBody.GetSkeletonPoint2D(); isExists = arBody.GetSkeletonPointIsExist2D(); } // Filter out valid skeleton connection lines based on the returned results, // which consist of indexes of two ends, for example, [p0,p1;p0,p3;p0,p5;p1,p2]. // The loop takes out the 3D coordinates of the end points of the valid connection // line and saves them in sequence. for (int j = 0; j < connections.Length; j += 2) { if (isExists[connections[j]] != 0 && isExists[connections[j + 1]] != 0) { linePoints[mPointsLineNum * 3] = coors[3 * connections[j]]; linePoints[mPointsLineNum * 3 + 1] = coors[3 * connections[j] + 1]; linePoints[mPointsLineNum * 3 + 2] = coors[3 * connections[j] + 2]; linePoints[mPointsLineNum * 3 + 3] = coors[3 * connections[j + 1]]; linePoints[mPointsLineNum * 3 + 4] = coors[3 * connections[j + 1] + 1]; linePoints[mPointsLineNum * 3 + 5] = coors[3 * connections[j + 1] + 2]; mPointsLineNum += 2; } } mLinePoints = FloatBuffer.Wrap(linePoints); }