Animated 3D Models#
Script for loading animated 3D models (glTF 2.0 / GLB)
This script turns a keyframe-animated glTF 2.0 or GLB file into ordinary
RadarSimPy target dictionaries. Each animated node of the model becomes its own
target carrying per-timestamp location/speed/rotation/
rotation_rate arrays sampled at radar.time_prop["timestamp"], so a
spinning rotor, a turning wheel or a keyframed flight path is simulated with
the motion authored in the 3D file rather than re-derived by hand.
Only rigid node animation is supported. Skinning, morph targets and animated scale would require per-timestep vertex geometry, which the ray tracer does not model; those inputs raise a descriptive error.
—
Copyright (C) 2018 - PRESENT radarsimx.com
E-mail: info@radarsimx.com
Website: https://radarsimx.com
██████╗ █████╗ ██████╗ █████╗ ██████╗ ███████╗██╗███╗ ███╗██╗ ██╗
██╔══██╗██╔══██╗██╔══██╗██╔══██╗██╔══██╗██╔════╝██║████╗ ████║╚██╗██╔╝
██████╔╝███████║██║ ██║███████║██████╔╝███████╗██║██╔████╔██║ ╚███╔╝
██╔══██╗██╔══██║██║ ██║██╔══██║██╔══██╗╚════██║██║██║╚██╔╝██║ ██╔██╗
██║ ██║██║ ██║██████╔╝██║ ██║██║ ██║███████║██║██║ ╚═╝ ██║██╔╝ ██╗
╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝╚═╝ ╚═╝╚═╝ ╚═╝
- radarsimpy.animation_kit.import_gltf_module()[source]#
Import the glTF parsing module used to read animated models
- Returns:
The
pygltflibmodule object- Return type:
object
- Raises:
ImportError – If
pygltflibis not installed
- radarsimpy.animation_kit.load_animated_model(filename, *, animation=None, unit='m', up_axis='y', merge_static=True)[source]#
Load an animated glTF 2.0 / GLB model and split it into rigid parts
Geometry is grouped by the nearest animated ancestor node, so each returned part moves as one rigid body. Parts are expressed in their own node frame, which is the frame their sampled pose applies to.
- Parameters:
filename (str) – Path to a
.gltfor.glbfileanimation (str | int | None) – Animation name or index to read. Default: the first one.
unit (str) – Unit the file is authored in (
'm','cm','mm'). Default:'m', which is what the glTF specification mandates.up_axis (str) – Up axis of the file,
'y'(glTF default) or'z'. Geometry and motion are rotated into RadarSimPy’s Z-up frame.merge_static (bool) – Merge all non-animated geometry into a single part. Default:
True.
- Returns:
Dictionary containing:
parts (list): One entry per rigid part, each a dict with
name,points,cells,nodeandanimated.animation (str or None): Name of the selected animation.
animations (list): Names of every animation in the file.
duration (float): Length of the selected animation in seconds.
start_time (float): Time of its first keyframe in seconds.
- Return type:
dict
- Raises:
NotImplementedError – For skinning, morph targets, animated scale, non-uniform scale on an animated node, or non-triangle primitives.
- radarsimpy.animation_kit.load_animated_targets(filename, radar=None, *, at_time=None, animation=None, time_offset=0.0, time_scale=1.0, loop=True, location=(0, 0, 0), speed=(0, 0, 0), rotation=(0, 0, 0), rotation_rate=(0, 0, 0), unit='m', up_axis='y', merge_static=True, **target_kwargs)[source]#
Build RadarSimPy target dictionaries from an animated glTF 2.0 / GLB model
Each animated node of the model becomes one target whose
location,speed,rotationandrotation_rateare arrays sampled atradar.time_prop["timestamp"], so the motion authored in the file drives both the geometry and the Doppler. Non-animated geometry becomes a single static target.The returned list is passed straight to
radarsimpy.sim_radar():>>> targets = load_animated_targets("turbine.glb", radar, location=(50, 0, 0)) >>> data = sim_radar(radar, targets)
Only rigid node animation is supported. Skinned meshes, morph targets and animated scale raise
NotImplementedError, because the ray tracer transforms each target rigidly and cannot move individual vertices.Note
Every animated part allocates twelve
float32arrays the size ofradar.time_prop["timestamp"]. Models with many independently moving parts, simulated over long time records, use a correspondingly large amount of memory. Merge parts that do not move independently to reduce it.- Parameters:
filename (str | Dict[str, Any]) – Path to a
.gltf/.glbfile, or a model already returned byload_animated_model().radar (Any) –
radarsimpy.Radarwhose timestamps the animation is sampled at. Required unlessat_timeis given.at_time (float | None) – Sample a single instant instead, returning static targets. Use this for
radarsimpy.sim_rcs()andradarsimpy.sim_lidar(), which do not accept time-varying motion.animation (str | int | None) – Animation name or index. Default: the first one.
time_offset (float) – Animation time at simulation time zero (s).
time_scale (float) – Playback rate;
2.0plays twice as fast.loop (bool) – Wrap the animation when the simulation outlasts the clip. When
Falsethe first and last poses are held. Default:True.location (Sequence[float]) – Position of the whole model in the global frame [x, y, z] (m).
speed (Sequence[float]) – Velocity of the whole model [vx, vy, vz] (m/s).
rotation (Sequence[float]) – Orientation of the whole model [yaw, pitch, roll] (deg).
rotation_rate (Sequence[float]) – Rotation rate of the whole model [yaw rate, pitch rate, roll rate] (deg/s).
unit (str) – Unit the file is authored in. Default:
'm'.up_axis (str) – Up axis of the file,
'y'or'z'. Default:'y'.merge_static (bool) – Merge all non-animated geometry into one target.
target_kwargs (Any) – Extra keys copied into every target dictionary, such as
permittivity,permeability,skip_diffusion,densityandenvironment.
- Returns:
Target dictionaries ready for
radarsimpy.sim_radar()- Return type:
list
- Raises:
ValueError – If neither
radarnorat_timeis provided