3.9 KiB
PinPoint (BowlEye)
An Android application for analyzing a bowler's approach and delivery form using on-device pose detection. The app captures video of a bowler via the phone camera, tracks body landmarks in real time, and surfaces step-count, joint-angle, and phase feedback to help improve technique.
See docs/ for the project proposal, architecture, and deliverables/ownership breakdown.
Tech stack
- Language: Kotlin (application/feature code), Java (legacy entry point), C++ (native game shell)
- Platform: Android (min SDK 24, target/compile SDK 36)
- Build system: Gradle (Kotlin DSL version catalog) + CMake 3.22.1 for the native module
- Key libraries: CameraX (capture), ML Kit Pose Detection — accurate model (landmark tracking), Kotlin Coroutines, AndroidX Lifecycle/ViewModel
Prerequisites
- Android Studio (current stable channel) — bundles a compatible JDK, so no separate JDK install is required
- Android SDK with:
- Android SDK Platform 36 (and 36.1)
- NDK (side by side) — a recent version compatible with AGP
- CMake 3.22.1
- Android SDK Build-Tools 36.0.0
- A physical Android device with a camera (recommended) or an emulator with a virtual/webcam camera. Real camera input is strongly recommended since pose detection needs an actual moving subject.
The NDK/CMake/platform components above do not need to be installed manually — both Android Studio's "install missing components" prompt and a plain
./gradlewcommand-line build will fetch them automatically on first sync/build, provided you have internet access and accept the SDK license prompts.
Getting started
Option A — Android Studio
File > Openand select the repository root.- Let Gradle sync; approve any "install missing SDK components" prompts.
- Connect a device (enable Developer Options > USB debugging on the phone) or start an emulator.
- Click Run ▶ with the
appconfiguration selected.
Option B — Command line
# Windows
.\gradlew.bat assembleDebug
.\gradlew.bat installDebug
# macOS / Linux
./gradlew assembleDebug
./gradlew installDebug
Then launch an activity directly, e.g.:
adb shell am start -n com.example.jnicpp/.MainActivity
adb shell am start -n com.example.jnicpp/.bowling.BowlingCameraActivity
First-time local setup notes
- Gradle needs a
local.propertiesfile at the repository root (not insideapp/) pointing at your local Android SDK, e.g.:Android Studio creates/updates this automatically on first sync. This file is machine-specific and is gitignored — never commit it.sdk.dir=/Users/you/Library/Android/sdk - The app requests Camera and Record Audio permissions at runtime; grant both to use the bowling analysis screen.
Project structure
app/
├── src/main/cpp/ # Native C++ game shell (OpenGL ES menu, JNI bridge), built via CMake
├── src/main/java/.../ # MainActivity (native GL menu host)
└── src/main/java/.../bowling/ # Bowling capture + pose analysis feature (Kotlin, CameraX + ML Kit)
docs/ # Proposal, architecture, design, and deliverables documentation
The native GL menu (MainActivity) and the bowling camera/pose-analysis screen (BowlingCameraActivity) are currently two independent entry points — see docs/architecture.md for how they're intended to connect.
Running tests
./gradlew test # JVM unit tests
./gradlew connectedCheck # Instrumented tests (requires a connected device/emulator)
Cross-platform notes
The native game-state code under app/src/main/cpp/my_gl_app/ is written behind a Platform.h seam with both PLATFORM_ANDROID and PLATFORM_WINDOWS (GLFW) code paths, so the menu/state-machine logic itself is portable. Only the Android (Gradle/CMake) build is wired up today; there is no standalone desktop build target yet.