Files
RuView/integrations/iphone-lidar/native/RuViewLiDAR/RuViewFrame.swift
rUv 0df48df7b2 feat: add native iPhone LiDAR sensor and web viewer (#1684)
* feat(ios): add RuView LiDAR frame protocol

* feat(ios): capture ARKit scene depth for RuView

* feat(ios): stream compact LiDAR frames over websocket

* feat(ios): add native LiDAR capture UI

* feat(ios): add RuView LiDAR app entrypoint

* feat(web): add LiDAR bridge web package

* feat(web): decode RuView LiDAR wire frames

* feat(web): add local LiDAR websocket relay

* feat(web): add LiDAR browser viewer

* feat(web): render live LiDAR point cloud

* fix(ios): use wall clock time for LiDAR provenance

* feat(web): style LiDAR viewer

* test(web): add LiDAR codec tests

* docs: add iPhone LiDAR integration guide

* docs(adr): define iPhone LiDAR sensor bridge

* fix(ios): harden and validate LiDAR bridge

* fix(ios): qualify LiDAR wire depth type
2026-08-22 18:06:16 -04:00

119 lines
3.2 KiB
Swift

import Foundation
import simd
struct RuViewLiDARFrame: Codable, Sendable {
struct Intrinsics: Codable, Sendable {
let fx: Float
let fy: Float
let cx: Float
let cy: Float
let imageWidth: Int
let imageHeight: Int
}
struct Pose: Codable, Sendable {
let matrix: [Float]
}
struct Depth: Codable, Sendable {
let width: Int
let height: Int
let meters: [Float]
let confidence: [UInt8]
}
struct Provenance: Codable, Sendable {
let sensor: String
let source: String
let privacyClass: String
let sequence: UInt64
let timestampNs: UInt64
let schema: String
}
let type: String
let intrinsics: Intrinsics
let pose: Pose
let depth: Depth
let provenance: Provenance
init(
intrinsics: simd_float3x3,
imageResolution: CGSize,
cameraTransform: simd_float4x4,
depthWidth: Int,
depthHeight: Int,
depthMeters: [Float],
confidence: [UInt8],
sequence: UInt64,
timestamp: TimeInterval
) {
self.type = "ruview.lidar.depth.v1"
self.intrinsics = Intrinsics(
fx: intrinsics.columns.0.x,
fy: intrinsics.columns.1.y,
cx: intrinsics.columns.2.x,
cy: intrinsics.columns.2.y,
imageWidth: Int(imageResolution.width),
imageHeight: Int(imageResolution.height)
)
self.pose = Pose(matrix: cameraTransform.columnMajorArray)
self.depth = Depth(
width: depthWidth,
height: depthHeight,
meters: depthMeters,
confidence: confidence
)
self.provenance = Provenance(
sensor: "apple-arkit-scene-depth",
source: "live",
privacyClass: "geometry-only",
sequence: sequence,
timestampNs: UInt64(max(0, timestamp) * 1_000_000_000),
schema: "ruview.lidar.depth.v1"
)
}
func assigningSequence(_ sequence: UInt64) -> RuViewLiDARFrame {
RuViewLiDARFrame(
type: type,
intrinsics: intrinsics,
pose: pose,
depth: depth,
provenance: Provenance(
sensor: provenance.sensor,
source: provenance.source,
privacyClass: provenance.privacyClass,
sequence: sequence,
timestampNs: provenance.timestampNs,
schema: provenance.schema
)
)
}
private init(
type: String,
intrinsics: Intrinsics,
pose: Pose,
depth: Depth,
provenance: Provenance
) {
self.type = type
self.intrinsics = intrinsics
self.pose = pose
self.depth = depth
self.provenance = provenance
}
}
private extension simd_float4x4 {
var columnMajorArray: [Float] {
[
columns.0.x, columns.0.y, columns.0.z, columns.0.w,
columns.1.x, columns.1.y, columns.1.z, columns.1.w,
columns.2.x, columns.2.y, columns.2.z, columns.2.w,
columns.3.x, columns.3.y, columns.3.z, columns.3.w
]
}
}