Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_dead_reckoning.h
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
81#ifndef N_DEAD_RECKONING_H
82#define N_DEAD_RECKONING_H
83
84#ifdef __cplusplus
85extern "C" {
86#endif
87
93#include <stdbool.h>
94#include <math.h>
95
96/*---------------------------------------------------------------------------
97 * 3D Vector type for dead reckoning
98 *-------------------------------------------------------------------------*/
99
101typedef struct DR_VEC3 {
102 double x;
103 double y;
104 double z;
105} DR_VEC3;
106
107/*---------------------------------------------------------------------------
108 * Enumerations
109 *-------------------------------------------------------------------------*/
110
119
128
129/*---------------------------------------------------------------------------
130 * Kinematic state snapshot
131 *-------------------------------------------------------------------------*/
132
140
141/*---------------------------------------------------------------------------
142 * Dead reckoning entity
143 *-------------------------------------------------------------------------*/
144
149typedef struct DR_ENTITY {
150 /* --- Configuration --- */
154 double blend_time;
156 /* --- Last known authoritative state (received from network) --- */
159 /* --- State at the moment we received the last update --- */
162 /* --- Convergence tracking --- */
163 double blend_start;
164 bool blending;
166 /* --- Cubic Bezier control points (computed on update) --- */
172 /* --- Output --- */
176 /* --- Statistics --- */
178} DR_ENTITY;
179
180/*---------------------------------------------------------------------------
181 * Vector operations (inline helpers)
182 *-------------------------------------------------------------------------*/
183
185static inline DR_VEC3 dr_vec3(double x, double y, double z) {
186 DR_VEC3 v = {x, y, z};
187 return v;
188}
189
191static inline DR_VEC3 dr_vec3_zero(void) {
192 DR_VEC3 v = {0.0, 0.0, 0.0};
193 return v;
194}
195
197static inline DR_VEC3 dr_vec3_add(DR_VEC3 a, DR_VEC3 b) {
198 DR_VEC3 v = {a.x + b.x, a.y + b.y, a.z + b.z};
199 return v;
200}
201
203static inline DR_VEC3 dr_vec3_sub(DR_VEC3 a, DR_VEC3 b) {
204 DR_VEC3 v = {a.x - b.x, a.y - b.y, a.z - b.z};
205 return v;
206}
207
209static inline DR_VEC3 dr_vec3_scale(DR_VEC3 v, double s) {
210 DR_VEC3 r = {v.x * s, v.y * s, v.z * s};
211 return r;
212}
213
215static inline DR_VEC3 dr_vec3_lerp(DR_VEC3 a, DR_VEC3 b, double t) {
216 DR_VEC3 r = {
217 a.x + (b.x - a.x) * t,
218 a.y + (b.y - a.y) * t,
219 a.z + (b.z - a.z) * t};
220 return r;
221}
222
224static inline double dr_vec3_length_sq(DR_VEC3 v) {
225 return v.x * v.x + v.y * v.y + v.z * v.z;
226}
227
229static inline double dr_vec3_length(DR_VEC3 v) {
230 return sqrt(dr_vec3_length_sq(v));
231}
232
234static inline double dr_vec3_distance(DR_VEC3 a, DR_VEC3 b) {
235 return dr_vec3_length(dr_vec3_sub(a, b));
236}
237
238/*---------------------------------------------------------------------------
239 * API Functions
240 *-------------------------------------------------------------------------*/
241
243DR_ENTITY* dr_entity_create(DR_ALGO algo, DR_BLEND blend_mode, double pos_threshold, double blend_time);
245void dr_entity_destroy(DR_ENTITY** entity_ptr);
248 const DR_VEC3* pos,
249 const DR_VEC3* vel,
250 const DR_VEC3* acc,
251 double time);
253void dr_entity_compute(DR_ENTITY* entity, double time, DR_VEC3* out_pos);
255DR_VEC3 dr_entity_extrapolate(const DR_ENTITY* entity, const DR_STATE* state, double dt);
257bool dr_entity_check_threshold(const DR_ENTITY* entity,
258 const DR_VEC3* true_pos,
259 const DR_VEC3* true_vel,
260 const DR_VEC3* true_acc,
261 double time);
263void dr_entity_set_algo(DR_ENTITY* entity, DR_ALGO algo);
265void dr_entity_set_blend_mode(DR_ENTITY* entity, DR_BLEND blend_mode);
267void dr_entity_set_threshold(DR_ENTITY* entity, double threshold);
269void dr_entity_set_blend_time(DR_ENTITY* entity, double blend_time);
272 const DR_VEC3* pos,
273 const DR_VEC3* vel,
274 const DR_VEC3* acc,
275 double time);
276
281#ifdef __cplusplus
282}
283#endif
284
285#endif /* N_DEAD_RECKONING_H */
DR_VEC3 pos
Position.
double blend_start
Timestamp when blending started.
double x
X component.
DR_VEC3 bezier_p2
Control point 2.
DR_VEC3 bezier_p3
End point (extrapolated last_known at blend_time)
double y
Y component.
DR_ALGO algo
Extrapolation algorithm.
DR_VEC3 bezier_p1
Control point 1.
double blend_time
Duration of convergence blend in seconds.
double z
Z component.
DR_STATE prev_predicted
Where we THOUGHT entity was when update arrived (P0, V0)
DR_VEC3 vel
Velocity.
DR_VEC3 acc
Acceleration.
double time
Timestamp (seconds) when this state was captured.
bool blending
True if currently blending toward last_known.
DR_VEC3 display_vel
Current blended/rendered velocity.
DR_VEC3 bezier_p0
Start point (previous predicted position)
DR_STATE last_known
Most recent authoritative state (P0', V0', A0')
DR_BLEND blend_mode
Convergence blending mode.
double pos_threshold
Position error threshold for sending updates (distance)
DR_VEC3 display_pos
Current blended/rendered position.
int update_count
Number of state updates received.
static DR_VEC3 dr_vec3_scale(DR_VEC3 v, double s)
Scalar multiplication: v * s.
void dr_entity_destroy(DR_ENTITY **entity_ptr)
destroy a dead reckoning entity and free its memory
static DR_VEC3 dr_vec3_lerp(DR_VEC3 a, DR_VEC3 b, double t)
Linear interpolation: a + (b - a) * t.
static DR_VEC3 dr_vec3(double x, double y, double z)
Create a DR_VEC3 from components.
void dr_entity_set_threshold(DR_ENTITY *entity, double threshold)
set the position error threshold
void dr_entity_compute(DR_ENTITY *entity, double time, DR_VEC3 *out_pos)
compute the dead reckoned display position at a given time
DR_ENTITY * dr_entity_create(DR_ALGO algo, DR_BLEND blend_mode, double pos_threshold, double blend_time)
create a new dead reckoning entity
void dr_entity_set_blend_time(DR_ENTITY *entity, double blend_time)
set the convergence blend duration
DR_BLEND
Dead reckoning convergence/blending mode.
void dr_entity_set_blend_mode(DR_ENTITY *entity, DR_BLEND blend_mode)
set the convergence blending mode
static DR_VEC3 dr_vec3_sub(DR_VEC3 a, DR_VEC3 b)
Vector subtraction: a - b.
bool dr_entity_check_threshold(const DR_ENTITY *entity, const DR_VEC3 *true_pos, const DR_VEC3 *true_vel, const DR_VEC3 *true_acc, double time)
check if the owner's true state has diverged beyond the threshold
DR_ALGO
Dead reckoning extrapolation algorithm.
void dr_entity_set_algo(DR_ENTITY *entity, DR_ALGO algo)
set the extrapolation algorithm
static double dr_vec3_length_sq(DR_VEC3 v)
Squared length of vector.
static DR_VEC3 dr_vec3_zero(void)
Zero vector.
static DR_VEC3 dr_vec3_add(DR_VEC3 a, DR_VEC3 b)
Vector addition: a + b.
static double dr_vec3_distance(DR_VEC3 a, DR_VEC3 b)
Distance between two points.
static double dr_vec3_length(DR_VEC3 v)
Length of vector.
void dr_entity_receive_state(DR_ENTITY *entity, const DR_VEC3 *pos, const DR_VEC3 *vel, const DR_VEC3 *acc, double time)
receive a new authoritative state update from the network
void dr_entity_set_position(DR_ENTITY *entity, const DR_VEC3 *pos, const DR_VEC3 *vel, const DR_VEC3 *acc, double time)
force-set entity position without blending
DR_VEC3 dr_entity_extrapolate(const DR_ENTITY *entity, const DR_STATE *state, double dt)
extrapolate a kinematic state forward by dt seconds
@ DR_BLEND_CUBIC
Cubic Bezier spline convergence.
@ DR_BLEND_PVB
Projective Velocity Blending (recommended)
@ DR_BLEND_SNAP
Snap instantly to new state (no smoothing)
@ DR_ALGO_VEL_ACC
Velocity + acceleration: P(t) = P0 + V0*t + 0.5*A0*t^2.
@ DR_ALGO_VEL
Velocity only: P(t) = P0 + V0*t.
@ DR_ALGO_STATIC
No extrapolation; entity stays at last position.
Dead reckoned entity with extrapolation and convergence state.
A snapshot of entity kinematic state at a point in time.
3D vector used for position, velocity, and acceleration