@osobh/reactar
Version:
AR Library for React Native and Expo
112 lines (98 loc) • 3.13 kB
text/typescript
import { THREE } from 'expo-three';
export interface Plane {
id: string;
center: THREE.Vector3;
normal: THREE.Vector3;
extent: {
width: number;
length: number;
};
confidence: number;
}
export class PlaneDetection {
private scene: THREE.Scene | null = null;
private camera: THREE.Camera | null = null;
private planes: Map<string, Plane> = new Map();
private planeMeshes: Map<string, THREE.Mesh> = new Map();
private planeMaterial: THREE.MeshBasicMaterial;
constructor() {
this.planeMaterial = new THREE.MeshBasicMaterial({
color: 0x00ff00,
transparent: true,
opacity: 0.3,
side: THREE.DoubleSide
});
}
setScene(scene: THREE.Scene) {
this.scene = scene;
}
setCamera(camera: THREE.Camera) {
this.camera = camera;
}
async detectPlanes(): Promise<Plane[]> {
if (!this.scene || !this.camera) {
throw new Error('Scene and camera must be set before detecting planes');
}
try {
// Simulate plane detection with sample data
// In a real implementation, this would process camera frames and use
// computer vision algorithms to detect planes
const detectedPlanes = this.simulatePlaneDetection();
this.updatePlanes(detectedPlanes);
return Array.from(this.planes.values());
} catch (error) {
console.error('Error detecting planes:', error);
throw error;
}
}
private simulatePlaneDetection(): Plane[] {
// This is a placeholder implementation
// In a real app, this would use actual plane detection algorithms
return [
{
id: 'plane1',
center: new THREE.Vector3(0, -1, -3),
normal: new THREE.Vector3(0, 1, 0),
extent: { width: 2, length: 2 },
confidence: 0.9
}
];
}
private updatePlanes(detectedPlanes: Plane[]) {
// Remove planes that are no longer detected
const currentPlaneIds = new Set(detectedPlanes.map(plane => plane.id));
for (const [id, mesh] of this.planeMeshes) {
if (!currentPlaneIds.has(id)) {
this.scene!.remove(mesh);
this.planeMeshes.delete(id);
this.planes.delete(id);
}
}
// Update or add new planes
for (const plane of detectedPlanes) {
this.planes.set(plane.id, plane);
let planeMesh = this.planeMeshes.get(plane.id);
if (!planeMesh) {
// Create new mesh for newly detected plane
const geometry = new THREE.PlaneGeometry(plane.extent.width, plane.extent.length);
planeMesh = new THREE.Mesh(geometry, this.planeMaterial);
this.planeMeshes.set(plane.id, planeMesh);
this.scene!.add(planeMesh);
}
// Update mesh position and rotation
planeMesh.position.copy(plane.center);
planeMesh.lookAt(plane.center.clone().add(plane.normal));
}
}
getDetectedPlanes(): Plane[] {
return Array.from(this.planes.values());
}
clear() {
// Remove all plane meshes from the scene
for (const mesh of this.planeMeshes.values()) {
this.scene?.remove(mesh);
}
this.planeMeshes.clear();
this.planes.clear();
}
}