Spaces:
Sleeping
Sleeping
| /** | |
| * Fetch bounding box data from a JSON file in the specified directory. | |
| * @param {string} dirUrl - The directory URL where the boundingBox.json is located. | |
| * @returns {Promise<Array<THREE.Vector2>>} - Returns a promise resolving to an array of 2D vectors. | |
| */ | |
| async function fetchBoundingBox(dirUrl) { | |
| try { | |
| // Extract the base directory by removing everything after the last "/" | |
| const baseDir = dirUrl.split('/')[0]; | |
| // Construct the full path for the boundingBox.json | |
| const boundingBoxPath = `${baseDir}/boundingBox.json`; | |
| // Use the loadJSONFile function to fetch the bounding box | |
| const jsonData = await loadJSONFile(boundingBoxPath); | |
| // Extract the sphere positions from the boundingBox data | |
| const spheres = jsonData.boundingBox.spheres || []; | |
| const vertices = spheres.map(sphere => new THREE.Vector2(sphere.x, sphere.z)); | |
| return vertices; | |
| } catch (error) { | |
| console.error('Erreur lors de la récupération des données de la bounding box :', error); | |
| throw error; | |
| } | |
| } | |
| /** | |
| * Sets up camera restriction using bounding box data. | |
| * @param {THREE.Camera} gCamera - The camera to restrict. | |
| * @param {THREE.Renderer} gRenderer - The renderer for rendering the scene. | |
| * @param {THREE.Scene} gRayMarchScene - The scene to which restrictions are applied. | |
| * @param {string} dirUrl - The directory URL where the boundingBox.json is located. | |
| */ | |
| async function setupCameraRestriction(gCamera, gRenderer, gRayMarchScene, dirUrl) { | |
| const fixedHeight = 0.5; // Fixed y-coordinate for the camera | |
| // Fetch the bounding box data | |
| const polygonVertices = await fetchBoundingBox(dirUrl); | |
| // Visualize the bounding box in the scene | |
| function createPolygonVisualization() { | |
| const material = new THREE.LineBasicMaterial({ color: 0x00ff00 }); | |
| const points = []; | |
| // Convert 2D points to 3D for visualization | |
| polygonVertices.forEach(vertex => { | |
| points.push(new THREE.Vector3(vertex.x, fixedHeight, vertex.y)); | |
| }); | |
| // Close the polygon by adding the first point to the end | |
| points.push(new THREE.Vector3(polygonVertices[0].x, fixedHeight, polygonVertices[0].y)); | |
| // Create a line geometry for visualization | |
| const geometry = new THREE.BufferGeometry().setFromPoints(points); | |
| const line = new THREE.Line(geometry, material); | |
| gRayMarchScene.add(line); | |
| // Add spheres to mark the vertices | |
| const sphereGeometry = new THREE.SphereGeometry(0.01, 16, 16); | |
| const sphereMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); | |
| polygonVertices.forEach(vertex => { | |
| const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial); | |
| sphere.position.set(vertex.x, fixedHeight, vertex.y); | |
| gRayMarchScene.add(sphere); | |
| }); | |
| } | |
| createPolygonVisualization(); | |
| // Check if a point is inside the polygon | |
| function isPointInPolygon(point, vertices) { | |
| let intersects = 0; | |
| for (let i = 0; i < vertices.length; i++) { | |
| const v1 = vertices[i]; | |
| const v2 = vertices[(i + 1) % vertices.length]; | |
| if ((v1.y > point.y) !== (v2.y > point.y) && | |
| point.x < ((v2.x - v1.x) * (point.y - v1.y)) / (v2.y - v1.y) + v1.x) { | |
| intersects++; | |
| } | |
| } | |
| return intersects % 2 === 1; | |
| } | |
| // Restrict camera position based on bounding box | |
| function restrictCameraPosition() { | |
| gCamera.position.y = fixedHeight; | |
| const cameraPos2D = new THREE.Vector2(gCamera.position.x, gCamera.position.z); | |
| if (!isPointInPolygon(cameraPos2D, polygonVertices)) { | |
| let closestPoint = cameraPos2D; | |
| let minDistance = Infinity; | |
| for (let i = 0; i < polygonVertices.length; i++) { | |
| const v1 = polygonVertices[i]; | |
| const v2 = polygonVertices[(i + 1) % polygonVertices.length]; | |
| const closestPointOnEdge = closestPointOnLineSegment(cameraPos2D, v1, v2); | |
| const distance = cameraPos2D.distanceTo(closestPointOnEdge); | |
| if (distance < minDistance) { | |
| minDistance = distance; | |
| closestPoint = closestPointOnEdge; | |
| } | |
| } | |
| gCamera.position.x = closestPoint.x; | |
| gCamera.position.z = closestPoint.y; | |
| } | |
| } | |
| function closestPointOnLineSegment(point, v1, v2) { | |
| const lineVec = new THREE.Vector2().subVectors(v2, v1); | |
| const pointVec = new THREE.Vector2().subVectors(point, v1); | |
| const lineLen = lineVec.length(); | |
| const lineUnitVec = lineVec.normalize(); | |
| const projection = pointVec.dot(lineUnitVec); | |
| const t = Math.max(0, Math.min(lineLen, projection)); | |
| return new THREE.Vector2().copy(v1).add(lineUnitVec.multiplyScalar(t)); | |
| } | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| restrictCameraPosition(); | |
| gRenderer.render(gRayMarchScene, gCamera); | |
| } | |
| animate(); | |
| } |