diff --git a/README.md b/README.md index f8d833a..bc67903 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Requires **Blender 5.2 LTS** or newer (files were written with 5.2.3). | Folder | What is in it | |---|---| -| [`instruments/`](instruments/) | One `.blend` per ARM instrument (AERI, KAZR, DL, MPL, MWR3C, MET tower, ECOR, SEBS, SIRS, RWP, …) plus the C-SAPR2 radar and the KAWG AWOS | +| [`instruments/`](instruments/) | One `.blend` per ARM instrument (AERI, KAZR, DL, MPL, MWR3C, MET tower, ECOR, SEBS, SIRS, RWP, …) plus the C-SAPR2 radar, the KAWG AWOS and the radiosonde balloon launch (balloon, sonde, line and launch crew, animated) | | [`containers/`](containers/) | AMF2 instrument containers, AOS platform, office shelter, and the SACR container (M1 and S2 versions) | | [`buildings/`](buildings/) | Farmstead (M1), MIRF buildings and center pivots (S1), KAWG hangars and terminal (S2), Louisa power station, flagpole, site signs | | [`vehicles/`](vehicles/) | Farm vehicles and implements, and the ARM Challenger 850 research aircraft | diff --git a/instruments/BALLOON/BALLOON.blend b/instruments/BALLOON/BALLOON.blend new file mode 100644 index 0000000..9104dd2 Binary files /dev/null and b/instruments/BALLOON/BALLOON.blend differ diff --git a/instruments/README.md b/instruments/README.md index c6a9d25..ab96d8c 100644 --- a/instruments/README.md +++ b/instruments/README.md @@ -2,18 +2,21 @@ One file per instrument; link the `INST_*` (or `CSAPR2`) collection. Root at the origin. +`INST_BALLOON` is the radiosonde launch at M1: balloon, sonde, the line (a stretch-to constraint from sonde to balloon) and the two-person launch crew (`BALLOON_Crew`). It carries the release animation over frames 1–480; the *_Hold/*_Release crew poses swap visibility at release. + | Preview | Collection | File | |---|---|---| | | `INST_AERI` | [`AERI/AERI.blend`](AERI/AERI.blend) (0.2 MB) | | | `INST_AOSMET` | [`AOSMET/AOSMET.blend`](AOSMET/AOSMET.blend) (0.1 MB) | | | `INST_ASI` | [`ASI/ASI.blend`](ASI/ASI.blend) (0.2 MB) | | | `INST_AWOS` | [`AWOS/AWOS.blend`](AWOS/AWOS.blend) (0.3 MB) | +| | `INST_BALLOON` | [`BALLOON/BALLOON.blend`](BALLOON/BALLOON.blend) (1.9 MB) | | | `INST_CEIL` | [`CEIL/CEIL.blend`](CEIL/CEIL.blend) (0.1 MB) | | | `CSAPR2` | [`CSAPR2/CSAPR2.blend`](CSAPR2/CSAPR2.blend) (1.2 MB) | | | `INST_CSPHOT` | [`CSPHOT/CSPHOT.blend`](CSPHOT/CSPHOT.blend) (0.2 MB) | | | `INST_DL` | [`DL/DL.blend`](DL/DL.blend) (0.2 MB) | -| | `INST_ECOR_4m` | [`ECOR/ECOR.blend`](ECOR/ECOR.blend) (0.3 MB) | | | `INST_ECOR` | [`ECOR/ECOR.blend`](ECOR/ECOR.blend) (0.3 MB) | +| | `INST_ECOR_4m` | [`ECOR/ECOR.blend`](ECOR/ECOR.blend) (0.3 MB) | | | `INST_IRT` | [`IRT/IRT.blend`](IRT/IRT.blend) (0.1 MB) | | | `INST_KAZR` | [`KAZR/KAZR.blend`](KAZR/KAZR.blend) (0.2 MB) | | | `INST_LDIS` | [`LDIS/LDIS.blend`](LDIS/LDIS.blend) (0.1 MB) | diff --git a/instruments/preview/BALLOON.jpg b/instruments/preview/BALLOON.jpg new file mode 100644 index 0000000..1ff58d4 Binary files /dev/null and b/instruments/preview/BALLOON.jpg differ diff --git a/scenes/M1/M1.blend b/scenes/M1/M1.blend index e34d96c..de211c5 100644 Binary files a/scenes/M1/M1.blend and b/scenes/M1/M1.blend differ diff --git a/scenes/README.md b/scenes/README.md index 9112867..e75dca0 100644 --- a/scenes/README.md +++ b/scenes/README.md @@ -4,7 +4,7 @@ Each site scene is a thin file holding cameras, lights, world and render setting ## M1 -`M1/M1.blend` (2.3 MB) — layers: `M1/layers/m1_amf2_site.blend` (0.2 MB), `M1/layers/m1_fields.blend` (11.8 MB), `M1/layers/m1_ground.blend` (45.4 MB) +`M1/M1.blend` (0.5 MB) — layers: `M1/layers/m1_amf2_site.blend` (0.2 MB), `M1/layers/m1_fields.blend` (11.8 MB), `M1/layers/m1_ground.blend` (45.4 MB) diff --git a/tools/balloon_track.py b/tools/balloon_track.py new file mode 100644 index 0000000..0ad23d4 --- /dev/null +++ b/tools/balloon_track.py @@ -0,0 +1,15 @@ +"""Print world positions of the balloon-launch parts over the animation (for before/after checks).""" +import bpy, json, sys +out = sys.argv[sys.argv.index('--') + 1] +sc = bpy.context.scene +names = ('Balloon', 'Sonde', 'BalloonLine', 'Launcher_Hold', 'Launcher_Release', 'Helper_Hold', 'Helper_Release') +res = {} +for f in (1, 60, 120, 180, 240, 300, 360, 480): + sc.frame_set(f) + dg = bpy.context.evaluated_depsgraph_get() + for inst in dg.object_instances: + n = inst.object.name.split('.')[0] + if n in names and inst.show_self: + m = inst.matrix_world + res[f'{f}:{n}'] = [round(v, 3) for v in list(m.translation) + list(m.col[2][:3])] +json.dump(res, open(out, 'w'), indent=0, sort_keys=True) diff --git a/tools/build_balloon.py b/tools/build_balloon.py new file mode 100644 index 0000000..4d7c52e --- /dev/null +++ b/tools/build_balloon.py @@ -0,0 +1,38 @@ +"""Move the M1 radiosonde balloon launch (balloon, sonde, line and launch crew) out of +scenes/M1/M1.blend into instruments/BALLOON/BALLOON.blend and link it back. +blender -b scenes/M1/M1.blend --python tools/build_balloon.py + +All parts are parented to a new root at the launch point (transforms and the +release animation preserved), the root is moved to the origin in the library, +and M1 gets a collection instance at the original launch point. +""" +import bpy, os, sys +from mathutils import Matrix, Vector +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +import ablib as A +D = bpy.data +c = D.collections['BalloonLaunch'] +c.name = 'INST_BALLOON' +crew = D.collections['BalloonCrew'] +crew.name = 'BALLOON_Crew' + +sonde = D.objects['Sonde'] +root = D.objects.new('BALLOON_root', None) +root.empty_display_size = 1.0 +c.objects.link(root) +root.matrix_world = Matrix.Translation(Vector((sonde.matrix_world.translation.x, + sonde.matrix_world.translation.y, -0.08))) +bpy.context.view_layer.update() +inv = root.matrix_world.inverted() +for o in list(c.all_objects): + if o is root or o.parent is not None: + continue + o.parent = root + o.matrix_parent_inverse = inv # keeps world placement and the keyframed motion +bpy.context.view_layer.update() + +A.extract_normalized('instruments/BALLOON/BALLOON.blend', [('INST_BALLOON', 'BALLOON_root')]) +A.purge() +bpy.ops.file.make_paths_relative() +bpy.ops.wm.save_mainfile(compress=True, relative_remap=True) +print('BALLOON_DONE') diff --git a/tools/preview_jobs/instruments.json b/tools/preview_jobs/instruments.json index 92587d2..c448a0d 100644 --- a/tools/preview_jobs/instruments.json +++ b/tools/preview_jobs/instruments.json @@ -43,6 +43,19 @@ ], "samples": 64 }, + { + "lib": "instruments/BALLOON/BALLOON.blend", + "coll": "INST_BALLOON", + "out": "instruments/preview/BALLOON.jpg", + "view": "front_x", + "res": [ + 1024, + 768 + ], + "samples": 64, + "tight": 0.75, + "zfrac": 0.45 + }, { "lib": "instruments/CEIL/CEIL.blend", "coll": "INST_CEIL", @@ -89,8 +102,8 @@ }, { "lib": "instruments/ECOR/ECOR.blend", - "coll": "INST_ECOR_4m", - "out": "instruments/preview/ECOR_4m.jpg", + "coll": "INST_ECOR", + "out": "instruments/preview/ECOR.jpg", "view": "34", "res": [ 1024, @@ -100,8 +113,8 @@ }, { "lib": "instruments/ECOR/ECOR.blend", - "coll": "INST_ECOR", - "out": "instruments/preview/ECOR.jpg", + "coll": "INST_ECOR_4m", + "out": "instruments/preview/ECOR_4m.jpg", "view": "34", "res": [ 1024,