Step counter test1

This commit is contained in:
2026-08-14 18:16:55 +08:00
parent 5d07c8c8bd
commit 905400a59a
17 changed files with 1397 additions and 136 deletions
@@ -1,3 +1,7 @@
/**
* @file PoseOverlayView.kt
* @brief Live on-screen View that draws the pose skeleton and angle labels over the camera preview.
*/
package com.example.jnicpp.bowling
import android.content.Context
@@ -10,12 +14,16 @@ import androidx.core.content.ContextCompat
import com.example.jnicpp.R
/**
* Draws the 33 ML Kit pose landmarks and connecting skeleton lines on top of
* the camera preview. The landmark topology and the coordinate mapping math
* (analysis-image pixels -> view pixels, replicating `PreviewView`'s
* `FILL_CENTER` scaling) live in [PoseSkeletonRenderer], shared with
* [CameraXController]'s baked-into-the-recorded-video overlay so both paths
* can't drift apart.
* @brief Draws the 33 ML Kit pose landmarks and connecting skeleton lines
* on top of the camera preview.
*
* The landmark topology and the coordinate mapping math (analysis-image
* pixels -> view pixels, replicating `PreviewView`'s `FILL_CENTER` scaling)
* live in [PoseSkeletonRenderer], shared with [CameraXController]'s
* baked-into-the-recorded-video overlay so both paths can't drift apart.
*
* @param context Android context, as required by [View]'s constructor.
* @param attrs XML attribute set, as required by [View]'s constructor; null when constructed in code.
*/
class PoseOverlayView @JvmOverloads constructor(
context: Context,
@@ -55,7 +63,11 @@ class PoseOverlayView @JvmOverloads constructor(
private var transform = Matrix()
/** Called from the main thread with the latest analyzer result, or null to clear. */
/**
* @brief Updates the view with the latest analyzer result and triggers a redraw.
* @param frame The latest analyzer result to draw, or null to clear the overlay.
* Called from the main thread.
*/
fun update(frame: PoseAnalyzer.PoseFrameResult?) {
landmarks = frame?.landmarks
angles = frame?.angles
@@ -69,17 +81,26 @@ class PoseOverlayView @JvmOverloads constructor(
invalidate()
}
/** @brief Clears the drawn skeleton/angles and triggers a redraw. */
fun clear() {
landmarks = null
angles = null
invalidate()
}
/**
* @brief Recomputes the source-to-view coordinate transform whenever the view's own size changes.
* @param w New view width, in pixels.
* @param h New view height, in pixels.
* @param oldw Previous view width, in pixels.
* @param oldh Previous view height, in pixels.
*/
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
recomputeTransform()
}
/** @brief Rebuilds [transform] from the current source image size/rotation and this view's current size. */
private fun recomputeTransform() {
transform = PoseSkeletonRenderer.computeTransform(
sourceWidth = sourceWidth,
@@ -93,6 +114,10 @@ class PoseOverlayView @JvmOverloads constructor(
)
}
/**
* @brief Draws the skeleton and angle labels for the most recent [update] call, if any.
* @param canvas Canvas supplied by the View system to draw onto.
*/
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
val currentLandmarks = landmarks ?: return