import { PDBLoader } from 'three/examples/jsm/loaders/PDBLoader.js' async function loadMolecule(url) { const loader = new PDBLoader() return new Promise((resolve, reject) => { loader.load( url, pdb => { // pdb contient: // pdb.geometryAtoms : BufferGeometry des atomes // pdb.geometryBonds : BufferGeometry des liaisons // pdb.json : infos (numéro atomique, couleurs…) const group = new THREE.Group() // --- Atomes --- const atomsGeo = pdb.geometryAtoms const atomsInfo = pdb.json.atoms for (let i = 0; i < atomsInfo.length; i++) { const atom = atomsInfo[i] const position = new THREE.Vector3( atomsGeo.attributes.position.getX(i), atomsGeo.attributes.position.getY(i), atomsGeo.attributes.position.getZ(i) ) const color = new THREE.Color(atom.color) const radius = atom.radius const sphere = new THREE.Mesh( new THREE.SphereGeometry(radius, 32, 16), new THREE.MeshPhongMaterial({ color }) ) sphere.position.copy(position) group.add(sphere) } // --- Liaisons --- const bondsGeo = pdb.geometryBonds for (let i = 0; i < bondsGeo.attributes.position.count; i += 2) { const start = new THREE.Vector3().fromBufferAttribute(bondsGeo.attributes.position, i) const end = new THREE.Vector3().fromBufferAttribute(bondsGeo.attributes.position, i + 1) const bondLength = start.distanceTo(end) const cyl = new THREE.Mesh( new THREE.CylinderGeometry(0.1, 0.1, bondLength, 16), new THREE.MeshPhongMaterial({ color: 0xffffff }) ) // Orienter et positionner le cylindre cyl.position.copy(start).lerp(end, 0.5) cyl.lookAt(end) cyl.rotateX(Math.PI / 2) group.add(cyl) } resolve(group) }, undefined, reject ) }) }