From 40ae4e4361196ac45bac467e1539d9c1797b4089 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sat, 17 Jan 2026 08:48:43 +0100 Subject: [PATCH] update docs --- CLAUDE.md | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 105b4a5..2da146d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -517,3 +517,212 @@ RMLUI: goBack called (history depth: 1) Loading screen: apps/home/home.rml RMLUI: Back to: home ``` + +## Documentation Guidelines + +**IMPORTANT**: Always document progress and new commands to avoid rediscovery. + +### Where to Put Documentation + +| Content Type | Location | +|--------------|----------| +| General concepts, architecture | `MosisService/CLAUDE.md` (this file) | +| Unreal plugin docs | `MosisUnreal/Plugins/MosisSDK/README.md` | +| Unity package docs | `MosisVR/Packages/com.omarator.mosissdk/README.md` | +| Project-specific build commands | Each project's own docs | + +**DO NOT** put documentation in the root `D:\Dev\Mosis\` directory - it is not versioned. + +### What to Document + +1. **Build commands** - Every new build command discovered or created +2. **Environment setup** - Required environment variables, SDK versions +3. **Architecture decisions** - Why something was done a certain way +4. **Issues and solutions** - Problems encountered and how they were fixed +5. **File locations** - Where important files are and what they do + +### When to Document + +- After completing a milestone or feature +- When discovering new build commands +- When fixing a non-obvious issue +- When adding new dependencies or requirements + +## Game Engine Integrations + +MosisService provides a virtual phone that game engines can display and interact with. + +### Integration Architecture + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ MosisService │ +│ (OpenGL ES rendering → AHardwareBuffer) │ +└───────────────────────────┬─────────────────────────────────────┘ + │ Binder IPC + Shared Memory + ┌─────────────────┴─────────────────┐ + ▼ ▼ +┌─────────────────────┐ ┌─────────────────────┐ +│ MosisUnreal │ │ MosisVR │ +│ (UE5.5 Plugin) │ │ (Unity Package) │ +│ Vulkan Import │ │ Vulkan/OpenGL │ +└─────────────────────┘ └─────────────────────┘ +``` + +### MosisUnreal (Unreal Engine 5.5) + +**Location**: `D:\Dev\Mosis\MosisUnreal\Plugins\MosisSDK\` + +#### Build Commands + +```batch +:: Windows Editor Build +"D:\Epic\UE_5.5\Engine\Build\BatchFiles\Build.bat" ^ + MosisUnrealEditor Win64 Development ^ + -Project="D:\Dev\Mosis\MosisUnreal\MosisUnreal.uproject" + +:: Android APK Build +"D:\Epic\UE_5.5\Engine\Build\BatchFiles\RunUAT.bat" ^ + BuildCookRun ^ + -project="D:\Dev\Mosis\MosisUnreal\MosisUnreal.uproject" ^ + -platform=Android -clientconfig=Development ^ + -build -cook -stage -pak -package -noP4 + +:: Clean Build (delete these folders first) +rmdir /s /q "Intermediate\Build" +rmdir /s /q "Binaries" +``` + +#### Output Files + +| Build | Output | +|-------|--------| +| Windows Editor | `Plugins/MosisSDK/Binaries/Win64/UnrealEditor-MosisSDK.dll` | +| Android | `Binaries/Android/MosisUnreal-arm64.apk` | + +#### Requirements + +- Android SDK Platform 36 (for AIDL binder headers) +- Android Build Tools 36.1.0 (for AIDL compiler) +- `ANDROID_HOME` environment variable set + +### MosisVR (Unity 6000.3.2f1) + +**Location**: `D:\Dev\Mosis\MosisVR\Packages\com.omarator.mosissdk\` + +#### Build Commands + +Build via Unity Editor: +1. File > Build Settings +2. Switch Platform to Android +3. Player Settings > Graphics APIs: Vulkan + OpenGLES3 +4. Build and Run + +#### Native Plugin Build + +```batch +:: From Plugins/Android/cpp/ +cmake -B build -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK_HOME%/build/cmake/android.toolchain.cmake ^ + -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-29 +cmake --build build +``` + +### Device Testing (Both Engines) + +```bash +# Install MosisService first +adb install -r MosisService-debug.apk + +# Install game client +adb install -r MosisUnreal-arm64.apk # or MosisVR.apk + +# Launch service +adb shell am start -n com.omixlab.mosis/.MainActivity + +# Launch client +adb shell am start -n com.omixlab.MosisUnreal/com.epicgames.unreal.GameActivity +# or for Unity: +adb shell am start -n com.omixlab.mosisvr/com.unity3d.player.UnityPlayerActivity + +# Monitor all Mosis logs +adb logcat -s MosisSDK MosisTest RMLUI Vulkan +``` + +## Vulkan HardwareBuffer Import + +Both game engines use Vulkan to import AHardwareBuffer from MosisService. + +### Required Vulkan Extensions + +``` +VK_ANDROID_external_memory_android_hardware_buffer +VK_KHR_external_memory +VK_KHR_dedicated_allocation +``` + +### Import Pattern + +```cpp +// 1. Query buffer properties +VkAndroidHardwareBufferPropertiesANDROID props = { + .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID +}; +VkAndroidHardwareBufferFormatPropertiesANDROID formatProps = { + .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID +}; +props.pNext = &formatProps; +vkGetAndroidHardwareBufferPropertiesANDROID(device, buffer, &props); + +// 2. Create image with external memory +VkExternalMemoryImageCreateInfo extInfo = { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID +}; + +AHardwareBuffer_Desc desc; +AHardwareBuffer_describe(buffer, &desc); + +VkImageCreateInfo imageInfo = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = &extInfo, + .imageType = VK_IMAGE_TYPE_2D, + .format = formatProps.format, + .extent = {desc.width, desc.height, 1}, + .mipLevels = 1, + .arrayLayers = 1, + .samples = VK_SAMPLE_COUNT_1_BIT, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE +}; +vkCreateImage(device, &imageInfo, nullptr, &image); + +// 3. Import memory from HardwareBuffer +VkImportAndroidHardwareBufferInfoANDROID importInfo = { + .sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID, + .buffer = buffer +}; + +VkMemoryDedicatedAllocateInfo dedicatedInfo = { + .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, + .pNext = &importInfo, + .image = image +}; + +VkMemoryAllocateInfo allocInfo = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .pNext = &dedicatedInfo, + .allocationSize = props.allocationSize, + .memoryTypeIndex = FindMemoryType(props.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) +}; +vkAllocateMemory(device, &allocInfo, nullptr, &memory); +vkBindImageMemory(device, image, memory, 0); +``` + +### Synchronization + +Currently using CPU synchronization (`vkQueueWaitIdle` / `glFinish`). Future improvement: use Vulkan semaphores for GPU-GPU sync. + +### Double Buffering + +The imported image is copied to a local texture each frame to prevent data races with MosisService rendering.