molgfx_render/engine/chunk_placement/bonds.rs
1use super::{ChunkPlacementError, ChunkPlacementId};
2use molgfx_core::ResidencyTicket;
3use molgfx_math::{Mat4, Rgba8};
4
5/// Declarative analytic rendering of one resident provider bond chunk.
6#[derive(Clone, Copy, Debug, PartialEq)]
7pub struct BondChunkPlacement {
8 /// Stable placement identity in the shared bounded placement table.
9 pub id: ChunkPlacementId,
10 /// Exact resident bond generation to draw.
11 pub ticket: ResidencyTicket,
12 /// Atom-dataset coordinates to world space.
13 pub model_to_world: Mat4,
14 /// Analytic cylinder radius in local coordinate units.
15 pub radius: f32,
16 /// Uniform packed display color.
17 pub color: Rgba8,
18}
19
20impl BondChunkPlacement {
21 /// Creates a licorice-style analytic cylinder placement.
22 ///
23 /// Ball-and-stick is composed by declaring this placement together with
24 /// space-filling atom placements; both reference the same coordinate arena.
25 ///
26 /// # Errors
27 ///
28 /// Rejects a non-finite transform or a non-positive/non-finite radius.
29 pub fn licorice(
30 id: ChunkPlacementId,
31 ticket: ResidencyTicket,
32 model_to_world: Mat4,
33 radius: f32,
34 color: Rgba8,
35 ) -> Result<Self, ChunkPlacementError> {
36 if !model_to_world.is_finite() {
37 return Err(ChunkPlacementError::NonFiniteTransform);
38 }
39 if !radius.is_finite() || radius <= 0.0 {
40 return Err(ChunkPlacementError::InvalidBondRadius);
41 }
42 Ok(Self {
43 id,
44 ticket,
45 model_to_world,
46 radius,
47 color,
48 })
49 }
50}