Files
P42_UI/app/helpers/helpers3DLoaders.module.js

70 lines
2.0 KiB
JavaScript

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
)
})
}