1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! Floating origin marker component for camera / player entities.
use Component;
use ReflectComponent;
use Reflect;
use Transform;
use crateGeoCell;
/// Marker component designating an entity as the floating origin.
///
/// The entity with this component is the **rendering reference point**: it
/// always renders at world `(0, 0, 0)` (with its own `Transform.rotation`
/// and `Transform.scale` preserved). Every other entity with a [`GeoCell`]
/// is placed by [`propagate_geo_transforms`](crate::systems::propagate_geo_transforms)
/// in the origin's local cell frame, at its true sphere-space position
/// relative to the origin. This is the same "big-space" convention used by
/// the `big_space` crate — keeps float precision tight even when the
/// underlying cell coordinate is on the far side of a planet.
///
/// The origin's `Transform.translation` is the *local offset within its
/// current cell*, **not** a world-space coordinate. Move the origin by
/// mutating that translation; when its length exceeds
/// [`recenter_threshold`](Self::recenter_threshold) the recenter system
/// swaps the origin to a neighbouring cell and rebases both the translation
/// and the rotation so the world-space pose is unchanged. Recentres are
/// therefore visually invisible.
///
/// # Required components
///
/// `FloatingOrigin` requires a [`GeoCell`] (which cell the origin is in) and a
/// [`Transform`] (the local offset within that cell). Bevy's `#[require]`
/// attribute auto-inserts defaults if you don't provide them, so the smallest
/// valid spawn is `commands.spawn(FloatingOrigin::default())`.
///
/// # Per-origin recenter threshold
///
/// Each `FloatingOrigin` carries its own [`recenter_threshold`](Self::recenter_threshold)
/// in world units (metres). Multiple floating origins (split-screen,
/// networked players) can have different thresholds.
///
/// # Example
///
/// ```rust,ignore
/// commands.spawn((
/// FloatingOrigin::with_threshold(50.0),
/// GeoCell::from_lon_lat(2.3522, 48.8566, 9).unwrap(),
/// Transform::default(),
/// ));
/// ```