70 lines
2.0 KiB
JavaScript
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
|
|
)
|
|
})
|
|
} |