csp-security-project / ar-controller.js
AbdulElahGwaith's picture
Upload folder using huggingface_hub
d0a2071 verified
/**
* 📱 AR Controller - تحكم الواقع المعزز
* نظام متقدم للواقع المعزز لمركز القيادة الغامر
*
* المميزات:
* - كشف الأسطح التلقائي
* - وضع العناصر المجسمة
* - تتبع المواقع الجغرافية
* - دمج البيانات الحقيقية
* - دعم المحاكاة التعليمية
*
* @author MiniMax Agent
* @version 2025.12.10
*/
class ARController {
constructor(scene, camera, renderer) {
this.scene = scene;
this.camera = camera;
this.renderer = renderer;
this.isInitialized = false;
this.isSessionActive = false;
this.session = null;
this.referenceSpace = null;
this.planes = new Map();
this.anchors = new Map();
this.trackedImages = new Map();
this.currentAnchor = null;
// إعدادات AR
this.config = {
sessionType: 'immersive-ar',
requiredFeatures: ['local'],
optionalFeatures: ['hit-test', 'dom-overlay', 'plane-detection', 'light-estimation'],
maxAnchors: 20,
planeDetection: true,
domOverlay: {
root: document.body
},
trackedImages: []
};
// بيانات الأسطح المحاكاة
this.mockPlanes = this.createMockPlanes();
// حالة النظام
this.systemState = {
lightIntensity: 0.8,
planeCount: 0,
anchorCount: 0,
isTracking: false
};
console.log('📱 تم تهيئة AR Controller');
}
/**
* تهيئة نظام AR
*/
async initialize() {
try {
console.log('🔧 بدء تهيئة AR...');
// فحص دعم WebXR
if (!navigator.xr) {
throw new Error('WebXR غير مدعوم في هذا المتصفح');
}
// فحص دعم AR
const isARAvailable = await navigator.xr.isSessionSupported(this.config.sessionType);
if (!isARAvailable) {
throw new Error('AR غير متاح على هذا الجهاز');
}
// تهيئة كشف الأسطح
if (this.config.planeDetection) {
await this.initializePlaneDetection();
}
// تهيئة تقدير الإضاءة
await this.initializeLightEstimation();
// تهيئة تتبع الصور (اختياري)
if (this.config.trackedImages.length > 0) {
await this.initializeImageTracking();
}
this.isInitialized = true;
console.log('✅ تم تهيئة AR بنجاح');
return true;
} catch (error) {
console.error('❌ خطأ في تهيئة AR:', error);
throw error;
}
}
/**
* تهيئة كشف الأسطح
*/
async initializePlaneDetection() {
console.log('🟦 تهيئة كشف الأسطح...');
// إنشاء نظام كشف أسطح وهمي
this.planeDetection = {
planes: new Map(),
onPlaneDetected: (plane) => {
this.handlePlaneDetected(plane);
},
onPlaneUpdated: (plane) => {
this.handlePlaneUpdated(plane);
},
onPlaneRemoved: (plane) => {
this.handlePlaneRemoved(plane);
}
};
console.log('✅ تم تهيئة كشف الأسطح');
}
/**
* تهيئة تقدير الإضاءة
*/
async initializeLightEstimation() {
console.log('💡 تهيئة تقدير الإضاءة...');
this.lightEstimation = {
isAvailable: true,
currentLight: {
primaryLightDirection: { x: 0.5, y: -1, z: 0.3 },
primaryLightIntensity: 0.8,
sphericalHarmonics: {
coefficients: Array(9).fill(0).map(() => Math.random() * 0.5)
}
},
update: (estimation) => {
this.handleLightEstimationUpdate(estimation);
}
};
console.log('✅ تم تهيئة تقدير الإضاءة');
}
/**
* تهيئة تتبع الصور
*/
async initializeImageTracking() {
console.log('🖼️ تهيئة تتبع الصور...');
// تحميل الصور للتتبع
for (const imageData of this.config.trackedImages) {
try {
const image = await this.loadImage(imageData.src);
this.trackedImages.set(imageData.id, {
image: image,
width: imageData.width,
tracked: false,
pose: null
});
} catch (error) {
console.warn(`تعذر تحميل صورة التتبع ${imageData.id}:`, error);
}
}
console.log('✅ تم تهيئة تتبع الصور');
}
/**
* تحميل صورة
*/
loadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
}
/**
* بدء جلسة AR
*/
async startSession() {
if (!this.isInitialized) {
throw new Error('AR غير مهيأ بعد');
}
try {
console.log('🚀 بدء جلسة AR...');
// طلب جلسة AR
this.session = await navigator.xr.requestSession(this.config.sessionType, {
requiredFeatures: this.config.requiredFeatures,
optionalFeatures: this.config.optionalFeatures,
domOverlay: this.config.domOverlay
});
// ربط أحداث الجلسة
this.bindSessionEvents();
// بدء تقديم المشهد
this.renderer.xr.enabled = true;
this.renderer.xr.setReferenceSpaceType('local');
await this.renderer.xr.setSession(this.session);
this.isSessionActive = true;
this.startSessionLoop();
console.log('✅ تم بدء جلسة AR بنجاح');
this.emit('session_start');
} catch (error) {
console.error('❌ خطأ في بدء جلسة AR:', error);
throw error;
}
}
/**
* إنهاء جلسة AR
*/
async endSession() {
if (!this.session || !this.isSessionActive) {
return;
}
try {
console.log('🛑 إنهاء جلسة AR...');
this.isSessionActive = false;
if (this.session) {
await this.session.end();
this.session = null;
}
// إيقاف تقديم المشهد
this.renderer.xr.enabled = false;
// تنظيف المراسي والأسطح
this.cleanupAnchors();
this.cleanupPlanes();
console.log('✅ تم إنهاء جلسة AR');
this.emit('session_end');
} catch (error) {
console.error('❌ خطأ في إنهاء جلسة AR:', error);
}
}
/**
* ربط أحداث الجلسة
*/
bindSessionEvents() {
this.session.addEventListener('end', () => {
this.isSessionActive = false;
this.emit('session_end');
});
this.session.addEventListener('inputsourceschange', (event) => {
this.handleInputSourcesChange(event);
});
this.session.addEventListener('select', (event) => {
this.handleSelect(event);
});
}
/**
* معالجة تغيير مصادر الإدخال
*/
handleInputSourcesChange(event) {
const { added, removed } = event;
added.forEach(inputSource => {
console.log('➕ إضافة مصدر إدخال AR:', inputSource.handedness);
});
removed.forEach(inputSource => {
console.log('➖ إزالة مصدر إدخال AR:', inputSource.handedness);
});
}
/**
* معالجة الاختيار
*/
handleSelect(event) {
console.log('👆 حدث اختيار في AR');
// تنفيذ hit test
this.performHitTest(event);
}
/**
* إجراء hit test
*/
async performHitTest(event) {
try {
// محاكاة hit test
const hitTestResults = await this.simulateHitTest(event);
if (hitTestResults.length > 0) {
const hit = hitTestResults[0];
console.log('🎯 hit test نجح:', hit);
// إنشاء مرساة في الموقع المحدد
await this.createAnchor(hit.position, hit.rotation);
}
} catch (error) {
console.warn('خطأ في hit test:', error);
}
}
/**
* محاكاة hit test
*/
simulateHitTest(event) {
return new Promise((resolve) => {
// محاكاة نتائج hit test
const results = [];
// فحص الأسطح المتاحة
const availablePlanes = Array.from(this.planes.values());
if (availablePlanes.length > 0) {
const plane = availablePlanes[0];
// إنشاء نتيجة hit test وهمية
const result = {
position: {
x: plane.center.x + (Math.random() - 0.5) * plane.width,
y: plane.center.y,
z: plane.center.z + (Math.random() - 0.5) * plane.depth
},
rotation: { x: 0, y: 0, z: 0, w: 1 },
plane: plane
};
results.push(result);
}
// إرجاع النتائج بعد تأخير قصير
setTimeout(() => resolve(results), 100);
});
}
/**
* إنشاء مرساة
*/
async createAnchor(position, rotation) {
try {
const anchorId = `anchor_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
// إنشاء كائن ثلاثي الأبعاد للمرساة
const anchorMesh = this.createAnchorMesh();
anchorMesh.position.set(position.x, position.y, position.z);
if (rotation) {
anchorMesh.quaternion.set(rotation.x, rotation.y, rotation.z, rotation.w);
}
this.scene.add(anchorMesh);
// حفظ المرساة
const anchor = {
id: anchorId,
position: position,
rotation: rotation,
mesh: anchorMesh,
objects: [],
createdAt: new Date()
};
this.anchors.set(anchorId, anchor);
this.systemState.anchorCount = this.anchors.size;
console.log('📌 تم إنشاء مرساة:', anchorId);
this.emit('anchor_created', anchor);
return anchor;
} catch (error) {
console.error('خطأ في إنشاء المرساة:', error);
throw error;
}
}
/**
* إنشاء شكل المرساة ثلاثي الأبعاد
*/
createAnchorMesh() {
// إنشاء حلقة مرساة
const torusGeometry = new THREE.TorusGeometry(0.1, 0.02, 8, 16);
const torusMaterial = new THREE.MeshBasicMaterial({
color: 0x22d3ee,
transparent: true,
opacity: 0.8
});
const torus = new THREE.Mesh(torusGeometry, torusMaterial);
torus.rotation.x = Math.PI / 2;
// إضافة نقطة مركزية
const centerGeometry = new THREE.SphereGeometry(0.02, 8, 8);
const centerMaterial = new THREE.MeshBasicMaterial({
color: 0x22d3ee,
emissive: 0x22d3ee,
emissiveIntensity: 0.3
});
const center = new THREE.Mesh(centerGeometry, centerMaterial);
torus.add(center);
// إضافة أنيميشن نبضة
const animate = () => {
torus.scale.setScalar(1 + Math.sin(Date.now() * 0.005) * 0.1);
requestAnimationFrame(animate);
};
animate();
return torus;
}
/**
* وضع عنصر على المرساة
*/
placeObjectOnAnchor(anchorId, objectType, data = {}) {
const anchor = this.anchors.get(anchorId);
if (!anchor) {
throw new Error(`المرساة ${anchorId} غير موجودة`);
}
try {
// إنشاء الكائن ثلاثي الأبعاد
const object = this.createObject3D(objectType, data);
// وضع الكائن على المرساة
object.position.set(0, 0, 0);
anchor.mesh.add(object);
// حفظ الكائن في المرساة
anchor.objects.push({
id: `object_${Date.now()}`,
type: objectType,
mesh: object,
data: data,
createdAt: new Date()
});
console.log('📦 تم وضع كائن على المرساة:', objectType);
this.emit('object_placed', { anchor, object });
return object;
} catch (error) {
console.error('خطأ في وضع الكائن:', error);
throw error;
}
}
/**
* إنشاء كائن ثلاثي الأبعاد
*/
createObject3D(type, data) {
let geometry, material, mesh;
switch (type) {
case 'threat':
geometry = this.createThreatGeometry(data.threatType || 'XSS');
material = new THREE.MeshBasicMaterial({
color: this.getThreatColor(data.severity),
transparent: true,
opacity: 0.8
});
mesh = new THREE.Mesh(geometry, material);
break;
case 'network_node':
geometry = new THREE.SphereGeometry(0.05, 16, 16);
material = new THREE.MeshBasicMaterial({
color: 0x22d3ee,
transparent: true,
opacity: 0.9
});
mesh = new THREE.Mesh(geometry, material);
break;
case 'info_panel':
geometry = new THREE.PlaneGeometry(0.3, 0.2);
material = new THREE.MeshBasicMaterial({
color: 0x000000,
transparent: true,
opacity: 0.8,
side: THREE.DoubleSide
});
mesh = new THREE.Mesh(geometry, material);
// إضافة نص
const canvas = document.createElement('canvas');
canvas.width = 256;
canvas.height = 128;
const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#22d3ee';
ctx.font = '16px Arial';
ctx.textAlign = 'center';
ctx.fillText(data.title || 'معلومات', canvas.width / 2, 40);
ctx.fillStyle = '#f0f2f5';
ctx.font = '12px Arial';
ctx.fillText(data.description || 'وصف المعلومات', canvas.width / 2, 80);
const texture = new THREE.CanvasTexture(canvas);
material.map = texture;
break;
default:
geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1);
material = new THREE.MeshBasicMaterial({ color: 0x22d3ee });
mesh = new THREE.Mesh(geometry, material);
}
// إضافة بيانات المستخدم
mesh.userData = {
type: type,
data: data,
createdAt: new Date()
};
return mesh;
}
/**
* إنشاء شكل التهديد
*/
createThreatGeometry(threatType) {
switch (threatType) {
case 'XSS':
return new THREE.SphereGeometry(0.05, 16, 16);
case 'SQL Injection':
return new THREE.BoxGeometry(0.08, 0.08, 0.08);
case 'Malware':
return new THREE.TetrahedronGeometry(0.07);
case 'DDoS':
return new THREE.OctahedronGeometry(0.06);
case 'Phishing':
return new THREE.ConeGeometry(0.05, 0.1, 8);
case 'Ransomware':
return new THREE.TorusGeometry(0.05, 0.02, 8, 16);
default:
return new THREE.IcosahedronGeometry(0.05);
}
}
/**
* الحصول على لون التهديد
*/
getThreatColor(severity) {
switch (severity) {
case 'منخفض':
return 0x34d399;
case 'متوسط':
return 0xfbbf24;
case 'عالي':
return 0xf97316;
case 'حرج':
return 0xf87171;
default:
return 0x22d3ee;
}
}
/**
* معالجة اكتشاف سطح
*/
handlePlaneDetected(plane) {
console.log('🟦 تم اكتشاف سطح جديد');
// إنشاء شكل السطح
const planeMesh = this.createPlaneMesh(plane);
// حفظ السطح
this.planes.set(plane.id, {
id: plane.id,
center: plane.center,
width: plane.width,
height: plane.height,
orientation: plane.orientation,
mesh: planeMesh,
createdAt: new Date()
});
this.systemState.planeCount = this.planes.size;
// إضافة للمشهد
this.scene.add(planeMesh);
this.emit('plane_detected', plane);
}
/**
* معالجة تحديث سطح
*/
handlePlaneUpdated(plane) {
const trackedPlane = this.planes.get(plane.id);
if (trackedPlane) {
// تحديث الموقع والأبعاد
trackedPlane.center = plane.center;
trackedPlane.width = plane.width;
trackedPlane.height = plane.height;
// تحديث الشبكة ثلاثية الأبعاد
trackedPlane.mesh.position.set(plane.center.x, plane.center.y, plane.center.z);
trackedPlane.mesh.rotation.setFromQuaternion(plane.orientation);
// تحديث الأبعاد
trackedPlane.mesh.scale.set(plane.width, 1, plane.height);
}
}
/**
* معالجة إزالة سطح
*/
handlePlaneRemoved(plane) {
const trackedPlane = this.planes.get(plane.id);
if (trackedPlane) {
this.scene.remove(trackedPlane.mesh);
this.planes.delete(plane.id);
this.systemState.planeCount = this.planes.size;
}
}
/**
* إنشاء شكل السطح
*/
createPlaneMesh(plane) {
const geometry = new THREE.PlaneGeometry(1, 1);
const material = new THREE.MeshBasicMaterial({
color: 0x22d3ee,
transparent: true,
opacity: 0.1,
side: THREE.DoubleSide
});
const mesh = new THREE.Mesh(geometry, material);
// تحديد الموقع والتوجيه
mesh.position.set(plane.center.x, plane.center.y, plane.center.z);
mesh.quaternion.set(plane.orientation.x, plane.orientation.y, plane.orientation.z, plane.orientation.w);
mesh.scale.set(plane.width, 1, plane.height);
// إضافة شبكة للتوضيح
const gridHelper = new THREE.GridHelper(plane.width, 10, 0x22d3ee, 0x22d3ee);
gridHelper.position.y = 0.001;
mesh.add(gridHelper);
return mesh;
}
/**
* إنشاء أسطح وهمية للاختبار
*/
createMockPlanes() {
return [
{
id: 'mock_plane_1',
center: { x: 0, y: 0, z: -1 },
width: 1,
height: 0.8,
orientation: { x: 0, y: 0, z: 0, w: 1 }
}
];
}
/**
* معالجة تحديث تقدير الإضاءة
*/
handleLightEstimationUpdate(estimation) {
if (estimation) {
this.systemState.lightIntensity = estimation.primaryLightIntensity || 0.8;
// تحديث إضاءة المشهد
this.updateSceneLighting(estimation);
console.log('💡 تم تحديث تقدير الإضاءة:', this.systemState.lightIntensity);
}
}
/**
* تحديث إضاءة المشهد
*/
updateSceneLighting(lightEstimation) {
// العثور على الإضاءة الرئيسية في المشهد
const directionalLight = this.scene.children.find(child =>
child.isDirectionalLight && child.userData.isMainLight
);
if (directionalLight) {
// تحديث اتجاه الإضاءة
if (lightEstimation.primaryLightDirection) {
const dir = lightEstimation.primaryLightDirection;
directionalLight.position.set(dir.x * 10, dir.y * 10, dir.z * 10);
}
// تحديث شدة الإضاءة
if (lightEstimation.primaryLightIntensity) {
directionalLight.intensity = lightEstimation.primaryLightIntensity;
}
}
}
/**
* بدء حلقة الجلسة
*/
startSessionLoop() {
const animate = () => {
if (!this.isSessionActive) return;
// تحديث الأسطح
this.updatePlanes();
// تحديث المراسي
this.updateAnchors();
// تحديث تتبع الصور
this.updateImageTracking();
// تحديث تقدير الإضاءة
this.updateLightEstimation();
// طلب الإطار التالي
this.session.requestAnimationFrame(animate);
};
this.session.requestAnimationFrame(animate);
}
/**
* تحديث الأسطح
*/
updatePlanes() {
// محاكاة تحديث الأسطح المكتشفة
if (this.mockPlanes.length > 0) {
this.mockPlanes.forEach(mockPlane => {
// فحص ما إذا كان السطح موجود بالفعل
let plane = this.planes.get(mockPlane.id);
if (!plane) {
// إنشاء سطح جديد
this.handlePlaneDetected(mockPlane);
} else {
// تحديث السطح الموجود
this.handlePlaneUpdated(mockPlane);
}
});
}
}
/**
* تحديث المراسي
*/
updateAnchors() {
this.anchors.forEach(anchor => {
// تحديث المرساة بناءً على موقعها
if (anchor.mesh) {
// إضافة دوران بطيء للمرساة
anchor.mesh.rotation.y += 0.01;
// تحديث حالة الرؤية
const distanceFromCamera = this.camera.position.distanceTo(anchor.mesh.position);
anchor.mesh.visible = distanceFromCamera < 5; // إخفاء المرساة إذا كانت بعيدة جداً
}
});
}
/**
* تحديث تتبع الصور
*/
updateImageTracking() {
this.trackedImages.forEach((imageData, id) => {
// محاكاة تتبع الصور
if (Math.random() > 0.95) { // 5% احتمال تتبع الصورة
if (!imageData.tracked) {
imageData.tracked = true;
imageData.pose = this.generateRandomPose();
console.log('🖼️ تم تتبع صورة:', id);
this.emit('image_tracked', { id, pose: imageData.pose });
}
} else {
imageData.tracked = false;
}
});
}
/**
* توليد وضعية عشوائية
*/
generateRandomPose() {
return {
position: {
x: (Math.random() - 0.5) * 2,
y: Math.random() * 2,
z: (Math.random() - 0.5) * 2
},
rotation: {
x: 0,
y: (Math.random() - 0.5) * Math.PI * 2,
z: 0,
w: 1
}
};
}
/**
* تحديث تقدير الإضاءة
*/
updateLightEstimation() {
// محاكاة تغييرات الإضاءة
const time = Date.now() * 0.001;
this.systemState.lightIntensity = 0.7 + Math.sin(time * 0.5) * 0.3;
if (this.lightEstimation) {
this.lightEstimation.currentLight.primaryLightIntensity = this.systemState.lightIntensity;
}
}
/**
* تنظيف المراسي
*/
cleanupAnchors() {
this.anchors.forEach(anchor => {
if (anchor.mesh) {
this.scene.remove(anchor.mesh);
}
});
this.anchors.clear();
this.systemState.anchorCount = 0;
}
/**
* تنظيف الأسطح
*/
cleanupPlanes() {
this.planes.forEach(plane => {
if (plane.mesh) {
this.scene.remove(plane.mesh);
}
});
this.planes.clear();
this.systemState.planeCount = 0;
}
/**
* الحصول على حالة النظام
*/
getSystemState() {
return {
...this.systemState,
isSessionActive: this.isSessionActive,
planes: Array.from(this.planes.values()).map(plane => ({
id: plane.id,
center: plane.center,
width: plane.width,
height: plane.height
})),
anchors: Array.from(this.anchors.values()).map(anchor => ({
id: anchor.id,
position: anchor.position,
objectCount: anchor.objects.length
}))
};
}
/**
* عرض تهديد في الواقع المعزز
*/
displayThreatInAR(threat, position) {
if (!this.isSessionActive) {
throw new Error('جلسة AR غير نشطة');
}
// إنشاء مرساة للتهديد
this.createAnchor(position, { x: 0, y: 0, z: 0, w: 1 })
.then(anchor => {
// وضع التهديد على المرساة
this.placeObjectOnAnchor(anchor.id, 'threat', {
threatType: threat.type,
severity: threat.severity,
description: threat.description
});
console.log('⚠️ تم عرض تهديد في AR:', threat.type);
})
.catch(error => {
console.error('خطأ في عرض التهديد في AR:', error);
});
}
/**
* عرض خريطة شبكة في الواقع المعزز
*/
displayNetworkMapInAR(networkData, centerPosition) {
if (!this.isSessionActive) {
throw new Error('جلسة AR غير نشطة');
}
// إنشاء مرساة للخريطة
this.createAnchor(centerPosition, { x: 0, y: 0, z: 0, w: 1 })
.then(anchor => {
// إضافة عقد الشبكة
networkData.nodes.forEach((node, index) => {
const nodePosition = {
x: (index % 5) * 0.3 - 0.6,
y: 0,
z: Math.floor(index / 5) * 0.3 - 0.6
};
this.placeObjectOnAnchor(anchor.id, 'network_node', {
zone: node.zone,
status: node.status,
connections: node.connections
});
});
// إضافة لوحة معلومات
this.placeObjectOnAnchor(anchor.id, 'info_panel', {
title: 'خريطة الشبكة',
description: `${networkData.nodes.length} عقدة نشطة`
});
console.log('🌐 تم عرض خريطة شبكة في AR');
})
.catch(error => {
console.error('خطأ في عرض خريطة الشبكة في AR:', error);
});
}
/**
* نظام الأحداث
*/
emit(eventName, data) {
if (this.eventListeners[eventName]) {
this.eventListeners[eventName].forEach(callback => {
try {
callback(data);
} catch (error) {
console.error('خطأ في مستمع الحدث:', error);
}
});
}
}
on(eventName, callback) {
if (!this.eventListeners[eventName]) {
this.eventListeners[eventName] = [];
}
this.eventListeners[eventName].push(callback);
}
off(eventName, callback) {
if (this.eventListeners[eventName]) {
this.eventListeners[eventName] = this.eventListeners[eventName].filter(cb => cb !== callback);
}
}
/**
* تدمير النظام
*/
destroy() {
console.log('🗑️ تدمير AR Controller...');
// إنهاء الجلسة النشطة
if (this.isSessionActive) {
this.endSession();
}
// تنظيف الموارد
this.cleanupAnchors();
this.cleanupPlanes();
this.trackedImages.clear();
this.planes.clear();
console.log('✅ تم تدمير AR Controller');
}
}
// تصدير للاستخدام في الوحدات الأخرى
if (typeof module !== 'undefined' && module.exports) {
module.exports = ARController;
}