Phase 1 complete. build Ok, apk OK
Signed-off-by: chaoq <chaoq@gxtech.ltd>
This commit is contained in:
@@ -25,6 +25,14 @@ object NetworkModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGxrtcApi(retrofit: Retrofit): GxrtcApi = retrofit.create(GxrtcApi::class.java)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideArAnnotationApi(retrofit: Retrofit): ArAnnotationApi = retrofit.create(ArAnnotationApi::class.java)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFeaturePointApi(retrofit: Retrofit): FeaturePointApi = retrofit.create(FeaturePointApi::class.java)
|
||||
}
|
||||
|
||||
// data/remote/GxrtcApi.kt - 新增
|
||||
@@ -44,6 +52,128 @@ interface GxrtcApi {
|
||||
suspend fun getRooms(): Response<GxrtcResponse<List<RoomResponse>>>
|
||||
}
|
||||
|
||||
// data/remote/ArAnnotationApi.kt - 新增
|
||||
interface ArAnnotationApi {
|
||||
@POST("ar/anchor/save")
|
||||
suspend fun saveAnchor(@Body request: SaveAnchorRequest): Response<GxrtcResponse<Unit>>
|
||||
|
||||
@GET("ar/room/{roomId}/anchors")
|
||||
suspend fun getRoomAnchors(@Path("roomId") roomId: String): Response<GxrtcResponse<AnchorListResponse>>
|
||||
|
||||
@POST("ar/annotation/save")
|
||||
suspend fun saveAnnotation(@Body annotation: ArAnnotation): Response<GxrtcResponse<Unit>>
|
||||
|
||||
@GET("ar/room/{roomId}/annotations")
|
||||
suspend fun getRoomAnnotations(@Path("roomId") roomId: String): Response<GxrtcResponse<AnnotationListResponse>>
|
||||
|
||||
@DELETE("ar/annotation/{annotationId}")
|
||||
suspend fun deleteAnnotation(@Path("annotationId") annotationId: String): Response<GxrtcResponse<Unit>>
|
||||
|
||||
@POST("ar/spatial/validate")
|
||||
suspend fun validateSpatialConsistency(@Body request: SpatialValidationRequest): Response<GxrtcResponse<SpatialValidationResult>>
|
||||
|
||||
@POST("ar/annotations/version")
|
||||
suspend fun createAnnotationVersion(@Body request: CreateVersionRequest): Response<GxrtcResponse<VersionResponse>>
|
||||
|
||||
@GET("ar/annotations/{roomId}/versions")
|
||||
suspend fun getAnnotationVersions(@Path("roomId") roomId: String): Response<GxrtcResponse<List<VersionResponse>>>
|
||||
}
|
||||
|
||||
// data/remote/FeaturePointApi.kt - 新增
|
||||
interface FeaturePointApi {
|
||||
@POST("ar/feature-points/save")
|
||||
suspend fun saveFeaturePoints(@Body request: SaveFeaturePointsRequest): Response<GxrtcResponse<Unit>>
|
||||
|
||||
@GET("ar/feature-points/{anchorId}")
|
||||
suspend fun getAnchorFeatures(@Path("anchorId") anchorId: String): Response<GxrtcResponse<FeaturePointListResponse>>
|
||||
|
||||
@POST("ar/feature-points/match")
|
||||
suspend fun matchFeaturePoints(@Body request: FeatureMatchRequest): Response<GxrtcResponse<FeatureMatchResponse>>
|
||||
|
||||
@POST("ar/feature-points/quality-assessment")
|
||||
suspend fun assessFeatureQuality(@Body request: FeatureQualityRequest): Response<GxrtcResponse<FeatureQualityResponse>>
|
||||
}
|
||||
|
||||
// 请求和响应数据模型
|
||||
data class SaveAnchorRequest(
|
||||
val roomId: String,
|
||||
val anchorId: String,
|
||||
val position: List<Float>,
|
||||
val rotation: List<Float>,
|
||||
val createdBy: String
|
||||
)
|
||||
|
||||
data class AnchorListResponse(val anchors: List<AnchorData>)
|
||||
|
||||
data class AnnotationListResponse(val annotations: List<ArAnnotation>)
|
||||
|
||||
data class SaveFeaturePointsRequest(
|
||||
val anchorId: String,
|
||||
val roomId: String,
|
||||
val featurePoints: List<FeaturePoint>,
|
||||
val deviceInfo: DeviceInfo
|
||||
)
|
||||
|
||||
data class FeaturePointListResponse(val featurePoints: List<FeaturePoint>)
|
||||
|
||||
data class SpatialValidationRequest(
|
||||
val anchorId: String,
|
||||
val currentPosition: List<Float>,
|
||||
val currentRotation: List<Float>,
|
||||
val deviceInfo: DeviceInfo
|
||||
)
|
||||
|
||||
data class SpatialValidationResult(
|
||||
val isValid: Boolean,
|
||||
val confidence: Float,
|
||||
val suggestedCorrection: SpatialTransform?,
|
||||
val errorMessage: String?
|
||||
)
|
||||
|
||||
data class FeatureMatchRequest(
|
||||
val anchorId: String,
|
||||
val queryFeatures: List<FeaturePoint>,
|
||||
val maxResults: Int = 10
|
||||
)
|
||||
|
||||
data class FeatureMatchResponse(
|
||||
val matches: List<FeatureMatch>,
|
||||
val confidence: Float
|
||||
)
|
||||
|
||||
data class FeatureMatch(
|
||||
val featurePoint: FeaturePoint,
|
||||
val similarity: Float,
|
||||
val spatialDistance: Float
|
||||
)
|
||||
|
||||
data class FeatureQualityRequest(
|
||||
val anchorId: String,
|
||||
val featurePoints: List<FeaturePoint>
|
||||
)
|
||||
|
||||
data class FeatureQualityResponse(
|
||||
val overallQuality: Float,
|
||||
val individualScores: Map<String, Float>,
|
||||
val recommendations: List<String>
|
||||
)
|
||||
|
||||
data class CreateVersionRequest(
|
||||
val roomId: String,
|
||||
val versionName: String,
|
||||
val description: String,
|
||||
val createdBy: String
|
||||
)
|
||||
|
||||
data class VersionResponse(
|
||||
val versionId: String,
|
||||
val versionName: String,
|
||||
val description: String,
|
||||
val createdAt: Long,
|
||||
val createdBy: String,
|
||||
val annotationCount: Int
|
||||
)
|
||||
|
||||
// 响应数据结构
|
||||
data class GxrtcResponse<T>(
|
||||
@SerializedName("meta") val meta: Meta,
|
||||
@@ -423,35 +553,53 @@ data class AnchorData(
|
||||
)
|
||||
```
|
||||
|
||||
#### 4.2 AR标注持久化服务
|
||||
#### 4.2 AR标注持久化服务(增强版)
|
||||
```kotlin
|
||||
// domain/service/ArAnnotationService.kt - 新增
|
||||
class ArAnnotationService @Inject constructor(
|
||||
private val arAnnotationApi: ArAnnotationApi
|
||||
private val arAnnotationApi: ArAnnotationApi,
|
||||
private val featurePointApi: FeaturePointApi,
|
||||
private val userRepository: UserRepository
|
||||
) {
|
||||
suspend fun saveAnchor(
|
||||
suspend fun saveAnchorWithFeatures(
|
||||
roomId: String,
|
||||
anchorId: String,
|
||||
position: Pose
|
||||
position: Pose,
|
||||
featurePoints: List<FeaturePoint>,
|
||||
deviceInfo: DeviceInfo
|
||||
): Result<Unit> {
|
||||
return try {
|
||||
val request = SaveAnchorRequest(
|
||||
// 保存锚点基本信息
|
||||
val anchorRequest = SaveAnchorRequest(
|
||||
roomId = roomId,
|
||||
anchorId = anchorId,
|
||||
position = listOf(position.tx(), position.ty(), position.tz()),
|
||||
rotation = listOf(position.qx(), position.qy(), position.qz(), position.qw()),
|
||||
createdBy = currentUserId
|
||||
createdBy = userRepository.getCurrentUser()?.id ?: ""
|
||||
)
|
||||
arAnnotationApi.saveAnchor(anchorRequest)
|
||||
|
||||
// 保存特征点数据
|
||||
val featureRequest = SaveFeaturePointsRequest(
|
||||
anchorId = anchorId,
|
||||
roomId = roomId,
|
||||
featurePoints = featurePoints,
|
||||
deviceInfo = deviceInfo
|
||||
)
|
||||
featurePointApi.saveFeaturePoints(featureRequest)
|
||||
|
||||
arAnnotationApi.saveAnchor(request)
|
||||
Result.success(Unit)
|
||||
} catch (e: Exception) {
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun loadRoomAnchors(roomId: String): List<AnchorData> {
|
||||
return arAnnotationApi.getRoomAnchors(roomId).anchors
|
||||
suspend fun loadRoomAnchorsWithFeatures(roomId: String): List<AnchorWithFeatures> {
|
||||
val anchors = arAnnotationApi.getRoomAnchors(roomId).anchors
|
||||
return anchors.map { anchor ->
|
||||
val features = featurePointApi.getAnchorFeatures(anchor.anchorId).featurePoints
|
||||
AnchorWithFeatures(anchor, features)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun saveAnnotation(annotation: ArAnnotation): Result<Unit> {
|
||||
@@ -466,9 +614,59 @@ class ArAnnotationService @Inject constructor(
|
||||
suspend fun loadRoomAnnotations(roomId: String): List<ArAnnotation> {
|
||||
return arAnnotationApi.getRoomAnnotations(roomId).annotations
|
||||
}
|
||||
|
||||
suspend fun validateSpatialConsistency(
|
||||
anchorId: String,
|
||||
currentPose: Pose,
|
||||
deviceInfo: DeviceInfo
|
||||
): Result<SpatialValidationResult> {
|
||||
return try {
|
||||
val request = SpatialValidationRequest(
|
||||
anchorId = anchorId,
|
||||
currentPosition = listOf(currentPose.tx(), currentPose.ty(), currentPose.tz()),
|
||||
currentRotation = listOf(currentPose.qx(), currentPose.qy(), currentPose.qz(), currentPose.qw()),
|
||||
deviceInfo = deviceInfo
|
||||
)
|
||||
val result = arAnnotationApi.validateSpatialConsistency(request)
|
||||
Result.success(result)
|
||||
} catch (e: Exception) {
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// data/model/ArAnnotation.kt - 新增
|
||||
// 数据模型增强
|
||||
data class AnchorWithFeatures(
|
||||
val anchor: AnchorData,
|
||||
val featurePoints: List<FeaturePoint>
|
||||
)
|
||||
|
||||
data class FeaturePoint(
|
||||
val position: List<Float>,
|
||||
val descriptor: String, // base64编码的特征描述符
|
||||
val qualityScore: Float,
|
||||
val timestamp: Long = System.currentTimeMillis()
|
||||
)
|
||||
|
||||
data class DeviceInfo(
|
||||
val model: String,
|
||||
val arCoreVersion: String,
|
||||
val cameraCalibration: CameraCalibration?,
|
||||
val imuCalibration: ImuCalibration?
|
||||
)
|
||||
|
||||
data class CameraCalibration(
|
||||
val focalLength: List<Float>,
|
||||
val principalPoint: List<Float>,
|
||||
val distortionCoefficients: List<Float>?
|
||||
)
|
||||
|
||||
data class ImuCalibration(
|
||||
val gyroBias: List<Float>?,
|
||||
val accelBias: List<Float>?,
|
||||
val magnetometerBias: List<Float>?
|
||||
)
|
||||
|
||||
data class ArAnnotation(
|
||||
val id: String,
|
||||
val anchorId: String,
|
||||
@@ -478,12 +676,21 @@ data class ArAnnotation(
|
||||
val size: Float,
|
||||
val roomId: String,
|
||||
val createdBy: String,
|
||||
val spatialTransform: SpatialTransform? = null,
|
||||
val createdAt: Long = System.currentTimeMillis(),
|
||||
val updatedAt: Long = System.currentTimeMillis()
|
||||
val updatedAt: Long = System.currentTimeMillis(),
|
||||
val version: Int = 1
|
||||
)
|
||||
|
||||
data class SpatialTransform(
|
||||
val position: List<Float>,
|
||||
val rotation: List<Float>,
|
||||
val scale: List<Float>,
|
||||
val confidence: Float
|
||||
)
|
||||
|
||||
enum class AnnotationType {
|
||||
ARROW, CIRCLE, RECTANGLE, TEXT, HIGHLIGHT
|
||||
ARROW, CIRCLE, RECTANGLE, TEXT, HIGHLIGHT, MEASUREMENT, NOTE
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1025,6 +1232,139 @@ GET /ar/analytics/accuracy?room_id={roomId}
|
||||
GET /ar/analytics/compatibility
|
||||
```
|
||||
|
||||
### 7. 特征点管理API(关键补充)
|
||||
```kotlin
|
||||
// 保存ARCore特征点数据
|
||||
POST /ar/feature-points/save
|
||||
Content-Type: application/json
|
||||
{
|
||||
"anchor_id": "string",
|
||||
"room_id": "string",
|
||||
"feature_points": [
|
||||
{
|
||||
"position": [0.0, 0.0, 0.0],
|
||||
"descriptor": "base64_encoded_descriptor",
|
||||
"quality_score": 0.95
|
||||
}
|
||||
],
|
||||
"device_info": {
|
||||
"model": "Pixel 6",
|
||||
"ar_core_version": "1.50.0",
|
||||
"camera_calibration": {
|
||||
"focal_length": [1000.0, 1000.0],
|
||||
"principal_point": [500.0, 500.0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取特征点数据用于重定位
|
||||
GET /ar/feature-points/{anchorId}
|
||||
|
||||
// 批量特征点匹配(跨设备空间对齐)
|
||||
POST /ar/feature-points/match
|
||||
{
|
||||
"anchor_id": "string",
|
||||
"query_features": [
|
||||
{
|
||||
"position": [0.0, 0.0, 0.0],
|
||||
"descriptor": "base64_encoded_descriptor"
|
||||
}
|
||||
],
|
||||
"max_results": 10
|
||||
}
|
||||
|
||||
// 特征点质量评估
|
||||
POST /ar/feature-points/quality-assessment
|
||||
{
|
||||
"anchor_id": "string",
|
||||
"feature_points": [
|
||||
{
|
||||
"position": [0.0, 0.0, 0.0],
|
||||
"descriptor": "base64_encoded_descriptor"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 8. 空间一致性验证API
|
||||
```kotlin
|
||||
// 空间坐标转换验证
|
||||
POST /ar/spatial/validate-transform
|
||||
{
|
||||
"source_anchor": "anchor_123",
|
||||
"target_anchor": "anchor_456",
|
||||
"transform_matrix": [
|
||||
[1.0, 0.0, 0.0, 0.0],
|
||||
[0.0, 1.0, 0.0, 0.0],
|
||||
[0.0, 0.0, 1.0, 0.0],
|
||||
[1.5, 2.0, 0.5, 1.0]
|
||||
],
|
||||
"confidence": 0.92
|
||||
}
|
||||
|
||||
// 多设备空间对齐状态
|
||||
GET /ar/spatial/alignment-status?room_id={roomId}
|
||||
|
||||
// 强制空间重新对齐
|
||||
POST /ar/spatial/realign
|
||||
{
|
||||
"room_id": "string",
|
||||
"anchor_ids": ["anchor1", "anchor2", "anchor3"]
|
||||
}
|
||||
```
|
||||
|
||||
### 9. 标注版本管理API
|
||||
```kotlin
|
||||
// 创建标注版本
|
||||
POST /ar/annotations/version
|
||||
{
|
||||
"room_id": "string",
|
||||
"version_name": "v1.0",
|
||||
"description": "初始标注版本",
|
||||
"created_by": "user123"
|
||||
}
|
||||
|
||||
// 获取标注版本历史
|
||||
GET /ar/annotations/{roomId}/versions
|
||||
|
||||
// 恢复到特定版本
|
||||
POST /ar/annotations/{roomId}/restore/{versionId}
|
||||
|
||||
// 标注差异比较
|
||||
GET /ar/annotations/{roomId}/diff?version1={v1}&version2={v2}
|
||||
```
|
||||
|
||||
### 10. 设备性能优化API
|
||||
```kotlin
|
||||
// 设备性能基准上报
|
||||
POST /ar/device/performance
|
||||
{
|
||||
"device_model": "Pixel 6",
|
||||
"ar_core_version": "1.50.0",
|
||||
"performance_metrics": {
|
||||
"frame_rate": 60.0,
|
||||
"tracking_quality": 0.95,
|
||||
"memory_usage": 256,
|
||||
"battery_drain": 15.0
|
||||
},
|
||||
"recommended_settings": {
|
||||
"max_annotations": 50,
|
||||
"feature_point_density": 0.8,
|
||||
"texture_quality": "medium"
|
||||
}
|
||||
}
|
||||
|
||||
// 获取设备优化配置
|
||||
GET /ar/device/{deviceModel}/optimization
|
||||
|
||||
// 性能问题诊断
|
||||
POST /ar/device/diagnose
|
||||
{
|
||||
"device_info": {...},
|
||||
"performance_issues": ["low_framerate", "high_memory"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 阶段8:优化和兼容性(增强版)
|
||||
|
||||
1940
docs/ui.html
1940
docs/ui.html
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user