framefields 2.14.0 → 2.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE.md +5 -1
- package/dist/audio/index.d.mts +3 -3
- package/dist/audio/index.mjs +10 -10
- package/dist/{audio-DFwRbID_.mjs → audio-6TfPlfl4.mjs} +3 -3
- package/dist/{audio-DFwRbID_.mjs.map → audio-6TfPlfl4.mjs.map} +1 -1
- package/dist/{audio-CdCuGK5d.d.mts → audio-7oqTUi4G.d.mts} +2 -2
- package/dist/{audio-CdCuGK5d.d.mts.map → audio-7oqTUi4G.d.mts.map} +1 -1
- package/dist/cli/check-worker.mjs +44 -44
- package/dist/cli.mjs +1 -1
- package/dist/cloud/index.mjs +1 -1
- package/dist/{cloud-Cj1TIme8.mjs → cloud-jnk1hPYf.mjs} +2 -2
- package/dist/{cloud-Cj1TIme8.mjs.map → cloud-jnk1hPYf.mjs.map} +1 -1
- package/dist/components/index.d.mts +11 -11
- package/dist/components/index.mjs +43 -43
- package/dist/{dist-Kbf-JTry.mjs → dist-BtI6ukB5.mjs} +2 -2
- package/dist/{dist-Kbf-JTry.mjs.map → dist-BtI6ukB5.mjs.map} +1 -1
- package/dist/{dist-B8Nby2CU.mjs → dist-COOpgG9G.mjs} +4 -3
- package/dist/{dist-B8Nby2CU.mjs.map → dist-COOpgG9G.mjs.map} +1 -1
- package/dist/{dist--Uu5bQ_6.mjs → dist-XqlFM2a8.mjs} +13733 -5323
- package/dist/dist-XqlFM2a8.mjs.map +1 -0
- package/dist/{dist-CiTgmfUw.mjs → dist-f1zkl69f.mjs} +4 -4
- package/dist/dist-f1zkl69f.mjs.map +1 -0
- package/dist/{dist-B_rSWeOz.mjs → dist-umQOWz0a.mjs} +1 -1
- package/dist/effects/index.d.mts +4 -4
- package/dist/effects/index.mjs +35 -35
- package/dist/{effects-WMgv8ZaD.mjs → effects-DlRMovU5.mjs} +2 -2
- package/dist/{effects-WMgv8ZaD.mjs.map → effects-DlRMovU5.mjs.map} +1 -1
- package/dist/fonts/index.d.mts +1 -1
- package/dist/fonts/index.mjs +2 -2
- package/dist/{fonts-OW3yAfO5.mjs → fonts-BWYcXjyK.mjs} +3 -3
- package/dist/fonts-BWYcXjyK.mjs.map +1 -0
- package/dist/{gpu-R4T2Tndu.mjs → gpu-CH1PdM4T.mjs} +2 -2
- package/dist/{gpu-R4T2Tndu.mjs.map → gpu-CH1PdM4T.mjs.map} +1 -1
- package/dist/{index-CEKxvGY-.d.mts → index-BHTycml5.d.mts} +2 -2
- package/dist/{index-CEKxvGY-.d.mts.map → index-BHTycml5.d.mts.map} +1 -1
- package/dist/{index-DoP6EiHj.d.mts → index-BcxxxwhV.d.mts} +4 -4
- package/dist/{index-DoP6EiHj.d.mts.map → index-BcxxxwhV.d.mts.map} +1 -1
- package/dist/index-C-V6CAhP.d.mts.map +1 -1
- package/dist/{index-D1FqV1eu.d.mts → index-CMhkkc56.d.mts} +43 -11
- package/dist/index-CMhkkc56.d.mts.map +1 -0
- package/dist/{index-B0Vq8Bwf.d.mts → index-CYVpYGM-.d.mts} +2 -2
- package/dist/{index-B0Vq8Bwf.d.mts.map → index-CYVpYGM-.d.mts.map} +1 -1
- package/dist/{index-Bv7gxGK1.d.mts → index-Cq8jgdNY.d.mts} +90 -3
- package/dist/index-Cq8jgdNY.d.mts.map +1 -0
- package/dist/{index-9xte4JgL.d.mts → index-Dg5BAtDq.d.mts} +1446 -541
- package/dist/index-Dg5BAtDq.d.mts.map +1 -0
- package/dist/{index-C7-p9zwU.d.mts → index-DhL7ckvs.d.mts} +5 -5
- package/dist/index-DhL7ckvs.d.mts.map +1 -0
- package/dist/{index-GA9_Z8Fn.d.mts → index-RILu3ULT.d.mts} +2 -2
- package/dist/{index-GA9_Z8Fn.d.mts.map → index-RILu3ULT.d.mts.map} +1 -1
- package/dist/{index-C5sgRLlG.d.mts → index-TCtdSXd7.d.mts} +3 -1
- package/dist/index-TCtdSXd7.d.mts.map +1 -0
- package/dist/{index-CRaydvLi.d.mts → index-s2qQ8ifZ.d.mts} +886 -51
- package/dist/index-s2qQ8ifZ.d.mts.map +1 -0
- package/dist/index.d.mts +13 -13
- package/dist/index.mjs +52 -52
- package/dist/preview/index.d.mts +4 -4
- package/dist/preview/index.mjs +11 -11
- package/dist/preview-Dm912wly.mjs +1037 -0
- package/dist/preview-Dm912wly.mjs.map +1 -0
- package/dist/preview-engine/audio.mjs +1 -1
- package/dist/preview-engine/{chunk-64L4GUOF.mjs → chunk-4F3DG6YB.mjs} +2 -2
- package/dist/preview-engine/chunk-A2OTOW3B.mjs +4694 -0
- package/dist/preview-engine/{chunk-GNDE3OXQ.mjs → chunk-BR56TQBP.mjs} +1 -1
- package/dist/preview-engine/{chunk-ADLIF544.mjs → chunk-H2XKXXAU.mjs} +1 -1
- package/dist/preview-engine/chunk-NDUODAY2.mjs +3 -0
- package/dist/preview-engine/{chunk-FZ4RD7HV.mjs → chunk-QAQJSWUT.mjs} +1 -1
- package/dist/preview-engine/chunk-SWRGQTVC.mjs +138 -0
- package/dist/preview-engine/{chunk-52X7SURQ.mjs → chunk-TEA3GVBJ.mjs} +1 -1
- package/dist/preview-engine/chunk-VZUVB3BP.mjs +644 -0
- package/dist/preview-engine/{chunk-UBY2UYEL.mjs → chunk-XSHNQJ7L.mjs} +1 -1
- package/dist/preview-engine/components.mjs +1 -1
- package/dist/preview-engine/effects.mjs +1 -1
- package/dist/preview-engine/fonts.mjs +1 -1
- package/dist/preview-engine/framefields.mjs +1 -1
- package/dist/preview-engine/player.mjs +3 -3
- package/dist/preview-engine/{renderers-DU7KPFVV.mjs → renderers-6C7NWWDX.mjs} +1 -1
- package/dist/preview-engine/renderers-HHVGNMSJ.mjs +206 -0
- package/dist/preview-engine/{src-YXNX4MLK.mjs → src-RCNEKIRP.mjs} +1 -1
- package/dist/preview-page/index.html +19 -0
- package/dist/preview-page/main.css +1 -0
- package/dist/preview-page/main.js +326 -0
- package/dist/{program-tFKCWU2j.mjs → program-CMigyfso.mjs} +829 -52
- package/dist/program-CMigyfso.mjs.map +1 -0
- package/dist/renderer/index.d.mts +2 -2
- package/dist/renderer/index.mjs +2 -2
- package/dist/{renderer-DkOuQi84.mjs → renderer-0GMEL_Zi.mjs} +3 -3
- package/dist/{renderer-DkOuQi84.mjs.map → renderer-0GMEL_Zi.mjs.map} +1 -1
- package/dist/{renderer-BGp0An5A.mjs → renderer-3Wv2ZBJG.mjs} +3 -3
- package/dist/{renderer-BGp0An5A.mjs.map → renderer-3Wv2ZBJG.mjs.map} +1 -1
- package/dist/{renderer-BVIXKfbC.mjs → renderer-4nXkaAWu.mjs} +1178 -199
- package/dist/renderer-4nXkaAWu.mjs.map +1 -0
- package/dist/{renderer-Cw6_NL2i.mjs → renderer-6SnfLXeg.mjs} +3 -3
- package/dist/{renderer-Cw6_NL2i.mjs.map → renderer-6SnfLXeg.mjs.map} +1 -1
- package/dist/{renderer-BVU22lBS.mjs → renderer-8gHw3O0P.mjs} +2 -2
- package/dist/{renderer-BVU22lBS.mjs.map → renderer-8gHw3O0P.mjs.map} +1 -1
- package/dist/{renderer-BjDddtw9.mjs → renderer-AOBglZHC.mjs} +2 -2
- package/dist/{renderer-D-KHHWQD.mjs → renderer-B0bSARK3.mjs} +3 -3
- package/dist/{renderer-D-KHHWQD.mjs.map → renderer-B0bSARK3.mjs.map} +1 -1
- package/dist/{renderer-CCxk-RJR.mjs → renderer-B2_tuRfl.mjs} +2 -2
- package/dist/{renderer-CCxk-RJR.mjs.map → renderer-B2_tuRfl.mjs.map} +1 -1
- package/dist/{renderer-k5d7JSbs.mjs → renderer-B82FhkEr.mjs} +3 -3
- package/dist/{renderer-k5d7JSbs.mjs.map → renderer-B82FhkEr.mjs.map} +1 -1
- package/dist/{renderer-I0Hh9cLK.mjs → renderer-B9lzA0PY.mjs} +3 -3
- package/dist/{renderer-I0Hh9cLK.mjs.map → renderer-B9lzA0PY.mjs.map} +1 -1
- package/dist/{renderer-Dwwnx7Dk.mjs → renderer-BBSIWSry.mjs} +2 -2
- package/dist/{renderer-Dwwnx7Dk.mjs.map → renderer-BBSIWSry.mjs.map} +1 -1
- package/dist/{renderer-_pC-jB9O.mjs → renderer-BEKDMxbi.mjs} +2 -2
- package/dist/{renderer-_pC-jB9O.mjs.map → renderer-BEKDMxbi.mjs.map} +1 -1
- package/dist/renderer-BERGAxqA.mjs +5 -0
- package/dist/{renderer-raxwsiGI.mjs → renderer-BF960HY8.mjs} +3 -3
- package/dist/{renderer-raxwsiGI.mjs.map → renderer-BF960HY8.mjs.map} +1 -1
- package/dist/{renderer-Dr0tXA4k.mjs → renderer-BFwyVxCu.mjs} +3 -3
- package/dist/{renderer-Dr0tXA4k.mjs.map → renderer-BFwyVxCu.mjs.map} +1 -1
- package/dist/{renderer-DEjo6dw_.mjs → renderer-BNiwcI3-.mjs} +2 -2
- package/dist/{renderer-DEjo6dw_.mjs.map → renderer-BNiwcI3-.mjs.map} +1 -1
- package/dist/{renderer-DIEeHiQA.mjs → renderer-BPbVb2Q4.mjs} +2 -2
- package/dist/{renderer-DIEeHiQA.mjs.map → renderer-BPbVb2Q4.mjs.map} +1 -1
- package/dist/renderer-BQ_YkBMt.mjs +6 -0
- package/dist/{renderer-BBMtmxks.mjs → renderer-BUWxlA8T.mjs} +3 -3
- package/dist/{renderer-BBMtmxks.mjs.map → renderer-BUWxlA8T.mjs.map} +1 -1
- package/dist/renderer-BW0Tjsv9.mjs +5 -0
- package/dist/{renderer-Dgj46uEU.mjs → renderer-BX8liu-e.mjs} +2 -2
- package/dist/{renderer-ZnrEfkYh.mjs → renderer-BXIwDAr_.mjs} +2 -2
- package/dist/{renderer-ZnrEfkYh.mjs.map → renderer-BXIwDAr_.mjs.map} +1 -1
- package/dist/{renderer-DA8YEo_d.mjs → renderer-B_Hy1W-g.mjs} +3 -3
- package/dist/{renderer-DA8YEo_d.mjs.map → renderer-B_Hy1W-g.mjs.map} +1 -1
- package/dist/{renderer-iMiYStcW.mjs → renderer-Bb6cvSgh.mjs} +2 -2
- package/dist/{renderer-iMiYStcW.mjs.map → renderer-Bb6cvSgh.mjs.map} +1 -1
- package/dist/{renderer-BacY4nh8.mjs → renderer-BdppwWC9.mjs} +2 -2
- package/dist/{renderer-BacY4nh8.mjs.map → renderer-BdppwWC9.mjs.map} +1 -1
- package/dist/{renderer-CrxwW6VQ.mjs → renderer-Bhc24HVe.mjs} +3 -3
- package/dist/{renderer-CrxwW6VQ.mjs.map → renderer-Bhc24HVe.mjs.map} +1 -1
- package/dist/{renderer-BH7UCMPQ.mjs → renderer-BiNA2wF0.mjs} +2 -2
- package/dist/{renderer-BH7UCMPQ.mjs.map → renderer-BiNA2wF0.mjs.map} +1 -1
- package/dist/{renderer-DVPgWHZw.mjs → renderer-BmoBgTp5.mjs} +3 -3
- package/dist/{renderer-DVPgWHZw.mjs.map → renderer-BmoBgTp5.mjs.map} +1 -1
- package/dist/{renderer-C20efMI0.mjs → renderer-BmqFmCWS.mjs} +3 -3
- package/dist/{renderer-C20efMI0.mjs.map → renderer-BmqFmCWS.mjs.map} +1 -1
- package/dist/{renderer-B0yVUOPP.mjs → renderer-BnVwAObV.mjs} +2 -2
- package/dist/{renderer-B0yVUOPP.mjs.map → renderer-BnVwAObV.mjs.map} +1 -1
- package/dist/{renderer-CP8wLzTU.mjs → renderer-BxttZHme.mjs} +2 -2
- package/dist/{renderer-CP8wLzTU.mjs.map → renderer-BxttZHme.mjs.map} +1 -1
- package/dist/renderer-BzyPdUD1.mjs +5 -0
- package/dist/renderer-C0hM-mtY.mjs +5 -0
- package/dist/renderer-C6cyUTvk.mjs +5 -0
- package/dist/{renderer-BOSZAdgF.mjs → renderer-C8E4XsSg.mjs} +2 -2
- package/dist/{renderer-BOSZAdgF.mjs.map → renderer-C8E4XsSg.mjs.map} +1 -1
- package/dist/renderer-C8zY3pzk.mjs +5 -0
- package/dist/{renderer-DWq9gYRw.mjs → renderer-C9U-LY50.mjs} +3 -3
- package/dist/{renderer-DWq9gYRw.mjs.map → renderer-C9U-LY50.mjs.map} +1 -1
- package/dist/{renderer-Dj2H5JPR.mjs → renderer-CB2JVu5x.mjs} +3 -3
- package/dist/{renderer-Dj2H5JPR.mjs.map → renderer-CB2JVu5x.mjs.map} +1 -1
- package/dist/{renderer-Bcu3UrI-.mjs → renderer-CC4YBJ8Z.mjs} +3 -3
- package/dist/{renderer-Bcu3UrI-.mjs.map → renderer-CC4YBJ8Z.mjs.map} +1 -1
- package/dist/renderer-CEkSOyKu.mjs +5 -0
- package/dist/{renderer-DzLrvCB2.mjs → renderer-CIycc5O-.mjs} +2 -2
- package/dist/{renderer-DzLrvCB2.mjs.map → renderer-CIycc5O-.mjs.map} +1 -1
- package/dist/renderer-CJYtfa4x.mjs +5 -0
- package/dist/{renderer-BeNl_6EG.mjs → renderer-CJraQlV-.mjs} +2 -2
- package/dist/{renderer-BeNl_6EG.mjs.map → renderer-CJraQlV-.mjs.map} +1 -1
- package/dist/renderer-CKMtHGZh.mjs +5 -0
- package/dist/renderer-CLzicoiy.mjs +5 -0
- package/dist/renderer-CM2A4BHd.mjs +5 -0
- package/dist/{renderer-DtMVitEF.mjs → renderer-COWGWtob.mjs} +2 -2
- package/dist/{renderer-DtMVitEF.mjs.map → renderer-COWGWtob.mjs.map} +1 -1
- package/dist/{renderer-CT3zkfbf.mjs → renderer-COxG2XGf.mjs} +2 -2
- package/dist/{renderer-CT3zkfbf.mjs.map → renderer-COxG2XGf.mjs.map} +1 -1
- package/dist/{renderer-DNxWOz8Q.mjs → renderer-CQDCIsQm.mjs} +2 -2
- package/dist/{renderer-DNxWOz8Q.mjs.map → renderer-CQDCIsQm.mjs.map} +1 -1
- package/dist/{renderer-C5AoaymD.mjs → renderer-CRUeag8i.mjs} +3 -3
- package/dist/{renderer-C5AoaymD.mjs.map → renderer-CRUeag8i.mjs.map} +1 -1
- package/dist/{renderer-ngmYIIob.mjs → renderer-CWVput06.mjs} +3 -3
- package/dist/{renderer-ngmYIIob.mjs.map → renderer-CWVput06.mjs.map} +1 -1
- package/dist/renderer-CZlHjcxr.mjs +5 -0
- package/dist/{renderer-0rveCDm-.mjs → renderer-CbbnBLOB.mjs} +3 -3
- package/dist/{renderer-0rveCDm-.mjs.map → renderer-CbbnBLOB.mjs.map} +1 -1
- package/dist/renderer-CbimvSU8.mjs +5 -0
- package/dist/renderer-Ccvc63yd.mjs +5 -0
- package/dist/renderer-Cdp-SGfq.mjs +5 -0
- package/dist/renderer-CeTcSs3e.mjs +5 -0
- package/dist/{renderer-Brmbl12Y.mjs → renderer-CfLZein2.mjs} +3 -3
- package/dist/{renderer-Brmbl12Y.mjs.map → renderer-CfLZein2.mjs.map} +1 -1
- package/dist/{renderer-BJ8ea92W.mjs → renderer-Ch-q1O-q.mjs} +3 -3
- package/dist/{renderer-BJ8ea92W.mjs.map → renderer-Ch-q1O-q.mjs.map} +1 -1
- package/dist/{renderer-CP108ABB.mjs → renderer-Ch5JvJWl.mjs} +2 -2
- package/dist/{renderer-CP108ABB.mjs.map → renderer-Ch5JvJWl.mjs.map} +1 -1
- package/dist/{renderer-47y12Z37.mjs → renderer-ChtEzq-R.mjs} +2 -2
- package/dist/{renderer-47y12Z37.mjs.map → renderer-ChtEzq-R.mjs.map} +1 -1
- package/dist/{renderer-DhyMfG1v.mjs → renderer-Cj9nTC5l.mjs} +3 -3
- package/dist/{renderer-DhyMfG1v.mjs.map → renderer-Cj9nTC5l.mjs.map} +1 -1
- package/dist/{renderer-BDzn1AKF.mjs → renderer-CqT8HsSS.mjs} +2 -2
- package/dist/{renderer-BDzn1AKF.mjs.map → renderer-CqT8HsSS.mjs.map} +1 -1
- package/dist/{renderer-B7G1KohJ.mjs → renderer-CuQjMhdV.mjs} +2 -2
- package/dist/renderer-CvNuu52U.mjs +5 -0
- package/dist/renderer-CwciC0oI.mjs +5 -0
- package/dist/renderer-CysLUbIr.mjs +5 -0
- package/dist/{renderer-Cm0tsbQH.mjs → renderer-Cz30EVws.mjs} +2 -2
- package/dist/{renderer-Cm0tsbQH.mjs.map → renderer-Cz30EVws.mjs.map} +1 -1
- package/dist/renderer-D3A22Vxb.mjs +5 -0
- package/dist/renderer-D5SY9EmA.mjs +5 -0
- package/dist/renderer-D8h3ZvaE.mjs +5 -0
- package/dist/renderer-DE-B6N9n.mjs +5 -0
- package/dist/renderer-DETZTI7t.mjs +5 -0
- package/dist/{renderer-nHS3Sius.mjs → renderer-DHoX-5U_.mjs} +3 -3
- package/dist/{renderer-nHS3Sius.mjs.map → renderer-DHoX-5U_.mjs.map} +1 -1
- package/dist/{renderer-BWSRryIA.mjs → renderer-DOkm0Ycd.mjs} +2 -2
- package/dist/{renderer-BWSRryIA.mjs.map → renderer-DOkm0Ycd.mjs.map} +1 -1
- package/dist/{renderer-BHYJlK6H.d.mts → renderer-DU3f6ZrS.d.mts} +2 -2
- package/dist/{renderer-BHYJlK6H.d.mts.map → renderer-DU3f6ZrS.d.mts.map} +1 -1
- package/dist/{renderer-BpVOk9ux.mjs → renderer-DUzv-shq.mjs} +2 -2
- package/dist/{renderer-BpVOk9ux.mjs.map → renderer-DUzv-shq.mjs.map} +1 -1
- package/dist/renderer-DWnDj0IM.mjs +5 -0
- package/dist/renderer-DcGUIbQF.mjs +5 -0
- package/dist/renderer-Dfq6FoNO.mjs +5 -0
- package/dist/renderer-DhasXW6S.mjs +3 -0
- package/dist/{renderer-NRMlYkX6.mjs → renderer-DhnOWnEA.mjs} +3 -3
- package/dist/{renderer-NRMlYkX6.mjs.map → renderer-DhnOWnEA.mjs.map} +1 -1
- package/dist/{renderer-COgwYqev.mjs → renderer-Dhy1XHzz.mjs} +3 -3
- package/dist/{renderer-COgwYqev.mjs.map → renderer-Dhy1XHzz.mjs.map} +1 -1
- package/dist/renderer-DjCvpsV_.mjs +5 -0
- package/dist/{renderer-BfZNIiSv.mjs → renderer-DjJshz9Y.mjs} +2 -2
- package/dist/{renderer-BfZNIiSv.mjs.map → renderer-DjJshz9Y.mjs.map} +1 -1
- package/dist/{renderer-CKo7VR8x.mjs → renderer-DmTUIdus.mjs} +3 -3
- package/dist/{renderer-CKo7VR8x.mjs.map → renderer-DmTUIdus.mjs.map} +1 -1
- package/dist/{renderer-Baw6Utxi.mjs → renderer-Dq7AioJa.mjs} +2 -2
- package/dist/{renderer-Baw6Utxi.mjs.map → renderer-Dq7AioJa.mjs.map} +1 -1
- package/dist/renderer-DrAaM6JD.mjs +5 -0
- package/dist/{renderer-D-GWBoVT.mjs → renderer-Dt4sqNEu.mjs} +2 -2
- package/dist/{renderer-D-GWBoVT.mjs.map → renderer-Dt4sqNEu.mjs.map} +1 -1
- package/dist/{renderer-FYOL5Za6.mjs → renderer-Dtcs4idV.mjs} +3 -3
- package/dist/{renderer-FYOL5Za6.mjs.map → renderer-Dtcs4idV.mjs.map} +1 -1
- package/dist/renderer-Dxlv8LYm.mjs +5 -0
- package/dist/{renderer-D-RhYvVl.mjs → renderer-Gj8SrE2W.mjs} +2 -2
- package/dist/{renderer-D-RhYvVl.mjs.map → renderer-Gj8SrE2W.mjs.map} +1 -1
- package/dist/{renderer-D_j1WKMD.mjs → renderer-KfnXDJS0.mjs} +3 -3
- package/dist/{renderer-D_j1WKMD.mjs.map → renderer-KfnXDJS0.mjs.map} +1 -1
- package/dist/{renderer-Bpm145BW.mjs → renderer-MXVlg4p5.mjs} +3 -3
- package/dist/{renderer-Bpm145BW.mjs.map → renderer-MXVlg4p5.mjs.map} +1 -1
- package/dist/{renderer-Nnmi8Gt6.mjs → renderer-N2b6QZ1E.mjs} +3 -3
- package/dist/{renderer-Nnmi8Gt6.mjs.map → renderer-N2b6QZ1E.mjs.map} +1 -1
- package/dist/renderer-Pb43OO2t.mjs +5 -0
- package/dist/{renderer-Ca1KjNCO.mjs → renderer-Q7gDzm8c.mjs} +2 -2
- package/dist/{renderer-Ca1KjNCO.mjs.map → renderer-Q7gDzm8c.mjs.map} +1 -1
- package/dist/{renderer-D2wNFNRf.mjs → renderer-RCiANtRV.mjs} +2 -2
- package/dist/{renderer-D2wNFNRf.mjs.map → renderer-RCiANtRV.mjs.map} +1 -1
- package/dist/{renderer-Cqb7PGrI.mjs → renderer-Sig9nZcI.mjs} +2 -2
- package/dist/renderer-VQbm-cGr.mjs +5 -0
- package/dist/{renderer-W1bVNVR6.mjs → renderer-fabBgwQX.mjs} +3 -3
- package/dist/{renderer-W1bVNVR6.mjs.map → renderer-fabBgwQX.mjs.map} +1 -1
- package/dist/{renderer-zRq0j6Xy.mjs → renderer-g-0PCNoo.mjs} +3 -3
- package/dist/{renderer-zRq0j6Xy.mjs.map → renderer-g-0PCNoo.mjs.map} +1 -1
- package/dist/{renderer-2PjR3w-q.mjs → renderer-gmHKIbKI.mjs} +3 -3
- package/dist/{renderer-2PjR3w-q.mjs.map → renderer-gmHKIbKI.mjs.map} +1 -1
- package/dist/{renderer-03mYJLgX.mjs → renderer-kVZwiRoK.mjs} +3 -3
- package/dist/{renderer-03mYJLgX.mjs.map → renderer-kVZwiRoK.mjs.map} +1 -1
- package/dist/renderer-oPMypDM1.mjs +5 -0
- package/dist/{renderer-DcAKDAnS.mjs → renderer-p7tgxP-A.mjs} +3 -3
- package/dist/{renderer-DcAKDAnS.mjs.map → renderer-p7tgxP-A.mjs.map} +1 -1
- package/dist/{renderer-jUKdkmG5.mjs → renderer-tvYj306A.mjs} +81 -78
- package/dist/renderer-tvYj306A.mjs.map +1 -0
- package/dist/renderer-xvWGpVyp.mjs +5 -0
- package/dist/renderer-zafZbD6Q.mjs +5 -0
- package/dist/{renderers-CP8CFWDs-CshljORp.mjs → renderers-CP8CFWDs-DLjtjrwx.mjs} +2 -2
- package/dist/{renderers-CP8CFWDs-CshljORp.mjs.map → renderers-CP8CFWDs-DLjtjrwx.mjs.map} +1 -1
- package/dist/sam/index.d.mts +2 -2
- package/dist/sam/index.mjs +1 -1
- package/dist/signals/index.d.mts +4 -4
- package/dist/signals/index.mjs +4 -4
- package/dist/{src-BU6vm9sP-DdTHmCr4.mjs → src-B23p_eh7-Cj6-lvV6.mjs} +293 -6
- package/dist/src-B23p_eh7-Cj6-lvV6.mjs.map +1 -0
- package/dist/{src-Dy4gnc6w.mjs → src-CoHAjviq.mjs} +1349 -177
- package/dist/src-CoHAjviq.mjs.map +1 -0
- package/dist/storage/index.mjs +1 -1
- package/package.json +63 -60
- package/dist/dist--Uu5bQ_6.mjs.map +0 -1
- package/dist/dist-CiTgmfUw.mjs.map +0 -1
- package/dist/fonts-OW3yAfO5.mjs.map +0 -1
- package/dist/index-9xte4JgL.d.mts.map +0 -1
- package/dist/index-Bv7gxGK1.d.mts.map +0 -1
- package/dist/index-C5sgRLlG.d.mts.map +0 -1
- package/dist/index-C7-p9zwU.d.mts.map +0 -1
- package/dist/index-CRaydvLi.d.mts.map +0 -1
- package/dist/index-D1FqV1eu.d.mts.map +0 -1
- package/dist/preview-D7BGmE1E.mjs +0 -2446
- package/dist/preview-D7BGmE1E.mjs.map +0 -1
- package/dist/preview-engine/chunk-5DZTPUMH.mjs +0 -2568
- package/dist/preview-engine/chunk-NCQHOGZK.mjs +0 -3
- package/dist/preview-engine/chunk-PH3UUX6A.mjs +0 -138
- package/dist/preview-engine/chunk-UPZURPJY.mjs +0 -2227
- package/dist/preview-engine/renderers-DLJOA3BM.mjs +0 -228
- package/dist/program-tFKCWU2j.mjs.map +0 -1
- package/dist/renderer-6_bzbbXt.mjs +0 -5
- package/dist/renderer-8M-9G6F_.mjs +0 -5
- package/dist/renderer-B5OzKvF8.mjs +0 -5
- package/dist/renderer-BBCZ2qbE.mjs +0 -5
- package/dist/renderer-BChbxCux.mjs +0 -5
- package/dist/renderer-BGeMPr8C.mjs +0 -5
- package/dist/renderer-BPQ8Pkjb.mjs +0 -5
- package/dist/renderer-BTRpA3HD.mjs +0 -5
- package/dist/renderer-BVIXKfbC.mjs.map +0 -1
- package/dist/renderer-BVsECSn-.mjs +0 -5
- package/dist/renderer-Bgos68gc.mjs +0 -6
- package/dist/renderer-BjHOvoqO.mjs +0 -5
- package/dist/renderer-BjXMPPlV.mjs +0 -5
- package/dist/renderer-Byobxqkv.mjs +0 -5
- package/dist/renderer-CKrsg3EG.mjs +0 -5
- package/dist/renderer-Cj875NuH.mjs +0 -5
- package/dist/renderer-CnmzJoMv.mjs +0 -5
- package/dist/renderer-CtklDaMg.mjs +0 -5
- package/dist/renderer-D1tK3in_.mjs +0 -5
- package/dist/renderer-D2yc9P61.mjs +0 -5
- package/dist/renderer-D4v-JvSr.mjs +0 -5
- package/dist/renderer-D5yp74NL.mjs +0 -3
- package/dist/renderer-D7WRWDwB.mjs +0 -5
- package/dist/renderer-DGvA0tdB.mjs +0 -5
- package/dist/renderer-DO7v5Sdm.mjs +0 -5
- package/dist/renderer-DRVvt7-V.mjs +0 -5
- package/dist/renderer-DYMCd3jL.mjs +0 -5
- package/dist/renderer-DmHKw-MM.mjs +0 -5
- package/dist/renderer-DoDsuZ6G.mjs +0 -5
- package/dist/renderer-EpgclS70.mjs +0 -5
- package/dist/renderer-GroKiYyK.mjs +0 -5
- package/dist/renderer-MQ5K_xIS.mjs +0 -5
- package/dist/renderer-U43SflML.mjs +0 -5
- package/dist/renderer-UqOmBgCv.mjs +0 -5
- package/dist/renderer-XLULgJM0.mjs +0 -5
- package/dist/renderer-jUKdkmG5.mjs.map +0 -1
- package/dist/renderer-lNjxY1GG.mjs +0 -5
- package/dist/renderer-ukufL7pl.mjs +0 -5
- package/dist/renderer-wb0NCKdF.mjs +0 -5
- package/dist/src-BU6vm9sP-DdTHmCr4.mjs.map +0 -1
- package/dist/src-Dy4gnc6w.mjs.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { G as ProgrammaticSignal, K as Signal, Mt as frameArraySignal, N as MediaSignalRecorder, St as createVirtualMedia, pt as appendOperation, rn as mediaSourceTime, tn as mediaSourceRange, y as Effect$1, yn as resolveFrameRequest } from "./dist-C8XSqfTx.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { n as decodeAudioSource, o as preflightMediaTime } from "./dist-
|
|
4
|
-
import { t as FontManager } from "./fonts-
|
|
2
|
+
import { B as fractureModel, C as buildShapeSvgPath, D as createTerrainSampler, Lt as Matrix4Math, Rt as Path3D, U as getPrimitiveGeometry, Ut as createRandom, V as generateExtrudedTextGeometry, et as mediaDecoderCache, ht as scatterOnSurface, m as SlugFontCache, ot as parseSvgPathToSegments, q as inputStore, tt as parseColor$1, xt as terrainSegments } from "./dist-XqlFM2a8.mjs";
|
|
3
|
+
import { n as decodeAudioSource, o as preflightMediaTime } from "./dist-COOpgG9G.mjs";
|
|
4
|
+
import { t as FontManager } from "./fonts-BWYcXjyK.mjs";
|
|
5
5
|
import { s as TensorPipeline } from "./dist-DgZpN6IK.mjs";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { C as effectFactories, H as Dither, I as ColorBalance, K as Iridescence, L as ColorKey, M as CRT, R as Contour, S as Vision, T as Ascii, Y as LayerStyle, _ as SelectiveColor, a as CustomEffect, at as Posterize, b as TileOffset, c as GradientMap, d as Levels, et as OpArt, f as Modulate, g as SSAO, h as Relight3D, ht as Vignette, i as Curves, it as Pixelate, l as HalftoneScreen, m as PBRGlass, nt as Painterly, o as DepthOfField, ot as ProceduralVFX, p as MotionBlur, pt as Toon, q as Kaleidoscope, r as Crop, s as FilmGrain, st as RGBSplit, t as ApplyLUT, u as HighPass, v as ShadowsHighlights, w as Blur, x as UnsharpMask, y as TemporalDeflicker } from "./effects-
|
|
9
|
-
import { n as renderFrameGrid, s as HeadlessMediaRenderer } from "./renderer-
|
|
6
|
+
import { C as maskObject, D as pinNodeToObject, E as pinNodeToLandmark, T as mergeSubjectMask, d as VisionNode, f as VisionRunner, g as defaultMatteBand, i as COCO17_KEYPOINT_NAMES, l as VisionBundle, p as analyzeSequence, t as CLIP_SUBJECT } from "./src-B23p_eh7-Cj6-lvV6.mjs";
|
|
7
|
+
import { $ as mergeAnimationTracks, Q as mediaSignalSampler, V as compositorToProgram, X as lintComposition, _ as LayerAnimation, et as numberAt, nt as sampleMediaTimeSignal, tt as sampleLayerProp, z as collectLayersOnClock } from "./program-CMigyfso.mjs";
|
|
8
|
+
import { C as effectFactories, H as Dither, I as ColorBalance, K as Iridescence, L as ColorKey, M as CRT, R as Contour, S as Vision, T as Ascii, Y as LayerStyle, _ as SelectiveColor, a as CustomEffect, at as Posterize, b as TileOffset, c as GradientMap, d as Levels, et as OpArt, f as Modulate, g as SSAO, h as Relight3D, ht as Vignette, i as Curves, it as Pixelate, l as HalftoneScreen, m as PBRGlass, nt as Painterly, o as DepthOfField, ot as ProceduralVFX, p as MotionBlur, pt as Toon, q as Kaleidoscope, r as Crop, s as FilmGrain, st as RGBSplit, t as ApplyLUT, u as HighPass, v as ShadowsHighlights, w as Blur, x as UnsharpMask, y as TemporalDeflicker } from "./effects-DlRMovU5.mjs";
|
|
9
|
+
import { n as renderFrameGrid, s as HeadlessMediaRenderer } from "./renderer-tvYj306A.mjs";
|
|
10
10
|
import { z, z as z$2 } from "zod";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import fs from "node:fs/promises";
|
|
@@ -223,7 +223,7 @@ const sleep = (ms, signal) => new Promise((resolve$1, reject) => {
|
|
|
223
223
|
}, { once: true });
|
|
224
224
|
});
|
|
225
225
|
/** Reads (status, result) are free and idempotent, so transient failures are retried. */
|
|
226
|
-
async function read(run$1, signal) {
|
|
226
|
+
async function read$1(run$1, signal) {
|
|
227
227
|
for (let attempt = 1;; attempt++) try {
|
|
228
228
|
return await run$1();
|
|
229
229
|
} catch (err) {
|
|
@@ -242,7 +242,7 @@ async function submit(model, { input, abortSignal }) {
|
|
|
242
242
|
return data;
|
|
243
243
|
}
|
|
244
244
|
function status(model, { requestId, logs, abortSignal }) {
|
|
245
|
-
return read(async () => {
|
|
245
|
+
return read$1(async () => {
|
|
246
246
|
const { data } = await gatewayJson({
|
|
247
247
|
service: "queue",
|
|
248
248
|
path: requestPath(model, requestId, "/status"),
|
|
@@ -253,7 +253,7 @@ function status(model, { requestId, logs, abortSignal }) {
|
|
|
253
253
|
}, abortSignal);
|
|
254
254
|
}
|
|
255
255
|
function result(model, { requestId, abortSignal }) {
|
|
256
|
-
return read(async () => {
|
|
256
|
+
return read$1(async () => {
|
|
257
257
|
const { data } = await gatewayJson({
|
|
258
258
|
service: "queue",
|
|
259
259
|
path: requestPath(model, requestId),
|
|
@@ -610,8 +610,8 @@ function parseMarkup(markup) {
|
|
|
610
610
|
} else if (tagName === "accent") style.fill = "#6366f1";
|
|
611
611
|
else if (tagName === "color") style.fill = attrs.value ?? attrs.hex ?? attrs.fill;
|
|
612
612
|
else if (tagName === "size") {
|
|
613
|
-
const num$
|
|
614
|
-
if (num$
|
|
613
|
+
const num$5 = parseFloat(attrs.value ?? attrs.px ?? attrs.pt ?? "0");
|
|
614
|
+
if (num$5 > 0) style.fontSize = num$5;
|
|
615
615
|
} else if (tagName === "mark") {
|
|
616
616
|
style.mark = {
|
|
617
617
|
background: attrs.bg ?? attrs.background ?? "#6366f133",
|
|
@@ -1332,12 +1332,170 @@ function translatePath(d, dx, dy) {
|
|
|
1332
1332
|
return out.join("");
|
|
1333
1333
|
}
|
|
1334
1334
|
|
|
1335
|
+
//#endregion
|
|
1336
|
+
//#region src/retarget.ts
|
|
1337
|
+
/**
|
|
1338
|
+
* Pose retargeting: a performer's 2D pose (vision keypoints, or any source
|
|
1339
|
+
* of named points) drives a 3D character's bones. Each bone is aimed along
|
|
1340
|
+
* its segment in the picture (shoulder → elbow, hip → knee, …), parents
|
|
1341
|
+
* first, so the character copies the performer's silhouette at its own
|
|
1342
|
+
* proportions. Aims run after clips and `pose`, before `lookAt` and `ik`,
|
|
1343
|
+
* so clips can carry what the camera can't see and IK can plant the feet.
|
|
1344
|
+
*
|
|
1345
|
+
* ```ts
|
|
1346
|
+
* const dancer = comp.vision("dance.mp4").person.place({ width: W, height: H });
|
|
1347
|
+
* Layer.glb("robot.glb", { aim: retargetPose(dancer, { rig: "mixamo" }) });
|
|
1348
|
+
* ```
|
|
1349
|
+
*
|
|
1350
|
+
* The picture has no depth: limbs swing in the plane facing the camera.
|
|
1351
|
+
*/
|
|
1352
|
+
/** Joint names of common rigs. */
|
|
1353
|
+
const RIG_PRESETS = {
|
|
1354
|
+
mixamo: {
|
|
1355
|
+
spine: "Spine",
|
|
1356
|
+
neck: "Neck",
|
|
1357
|
+
leftUpperArm: "LeftArm",
|
|
1358
|
+
leftLowerArm: "LeftForeArm",
|
|
1359
|
+
rightUpperArm: "RightArm",
|
|
1360
|
+
rightLowerArm: "RightForeArm",
|
|
1361
|
+
leftUpperLeg: "LeftUpLeg",
|
|
1362
|
+
leftLowerLeg: "LeftLeg",
|
|
1363
|
+
rightUpperLeg: "RightUpLeg",
|
|
1364
|
+
rightLowerLeg: "RightLeg"
|
|
1365
|
+
},
|
|
1366
|
+
humanoid: {
|
|
1367
|
+
spine: "Spine",
|
|
1368
|
+
neck: "Neck",
|
|
1369
|
+
leftUpperArm: "LeftUpperArm",
|
|
1370
|
+
leftLowerArm: "LeftLowerArm",
|
|
1371
|
+
rightUpperArm: "RightUpperArm",
|
|
1372
|
+
rightLowerArm: "RightLowerArm",
|
|
1373
|
+
leftUpperLeg: "LeftUpperLeg",
|
|
1374
|
+
leftLowerLeg: "LeftLowerLeg",
|
|
1375
|
+
rightUpperLeg: "RightUpperLeg",
|
|
1376
|
+
rightLowerLeg: "RightLowerLeg"
|
|
1377
|
+
},
|
|
1378
|
+
rigify: {
|
|
1379
|
+
spine: "spine",
|
|
1380
|
+
neck: "neck",
|
|
1381
|
+
leftUpperArm: "upper_arm.L",
|
|
1382
|
+
leftLowerArm: "forearm.L",
|
|
1383
|
+
rightUpperArm: "upper_arm.R",
|
|
1384
|
+
rightLowerArm: "forearm.R",
|
|
1385
|
+
leftUpperLeg: "thigh.L",
|
|
1386
|
+
leftLowerLeg: "shin.L",
|
|
1387
|
+
rightUpperLeg: "thigh.R",
|
|
1388
|
+
rightLowerLeg: "shin.R"
|
|
1389
|
+
}
|
|
1390
|
+
};
|
|
1391
|
+
/** Each bone's segment in the picture, parents first. */
|
|
1392
|
+
const SEGMENTS = [
|
|
1393
|
+
[
|
|
1394
|
+
"spine",
|
|
1395
|
+
["leftHip", "rightHip"],
|
|
1396
|
+
["leftShoulder", "rightShoulder"]
|
|
1397
|
+
],
|
|
1398
|
+
[
|
|
1399
|
+
"neck",
|
|
1400
|
+
["leftShoulder", "rightShoulder"],
|
|
1401
|
+
"nose"
|
|
1402
|
+
],
|
|
1403
|
+
[
|
|
1404
|
+
"leftUpperArm",
|
|
1405
|
+
"leftShoulder",
|
|
1406
|
+
"leftElbow"
|
|
1407
|
+
],
|
|
1408
|
+
[
|
|
1409
|
+
"leftLowerArm",
|
|
1410
|
+
"leftElbow",
|
|
1411
|
+
"leftWrist"
|
|
1412
|
+
],
|
|
1413
|
+
[
|
|
1414
|
+
"rightUpperArm",
|
|
1415
|
+
"rightShoulder",
|
|
1416
|
+
"rightElbow"
|
|
1417
|
+
],
|
|
1418
|
+
[
|
|
1419
|
+
"rightLowerArm",
|
|
1420
|
+
"rightElbow",
|
|
1421
|
+
"rightWrist"
|
|
1422
|
+
],
|
|
1423
|
+
[
|
|
1424
|
+
"leftUpperLeg",
|
|
1425
|
+
"leftHip",
|
|
1426
|
+
"leftKnee"
|
|
1427
|
+
],
|
|
1428
|
+
[
|
|
1429
|
+
"leftLowerLeg",
|
|
1430
|
+
"leftKnee",
|
|
1431
|
+
"leftAnkle"
|
|
1432
|
+
],
|
|
1433
|
+
[
|
|
1434
|
+
"rightUpperLeg",
|
|
1435
|
+
"rightHip",
|
|
1436
|
+
"rightKnee"
|
|
1437
|
+
],
|
|
1438
|
+
[
|
|
1439
|
+
"rightLowerLeg",
|
|
1440
|
+
"rightKnee",
|
|
1441
|
+
"rightAnkle"
|
|
1442
|
+
]
|
|
1443
|
+
];
|
|
1444
|
+
const mirrored = (name) => name.startsWith("left") ? `right${name.slice(4)}` : name.startsWith("right") ? `left${name.slice(5)}` : name;
|
|
1445
|
+
/** A keypoint, or the midpoint of two, with the lesser visibility. */
|
|
1446
|
+
function read(source, p, frame, mirror) {
|
|
1447
|
+
const name = (n) => mirror ? mirrored(n) : n;
|
|
1448
|
+
if (typeof p === "string") return source.point(name(p), frame);
|
|
1449
|
+
const a = source.point(name(p[0]), frame);
|
|
1450
|
+
const b = source.point(name(p[1]), frame);
|
|
1451
|
+
return {
|
|
1452
|
+
x: (a.x + b.x) / 2,
|
|
1453
|
+
y: (a.y + b.y) / 2,
|
|
1454
|
+
visibility: Math.min(a.visibility, b.visibility)
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
const smoothstep$1 = (lo, hi, v) => {
|
|
1458
|
+
const t = Math.min(1, Math.max(0, (v - lo) / (hi - lo)));
|
|
1459
|
+
return t * t * (3 - 2 * t);
|
|
1460
|
+
};
|
|
1461
|
+
/**
|
|
1462
|
+
* Aim constraints that make a character copy `source`'s pose: put them on
|
|
1463
|
+
* a glTF model's `aim`. Bones whose joints the rig map doesn't name, or
|
|
1464
|
+
* whose keypoints the vision isn't sure of, keep the animated pose.
|
|
1465
|
+
*/
|
|
1466
|
+
function retargetPose(source, options = {}) {
|
|
1467
|
+
const rig$1 = typeof options.rig === "object" ? options.rig : RIG_PRESETS[options.rig ?? "mixamo"];
|
|
1468
|
+
const only = options.bones ? new Set(options.bones) : void 0;
|
|
1469
|
+
const mirror = options.mirror ?? false;
|
|
1470
|
+
const lo = options.minVisibility ?? .3;
|
|
1471
|
+
return SEGMENTS.filter(([bone]) => rig$1[bone] && (!only || only.has(bone))).map(([bone, from, to]) => ({
|
|
1472
|
+
joint: rig$1[bone],
|
|
1473
|
+
direction: (frame) => {
|
|
1474
|
+
const a = read(source, from, frame, mirror);
|
|
1475
|
+
const b = read(source, to, frame, mirror);
|
|
1476
|
+
return [
|
|
1477
|
+
b.x - a.x,
|
|
1478
|
+
b.y - a.y,
|
|
1479
|
+
0
|
|
1480
|
+
];
|
|
1481
|
+
},
|
|
1482
|
+
weight: { get: (ctx) => {
|
|
1483
|
+
const clock = ctx;
|
|
1484
|
+
const a = read(source, from, clock.frame, mirror);
|
|
1485
|
+
const b = read(source, to, clock.frame, mirror);
|
|
1486
|
+
return smoothstep$1(lo, lo + .2, Math.min(a.visibility, b.visibility)) * numberAt(options.weight, clock, 1);
|
|
1487
|
+
} }
|
|
1488
|
+
}));
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1335
1491
|
//#endregion
|
|
1336
1492
|
//#region src/clip-vision.ts
|
|
1337
1493
|
/** Frames looked back over to bridge a gap where the person is lost. */
|
|
1338
1494
|
const HOLD = 24;
|
|
1339
1495
|
const CACHE_VERSION = 1;
|
|
1340
1496
|
const DEPTH_CACHE_VERSION = 1;
|
|
1497
|
+
const MATTE_CACHE_VERSION = 1;
|
|
1498
|
+
const MATTE_MODEL = "vitmatte-s";
|
|
1341
1499
|
const DEPTH_MODEL = "depth-anything-v2-s";
|
|
1342
1500
|
/** Depth frames held in memory when they also live on disk (each is about 1 MB). */
|
|
1343
1501
|
const DEPTH_MEMORY = 48;
|
|
@@ -1345,7 +1503,7 @@ let visionSam;
|
|
|
1345
1503
|
let clipVisionIds = 0;
|
|
1346
1504
|
/** SAM ships in its own chunk, loaded only when a clip asks for `sam2` or `sam3`. */
|
|
1347
1505
|
function loadVisionSam() {
|
|
1348
|
-
visionSam ??= import("./dist-
|
|
1506
|
+
visionSam ??= import("./dist-umQOWz0a.mjs");
|
|
1349
1507
|
return visionSam;
|
|
1350
1508
|
}
|
|
1351
1509
|
/**
|
|
@@ -1402,6 +1560,10 @@ var ClipVision = class {
|
|
|
1402
1560
|
subjects = /* @__PURE__ */ new Map();
|
|
1403
1561
|
wantSubjects = false;
|
|
1404
1562
|
subjectsLoaded;
|
|
1563
|
+
/** Soft alpha per source frame (`matting`); null when the frame holds no subject. */
|
|
1564
|
+
mattes = /* @__PURE__ */ new Map();
|
|
1565
|
+
mattesLoaded;
|
|
1566
|
+
unsavedMattes = 0;
|
|
1405
1567
|
/** Depth per source frame; null when the frame did not decode. Bounded when on disk. */
|
|
1406
1568
|
depths = /* @__PURE__ */ new Map();
|
|
1407
1569
|
/** Source frames whose depth is on disk. */
|
|
@@ -1441,7 +1603,7 @@ var ClipVision = class {
|
|
|
1441
1603
|
this.trimStartSec = options.trimStartSec ?? 0;
|
|
1442
1604
|
this.smoothing = Math.max(0, Math.round(options.smoothing ?? (options.sam2 || options.sam3 ? 0 : 2)));
|
|
1443
1605
|
this.cell = Math.max(1, Math.round(options.maskCell ?? 8));
|
|
1444
|
-
if (options.sam2 || options.sam3) this.wantSubjects = true;
|
|
1606
|
+
if (options.sam2 || options.sam3 || this.tracksMatting) this.wantSubjects = true;
|
|
1445
1607
|
}
|
|
1446
1608
|
/** @internal Explicit selections must never fall back to another detected subject. */
|
|
1447
1609
|
get exact() {
|
|
@@ -1538,9 +1700,11 @@ var ClipVision = class {
|
|
|
1538
1700
|
if (s === null || !this.sourceWidth) return null;
|
|
1539
1701
|
const width = this.sourceWidth;
|
|
1540
1702
|
const height = this.sourceHeight;
|
|
1703
|
+
const mask = this.alpha(sourceFrame, s);
|
|
1704
|
+
if (!mask) return void 0;
|
|
1541
1705
|
return {
|
|
1542
1706
|
category: s.category,
|
|
1543
|
-
mask
|
|
1707
|
+
mask,
|
|
1544
1708
|
width,
|
|
1545
1709
|
height,
|
|
1546
1710
|
area: s.area,
|
|
@@ -1582,6 +1746,34 @@ var ClipVision = class {
|
|
|
1582
1746
|
get tracksMask() {
|
|
1583
1747
|
return this.options.mask ?? !this.tracksDepth;
|
|
1584
1748
|
}
|
|
1749
|
+
/** Whether subjects are matted to soft alpha. */
|
|
1750
|
+
get tracksMatting() {
|
|
1751
|
+
return this.options.matting !== void 0 && this.options.matting !== false;
|
|
1752
|
+
}
|
|
1753
|
+
get matteSettings() {
|
|
1754
|
+
const m = this.options.matting;
|
|
1755
|
+
if (!m) return void 0;
|
|
1756
|
+
const o = m === true ? {} : m;
|
|
1757
|
+
return {
|
|
1758
|
+
band: o.band ?? (this.sourceWidth ? defaultMatteBand(this.sourceWidth, this.sourceHeight) : 0),
|
|
1759
|
+
resolution: o.resolution ?? 1024
|
|
1760
|
+
};
|
|
1761
|
+
}
|
|
1762
|
+
/**
|
|
1763
|
+
* A stored subject's alpha at a source frame: the matte when the clip mattes
|
|
1764
|
+
* (undefined until matted), else the mask. With `id`, that track only.
|
|
1765
|
+
*/
|
|
1766
|
+
alpha(c, stored, id) {
|
|
1767
|
+
const size$1 = this.sourceWidth * this.sourceHeight;
|
|
1768
|
+
if (!this.tracksMatting) return subjectAlpha(stored, size$1, id);
|
|
1769
|
+
const matte = this.mattes.get(c);
|
|
1770
|
+
if (!matte) return void 0;
|
|
1771
|
+
const alpha = decodeRuns(matte.alpha, size$1);
|
|
1772
|
+
if (id === void 0 || !matte.labels) return alpha;
|
|
1773
|
+
const labels = decodeRuns(matte.labels, size$1);
|
|
1774
|
+
for (let i = 0; i < size$1; i++) if (labels[i] !== id) alpha[i] = 0;
|
|
1775
|
+
return alpha;
|
|
1776
|
+
}
|
|
1585
1777
|
/** Whether frames carry relative depth. */
|
|
1586
1778
|
get tracksDepth() {
|
|
1587
1779
|
return this.options.depth === true;
|
|
@@ -1636,7 +1828,7 @@ var ClipVision = class {
|
|
|
1636
1828
|
return [Math.max(0, a - HOLD - this.smoothing), Math.max(0, b + this.smoothing)];
|
|
1637
1829
|
}
|
|
1638
1830
|
analysed(c) {
|
|
1639
|
-
return this.analysedSubject(c) && (!this.tracksDepth || this.hasDepth(c));
|
|
1831
|
+
return this.analysedSubject(c) && (!this.tracksDepth || this.hasDepth(c)) && (!this.tracksMatting || this.mattes.has(c));
|
|
1640
1832
|
}
|
|
1641
1833
|
/** Everything but depth, which is a pass of its own. */
|
|
1642
1834
|
analysedSubject(c) {
|
|
@@ -1660,6 +1852,11 @@ var ClipVision = class {
|
|
|
1660
1852
|
await this.subjectsLoaded;
|
|
1661
1853
|
}
|
|
1662
1854
|
if (this.tracksDepth) await this.computeDepth(from, to);
|
|
1855
|
+
await this.computeSubjects(from, to);
|
|
1856
|
+
if (this.tracksMatting) await this.computeMattes(from, to);
|
|
1857
|
+
}
|
|
1858
|
+
/** Pose, silhouette and subject of every frame in `from…to` not analysed yet. */
|
|
1859
|
+
async computeSubjects(from, to) {
|
|
1663
1860
|
let missing = false;
|
|
1664
1861
|
for (let c = from; c <= to; c++) if (!this.analysedSubject(c)) missing = true;
|
|
1665
1862
|
if (!missing) return;
|
|
@@ -1738,6 +1935,51 @@ var ClipVision = class {
|
|
|
1738
1935
|
});
|
|
1739
1936
|
return this.runner;
|
|
1740
1937
|
}
|
|
1938
|
+
/**
|
|
1939
|
+
* The soft alpha of every subject in `from…to` not matted yet: one
|
|
1940
|
+
* ViTMatte pass per frame over every track's edge. Prompted label maps grow
|
|
1941
|
+
* into the soft edge, so each track keeps its own alpha.
|
|
1942
|
+
*/
|
|
1943
|
+
async computeMattes(from, to) {
|
|
1944
|
+
if (!this.sourceWidth) return;
|
|
1945
|
+
this.mattesLoaded ??= this.loadMattes();
|
|
1946
|
+
await this.mattesLoaded;
|
|
1947
|
+
let decoder;
|
|
1948
|
+
for (let c = from; c <= to; c++) {
|
|
1949
|
+
if (this.mattes.has(c)) continue;
|
|
1950
|
+
const stored = this.subjects.get(c);
|
|
1951
|
+
if (stored === void 0) continue;
|
|
1952
|
+
if (stored === null) {
|
|
1953
|
+
this.mattes.set(c, null);
|
|
1954
|
+
continue;
|
|
1955
|
+
}
|
|
1956
|
+
decoder ??= this.decoder();
|
|
1957
|
+
const image = await decodedPixels(await decoder.getFrame(c / this.fps));
|
|
1958
|
+
if (!image) {
|
|
1959
|
+
this.mattes.set(c, null);
|
|
1960
|
+
continue;
|
|
1961
|
+
}
|
|
1962
|
+
const size$1 = image.width * image.height;
|
|
1963
|
+
const values = decodeRuns(stored, size$1);
|
|
1964
|
+
const hard = stored.scores ? values.map((label) => label ? 255 : 0) : values;
|
|
1965
|
+
const matte = await this.visionRunner().refineMatte(image, hard, this.matteSettings);
|
|
1966
|
+
let labels;
|
|
1967
|
+
if (stored.scores) {
|
|
1968
|
+
labels = new Uint8Array(size$1);
|
|
1969
|
+
for (let i = 0; i < size$1; i++) {
|
|
1970
|
+
const nearest = matte.nearest[i];
|
|
1971
|
+
if (matte.mask[i] && nearest >= 0) labels[i] = values[nearest];
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
this.mattes.set(c, {
|
|
1975
|
+
alpha: encodeRuns(matte.mask),
|
|
1976
|
+
...labels && { labels: encodeRuns(labels) }
|
|
1977
|
+
});
|
|
1978
|
+
this.signalMaskFrame = -1;
|
|
1979
|
+
if (++this.unsavedMattes >= 24) await this.saveMattes();
|
|
1980
|
+
}
|
|
1981
|
+
if (this.unsavedMattes > 0) await this.saveMattes();
|
|
1982
|
+
}
|
|
1741
1983
|
/** Depth of every source frame in `from…to` not analysed yet, saved one file per frame. */
|
|
1742
1984
|
async computeDepth(from, to) {
|
|
1743
1985
|
const dir = await this.depthCacheDir();
|
|
@@ -1996,11 +2238,13 @@ var ClipVision = class {
|
|
|
1996
2238
|
if (!this.results.has(c) || !this.sourceWidth) return void 0;
|
|
1997
2239
|
const stored = this.subjects.get(c);
|
|
1998
2240
|
const size$1 = this.sourceWidth * this.sourceHeight;
|
|
1999
|
-
const
|
|
2241
|
+
const alpha = stored ? this.alpha(c, stored, id) : new Uint8Array(size$1);
|
|
2242
|
+
if (!alpha) return void 0;
|
|
2243
|
+
const data = alpha;
|
|
2000
2244
|
let area$1 = stored?.area ?? 0;
|
|
2001
2245
|
if (id !== void 0 && stored?.scores) {
|
|
2002
2246
|
area$1 = 0;
|
|
2003
|
-
for (const alpha of data) if (alpha) area$1++;
|
|
2247
|
+
for (const alpha$1 of data) if (alpha$1) area$1++;
|
|
2004
2248
|
}
|
|
2005
2249
|
const mask = {
|
|
2006
2250
|
category: stored?.category ?? this.samCategory(),
|
|
@@ -2232,6 +2476,55 @@ var ClipVision = class {
|
|
|
2232
2476
|
}
|
|
2233
2477
|
} catch {}
|
|
2234
2478
|
}
|
|
2479
|
+
/**
|
|
2480
|
+
* Mattes live beside the subjects they refine, keyed by the matting model
|
|
2481
|
+
* and settings, so toggling matting never recomputes the masks.
|
|
2482
|
+
*/
|
|
2483
|
+
async mattesPath() {
|
|
2484
|
+
const file = await this.cachePath();
|
|
2485
|
+
const node = await nodeModules();
|
|
2486
|
+
const settings = this.matteSettings;
|
|
2487
|
+
if (!file || !node || !settings) return null;
|
|
2488
|
+
const hash = node.crypto.createHash("sha256").update(JSON.stringify([
|
|
2489
|
+
MATTE_CACHE_VERSION,
|
|
2490
|
+
MATTE_MODEL,
|
|
2491
|
+
settings.band,
|
|
2492
|
+
settings.resolution
|
|
2493
|
+
])).digest("hex").slice(0, 12);
|
|
2494
|
+
return file.replace(/\.json$/, `.matte-${hash}.json`);
|
|
2495
|
+
}
|
|
2496
|
+
async loadMattes() {
|
|
2497
|
+
const file = await this.mattesPath();
|
|
2498
|
+
if (!file) return;
|
|
2499
|
+
try {
|
|
2500
|
+
const fs$1 = await import("node:fs");
|
|
2501
|
+
if (!fs$1.existsSync(file)) return;
|
|
2502
|
+
const json = JSON.parse(fs$1.readFileSync(file, "utf8"));
|
|
2503
|
+
if (json.width !== this.sourceWidth || json.height !== this.sourceHeight) return;
|
|
2504
|
+
for (const [c, m] of Object.entries(json.frames)) this.mattes.set(Number(c), m && {
|
|
2505
|
+
alpha: fromStoredRuns(m.alpha),
|
|
2506
|
+
...m.labels && { labels: fromStoredRuns(m.labels) }
|
|
2507
|
+
});
|
|
2508
|
+
} catch {}
|
|
2509
|
+
}
|
|
2510
|
+
async saveMattes() {
|
|
2511
|
+
this.unsavedMattes = 0;
|
|
2512
|
+
const file = await this.mattesPath();
|
|
2513
|
+
if (!file || !this.sourceWidth) return;
|
|
2514
|
+
const frames = {};
|
|
2515
|
+
for (const [c, m] of this.mattes) frames[c] = m && {
|
|
2516
|
+
alpha: toStoredRuns(m.alpha),
|
|
2517
|
+
...m.labels && { labels: toStoredRuns(m.labels) }
|
|
2518
|
+
};
|
|
2519
|
+
const fs$1 = await import("node:fs");
|
|
2520
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
2521
|
+
fs$1.writeFileSync(tmp, JSON.stringify({
|
|
2522
|
+
width: this.sourceWidth,
|
|
2523
|
+
height: this.sourceHeight,
|
|
2524
|
+
frames
|
|
2525
|
+
}));
|
|
2526
|
+
fs$1.renameSync(tmp, file);
|
|
2527
|
+
}
|
|
2235
2528
|
async saveSubjects() {
|
|
2236
2529
|
this.unsavedSubjects = 0;
|
|
2237
2530
|
const file = await this.subjectsPath();
|
|
@@ -2310,16 +2603,24 @@ var PersonTrack = class PersonTrack {
|
|
|
2310
2603
|
visibility: a[2] + (b[2] - a[2]) * u
|
|
2311
2604
|
};
|
|
2312
2605
|
}
|
|
2606
|
+
/**
|
|
2607
|
+
* Aim constraints that make a 3D character copy this person's pose, for
|
|
2608
|
+
* a glTF model's `aim`: `Layer.glb(src, { aim: person.retarget({ rig: "mixamo" }) })`.
|
|
2609
|
+
* Place the person first (`place()`), so directions read in composition px.
|
|
2610
|
+
*/
|
|
2611
|
+
retarget(options) {
|
|
2612
|
+
return retargetPose(this, options);
|
|
2613
|
+
}
|
|
2313
2614
|
/** Signals for a keypoint, for `.signal("x", …)`; read while rendering. */
|
|
2314
2615
|
signals(name) {
|
|
2315
|
-
const read$
|
|
2616
|
+
const read$2 = (axis) => Signal.builder({
|
|
2316
2617
|
type: "custom",
|
|
2317
2618
|
fn: (ctx) => this.point(name, ctx.frame)[axis]
|
|
2318
2619
|
});
|
|
2319
2620
|
return {
|
|
2320
|
-
x: read$
|
|
2321
|
-
y: read$
|
|
2322
|
-
visibility: read$
|
|
2621
|
+
x: read$2("x"),
|
|
2622
|
+
y: read$2("y"),
|
|
2623
|
+
visibility: read$2("visibility")
|
|
2323
2624
|
};
|
|
2324
2625
|
}
|
|
2325
2626
|
/**
|
|
@@ -2358,14 +2659,14 @@ var PersonTrack = class PersonTrack {
|
|
|
2358
2659
|
const t = this.transform();
|
|
2359
2660
|
const cx = (x - t.ox) / t.sx / cell - .5;
|
|
2360
2661
|
const cy = (y - t.oy) / t.sy / cell - .5;
|
|
2361
|
-
const read$
|
|
2662
|
+
const read$2 = (gx, gy) => gx < 0 || gy < 0 || gx >= w || gy >= h ? 0 : grid[gy * w + gx];
|
|
2362
2663
|
const bil = (px, py) => {
|
|
2363
2664
|
const x0 = Math.floor(px);
|
|
2364
2665
|
const y0 = Math.floor(py);
|
|
2365
2666
|
const ux = px - x0;
|
|
2366
2667
|
const uy = py - y0;
|
|
2367
|
-
const a = read$
|
|
2368
|
-
return a + (read$
|
|
2668
|
+
const a = read$2(x0, y0) + (read$2(x0 + 1, y0) - read$2(x0, y0)) * ux;
|
|
2669
|
+
return a + (read$2(x0, y0 + 1) + (read$2(x0 + 1, y0 + 1) - read$2(x0, y0 + 1)) * ux - a) * uy;
|
|
2369
2670
|
};
|
|
2370
2671
|
return {
|
|
2371
2672
|
alpha: bil(cx, cy),
|
|
@@ -2465,6 +2766,19 @@ function downsampleMean(src, w, h, cell, dst, mw, mh) {
|
|
|
2465
2766
|
dst[my * mw + mx] = n ? Math.round(sum / n) : 0;
|
|
2466
2767
|
}
|
|
2467
2768
|
}
|
|
2769
|
+
function toStoredRuns(runs) {
|
|
2770
|
+
return {
|
|
2771
|
+
values: Buffer.from(runs.values).toString("base64"),
|
|
2772
|
+
lengths: Buffer.from(runs.lengths.buffer, runs.lengths.byteOffset, runs.lengths.byteLength).toString("base64")
|
|
2773
|
+
};
|
|
2774
|
+
}
|
|
2775
|
+
function fromStoredRuns(stored) {
|
|
2776
|
+
const lengths = Buffer.from(stored.lengths, "base64");
|
|
2777
|
+
return {
|
|
2778
|
+
values: new Uint8Array(Buffer.from(stored.values, "base64")),
|
|
2779
|
+
lengths: new Uint32Array(lengths.buffer.slice(lengths.byteOffset, lengths.byteOffset + lengths.byteLength))
|
|
2780
|
+
};
|
|
2781
|
+
}
|
|
2468
2782
|
/** A mask as (value, run length) pairs: long flat runs with soft edges. */
|
|
2469
2783
|
function encodeRuns(mask) {
|
|
2470
2784
|
let runs = 0;
|
|
@@ -2815,6 +3129,10 @@ var WorldCore = class {
|
|
|
2815
3129
|
forces = [];
|
|
2816
3130
|
impulses = [];
|
|
2817
3131
|
fields = [];
|
|
3132
|
+
/** Run after each simulated frame with the pairs that started touching in it. */
|
|
3133
|
+
stepHooks = [];
|
|
3134
|
+
/** Run once the whole simulation has finished (not in live worlds). */
|
|
3135
|
+
simulatedHooks = [];
|
|
2818
3136
|
worldRecording;
|
|
2819
3137
|
allCollisions = [];
|
|
2820
3138
|
/** No more bodies, joints or forces: the world has started (or finished). */
|
|
@@ -2869,6 +3187,7 @@ var WorldCore = class {
|
|
|
2869
3187
|
*/
|
|
2870
3188
|
live(comp, options = {}) {
|
|
2871
3189
|
if (this.locked) throw new Error("Physics: live() must come before simulate() or reading any body signal.");
|
|
3190
|
+
if (this.simulatedHooks.length) throw new Error("Physics: fracture() needs the whole run up front; use simulate() instead of live().");
|
|
2872
3191
|
this.locked = true;
|
|
2873
3192
|
this.liveMode = true;
|
|
2874
3193
|
const prepare = async (frame) => {
|
|
@@ -2947,6 +3266,7 @@ var WorldCore = class {
|
|
|
2947
3266
|
st.freed = true;
|
|
2948
3267
|
this.sim.free();
|
|
2949
3268
|
for (const body of this.bodies) this.bind(body);
|
|
3269
|
+
for (const hook of this.simulatedHooks) hook();
|
|
2950
3270
|
}
|
|
2951
3271
|
/** Records frame 0 and sets every channel to it, so frames not simulated yet hold the start pose. */
|
|
2952
3272
|
begin() {
|
|
@@ -3085,6 +3405,7 @@ var WorldCore = class {
|
|
|
3085
3405
|
if (level > loudest) loudest = level;
|
|
3086
3406
|
}
|
|
3087
3407
|
this.worldRecording.channel("impact")[frame] = loudest;
|
|
3408
|
+
for (const hook of this.stepHooks) hook(f, pairs);
|
|
3088
3409
|
st.current = f;
|
|
3089
3410
|
}
|
|
3090
3411
|
bind(body) {
|
|
@@ -3184,15 +3505,15 @@ var Particles = class extends Effect$1 {
|
|
|
3184
3505
|
}
|
|
3185
3506
|
particleFrame(frame, fps) {
|
|
3186
3507
|
const o = this.options;
|
|
3187
|
-
const read$
|
|
3508
|
+
const read$2 = (d, fallback) => d === void 0 ? fallback : sampleDriver(d, frame, fps);
|
|
3188
3509
|
const layerFrame = frame - (o.startFrame ?? 0);
|
|
3189
3510
|
const burst = (o.emitter?.bursts ?? []).filter((b) => Math.round(b.frame) === layerFrame).reduce((n, b) => n + b.count, 0);
|
|
3190
3511
|
const g = o.gravity;
|
|
3191
|
-
const gravity = Array.isArray(g) ? [read$
|
|
3512
|
+
const gravity = Array.isArray(g) ? [read$2(g[0], 0), read$2(g[1], 0)] : [0, read$2(g, 0)];
|
|
3192
3513
|
let push = null;
|
|
3193
3514
|
if (o.push) push = {
|
|
3194
|
-
strength: read$
|
|
3195
|
-
sweep: read$
|
|
3515
|
+
strength: read$2(o.push.strength, 6e3),
|
|
3516
|
+
sweep: read$2(o.push.sweep, 6e4),
|
|
3196
3517
|
mask: o.push.person.silhouetteGrid(frame),
|
|
3197
3518
|
previous: o.push.person.silhouetteGrid(Math.max(0, frame - 1))
|
|
3198
3519
|
};
|
|
@@ -3216,19 +3537,19 @@ var Particles = class extends Effect$1 {
|
|
|
3216
3537
|
}
|
|
3217
3538
|
return {
|
|
3218
3539
|
...emitter && { emitter },
|
|
3219
|
-
rate: read$
|
|
3540
|
+
rate: read$2(o.emitter?.rate, 1e3),
|
|
3220
3541
|
burst,
|
|
3221
3542
|
gravity,
|
|
3222
|
-
drag: read$
|
|
3543
|
+
drag: read$2(o.drag, .4),
|
|
3223
3544
|
noise: {
|
|
3224
|
-
strength: read$
|
|
3545
|
+
strength: read$2(o.noise?.strength, 0),
|
|
3225
3546
|
scale: o.noise?.scale ?? 300,
|
|
3226
3547
|
speed: o.noise?.speed ?? .3
|
|
3227
3548
|
},
|
|
3228
3549
|
attractors: (o.attractors ?? []).map((a) => ({
|
|
3229
|
-
x: read$
|
|
3230
|
-
y: read$
|
|
3231
|
-
strength: read$
|
|
3550
|
+
x: read$2(a.x, 0),
|
|
3551
|
+
y: read$2(a.y, 0),
|
|
3552
|
+
strength: read$2(a.strength, 0),
|
|
3232
3553
|
radius: a.radius ?? 200
|
|
3233
3554
|
})),
|
|
3234
3555
|
push
|
|
@@ -3236,6 +3557,172 @@ var Particles = class extends Effect$1 {
|
|
|
3236
3557
|
}
|
|
3237
3558
|
};
|
|
3238
3559
|
|
|
3560
|
+
//#endregion
|
|
3561
|
+
//#region src/procedural3d.ts
|
|
3562
|
+
/** Where a model node's mesh sits: its static transform. */
|
|
3563
|
+
function staticMatrix(n) {
|
|
3564
|
+
const rad = Math.PI / 180;
|
|
3565
|
+
const s = n.scale ?? 1;
|
|
3566
|
+
let m = Matrix4Math.translate(n.x ?? 0, n.y ?? 0, n.z ?? 0);
|
|
3567
|
+
if (n.rotateZ) m = Matrix4Math.multiply(m, Matrix4Math.rotateZ(n.rotateZ * rad));
|
|
3568
|
+
if (n.rotateY) m = Matrix4Math.multiply(m, Matrix4Math.rotateY(n.rotateY * rad));
|
|
3569
|
+
if (n.rotateX) m = Matrix4Math.multiply(m, Matrix4Math.rotateX(n.rotateX * rad));
|
|
3570
|
+
return Matrix4Math.multiply(m, Matrix4Math.scale(s * (n.scaleX ?? 1), s * (n.scaleY ?? 1), s * (n.scaleZ ?? 1)));
|
|
3571
|
+
}
|
|
3572
|
+
function defineHidden(target$1, values) {
|
|
3573
|
+
for (const [key, value] of Object.entries(values)) Object.defineProperty(target$1, key, {
|
|
3574
|
+
value,
|
|
3575
|
+
enumerable: false,
|
|
3576
|
+
configurable: true
|
|
3577
|
+
});
|
|
3578
|
+
}
|
|
3579
|
+
function surfaceHelpers(sampler, o) {
|
|
3580
|
+
const s = o.scale ?? 1;
|
|
3581
|
+
const sx = s * (o.scaleX ?? 1);
|
|
3582
|
+
const sy = s * (o.scaleY ?? 1);
|
|
3583
|
+
const sz = s * (o.scaleZ ?? 1);
|
|
3584
|
+
const local = (x, z$3) => [(x - (o.x ?? 0)) / sx, (z$3 - (o.z ?? 0)) / sz];
|
|
3585
|
+
return {
|
|
3586
|
+
heightAt: (x, z$3) => (o.y ?? 0) + sampler.heightAt(...local(x, z$3)) * sy,
|
|
3587
|
+
elevationAt: (x, z$3) => sampler.elevationAt(...local(x, z$3)),
|
|
3588
|
+
normalAt(x, z$3) {
|
|
3589
|
+
const n = sampler.normalAt(...local(x, z$3));
|
|
3590
|
+
const m = [
|
|
3591
|
+
n[0] / sx,
|
|
3592
|
+
n[1] / sy,
|
|
3593
|
+
n[2] / sz
|
|
3594
|
+
];
|
|
3595
|
+
const len = Math.hypot(m[0], m[1], m[2]) || 1;
|
|
3596
|
+
return [
|
|
3597
|
+
m[0] / len,
|
|
3598
|
+
m[1] / len,
|
|
3599
|
+
m[2] / len
|
|
3600
|
+
];
|
|
3601
|
+
}
|
|
3602
|
+
};
|
|
3603
|
+
}
|
|
3604
|
+
/** Procedural terrain (see `Layer3D.terrain`). */
|
|
3605
|
+
function terrain3d(options) {
|
|
3606
|
+
const { heightFn, ...o } = options;
|
|
3607
|
+
const geometry = {
|
|
3608
|
+
type: "terrain",
|
|
3609
|
+
width: o.width,
|
|
3610
|
+
depth: o.depth,
|
|
3611
|
+
height: o.height,
|
|
3612
|
+
segments: o.segments,
|
|
3613
|
+
noise: o.noise,
|
|
3614
|
+
heights: o.heights,
|
|
3615
|
+
overhangWarp: o.overhangWarp,
|
|
3616
|
+
colorByElevation: o.colorByElevation,
|
|
3617
|
+
flatShaded: o.flatShaded,
|
|
3618
|
+
base: o.base
|
|
3619
|
+
};
|
|
3620
|
+
if (heightFn) {
|
|
3621
|
+
const [cols, rows] = terrainSegments(geometry);
|
|
3622
|
+
const heights = [];
|
|
3623
|
+
for (let j = 0; j <= rows; j++) for (let i = 0; i <= cols; i++) heights.push(heightFn(i / cols, j / rows));
|
|
3624
|
+
geometry.heights = heights;
|
|
3625
|
+
}
|
|
3626
|
+
const node = primitiveNode("terrain", geometry, o);
|
|
3627
|
+
defineHidden(node, surfaceHelpers(createTerrainSampler(geometry), options));
|
|
3628
|
+
return node;
|
|
3629
|
+
}
|
|
3630
|
+
/** A signed-distance sculpture (see `Layer3D.sdf`). */
|
|
3631
|
+
function sdf3d(options) {
|
|
3632
|
+
return primitiveNode("sdf", {
|
|
3633
|
+
type: "sdf",
|
|
3634
|
+
primitives: options.primitives,
|
|
3635
|
+
bounds: options.bounds,
|
|
3636
|
+
resolution: options.resolution,
|
|
3637
|
+
flatShaded: options.flatShaded
|
|
3638
|
+
}, options);
|
|
3639
|
+
}
|
|
3640
|
+
const SURFACE_KEYS = [
|
|
3641
|
+
"x",
|
|
3642
|
+
"y",
|
|
3643
|
+
"z",
|
|
3644
|
+
"rotateX",
|
|
3645
|
+
"rotateY",
|
|
3646
|
+
"rotateZ",
|
|
3647
|
+
"scale",
|
|
3648
|
+
"scaleX",
|
|
3649
|
+
"scaleY",
|
|
3650
|
+
"scaleZ",
|
|
3651
|
+
"primitive3d",
|
|
3652
|
+
"src",
|
|
3653
|
+
"modelFormat",
|
|
3654
|
+
"center",
|
|
3655
|
+
"normalizeSize"
|
|
3656
|
+
];
|
|
3657
|
+
/** What the renderer rebuilds and places the surface from. */
|
|
3658
|
+
function surfaceSpec(surface) {
|
|
3659
|
+
const out = {};
|
|
3660
|
+
for (const k of SURFACE_KEYS) if (surface[k] !== void 0) out[k] = surface[k];
|
|
3661
|
+
if (!surface.primitive3d && !surface.src && surface.modelData) out.modelData = surface.modelData;
|
|
3662
|
+
return out;
|
|
3663
|
+
}
|
|
3664
|
+
/** The surface's mesh when it is already in memory (primitives, terrain, SDF). */
|
|
3665
|
+
function surfaceModel(surface) {
|
|
3666
|
+
const data = surface.modelData;
|
|
3667
|
+
if (data && "meshes" in data) return data;
|
|
3668
|
+
if (surface.primitive3d) return getPrimitiveGeometry(surface.primitive3d);
|
|
3669
|
+
}
|
|
3670
|
+
const SCATTER_KEYS = [
|
|
3671
|
+
"count",
|
|
3672
|
+
"minDistance",
|
|
3673
|
+
"seed",
|
|
3674
|
+
"slopeRange",
|
|
3675
|
+
"elevationRange",
|
|
3676
|
+
"alignToNormal",
|
|
3677
|
+
"scaleRange",
|
|
3678
|
+
"randomYaw",
|
|
3679
|
+
"exclude",
|
|
3680
|
+
"sink"
|
|
3681
|
+
];
|
|
3682
|
+
/** Instances scattered on a surface (see `Layer3D.scatter`). */
|
|
3683
|
+
function scatter3d(options) {
|
|
3684
|
+
const { surface, wind, ...rest } = options;
|
|
3685
|
+
const spec$1 = { surface: surfaceSpec(surface) };
|
|
3686
|
+
const instanceOptions = { ...rest };
|
|
3687
|
+
for (const k of SCATTER_KEYS) {
|
|
3688
|
+
if (rest[k] !== void 0) spec$1[k] = rest[k];
|
|
3689
|
+
delete instanceOptions[k];
|
|
3690
|
+
}
|
|
3691
|
+
const node = Layer3D.instances(instanceOptions);
|
|
3692
|
+
const target$1 = node;
|
|
3693
|
+
target$1.scatter3d = spec$1;
|
|
3694
|
+
if (wind) target$1.wind = wind;
|
|
3695
|
+
defineHidden(node, { points: () => {
|
|
3696
|
+
const model = surfaceModel(surface);
|
|
3697
|
+
if (!model) return [];
|
|
3698
|
+
return scatterOnSurface({
|
|
3699
|
+
model,
|
|
3700
|
+
matrix: staticMatrix(surface)
|
|
3701
|
+
}, spec$1).points;
|
|
3702
|
+
} });
|
|
3703
|
+
return node;
|
|
3704
|
+
}
|
|
3705
|
+
/**
|
|
3706
|
+
* Share of a scatter's surface its slope / altitude filters keep (for
|
|
3707
|
+
* `lint`), or undefined when the surface is a file not loaded yet.
|
|
3708
|
+
*/
|
|
3709
|
+
function scatterCoverage(spec$1) {
|
|
3710
|
+
const surface = spec$1.surface;
|
|
3711
|
+
const model = surfaceModel(surface);
|
|
3712
|
+
if (!model) return void 0;
|
|
3713
|
+
return scatterOnSurface({
|
|
3714
|
+
model,
|
|
3715
|
+
matrix: staticMatrix(surface)
|
|
3716
|
+
}, {
|
|
3717
|
+
...spec$1,
|
|
3718
|
+
count: 0
|
|
3719
|
+
}).acceptedArea;
|
|
3720
|
+
}
|
|
3721
|
+
/** `texture` on a Layer3D mesh: an image path, or any layer drawn each frame. */
|
|
3722
|
+
function textureLayerOf(texture, image) {
|
|
3723
|
+
return { node: typeof texture === "string" ? image(texture) : texture };
|
|
3724
|
+
}
|
|
3725
|
+
|
|
3239
3726
|
//#endregion
|
|
3240
3727
|
//#region src/swarm3d.ts
|
|
3241
3728
|
function createSwarm3D(options) {
|
|
@@ -3317,7 +3804,22 @@ const MATERIAL_KEYS = [
|
|
|
3317
3804
|
"envIntensity",
|
|
3318
3805
|
"emissive",
|
|
3319
3806
|
"emissiveIntensity",
|
|
3320
|
-
"castShadow"
|
|
3807
|
+
"castShadow",
|
|
3808
|
+
"clearcoat",
|
|
3809
|
+
"clearcoatRoughness",
|
|
3810
|
+
"anisotropy",
|
|
3811
|
+
"anisotropyRotation",
|
|
3812
|
+
"subsurface",
|
|
3813
|
+
"subsurfaceColor",
|
|
3814
|
+
"sheen",
|
|
3815
|
+
"sheenColor",
|
|
3816
|
+
"sheenRoughness",
|
|
3817
|
+
"iridescence",
|
|
3818
|
+
"iridescenceThickness",
|
|
3819
|
+
"iridescenceIor",
|
|
3820
|
+
"triplanar",
|
|
3821
|
+
"triplanarScale",
|
|
3822
|
+
"triplanarSharpness"
|
|
3321
3823
|
];
|
|
3322
3824
|
/** The material and surface options that were actually given. */
|
|
3323
3825
|
function materialProps(o) {
|
|
@@ -3334,6 +3836,7 @@ function normalizePathSpec(input) {
|
|
|
3334
3836
|
if (input instanceof Path3D) return input.getPoints(96);
|
|
3335
3837
|
return input;
|
|
3336
3838
|
}
|
|
3839
|
+
/** A Layer3D mesh node built from a procedural geometry spec. */
|
|
3337
3840
|
function primitiveNode(prefix, geometry, o) {
|
|
3338
3841
|
const spec$1 = Object.fromEntries(Object.entries({
|
|
3339
3842
|
...geometry,
|
|
@@ -3351,9 +3854,9 @@ function primitiveNode(prefix, geometry, o) {
|
|
|
3351
3854
|
x: o.x ?? 0,
|
|
3352
3855
|
y: o.y ?? 0,
|
|
3353
3856
|
z: o.z ?? 0,
|
|
3354
|
-
rotateX: o.rotateX ?? 0,
|
|
3355
|
-
rotateY: o.rotateY ?? 0,
|
|
3356
|
-
rotateZ: o.rotateZ ?? 0,
|
|
3857
|
+
rotateX: o.rotateX ?? o.rotationX ?? 0,
|
|
3858
|
+
rotateY: o.rotateY ?? o.rotationY ?? 0,
|
|
3859
|
+
rotateZ: o.rotateZ ?? o.rotationZ ?? 0,
|
|
3357
3860
|
scale: o.scale ?? 1,
|
|
3358
3861
|
scaleX: o.scaleX ?? 1,
|
|
3359
3862
|
scaleY: o.scaleY ?? 1,
|
|
@@ -3370,7 +3873,9 @@ function primitiveNode(prefix, geometry, o) {
|
|
|
3370
3873
|
twoSided: o.twoSided ?? false,
|
|
3371
3874
|
wireframe: o.wireframe,
|
|
3372
3875
|
startFrame: o.startFrame,
|
|
3373
|
-
durationFrames: o.durationFrames
|
|
3876
|
+
durationFrames: o.durationFrames,
|
|
3877
|
+
...o.wind && { wind: o.wind },
|
|
3878
|
+
...o.texture !== void 0 && { textureLayer: textureLayerOf(o.texture, (src) => Layer.image(src)) }
|
|
3374
3879
|
});
|
|
3375
3880
|
}
|
|
3376
3881
|
/**
|
|
@@ -3524,9 +4029,9 @@ const Layer3D = {
|
|
|
3524
4029
|
height: h,
|
|
3525
4030
|
is3D: true,
|
|
3526
4031
|
transformStyle: "preserve-3d",
|
|
3527
|
-
rotateX: options.rotateX ?? 0,
|
|
3528
|
-
rotateY: options.rotateY ?? 0,
|
|
3529
|
-
rotateZ: options.rotateZ ?? 0,
|
|
4032
|
+
rotateX: options.rotateX ?? options.rotationX ?? 0,
|
|
4033
|
+
rotateY: options.rotateY ?? options.rotationY ?? 0,
|
|
4034
|
+
rotateZ: options.rotateZ ?? options.rotationZ ?? 0,
|
|
3530
4035
|
opacity: options.opacity ?? 1,
|
|
3531
4036
|
background: "transparent",
|
|
3532
4037
|
children: faces
|
|
@@ -3562,18 +4067,20 @@ const Layer3D = {
|
|
|
3562
4067
|
height: options.itemHeight ?? 200,
|
|
3563
4068
|
is3D: true,
|
|
3564
4069
|
transformStyle: "preserve-3d",
|
|
3565
|
-
rotateX: options.rotateX ?? 0,
|
|
3566
|
-
rotateY: options.rotateY ?? 0,
|
|
3567
|
-
rotateZ: options.rotateZ ?? 0,
|
|
4070
|
+
rotateX: options.rotateX ?? options.rotationX ?? 0,
|
|
4071
|
+
rotateY: options.rotateY ?? options.rotationY ?? 0,
|
|
4072
|
+
rotateZ: options.rotateZ ?? options.rotationZ ?? 0,
|
|
3568
4073
|
opacity: options.opacity ?? 1,
|
|
3569
4074
|
background: "transparent",
|
|
3570
4075
|
children: transformedItems
|
|
3571
4076
|
}), { items: transformedItems });
|
|
3572
4077
|
},
|
|
3573
|
-
prism(options) {
|
|
3574
|
-
const n = Math.max(3, Math.round(options.sides));
|
|
4078
|
+
prism(options = {}) {
|
|
4079
|
+
const n = Math.max(3, Math.round(options.sides ?? 6));
|
|
4080
|
+
const radius = options.radius ?? 60;
|
|
4081
|
+
const height = options.height ?? 100;
|
|
3575
4082
|
if (options.sideConfigs && options.sideConfigs.length > 0) {
|
|
3576
|
-
const {
|
|
4083
|
+
const { twoSided = true } = options;
|
|
3577
4084
|
const sideWidth = 2 * radius * Math.tan(Math.PI / n);
|
|
3578
4085
|
const angleStep = 360 / n;
|
|
3579
4086
|
const panels = [];
|
|
@@ -3635,20 +4142,23 @@ const Layer3D = {
|
|
|
3635
4142
|
height,
|
|
3636
4143
|
is3D: true,
|
|
3637
4144
|
transformStyle: "preserve-3d",
|
|
3638
|
-
rotateX: options.rotateX ?? 0,
|
|
3639
|
-
rotateY: options.rotateY ?? 0,
|
|
3640
|
-
rotateZ: options.rotateZ ?? 0,
|
|
4145
|
+
rotateX: options.rotateX ?? options.rotationX ?? 0,
|
|
4146
|
+
rotateY: options.rotateY ?? options.rotationY ?? 0,
|
|
4147
|
+
rotateZ: options.rotateZ ?? options.rotationZ ?? 0,
|
|
3641
4148
|
opacity: options.opacity ?? 1,
|
|
3642
4149
|
background: "transparent",
|
|
3643
4150
|
children: panels
|
|
3644
|
-
}), {
|
|
4151
|
+
}), {
|
|
4152
|
+
faces: panels,
|
|
4153
|
+
items: panels
|
|
4154
|
+
});
|
|
3645
4155
|
}
|
|
3646
4156
|
const modelNode = primitiveNode("prism", {
|
|
3647
4157
|
type: "cylinder",
|
|
3648
|
-
radius
|
|
3649
|
-
radiusTop: options.radiusTop ?? options.radius,
|
|
3650
|
-
radiusBottom: options.radiusBottom ?? options.radius,
|
|
3651
|
-
height
|
|
4158
|
+
radius,
|
|
4159
|
+
radiusTop: options.radiusTop ?? options.topRadius ?? radius,
|
|
4160
|
+
radiusBottom: options.radiusBottom ?? options.bottomRadius ?? radius,
|
|
4161
|
+
height,
|
|
3652
4162
|
segments: n,
|
|
3653
4163
|
openEnded: options.openEnded ?? false,
|
|
3654
4164
|
flatShaded: options.flatShaded ?? true
|
|
@@ -3662,14 +4172,14 @@ const Layer3D = {
|
|
|
3662
4172
|
items: [modelNode]
|
|
3663
4173
|
});
|
|
3664
4174
|
},
|
|
3665
|
-
pyramid(options) {
|
|
4175
|
+
pyramid(options = {}) {
|
|
3666
4176
|
const n = Math.max(3, Math.round(options.sides ?? 4));
|
|
3667
4177
|
return primitiveNode("pyramid", {
|
|
3668
4178
|
type: "cylinder",
|
|
3669
4179
|
radius: options.radius ?? 60,
|
|
3670
|
-
radiusTop: options.radiusTop ?? 0,
|
|
4180
|
+
radiusTop: options.radiusTop ?? options.topRadius ?? 0,
|
|
3671
4181
|
radiusBottom: options.radius ?? 60,
|
|
3672
|
-
height: options.height,
|
|
4182
|
+
height: options.height ?? 100,
|
|
3673
4183
|
segments: n,
|
|
3674
4184
|
openEnded: options.openEnded ?? false,
|
|
3675
4185
|
flatShaded: options.flatShaded ?? true
|
|
@@ -3690,9 +4200,9 @@ const Layer3D = {
|
|
|
3690
4200
|
z: options.z ?? 0,
|
|
3691
4201
|
is3D: true,
|
|
3692
4202
|
twoSided: options.twoSided ?? true,
|
|
3693
|
-
rotateX: options.rotateX ?? 0,
|
|
3694
|
-
rotateY: options.rotateY ?? 0,
|
|
3695
|
-
rotateZ: options.rotateZ ?? 0,
|
|
4203
|
+
rotateX: options.rotateX ?? options.rotationX ?? 0,
|
|
4204
|
+
rotateY: options.rotateY ?? options.rotationY ?? 0,
|
|
4205
|
+
rotateZ: options.rotateZ ?? options.rotationZ ?? 0,
|
|
3696
4206
|
background: options.background ?? "#3b82f6",
|
|
3697
4207
|
borderRadius: options.borderRadius ?? 0,
|
|
3698
4208
|
opacity: options.opacity ?? 1,
|
|
@@ -3746,9 +4256,9 @@ const Layer3D = {
|
|
|
3746
4256
|
z: options.z ?? 0,
|
|
3747
4257
|
is3D: true,
|
|
3748
4258
|
transformStyle: "preserve-3d",
|
|
3749
|
-
rotateX: options.rotateX ?? 90,
|
|
3750
|
-
rotateY: options.rotateY ?? 0,
|
|
3751
|
-
rotateZ: options.rotateZ ?? 0,
|
|
4259
|
+
rotateX: options.rotateX ?? options.rotationX ?? 90,
|
|
4260
|
+
rotateY: options.rotateY ?? options.rotationY ?? 0,
|
|
4261
|
+
rotateZ: options.rotateZ ?? options.rotationZ ?? 0,
|
|
3752
4262
|
background: "transparent",
|
|
3753
4263
|
opacity: options.opacity ?? 1,
|
|
3754
4264
|
children: lines
|
|
@@ -3767,9 +4277,9 @@ const Layer3D = {
|
|
|
3767
4277
|
z: options.z ?? 0,
|
|
3768
4278
|
is3D: true,
|
|
3769
4279
|
twoSided: options.twoSided ?? true,
|
|
3770
|
-
rotateX: options.rotateX ?? 0,
|
|
3771
|
-
rotateY: options.rotateY ?? 0,
|
|
3772
|
-
rotateZ: options.rotateZ ?? 0,
|
|
4280
|
+
rotateX: options.rotateX ?? options.rotationX ?? 0,
|
|
4281
|
+
rotateY: options.rotateY ?? options.rotationY ?? 0,
|
|
4282
|
+
rotateZ: options.rotateZ ?? options.rotationZ ?? 0,
|
|
3773
4283
|
fontSize: options.fontSize ?? 48,
|
|
3774
4284
|
fontFamily: options.fontFamily,
|
|
3775
4285
|
fontWeight: options.fontWeight ?? "bold",
|
|
@@ -3825,9 +4335,9 @@ const Layer3D = {
|
|
|
3825
4335
|
x: options.x ?? 0,
|
|
3826
4336
|
y: options.y ?? 0,
|
|
3827
4337
|
z: options.z ?? 0,
|
|
3828
|
-
rotateX: options.rotateX ?? 0,
|
|
3829
|
-
rotateY: options.rotateY ?? 0,
|
|
3830
|
-
rotateZ: options.rotateZ ?? 0,
|
|
4338
|
+
rotateX: options.rotateX ?? options.rotationX ?? 0,
|
|
4339
|
+
rotateY: options.rotateY ?? options.rotationY ?? 0,
|
|
4340
|
+
rotateZ: options.rotateZ ?? options.rotationZ ?? 0,
|
|
3831
4341
|
scale: options.scale ?? 1,
|
|
3832
4342
|
scaleX: options.scaleX ?? 1,
|
|
3833
4343
|
scaleY: options.scaleY ?? 1,
|
|
@@ -3857,7 +4367,7 @@ const Layer3D = {
|
|
|
3857
4367
|
width: options.width,
|
|
3858
4368
|
height: options.height,
|
|
3859
4369
|
depth: options.depth,
|
|
3860
|
-
radius: options.radius,
|
|
4370
|
+
radius: options.radius ?? options.cornerRadius ?? options.borderRadius,
|
|
3861
4371
|
segments: options.segments,
|
|
3862
4372
|
taper: options.taper
|
|
3863
4373
|
}, options);
|
|
@@ -3873,8 +4383,8 @@ const Layer3D = {
|
|
|
3873
4383
|
return primitiveNode("cylinder", {
|
|
3874
4384
|
type: "cylinder",
|
|
3875
4385
|
radius: options.radius,
|
|
3876
|
-
radiusTop: options.radiusTop,
|
|
3877
|
-
radiusBottom: options.radiusBottom,
|
|
4386
|
+
radiusTop: options.radiusTop ?? options.topRadius,
|
|
4387
|
+
radiusBottom: options.radiusBottom ?? options.bottomRadius,
|
|
3878
4388
|
height: options.height,
|
|
3879
4389
|
segments: options.segments,
|
|
3880
4390
|
openEnded: options.openEnded,
|
|
@@ -3887,8 +4397,8 @@ const Layer3D = {
|
|
|
3887
4397
|
torus(options = {}) {
|
|
3888
4398
|
return primitiveNode("torus", {
|
|
3889
4399
|
type: "torus",
|
|
3890
|
-
radius: options.radius,
|
|
3891
|
-
tube: options.tube,
|
|
4400
|
+
radius: options.radius ?? options.majorRadius,
|
|
4401
|
+
tube: options.tube ?? options.minorRadius ?? options.tubeRadius,
|
|
3892
4402
|
radialSegments: options.radialSegments,
|
|
3893
4403
|
tubularSegments: options.tubularSegments,
|
|
3894
4404
|
arc: options.arc
|
|
@@ -4030,6 +4540,15 @@ const Layer3D = {
|
|
|
4030
4540
|
irregularity: options.irregularity
|
|
4031
4541
|
}, options);
|
|
4032
4542
|
},
|
|
4543
|
+
terrain(options) {
|
|
4544
|
+
return terrain3d(options);
|
|
4545
|
+
},
|
|
4546
|
+
sdf(options) {
|
|
4547
|
+
return sdf3d(options);
|
|
4548
|
+
},
|
|
4549
|
+
scatter(options) {
|
|
4550
|
+
return scatter3d(options);
|
|
4551
|
+
},
|
|
4033
4552
|
instances(options) {
|
|
4034
4553
|
const primaryMesh = Array.isArray(options.mesh) ? options.mesh[0] : options.mesh;
|
|
4035
4554
|
const node = {
|
|
@@ -4038,9 +4557,9 @@ const Layer3D = {
|
|
|
4038
4557
|
x: options.x ?? 0,
|
|
4039
4558
|
y: options.y ?? 0,
|
|
4040
4559
|
z: options.z ?? 0,
|
|
4041
|
-
rotateX: options.rotateX ?? 0,
|
|
4042
|
-
rotateY: options.rotateY ?? 0,
|
|
4043
|
-
rotateZ: options.rotateZ ?? 0,
|
|
4560
|
+
rotateX: options.rotateX ?? options.rotationX ?? 0,
|
|
4561
|
+
rotateY: options.rotateY ?? options.rotationY ?? 0,
|
|
4562
|
+
rotateZ: options.rotateZ ?? options.rotationZ ?? 0,
|
|
4044
4563
|
scale: options.scale ?? 1,
|
|
4045
4564
|
color: options.color,
|
|
4046
4565
|
colorTint: options.colorTint,
|
|
@@ -4055,6 +4574,8 @@ const Layer3D = {
|
|
|
4055
4574
|
startFrame: options.startFrame,
|
|
4056
4575
|
durationFrames: options.durationFrames,
|
|
4057
4576
|
instances3d: { ...options },
|
|
4577
|
+
...options.wind && { wind: options.wind },
|
|
4578
|
+
...options.crowd && { crowd: options.crowd },
|
|
4058
4579
|
...materialProps(options)
|
|
4059
4580
|
};
|
|
4060
4581
|
if (primaryMesh) {
|
|
@@ -4491,6 +5012,9 @@ function rig(name, options) {
|
|
|
4491
5012
|
exposure: options.exposure,
|
|
4492
5013
|
toneMapping: options.toneMapping,
|
|
4493
5014
|
fog: options.fog,
|
|
5015
|
+
volumetricFog: options.volumetricFog,
|
|
5016
|
+
ssr: options.ssr,
|
|
5017
|
+
gi: options.gi,
|
|
4494
5018
|
bloom: options.bloom
|
|
4495
5019
|
}), Light.directional({
|
|
4496
5020
|
id: `${id}-key`,
|
|
@@ -4602,6 +5126,20 @@ var RapierWorld2D = class {
|
|
|
4602
5126
|
x,
|
|
4603
5127
|
y
|
|
4604
5128
|
}, true),
|
|
5129
|
+
setPose: ([x, y], angle) => {
|
|
5130
|
+
body.setTranslation({
|
|
5131
|
+
x,
|
|
5132
|
+
y
|
|
5133
|
+
}, true);
|
|
5134
|
+
body.setRotation(angle, true);
|
|
5135
|
+
},
|
|
5136
|
+
setVelocity: ([x, y], w) => {
|
|
5137
|
+
body.setLinvel({
|
|
5138
|
+
x,
|
|
5139
|
+
y
|
|
5140
|
+
}, true);
|
|
5141
|
+
body.setAngvel(w, true);
|
|
5142
|
+
},
|
|
4605
5143
|
setKinematicTarget: ([x, y], angle) => {
|
|
4606
5144
|
body.setNextKinematicTranslation({
|
|
4607
5145
|
x,
|
|
@@ -4730,6 +5268,19 @@ var RapierWorld3D = class {
|
|
|
4730
5268
|
mass: () => body.mass(),
|
|
4731
5269
|
setEnabled: (on) => body.setEnabled(on),
|
|
4732
5270
|
applyImpulse: (v) => body.applyImpulse(vec3(v), true),
|
|
5271
|
+
setPose: (p, [x, y, z$3, w]) => {
|
|
5272
|
+
body.setTranslation(vec3(p), true);
|
|
5273
|
+
body.setRotation({
|
|
5274
|
+
x,
|
|
5275
|
+
y,
|
|
5276
|
+
z: z$3,
|
|
5277
|
+
w
|
|
5278
|
+
}, true);
|
|
5279
|
+
},
|
|
5280
|
+
setVelocity: (v, w) => {
|
|
5281
|
+
body.setLinvel(vec3(v), true);
|
|
5282
|
+
body.setAngvel(vec3(w), true);
|
|
5283
|
+
},
|
|
4733
5284
|
setKinematicTarget: (p, [x, y, z$3, w]) => {
|
|
4734
5285
|
body.setNextKinematicTranslation(vec3(p));
|
|
4735
5286
|
body.setNextKinematicRotation({
|
|
@@ -4837,6 +5388,7 @@ function shapeDesc3D(R, shape$1) {
|
|
|
4837
5388
|
if (!desc) throw new Error("Physics: could not build a convex hull for this shape.");
|
|
4838
5389
|
return desc;
|
|
4839
5390
|
}
|
|
5391
|
+
case "trimesh": return R.ColliderDesc.trimesh(new Float32Array(shape$1.vertices), new Uint32Array(shape$1.indices));
|
|
4840
5392
|
}
|
|
4841
5393
|
}
|
|
4842
5394
|
|
|
@@ -5030,6 +5582,8 @@ var PhysicsWorld2D = class extends WorldCore {
|
|
|
5030
5582
|
};
|
|
5031
5583
|
const simBody = this.sim.addBody(spec$1);
|
|
5032
5584
|
const body = new PhysicsBody2D(this, simBody, type, layer, geom, options, this.newRecording());
|
|
5585
|
+
const start = body.kinematicTarget(this.startFrame);
|
|
5586
|
+
if (start) simBody.setPose(start.position, start.rotation);
|
|
5033
5587
|
return this.addBody(body);
|
|
5034
5588
|
}
|
|
5035
5589
|
/** A fixed, very wide floor whose top edge sits at `y`. */
|
|
@@ -5224,7 +5778,7 @@ function effectiveMass(a, b) {
|
|
|
5224
5778
|
if (ma > 0 && mb > 0) return ma * mb / (ma + mb);
|
|
5225
5779
|
return Math.max(ma, mb, .001);
|
|
5226
5780
|
}
|
|
5227
|
-
function num$
|
|
5781
|
+
function num$4(v, fallback) {
|
|
5228
5782
|
return typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
5229
5783
|
}
|
|
5230
5784
|
function layerGeometry(layer, options) {
|
|
@@ -5235,31 +5789,31 @@ function layerGeometry(layer, options) {
|
|
|
5235
5789
|
if ((width === void 0 || height === void 0) && layer.kind === "text") {
|
|
5236
5790
|
const m = FontManager.measure(String(layer.text ?? ""), {
|
|
5237
5791
|
fontFamily: String(layer.fontFamily ?? "Inter"),
|
|
5238
|
-
fontSize: num$
|
|
5792
|
+
fontSize: num$4(layer.fontSize, 48),
|
|
5239
5793
|
fontWeight: layer.fontWeight,
|
|
5240
|
-
letterSpacing: num$
|
|
5794
|
+
letterSpacing: num$4(layer.letterSpacing, 0),
|
|
5241
5795
|
lineHeight: typeof layer.lineHeight === "number" ? layer.lineHeight : void 0
|
|
5242
5796
|
});
|
|
5243
5797
|
width ??= m.width;
|
|
5244
5798
|
height ??= m.height;
|
|
5245
5799
|
}
|
|
5246
5800
|
if (width === void 0 || height === void 0 || width <= 0 || height <= 0) throw new Error(`Physics: layer${id} needs a numeric \`width\` and \`height\` (or the \`size\` option) to become a body.`);
|
|
5247
|
-
const scale = num$
|
|
5801
|
+
const scale = num$4(layer.scale, 1);
|
|
5248
5802
|
return {
|
|
5249
5803
|
x: layer.x,
|
|
5250
5804
|
y: layer.y,
|
|
5251
5805
|
width,
|
|
5252
5806
|
height,
|
|
5253
5807
|
scale,
|
|
5254
|
-
anchorX: num$
|
|
5255
|
-
anchorY: num$
|
|
5256
|
-
rotation: num$
|
|
5808
|
+
anchorX: num$4(layer.anchorX, .5),
|
|
5809
|
+
anchorY: num$4(layer.anchorY, .5),
|
|
5810
|
+
rotation: num$4(layer.rotation, 0),
|
|
5257
5811
|
shape: scaleShape$1(colliderShape(layer, width, height, options.shape ?? "auto"), scale)
|
|
5258
5812
|
};
|
|
5259
5813
|
}
|
|
5260
5814
|
function colliderShape(layer, w, h, mode) {
|
|
5261
5815
|
const shapeType = layer.kind === "shape" ? String(layer.shapeType ?? "rect") : "rect";
|
|
5262
|
-
const radius = num$
|
|
5816
|
+
const radius = num$4(layer.borderRadius, num$4(layer.cornerRadius, 0));
|
|
5263
5817
|
const box = {
|
|
5264
5818
|
kind: "box",
|
|
5265
5819
|
hx: w / 2,
|
|
@@ -5287,7 +5841,7 @@ function outlinePoints(layer, shapeType, w, h) {
|
|
|
5287
5841
|
shapeType,
|
|
5288
5842
|
width: w,
|
|
5289
5843
|
height: h,
|
|
5290
|
-
cornerRadius: num$
|
|
5844
|
+
cornerRadius: num$4(layer.cornerRadius, num$4(layer.borderRadius, 0)),
|
|
5291
5845
|
polygonSides: layer.polygonSides,
|
|
5292
5846
|
starPoints: layer.starPoints,
|
|
5293
5847
|
starInnerRadiusRatio: layer.starInnerRadiusRatio,
|
|
@@ -5336,6 +5890,275 @@ function centerToLayer(cx, cy, rotationDeg, f) {
|
|
|
5336
5890
|
return [cx - ox - f.anchorX * f.width, cy - oy - f.anchorY * f.height];
|
|
5337
5891
|
}
|
|
5338
5892
|
|
|
5893
|
+
//#endregion
|
|
5894
|
+
//#region src/physics/fracture3d.ts
|
|
5895
|
+
/**
|
|
5896
|
+
* Voronoi destruction: a mesh layer stays whole (a fixed collider of its
|
|
5897
|
+
* own shape) until its fracture frame, or until a body hits it, then its
|
|
5898
|
+
* pieces wake as rigid bodies and fly apart. The pieces' recorded poses go
|
|
5899
|
+
* into the node (`fracture3d.track`), where the renderer turns them into
|
|
5900
|
+
* the joints of one rigidly skinned mesh.
|
|
5901
|
+
*/
|
|
5902
|
+
/** A fractured layer: its pieces, and the collider that stands in for it while whole. */
|
|
5903
|
+
var Fracture3D = class {
|
|
5904
|
+
/** @internal */ brokeAt;
|
|
5905
|
+
/** @internal */
|
|
5906
|
+
constructor(node, pieces, intact, world) {
|
|
5907
|
+
this.node = node;
|
|
5908
|
+
this.pieces = pieces;
|
|
5909
|
+
this.intact = intact;
|
|
5910
|
+
this.world = world;
|
|
5911
|
+
}
|
|
5912
|
+
/** Composition frame it broke at (after simulating); undefined if it never did. */
|
|
5913
|
+
get frame() {
|
|
5914
|
+
return this.brokeAt === void 0 ? void 0 : this.world.startFrame + this.brokeAt;
|
|
5915
|
+
}
|
|
5916
|
+
};
|
|
5917
|
+
const NEVER = Number.MAX_SAFE_INTEGER;
|
|
5918
|
+
const num$3 = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
5919
|
+
/** The node's placement as the renderer builds it: T · Rz · Ry · Rx · S. */
|
|
5920
|
+
function nodePose(t) {
|
|
5921
|
+
const position = [
|
|
5922
|
+
num$3(t.x, 0),
|
|
5923
|
+
num$3(t.y, 0),
|
|
5924
|
+
num$3(t.z, 0)
|
|
5925
|
+
];
|
|
5926
|
+
const rotation = [
|
|
5927
|
+
num$3(t.rotateX, 0),
|
|
5928
|
+
num$3(t.rotateY, 0),
|
|
5929
|
+
num$3(t.rotateZ, num$3(t.rotation, 0))
|
|
5930
|
+
];
|
|
5931
|
+
const s = num$3(t.scale, 1);
|
|
5932
|
+
const scale = [
|
|
5933
|
+
s * num$3(t.scaleX, 1),
|
|
5934
|
+
s * num$3(t.scaleY, 1),
|
|
5935
|
+
s * num$3(t.scaleZ, 1)
|
|
5936
|
+
];
|
|
5937
|
+
const rad = (d) => d * Math.PI / 180;
|
|
5938
|
+
let m = Matrix4Math.translate(...position);
|
|
5939
|
+
m = Matrix4Math.multiply(m, Matrix4Math.rotateZ(rad(rotation[2])));
|
|
5940
|
+
m = Matrix4Math.multiply(m, Matrix4Math.rotateY(rad(rotation[1])));
|
|
5941
|
+
m = Matrix4Math.multiply(m, Matrix4Math.rotateX(rad(rotation[0])));
|
|
5942
|
+
m = Matrix4Math.multiply(m, Matrix4Math.scale(...scale));
|
|
5943
|
+
return {
|
|
5944
|
+
position,
|
|
5945
|
+
rotation,
|
|
5946
|
+
scale,
|
|
5947
|
+
matrix: m
|
|
5948
|
+
};
|
|
5949
|
+
}
|
|
5950
|
+
const apply = (m, p) => [
|
|
5951
|
+
m[0] * p[0] + m[4] * p[1] + m[8] * p[2] + m[12],
|
|
5952
|
+
m[1] * p[0] + m[5] * p[1] + m[9] * p[2] + m[13],
|
|
5953
|
+
m[2] * p[0] + m[6] * p[1] + m[10] * p[2] + m[14]
|
|
5954
|
+
];
|
|
5955
|
+
const SCALE_PROPS = [
|
|
5956
|
+
"scale",
|
|
5957
|
+
"scaleX",
|
|
5958
|
+
"scaleY",
|
|
5959
|
+
"scaleZ"
|
|
5960
|
+
];
|
|
5961
|
+
/** The animated props among `props` (tracks on them). */
|
|
5962
|
+
function animatedProps(node, props) {
|
|
5963
|
+
const tracks = node.animation?.tracks ?? [];
|
|
5964
|
+
return props.filter((p) => tracks.some((t) => t.prop === p));
|
|
5965
|
+
}
|
|
5966
|
+
/** Rigid pieces cannot change size: a fractured layer's scale holds still. */
|
|
5967
|
+
function assertRigid(node) {
|
|
5968
|
+
const scaling = animatedProps(node, SCALE_PROPS);
|
|
5969
|
+
if (!scaling.length) return;
|
|
5970
|
+
const id = typeof node.id === "string" ? ` "${node.id}"` : "";
|
|
5971
|
+
throw new Error(`Physics.fracture: layer${id} animates ${scaling.join(", ")}; rigid pieces cannot change size. Keep a fractured layer's scale still (position and rotation may animate).`);
|
|
5972
|
+
}
|
|
5973
|
+
/**
|
|
5974
|
+
* The layer's animated position and rotation as kinematic drivers, sampled
|
|
5975
|
+
* as the compositor draws them (GSAP eases, stepped timing, signals), so the
|
|
5976
|
+
* stand-in collider is where the layer is; undefined when it holds still.
|
|
5977
|
+
* Read lazily: animation added after `fracture()` counts.
|
|
5978
|
+
*/
|
|
5979
|
+
function followLayer(node, fps) {
|
|
5980
|
+
const layer = node;
|
|
5981
|
+
const at = (prop) => (frame) => sampleLayerProp(layer, prop, frame, fps);
|
|
5982
|
+
const rotateZ = (frame) => animatedProps(node, ["rotateZ"]).length || typeof node.rotateZ === "number" ? sampleLayerProp(layer, "rotateZ", frame, fps) : sampleLayerProp(layer, "rotation", frame, fps);
|
|
5983
|
+
return {
|
|
5984
|
+
x: at("x"),
|
|
5985
|
+
y: at("y"),
|
|
5986
|
+
z: at("z"),
|
|
5987
|
+
rotateX: at("rotateX"),
|
|
5988
|
+
rotateY: at("rotateY"),
|
|
5989
|
+
rotateZ
|
|
5990
|
+
};
|
|
5991
|
+
}
|
|
5992
|
+
const MOVING_PROPS = [
|
|
5993
|
+
"x",
|
|
5994
|
+
"y",
|
|
5995
|
+
"z",
|
|
5996
|
+
"rotateX",
|
|
5997
|
+
"rotateY",
|
|
5998
|
+
"rotateZ",
|
|
5999
|
+
"rotation"
|
|
6000
|
+
];
|
|
6001
|
+
/** @internal */
|
|
6002
|
+
function createFracture(world, target$1, options) {
|
|
6003
|
+
const node = target$1;
|
|
6004
|
+
const model = node.modelData;
|
|
6005
|
+
if (!model?.meshes?.length) {
|
|
6006
|
+
const id = typeof node.id === "string" ? ` "${node.id}"` : "";
|
|
6007
|
+
throw new Error(`Physics.fracture: layer${id} has no mesh. Fracture a Layer3D primitive, extruded text, or a model node that carries modelData.`);
|
|
6008
|
+
}
|
|
6009
|
+
assertRigid(node);
|
|
6010
|
+
const pose = nodePose(node);
|
|
6011
|
+
const toObject = Matrix4Math.invert(pose.matrix) ?? Matrix4Math.identity();
|
|
6012
|
+
const spec$1 = {
|
|
6013
|
+
cells: Math.max(2, Math.min(256, Math.round(options.cells ?? 48))),
|
|
6014
|
+
seed: options.seed ?? 1,
|
|
6015
|
+
...options.impactPoint && { impactPoint: apply(toObject, options.impactPoint) },
|
|
6016
|
+
...options.interiorColor && { interiorColor: options.interiorColor },
|
|
6017
|
+
...options.interiorRoughness !== void 0 && { interiorRoughness: options.interiorRoughness }
|
|
6018
|
+
};
|
|
6019
|
+
const { cells } = fractureModel(model, spec$1);
|
|
6020
|
+
node.fracture3d = spec$1;
|
|
6021
|
+
const moving = animatedProps(node, MOVING_PROPS).length > 0;
|
|
6022
|
+
const intact = world.body(target$1, moving ? {
|
|
6023
|
+
type: "kinematic",
|
|
6024
|
+
output: "none",
|
|
6025
|
+
follow: followLayer(node, world.fps)
|
|
6026
|
+
} : {
|
|
6027
|
+
type: "fixed",
|
|
6028
|
+
output: "none"
|
|
6029
|
+
});
|
|
6030
|
+
const pieces = cells.map((cell) => world.shapedBody(void 0, apply(pose.matrix, cell.centroid), pose.rotation, {
|
|
6031
|
+
kind: "hull",
|
|
6032
|
+
points: cell.hull.map((v, i) => v * pose.scale[i % 3] * .97)
|
|
6033
|
+
}, {
|
|
6034
|
+
type: "dynamic",
|
|
6035
|
+
startFrame: NEVER,
|
|
6036
|
+
output: "none",
|
|
6037
|
+
density: options.density,
|
|
6038
|
+
friction: options.friction,
|
|
6039
|
+
restitution: options.restitution ?? .2
|
|
6040
|
+
}));
|
|
6041
|
+
const fracture = new Fracture3D(target$1, pieces, intact, world);
|
|
6042
|
+
const radius = model.bounds.boundingSphereRadius * Math.max(...pose.scale);
|
|
6043
|
+
world.onStep((f, pairs) => {
|
|
6044
|
+
if (fracture.brokeAt !== void 0) return;
|
|
6045
|
+
const ff = options.fractureFrame ?? "onImpact";
|
|
6046
|
+
const hit = pairs.find(([a, b]) => a === intact && b.type === "dynamic" || b === intact && a.type === "dynamic");
|
|
6047
|
+
const hitter = hit ? hit[0] === intact ? hit[1] : hit[0] : void 0;
|
|
6048
|
+
if (!(ff === "onImpact" ? Boolean(hitter) : f >= ff - world.startFrame)) return;
|
|
6049
|
+
fracture.brokeAt = f;
|
|
6050
|
+
intact.sim.setEnabled(false);
|
|
6051
|
+
breakApart(world, pieces, options, radius, intact, pose, hitter, f);
|
|
6052
|
+
});
|
|
6053
|
+
world.onSimulated(() => {
|
|
6054
|
+
assertRigid(node);
|
|
6055
|
+
spec$1.track = recordTrack(pieces, world.startFrame + world.frames);
|
|
6056
|
+
});
|
|
6057
|
+
return fracture;
|
|
6058
|
+
}
|
|
6059
|
+
/** Where the stand-in is and how it moves (px, quaternion, px/s, rad/s). */
|
|
6060
|
+
function standInState(world, intact) {
|
|
6061
|
+
const ppm = world.pixelsPerMeter;
|
|
6062
|
+
return {
|
|
6063
|
+
position: intact.sim.position().map((v) => v * ppm),
|
|
6064
|
+
rotation: intact.sim.rotation(),
|
|
6065
|
+
velocity: intact.sim.velocity().map((v) => v * ppm),
|
|
6066
|
+
spin: intact.sim.angularVelocity()
|
|
6067
|
+
};
|
|
6068
|
+
}
|
|
6069
|
+
/**
|
|
6070
|
+
* Wakes every piece where the layer is now (the stand-in's pose, which
|
|
6071
|
+
* follows its animation), carrying the layer's own motion, plus a burst
|
|
6072
|
+
* outward from the impact and some of the hitter's momentum.
|
|
6073
|
+
*/
|
|
6074
|
+
function breakApart(world, pieces, options, radius, intact, rest, hitter, frame) {
|
|
6075
|
+
const ppm = world.pixelsPerMeter;
|
|
6076
|
+
const layer = standInState(world, intact);
|
|
6077
|
+
const q0 = quatFromEuler(...rest.rotation);
|
|
6078
|
+
const undoRest = [
|
|
6079
|
+
-q0[0],
|
|
6080
|
+
-q0[1],
|
|
6081
|
+
-q0[2],
|
|
6082
|
+
q0[3]
|
|
6083
|
+
];
|
|
6084
|
+
const hitAt = hitter?.sim.position().map((v) => v * ppm);
|
|
6085
|
+
const transfer = options.momentumTransfer ?? .35;
|
|
6086
|
+
const hitVel = [
|
|
6087
|
+
0,
|
|
6088
|
+
0,
|
|
6089
|
+
0
|
|
6090
|
+
];
|
|
6091
|
+
if (hitter) {
|
|
6092
|
+
const at = world.startFrame + frame - 1;
|
|
6093
|
+
const rec = hitter.recording;
|
|
6094
|
+
hitVel[0] = rec.channel("vx")[at] ?? 0;
|
|
6095
|
+
hitVel[1] = rec.channel("vy")[at] ?? 0;
|
|
6096
|
+
hitVel[2] = rec.channel("vz")[at] ?? 0;
|
|
6097
|
+
hitter.sim.setVelocity(hitVel.map((v) => v * (1 - transfer) / ppm), hitter.sim.angularVelocity());
|
|
6098
|
+
}
|
|
6099
|
+
const impact = options.impactPoint ?? hitAt ?? layer.position;
|
|
6100
|
+
const speed = options.explosionSpeed ?? 0;
|
|
6101
|
+
const spin = options.spin ?? speed / 3;
|
|
6102
|
+
const rand = createRandom((options.seed ?? 1) * 7717 + 3);
|
|
6103
|
+
for (const piece of pieces) {
|
|
6104
|
+
const c = piece.center();
|
|
6105
|
+
const arm = rotateByQuat(rotateByQuat([
|
|
6106
|
+
c[0] - rest.position[0],
|
|
6107
|
+
c[1] - rest.position[1],
|
|
6108
|
+
c[2] - rest.position[2]
|
|
6109
|
+
], undoRest), layer.rotation);
|
|
6110
|
+
const p = [
|
|
6111
|
+
layer.position[0] + arm[0],
|
|
6112
|
+
layer.position[1] + arm[1],
|
|
6113
|
+
layer.position[2] + arm[2]
|
|
6114
|
+
];
|
|
6115
|
+
const w0 = layer.spin;
|
|
6116
|
+
const carried = [
|
|
6117
|
+
layer.velocity[0] + w0[1] * arm[2] - w0[2] * arm[1],
|
|
6118
|
+
layer.velocity[1] + w0[2] * arm[0] - w0[0] * arm[2],
|
|
6119
|
+
layer.velocity[2] + w0[0] * arm[1] - w0[1] * arm[0]
|
|
6120
|
+
];
|
|
6121
|
+
const d = [
|
|
6122
|
+
p[0] - impact[0],
|
|
6123
|
+
p[1] - impact[1],
|
|
6124
|
+
p[2] - impact[2]
|
|
6125
|
+
];
|
|
6126
|
+
const dist$2 = Math.hypot(...d) || 1;
|
|
6127
|
+
const falloff = 1 / (1 + (dist$2 / Math.max(1, radius)) ** 2);
|
|
6128
|
+
const v = d.map((x, i) => carried[i] + x / dist$2 * speed * falloff + hitVel[i] * transfer * falloff);
|
|
6129
|
+
const axis = [
|
|
6130
|
+
rand() - .5,
|
|
6131
|
+
rand() - .5,
|
|
6132
|
+
rand() - .5
|
|
6133
|
+
];
|
|
6134
|
+
const len = Math.hypot(...axis) || 1;
|
|
6135
|
+
const w = axis.map((a, i) => a / len * spin * (.5 + rand()) + w0[i] * 180 / Math.PI);
|
|
6136
|
+
piece.wake(frame, v, w, {
|
|
6137
|
+
position: p,
|
|
6138
|
+
rotation: layer.rotation
|
|
6139
|
+
});
|
|
6140
|
+
}
|
|
6141
|
+
}
|
|
6142
|
+
/** Every piece's pose per composition frame: [x, y, z, qx, qy, qz, qw] each. */
|
|
6143
|
+
function recordTrack(pieces, frames) {
|
|
6144
|
+
const channels = pieces.map((b) => [
|
|
6145
|
+
"x",
|
|
6146
|
+
"y",
|
|
6147
|
+
"z",
|
|
6148
|
+
"qx",
|
|
6149
|
+
"qy",
|
|
6150
|
+
"qz",
|
|
6151
|
+
"qw"
|
|
6152
|
+
].map((c) => b.recording.channel(c)));
|
|
6153
|
+
const out = new Array(frames * pieces.length * 7);
|
|
6154
|
+
let k = 0;
|
|
6155
|
+
for (let f = 0; f < frames; f++) for (const ch of channels) for (let c = 0; c < 7; c++) {
|
|
6156
|
+
const v = ch[c][f] ?? 0;
|
|
6157
|
+
out[k++] = c < 3 ? Math.round(v * 1e5) / 1e5 : Math.round(v * 1e7) / 1e7;
|
|
6158
|
+
}
|
|
6159
|
+
return out;
|
|
6160
|
+
}
|
|
6161
|
+
|
|
5339
6162
|
//#endregion
|
|
5340
6163
|
//#region src/physics/world3d.ts
|
|
5341
6164
|
const DEG = Math.PI / 180;
|
|
@@ -5361,6 +6184,7 @@ function quatFromEuler(rx, ry, rz) {
|
|
|
5361
6184
|
Math.cos(half(rz))
|
|
5362
6185
|
], qy), qx);
|
|
5363
6186
|
}
|
|
6187
|
+
/** @internal */
|
|
5364
6188
|
function quatMul(a, b) {
|
|
5365
6189
|
const [ax, ay, az, aw] = a;
|
|
5366
6190
|
const [bx, by, bz, bw] = b;
|
|
@@ -5440,7 +6264,32 @@ var PhysicsBody3D = class {
|
|
|
5440
6264
|
this.recording = recording;
|
|
5441
6265
|
}
|
|
5442
6266
|
get startFrame() {
|
|
5443
|
-
return Math.max(0, Math.round(this.options.startFrame ?? 0));
|
|
6267
|
+
return this.wokeAt ?? Math.max(0, Math.round(this.options.startFrame ?? 0));
|
|
6268
|
+
}
|
|
6269
|
+
wokeAt;
|
|
6270
|
+
/**
|
|
6271
|
+
* @internal Starts the body now, mid-simulation (`frame` relative to the
|
|
6272
|
+
* world's start): it moves from the next frame, at this velocity (px/s,
|
|
6273
|
+
* degrees per second), from `pose` (px) when given.
|
|
6274
|
+
*/
|
|
6275
|
+
wake(frame, velocity, angularVelocity, pose) {
|
|
6276
|
+
this.wokeAt = frame;
|
|
6277
|
+
const ppm = this.world.pixelsPerMeter;
|
|
6278
|
+
this.sim.setEnabled(true);
|
|
6279
|
+
if (pose) this.sim.setPose([
|
|
6280
|
+
pose.position[0] / ppm,
|
|
6281
|
+
pose.position[1] / ppm,
|
|
6282
|
+
pose.position[2] / ppm
|
|
6283
|
+
], pose.rotation);
|
|
6284
|
+
this.sim.setVelocity([
|
|
6285
|
+
velocity[0] / ppm,
|
|
6286
|
+
velocity[1] / ppm,
|
|
6287
|
+
velocity[2] / ppm
|
|
6288
|
+
], [
|
|
6289
|
+
angularVelocity[0] * DEG,
|
|
6290
|
+
angularVelocity[1] * DEG,
|
|
6291
|
+
angularVelocity[2] * DEG
|
|
6292
|
+
]);
|
|
5444
6293
|
}
|
|
5445
6294
|
get gravityScale() {
|
|
5446
6295
|
return this.options.gravityScale ?? 1;
|
|
@@ -5494,17 +6343,17 @@ var PhysicsBody3D = class {
|
|
|
5494
6343
|
const follow = this.options.follow;
|
|
5495
6344
|
if (this.type !== "kinematic" || !follow) return void 0;
|
|
5496
6345
|
const fps = this.world.fps;
|
|
5497
|
-
const read$
|
|
6346
|
+
const read$2 = (d, fallback) => d === void 0 ? fallback : sampleDriver(d, frame, fps);
|
|
5498
6347
|
const p = this.start.position;
|
|
5499
6348
|
const r = this.start.rotation;
|
|
5500
6349
|
const ppm = this.world.pixelsPerMeter;
|
|
5501
6350
|
return {
|
|
5502
6351
|
position: [
|
|
5503
|
-
read$
|
|
5504
|
-
read$
|
|
5505
|
-
read$
|
|
6352
|
+
read$2(follow.x, p[0]) / ppm,
|
|
6353
|
+
read$2(follow.y, p[1]) / ppm,
|
|
6354
|
+
read$2(follow.z, p[2]) / ppm
|
|
5506
6355
|
],
|
|
5507
|
-
rotation: quatFromEuler(read$
|
|
6356
|
+
rotation: quatFromEuler(read$2(follow.rotateX, r[0]), read$2(follow.rotateY, r[1]), read$2(follow.rotateZ, r[2]))
|
|
5508
6357
|
};
|
|
5509
6358
|
}
|
|
5510
6359
|
/** @internal */
|
|
@@ -5523,7 +6372,12 @@ var PhysicsBody3D = class {
|
|
|
5523
6372
|
ry[previous],
|
|
5524
6373
|
rz[previous]
|
|
5525
6374
|
];
|
|
5526
|
-
const
|
|
6375
|
+
const q = this.sim.rotation();
|
|
6376
|
+
rec.channel("qx")[index] = q[0];
|
|
6377
|
+
rec.channel("qy")[index] = q[1];
|
|
6378
|
+
rec.channel("qz")[index] = q[2];
|
|
6379
|
+
rec.channel("qw")[index] = q[3];
|
|
6380
|
+
const e = eulerFromQuat(q, prev);
|
|
5527
6381
|
rx[index] = e[0];
|
|
5528
6382
|
ry[index] = e[1];
|
|
5529
6383
|
rz[index] = e[2];
|
|
@@ -5576,6 +6430,7 @@ var PhysicsBody3D = class {
|
|
|
5576
6430
|
];
|
|
5577
6431
|
}
|
|
5578
6432
|
};
|
|
6433
|
+
/** @internal */
|
|
5579
6434
|
function rotateByQuat(v, q) {
|
|
5580
6435
|
const r = quatMul(quatMul(q, [
|
|
5581
6436
|
v[0],
|
|
@@ -5631,6 +6486,11 @@ var PhysicsWorld3D = class extends WorldCore {
|
|
|
5631
6486
|
num$2(options.rotateY ?? t.rotateY, 0),
|
|
5632
6487
|
num$2(options.rotateZ ?? t.rotateZ, 0)
|
|
5633
6488
|
];
|
|
6489
|
+
return this.shapedBody(layer, position, rotation, colliderShape3D(t, options), options);
|
|
6490
|
+
}
|
|
6491
|
+
/** @internal A body with an explicit collider (px), at a pose in px and degrees. */
|
|
6492
|
+
shapedBody(layer, position, rotation, shape$1, options) {
|
|
6493
|
+
this.assertOpen();
|
|
5634
6494
|
const ppm = this.pixelsPerMeter;
|
|
5635
6495
|
const type = options.type ?? "dynamic";
|
|
5636
6496
|
const v = options.velocity ?? [
|
|
@@ -5676,15 +6536,37 @@ var PhysicsWorld3D = class extends WorldCore {
|
|
|
5676
6536
|
density: options.density ?? 1,
|
|
5677
6537
|
friction: options.friction ?? .6,
|
|
5678
6538
|
restitution: options.restitution ?? .3,
|
|
5679
|
-
shape: scaleShape(
|
|
6539
|
+
shape: scaleShape(shape$1, 1 / ppm)
|
|
5680
6540
|
};
|
|
5681
6541
|
const simBody = this.sim.addBody(spec$1);
|
|
5682
6542
|
const body = new PhysicsBody3D(this, simBody, type, layer, {
|
|
5683
6543
|
position,
|
|
5684
6544
|
rotation
|
|
5685
6545
|
}, options, this.newRecording());
|
|
6546
|
+
const start = body.kinematicTarget(this.startFrame);
|
|
6547
|
+
if (start) simBody.setPose(start.position, start.rotation);
|
|
5686
6548
|
return this.addBody(body);
|
|
5687
6549
|
}
|
|
6550
|
+
/** @internal Runs after each simulated frame (frame relative to the world's start). */
|
|
6551
|
+
onStep(hook) {
|
|
6552
|
+
this.assertOpen();
|
|
6553
|
+
this.stepHooks.push(hook);
|
|
6554
|
+
}
|
|
6555
|
+
/** @internal Runs once the simulation has finished. */
|
|
6556
|
+
onSimulated(hook) {
|
|
6557
|
+
this.assertOpen();
|
|
6558
|
+
this.simulatedHooks.push(hook);
|
|
6559
|
+
}
|
|
6560
|
+
/**
|
|
6561
|
+
* Breaks a Layer3D primitive, extruded text or loaded model into Voronoi
|
|
6562
|
+
* pieces that stay together, looking intact, until the fracture frame (or
|
|
6563
|
+
* until something hits it), then fly apart as rigid bodies. The node is
|
|
6564
|
+
* changed in place: add it to the composition as usual. All pieces draw
|
|
6565
|
+
* in one call per material, the cut faces in `interiorColor`.
|
|
6566
|
+
*/
|
|
6567
|
+
fracture(target$1, options = {}) {
|
|
6568
|
+
return createFracture(this, target$1, options);
|
|
6569
|
+
}
|
|
5688
6570
|
/** A fixed, very large floor whose top face sits at `y`. */
|
|
5689
6571
|
ground(options) {
|
|
5690
6572
|
const t = 2e3;
|
|
@@ -5833,11 +6715,11 @@ var PhysicsWorld3D = class extends WorldCore {
|
|
|
5833
6715
|
/** A steady push, px/s² (mass-independent). Drivers are read every frame. */
|
|
5834
6716
|
force(body, accel) {
|
|
5835
6717
|
const ppm = this.pixelsPerMeter;
|
|
5836
|
-
const read$
|
|
6718
|
+
const read$2 = (d, frame) => d === void 0 ? 0 : sampleDriver(d, frame, this.fps) / ppm;
|
|
5837
6719
|
this.addForce(body, (frame) => [
|
|
5838
|
-
read$
|
|
5839
|
-
read$
|
|
5840
|
-
read$
|
|
6720
|
+
read$2(accel.x, frame),
|
|
6721
|
+
read$2(accel.y, frame),
|
|
6722
|
+
read$2(accel.z, frame)
|
|
5841
6723
|
]);
|
|
5842
6724
|
return this;
|
|
5843
6725
|
}
|
|
@@ -5942,6 +6824,10 @@ function colliderShape3D(t, options) {
|
|
|
5942
6824
|
points: pts.map((v, i) => v * scale[i % 3])
|
|
5943
6825
|
};
|
|
5944
6826
|
};
|
|
6827
|
+
if (mode === "mesh" || mode === "auto" && (options.type ?? "dynamic") !== "dynamic" && (prim.type === "terrain" || prim.type === "sdf")) {
|
|
6828
|
+
const mesh = meshTriangles(t.modelData, scale);
|
|
6829
|
+
if (mesh) return mesh;
|
|
6830
|
+
}
|
|
5945
6831
|
if (options.size || mode === "box") {
|
|
5946
6832
|
const [w, h$1, d] = options.size ?? boxSize(t, prim) ?? [
|
|
5947
6833
|
0,
|
|
@@ -6054,6 +6940,25 @@ function boxSize(t, prim) {
|
|
|
6054
6940
|
t.depth
|
|
6055
6941
|
];
|
|
6056
6942
|
}
|
|
6943
|
+
/** All of a model's triangles, scaled: an exact (non-convex) collider. */
|
|
6944
|
+
function meshTriangles(modelData, scale) {
|
|
6945
|
+
const meshes = modelData?.meshes;
|
|
6946
|
+
if (!meshes?.length) return void 0;
|
|
6947
|
+
const vertices = [];
|
|
6948
|
+
const indices = [];
|
|
6949
|
+
for (const m of meshes) {
|
|
6950
|
+
if (!m.positions || !m.indices) continue;
|
|
6951
|
+
if (m.topology && m.topology !== "triangle-list") continue;
|
|
6952
|
+
const base = vertices.length / 3;
|
|
6953
|
+
for (let i = 0; i < m.positions.length; i++) vertices.push(m.positions[i] * scale[i % 3]);
|
|
6954
|
+
for (let i = 0; i < m.indices.length; i++) indices.push(m.indices[i] + base);
|
|
6955
|
+
}
|
|
6956
|
+
return indices.length >= 3 ? {
|
|
6957
|
+
kind: "trimesh",
|
|
6958
|
+
vertices,
|
|
6959
|
+
indices
|
|
6960
|
+
} : void 0;
|
|
6961
|
+
}
|
|
6057
6962
|
/** Every vertex of a model, flat xyz, at most ~4k points (the hull needs no more). */
|
|
6058
6963
|
function meshPoints(modelData) {
|
|
6059
6964
|
const meshes = modelData?.meshes;
|
|
@@ -6093,6 +6998,11 @@ function scaleShape(shape$1, s) {
|
|
|
6093
6998
|
kind: "hull",
|
|
6094
6999
|
points: shape$1.points.map((v) => v * s)
|
|
6095
7000
|
};
|
|
7001
|
+
case "trimesh": return {
|
|
7002
|
+
kind: "trimesh",
|
|
7003
|
+
vertices: shape$1.vertices.map((v) => v * s),
|
|
7004
|
+
indices: shape$1.indices
|
|
7005
|
+
};
|
|
6096
7006
|
}
|
|
6097
7007
|
}
|
|
6098
7008
|
|
|
@@ -8667,7 +9577,7 @@ var Media = class Media {
|
|
|
8667
9577
|
return this.virtualMedia;
|
|
8668
9578
|
}
|
|
8669
9579
|
/**
|
|
8670
|
-
* Renders a single frame from this media pipeline to
|
|
9580
|
+
* Renders a single frame from this media pipeline to an image or raw RGBA Buffer.
|
|
8671
9581
|
* Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).
|
|
8672
9582
|
*/
|
|
8673
9583
|
async renderFrame(options = {}) {
|
|
@@ -8780,7 +9690,11 @@ var Composition = class Composition {
|
|
|
8780
9690
|
vision(sourceOrLayer, options = {}) {
|
|
8781
9691
|
const source = typeof sourceOrLayer === "string" ? sourceOrLayer : sourceOrLayer.src ?? sourceOrLayer.inputHandleId;
|
|
8782
9692
|
if (typeof sourceOrLayer !== "string") {
|
|
8783
|
-
const
|
|
9693
|
+
const found = collectLayersOnClock(this.toVirtualMedia({ resolveMediaSignal: this.mediaSignalResolver(true) }).children).find(({ vm: node }) => node.operation.id === sourceOrLayer.id);
|
|
9694
|
+
const layer = found && { operation: {
|
|
9695
|
+
...found.vm.operation,
|
|
9696
|
+
startFrame: found.startFrame
|
|
9697
|
+
} };
|
|
8784
9698
|
if (!layer) throw new Error("Add the media layer to the composition before calling comp.vision(layer)");
|
|
8785
9699
|
options = {
|
|
8786
9700
|
startFrame: layer.operation.startFrame ?? sourceOrLayer.startFrame,
|
|
@@ -8823,9 +9737,12 @@ var Composition = class Composition {
|
|
|
8823
9737
|
if (!node || typeof node !== "object") return;
|
|
8824
9738
|
const n = node;
|
|
8825
9739
|
if (n.kind === "media" && n.dataType === "Video" && typeof n.inputHandleId === "string" && n.vision instanceof Vision && !(CLIP_SUBJECT in n.vision)) {
|
|
8826
|
-
layers ??= new Map(
|
|
8827
|
-
const op =
|
|
8828
|
-
return [op.id,
|
|
9740
|
+
layers ??= new Map(collectLayersOnClock(this.toVirtualMedia().children).map(({ vm, startFrame }) => {
|
|
9741
|
+
const op = vm.operation;
|
|
9742
|
+
return [op.id, {
|
|
9743
|
+
startFrame,
|
|
9744
|
+
timeRemap: op.timeRemap
|
|
9745
|
+
}];
|
|
8829
9746
|
}));
|
|
8830
9747
|
const layer = layers.get(n.id);
|
|
8831
9748
|
const clip = this.clipForLayer(n.src ?? n.inputHandleId, n.vision, {
|
|
@@ -9378,10 +10295,11 @@ var Composition = class Composition {
|
|
|
9378
10295
|
return vm;
|
|
9379
10296
|
}
|
|
9380
10297
|
/**
|
|
9381
|
-
* Renders a single frame from the composition to
|
|
10298
|
+
* Renders a single frame from the composition to an image or raw RGBA Buffer.
|
|
9382
10299
|
* Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).
|
|
9383
10300
|
*/
|
|
9384
|
-
async renderFrame(
|
|
10301
|
+
async renderFrame(frameOrOptions = {}) {
|
|
10302
|
+
const options = typeof frameOrOptions === "number" ? { frame: frameOrOptions } : frameOrOptions;
|
|
9385
10303
|
const { frame } = resolveFrameRequest(options, this.fps);
|
|
9386
10304
|
if (options.fps !== void 0 && options.fps !== this.fps) throw new Error(`Composition fps is ${this.fps}; cannot render at fps ${options.fps}.`);
|
|
9387
10305
|
const vm = this.toVirtualMedia();
|
|
@@ -9399,7 +10317,9 @@ var Composition = class Composition {
|
|
|
9399
10317
|
}
|
|
9400
10318
|
return (options.renderer ?? new HeadlessMediaRenderer()).renderFrame(vm, {
|
|
9401
10319
|
fps: this.fps,
|
|
9402
|
-
frame
|
|
10320
|
+
frame,
|
|
10321
|
+
renderId: options.renderId,
|
|
10322
|
+
format: options.format
|
|
9403
10323
|
});
|
|
9404
10324
|
}
|
|
9405
10325
|
/**
|
|
@@ -9442,11 +10362,27 @@ var Composition = class Composition {
|
|
|
9442
10362
|
* never change. `renderVideo({ qa })` includes these automatically.
|
|
9443
10363
|
*/
|
|
9444
10364
|
lint() {
|
|
9445
|
-
return lintComposition(this.toSpec(), {
|
|
10365
|
+
return lintComposition(this.toSpec(), {
|
|
10366
|
+
emojiFont: FontManager.hasEmojiFont(),
|
|
10367
|
+
scatterCoverage
|
|
10368
|
+
});
|
|
9446
10369
|
}
|
|
9447
10370
|
};
|
|
9448
10371
|
function withAnimation(node) {
|
|
9449
10372
|
const target$1 = node;
|
|
10373
|
+
const raw = target$1;
|
|
10374
|
+
if (raw.rotationX !== void 0) {
|
|
10375
|
+
if (raw.rotateX === void 0) raw.rotateX = raw.rotationX;
|
|
10376
|
+
delete raw.rotationX;
|
|
10377
|
+
}
|
|
10378
|
+
if (raw.rotationY !== void 0) {
|
|
10379
|
+
if (raw.rotateY === void 0) raw.rotateY = raw.rotationY;
|
|
10380
|
+
delete raw.rotationY;
|
|
10381
|
+
}
|
|
10382
|
+
if (raw.rotationZ !== void 0) {
|
|
10383
|
+
if (raw.rotateZ === void 0) raw.rotateZ = raw.rotationZ;
|
|
10384
|
+
delete raw.rotationZ;
|
|
10385
|
+
}
|
|
9450
10386
|
if (target$1.animation instanceof LayerAnimation) target$1.animation = target$1.animation.toSpec();
|
|
9451
10387
|
Object.defineProperty(target$1, "animate", {
|
|
9452
10388
|
value: (...anims) => {
|
|
@@ -9633,8 +10569,89 @@ function withAnimation(node) {
|
|
|
9633
10569
|
writable: true,
|
|
9634
10570
|
configurable: true
|
|
9635
10571
|
});
|
|
10572
|
+
bindMaterialSignals(target$1);
|
|
9636
10573
|
return target$1;
|
|
9637
10574
|
}
|
|
10575
|
+
/**
|
|
10576
|
+
* Numeric surface props a live `Signal` may drive directly (`clearcoat: sig`):
|
|
10577
|
+
* the value written to the node is the static fallback, the signal becomes a
|
|
10578
|
+
* draw-time signal track. `iridescence` counts only when it is the number form.
|
|
10579
|
+
*/
|
|
10580
|
+
const MATERIAL_SIGNAL_PROPS = [
|
|
10581
|
+
{
|
|
10582
|
+
prop: "roughness",
|
|
10583
|
+
fallback: .5
|
|
10584
|
+
},
|
|
10585
|
+
{
|
|
10586
|
+
prop: "metallic",
|
|
10587
|
+
fallback: 0
|
|
10588
|
+
},
|
|
10589
|
+
{
|
|
10590
|
+
prop: "emissiveIntensity",
|
|
10591
|
+
fallback: 1
|
|
10592
|
+
},
|
|
10593
|
+
{
|
|
10594
|
+
prop: "clearcoat",
|
|
10595
|
+
fallback: 0
|
|
10596
|
+
},
|
|
10597
|
+
{
|
|
10598
|
+
prop: "clearcoatRoughness",
|
|
10599
|
+
fallback: .08
|
|
10600
|
+
},
|
|
10601
|
+
{
|
|
10602
|
+
prop: "anisotropy",
|
|
10603
|
+
fallback: 0
|
|
10604
|
+
},
|
|
10605
|
+
{
|
|
10606
|
+
prop: "anisotropyRotation",
|
|
10607
|
+
fallback: 0
|
|
10608
|
+
},
|
|
10609
|
+
{
|
|
10610
|
+
prop: "subsurface",
|
|
10611
|
+
fallback: 0
|
|
10612
|
+
},
|
|
10613
|
+
{
|
|
10614
|
+
prop: "sheen",
|
|
10615
|
+
fallback: 0
|
|
10616
|
+
},
|
|
10617
|
+
{
|
|
10618
|
+
prop: "sheenRoughness",
|
|
10619
|
+
fallback: .5
|
|
10620
|
+
},
|
|
10621
|
+
{
|
|
10622
|
+
prop: "iridescence",
|
|
10623
|
+
fallback: 0
|
|
10624
|
+
},
|
|
10625
|
+
{
|
|
10626
|
+
prop: "iridescenceThickness",
|
|
10627
|
+
fallback: 400
|
|
10628
|
+
},
|
|
10629
|
+
{
|
|
10630
|
+
prop: "iridescenceIor",
|
|
10631
|
+
fallback: 1.3
|
|
10632
|
+
},
|
|
10633
|
+
{
|
|
10634
|
+
prop: "triplanarScale",
|
|
10635
|
+
fallback: 1
|
|
10636
|
+
},
|
|
10637
|
+
{
|
|
10638
|
+
prop: "triplanarSharpness",
|
|
10639
|
+
fallback: 4
|
|
10640
|
+
}
|
|
10641
|
+
];
|
|
10642
|
+
/** Moves signal-valued material props of a node onto signal tracks. */
|
|
10643
|
+
function bindMaterialSignals(target$1) {
|
|
10644
|
+
const raw = target$1;
|
|
10645
|
+
let anim;
|
|
10646
|
+
for (const { prop, fallback } of MATERIAL_SIGNAL_PROPS) {
|
|
10647
|
+
const val = raw[prop];
|
|
10648
|
+
if (!isSignalLike(val)) continue;
|
|
10649
|
+
anim ??= LayerAnimation.create();
|
|
10650
|
+
anim.signal(prop, val);
|
|
10651
|
+
raw[prop] = fallback;
|
|
10652
|
+
}
|
|
10653
|
+
if (anim) target$1.animate(anim);
|
|
10654
|
+
}
|
|
9638
10655
|
const Layer = {
|
|
9639
10656
|
video: (src, options = {}) => withAnimation({
|
|
9640
10657
|
id: options.id ?? autoId("video"),
|
|
@@ -9912,29 +10929,42 @@ const Layer = {
|
|
|
9912
10929
|
});
|
|
9913
10930
|
},
|
|
9914
10931
|
chart: (options, props = {}) => buildChart(options, props, FontManager.getAll()[0]?.family ?? "Inter"),
|
|
9915
|
-
camera: (options = {}) =>
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
9920
|
-
|
|
9921
|
-
|
|
9922
|
-
|
|
9923
|
-
|
|
9924
|
-
|
|
10932
|
+
camera: (options = {}) => {
|
|
10933
|
+
const { fov, focalLength, sensorWidth, near, far, zoom, lens: existingLens, ...rest } = options;
|
|
10934
|
+
const mergedLens = fov !== void 0 || focalLength !== void 0 || sensorWidth !== void 0 || near !== void 0 || far !== void 0 || zoom !== void 0 || existingLens !== void 0 ? {
|
|
10935
|
+
...existingLens,
|
|
10936
|
+
...fov !== void 0 && { fov },
|
|
10937
|
+
...focalLength !== void 0 && { focalLength },
|
|
10938
|
+
...sensorWidth !== void 0 && { sensorWidth },
|
|
10939
|
+
...near !== void 0 && { near },
|
|
10940
|
+
...far !== void 0 && { far },
|
|
10941
|
+
...zoom !== void 0 && { zoom }
|
|
10942
|
+
} : void 0;
|
|
10943
|
+
return withAnimation({
|
|
10944
|
+
id: rest.id ?? autoId("camera"),
|
|
10945
|
+
kind: "camera",
|
|
10946
|
+
mode: rest.mode ?? "lookAt",
|
|
10947
|
+
pitch: rest.pitch ?? 0,
|
|
10948
|
+
yaw: rest.yaw ?? 0,
|
|
10949
|
+
roll: rest.roll ?? 0,
|
|
10950
|
+
...rest,
|
|
10951
|
+
...mergedLens !== void 0 && { lens: mergedLens }
|
|
10952
|
+
});
|
|
10953
|
+
},
|
|
10954
|
+
light: (options = {}) => buildLightNode({
|
|
9925
10955
|
id: options.id ?? autoId("light"),
|
|
9926
10956
|
kind: "light",
|
|
9927
10957
|
lightType: options.lightType ?? "point",
|
|
9928
10958
|
color: options.color ?? "#ffffff",
|
|
9929
|
-
intensity:
|
|
9930
|
-
|
|
9931
|
-
}),
|
|
10959
|
+
intensity: 1
|
|
10960
|
+
}, options),
|
|
9932
10961
|
ambientLight: (color$1 = "#ffffff", intensity = .5, options = {}) => Light.ambient(color$1, intensity, options),
|
|
9933
10962
|
sequence: (entries, options) => sequence(entries, options),
|
|
9934
10963
|
environment: (presetOrOptions = "studio", options = {}) => Light.environment(presetOrOptions, options),
|
|
9935
10964
|
directionalLight: (options = {}) => Light.directional(options),
|
|
9936
10965
|
pointLight: (options = {}) => Light.point(options),
|
|
9937
10966
|
spotLight: (options = {}) => Light.spot(options),
|
|
10967
|
+
rectLight: (options = {}) => Light.rect(options),
|
|
9938
10968
|
cube: (options) => Layer3D.cube(options),
|
|
9939
10969
|
carousel3d: (options) => Layer3D.carousel(options),
|
|
9940
10970
|
plane3d: (options) => Layer3D.plane(options),
|
|
@@ -9998,78 +11028,220 @@ const Layer = {
|
|
|
9998
11028
|
...options
|
|
9999
11029
|
})
|
|
10000
11030
|
};
|
|
11031
|
+
function isHdriPath(value) {
|
|
11032
|
+
return /\.(hdr|exr)$/i.test(value);
|
|
11033
|
+
}
|
|
11034
|
+
const LIGHT_SIGNAL_PROPS = [
|
|
11035
|
+
{
|
|
11036
|
+
prop: "intensity",
|
|
11037
|
+
fallback: 1
|
|
11038
|
+
},
|
|
11039
|
+
{
|
|
11040
|
+
prop: "x",
|
|
11041
|
+
fallback: 0
|
|
11042
|
+
},
|
|
11043
|
+
{
|
|
11044
|
+
prop: "y",
|
|
11045
|
+
fallback: 0
|
|
11046
|
+
},
|
|
11047
|
+
{
|
|
11048
|
+
prop: "z",
|
|
11049
|
+
fallback: 0
|
|
11050
|
+
},
|
|
11051
|
+
{
|
|
11052
|
+
prop: "targetX",
|
|
11053
|
+
fallback: 0
|
|
11054
|
+
},
|
|
11055
|
+
{
|
|
11056
|
+
prop: "targetY",
|
|
11057
|
+
fallback: 0
|
|
11058
|
+
},
|
|
11059
|
+
{
|
|
11060
|
+
prop: "targetZ",
|
|
11061
|
+
fallback: 0
|
|
11062
|
+
},
|
|
11063
|
+
{
|
|
11064
|
+
prop: "radius",
|
|
11065
|
+
fallback: 1e3
|
|
11066
|
+
},
|
|
11067
|
+
{
|
|
11068
|
+
prop: "angle",
|
|
11069
|
+
fallback: 45
|
|
11070
|
+
},
|
|
11071
|
+
{
|
|
11072
|
+
prop: "penumbra",
|
|
11073
|
+
fallback: .2
|
|
11074
|
+
},
|
|
11075
|
+
{
|
|
11076
|
+
prop: "decay",
|
|
11077
|
+
fallback: 1
|
|
11078
|
+
},
|
|
11079
|
+
{
|
|
11080
|
+
prop: "width",
|
|
11081
|
+
fallback: 240
|
|
11082
|
+
},
|
|
11083
|
+
{
|
|
11084
|
+
prop: "height",
|
|
11085
|
+
fallback: 140
|
|
11086
|
+
},
|
|
11087
|
+
{
|
|
11088
|
+
prop: "rotation",
|
|
11089
|
+
fallback: 0
|
|
11090
|
+
},
|
|
11091
|
+
{
|
|
11092
|
+
prop: "exposure",
|
|
11093
|
+
fallback: 0
|
|
11094
|
+
},
|
|
11095
|
+
{
|
|
11096
|
+
prop: "volumetricFogDensity",
|
|
11097
|
+
fallback: .02
|
|
11098
|
+
},
|
|
11099
|
+
{
|
|
11100
|
+
prop: "volumetricFogAnisotropy",
|
|
11101
|
+
fallback: .55
|
|
11102
|
+
},
|
|
11103
|
+
{
|
|
11104
|
+
prop: "volumetricFogNoiseStrength",
|
|
11105
|
+
fallback: .45
|
|
11106
|
+
}
|
|
11107
|
+
];
|
|
11108
|
+
function isSignalLike(val) {
|
|
11109
|
+
if (!val || typeof val !== "object") return false;
|
|
11110
|
+
const obj = val;
|
|
11111
|
+
return typeof obj.get === "function" || typeof obj.inputHandleId === "string" || typeof obj.gpuBinding === "object";
|
|
11112
|
+
}
|
|
11113
|
+
function buildLightNode(defaults, rawOpts) {
|
|
11114
|
+
const cleaned = {
|
|
11115
|
+
...defaults,
|
|
11116
|
+
...rawOpts
|
|
11117
|
+
};
|
|
11118
|
+
const signalBindings = [];
|
|
11119
|
+
for (const { prop, fallback } of LIGHT_SIGNAL_PROPS) {
|
|
11120
|
+
const val = cleaned[prop];
|
|
11121
|
+
if (isSignalLike(val)) {
|
|
11122
|
+
signalBindings.push([prop, val]);
|
|
11123
|
+
const defVal = defaults[prop];
|
|
11124
|
+
cleaned[prop] = typeof defVal === "number" ? defVal : fallback;
|
|
11125
|
+
}
|
|
11126
|
+
}
|
|
11127
|
+
const rawVf = cleaned.volumetricFog;
|
|
11128
|
+
if (rawVf && typeof rawVf === "object") {
|
|
11129
|
+
const vfCopy = { ...rawVf };
|
|
11130
|
+
if (isSignalLike(vfCopy.density)) {
|
|
11131
|
+
signalBindings.push(["volumetricFogDensity", vfCopy.density]);
|
|
11132
|
+
vfCopy.density = .02;
|
|
11133
|
+
}
|
|
11134
|
+
if (isSignalLike(vfCopy.anisotropy)) {
|
|
11135
|
+
signalBindings.push(["volumetricFogAnisotropy", vfCopy.anisotropy]);
|
|
11136
|
+
vfCopy.anisotropy = .55;
|
|
11137
|
+
}
|
|
11138
|
+
if (vfCopy.noise && typeof vfCopy.noise === "object") {
|
|
11139
|
+
const noiseCopy = { ...vfCopy.noise };
|
|
11140
|
+
if (isSignalLike(noiseCopy.strength)) {
|
|
11141
|
+
signalBindings.push(["volumetricFogNoiseStrength", noiseCopy.strength]);
|
|
11142
|
+
noiseCopy.strength = .45;
|
|
11143
|
+
}
|
|
11144
|
+
vfCopy.noise = noiseCopy;
|
|
11145
|
+
}
|
|
11146
|
+
cleaned.volumetricFog = vfCopy;
|
|
11147
|
+
}
|
|
11148
|
+
let node = withAnimation(cleaned);
|
|
11149
|
+
if (signalBindings.length > 0) {
|
|
11150
|
+
const anim = LayerAnimation.create();
|
|
11151
|
+
for (const [prop, sig] of signalBindings) anim.signal(prop, sig);
|
|
11152
|
+
node = node.animate(anim);
|
|
11153
|
+
}
|
|
11154
|
+
return node;
|
|
11155
|
+
}
|
|
10001
11156
|
const Light = {
|
|
10002
11157
|
environment: (presetOrOptions = "studio", options = {}) => {
|
|
10003
|
-
const opts =
|
|
10004
|
-
preset: presetOrOptions,
|
|
10005
|
-
...options
|
|
10006
|
-
} : {
|
|
10007
|
-
...presetOrOptions,
|
|
11158
|
+
const opts = {
|
|
11159
|
+
...typeof presetOrOptions !== "string" ? presetOrOptions : isHdriPath(presetOrOptions) ? { hdri: presetOrOptions } : { preset: presetOrOptions },
|
|
10008
11160
|
...options
|
|
10009
11161
|
};
|
|
10010
|
-
return
|
|
11162
|
+
return buildLightNode({
|
|
11163
|
+
id: opts.id ?? autoId("environment"),
|
|
10011
11164
|
kind: "light",
|
|
10012
11165
|
lightType: "environment",
|
|
10013
11166
|
preset: "studio",
|
|
10014
|
-
intensity: 1
|
|
10015
|
-
|
|
10016
|
-
id: opts.id ?? autoId("environment")
|
|
10017
|
-
});
|
|
11167
|
+
intensity: 1
|
|
11168
|
+
}, opts);
|
|
10018
11169
|
},
|
|
10019
|
-
ambient: (color$1 = "#ffffff", intensity = .5, options = {}) =>
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
10024
|
-
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
|
|
10028
|
-
|
|
11170
|
+
ambient: (color$1 = "#ffffff", intensity = .5, options = {}) => {
|
|
11171
|
+
const merged = {
|
|
11172
|
+
color: typeof color$1 === "string" ? color$1 : color$1.color ?? "#ffffff",
|
|
11173
|
+
intensity,
|
|
11174
|
+
...typeof color$1 === "object" && color$1,
|
|
11175
|
+
...options
|
|
11176
|
+
};
|
|
11177
|
+
return buildLightNode({
|
|
11178
|
+
id: merged.id ?? autoId("light-ambient"),
|
|
11179
|
+
kind: "light",
|
|
11180
|
+
lightType: "ambient",
|
|
11181
|
+
color: "#ffffff",
|
|
11182
|
+
intensity: .5
|
|
11183
|
+
}, merged);
|
|
11184
|
+
},
|
|
11185
|
+
directional: (options = {}) => buildLightNode({
|
|
10029
11186
|
id: options.id ?? autoId("light-directional"),
|
|
10030
11187
|
kind: "light",
|
|
10031
11188
|
lightType: "directional",
|
|
10032
11189
|
color: options.color ?? "#ffffff",
|
|
10033
|
-
intensity:
|
|
10034
|
-
x:
|
|
10035
|
-
y:
|
|
10036
|
-
z:
|
|
10037
|
-
targetX:
|
|
10038
|
-
targetY:
|
|
10039
|
-
targetZ:
|
|
10040
|
-
|
|
10041
|
-
})
|
|
10042
|
-
point: (options = {}) => withAnimation({
|
|
11190
|
+
intensity: 1,
|
|
11191
|
+
x: 0,
|
|
11192
|
+
y: -1e3,
|
|
11193
|
+
z: -1e3,
|
|
11194
|
+
targetX: 0,
|
|
11195
|
+
targetY: 0,
|
|
11196
|
+
targetZ: 0
|
|
11197
|
+
}, options),
|
|
11198
|
+
point: (options = {}) => buildLightNode({
|
|
10043
11199
|
id: options.id ?? autoId("light-point"),
|
|
10044
11200
|
kind: "light",
|
|
10045
11201
|
lightType: "point",
|
|
10046
11202
|
color: options.color ?? "#ffffff",
|
|
10047
|
-
intensity:
|
|
10048
|
-
x:
|
|
10049
|
-
y:
|
|
10050
|
-
z:
|
|
10051
|
-
radius:
|
|
10052
|
-
decay:
|
|
10053
|
-
|
|
10054
|
-
})
|
|
10055
|
-
spot: (options = {}) => withAnimation({
|
|
11203
|
+
intensity: 1,
|
|
11204
|
+
x: 0,
|
|
11205
|
+
y: 0,
|
|
11206
|
+
z: -500,
|
|
11207
|
+
radius: 1e3,
|
|
11208
|
+
decay: 1
|
|
11209
|
+
}, options),
|
|
11210
|
+
spot: (options = {}) => buildLightNode({
|
|
10056
11211
|
id: options.id ?? autoId("light-spot"),
|
|
10057
11212
|
kind: "light",
|
|
10058
11213
|
lightType: "spot",
|
|
10059
11214
|
color: options.color ?? "#ffffff",
|
|
10060
|
-
intensity:
|
|
10061
|
-
x:
|
|
10062
|
-
y:
|
|
10063
|
-
z:
|
|
10064
|
-
targetX:
|
|
10065
|
-
targetY:
|
|
10066
|
-
targetZ:
|
|
10067
|
-
angle:
|
|
10068
|
-
penumbra:
|
|
10069
|
-
radius:
|
|
10070
|
-
decay:
|
|
10071
|
-
|
|
10072
|
-
})
|
|
11215
|
+
intensity: 1,
|
|
11216
|
+
x: 0,
|
|
11217
|
+
y: -500,
|
|
11218
|
+
z: -1e3,
|
|
11219
|
+
targetX: 0,
|
|
11220
|
+
targetY: 0,
|
|
11221
|
+
targetZ: 0,
|
|
11222
|
+
angle: 45,
|
|
11223
|
+
penumbra: .2,
|
|
11224
|
+
radius: 2e3,
|
|
11225
|
+
decay: 1
|
|
11226
|
+
}, options),
|
|
11227
|
+
rect: (options = {}) => buildLightNode({
|
|
11228
|
+
id: options.id ?? autoId("light-rect"),
|
|
11229
|
+
kind: "light",
|
|
11230
|
+
lightType: "rect",
|
|
11231
|
+
color: options.color ?? "#ffffff",
|
|
11232
|
+
intensity: 1,
|
|
11233
|
+
x: 0,
|
|
11234
|
+
y: -300,
|
|
11235
|
+
z: -800,
|
|
11236
|
+
targetX: 0,
|
|
11237
|
+
targetY: 0,
|
|
11238
|
+
targetZ: 0,
|
|
11239
|
+
width: 240,
|
|
11240
|
+
height: 140,
|
|
11241
|
+
twoSided: false,
|
|
11242
|
+
radius: 2e3,
|
|
11243
|
+
decay: 1.5
|
|
11244
|
+
}, options)
|
|
10073
11245
|
};
|
|
10074
11246
|
function section(source, targetOrOptions = {}, options = {}) {
|
|
10075
11247
|
return Layer.section(source, targetOrOptions, options);
|
|
@@ -10110,5 +11282,5 @@ const Effect = Object.assign(Effect$1, effectFactories, {
|
|
|
10110
11282
|
});
|
|
10111
11283
|
|
|
10112
11284
|
//#endregion
|
|
10113
|
-
export { glyphAnimator as $, wordRanges as $t, boilKeys as A, squigglePath as At, defineTheme as B, themes as Bt, audioLevelsSchema as C,
|
|
10114
|
-
//# sourceMappingURL=src-
|
|
11285
|
+
export { glyphAnimator as $, wordRanges as $t, boilKeys as A, FRAMEFIELDS_AI_PROXY_URL as An, squigglePath as At, defineTheme as B, themes as Bt, audioLevelsSchema as C, parseMarkup as Cn, scaleFrames as Ct, basePropsSchema as D, sub as Dn, springKeys as Dt, bandEdges as E, span as En, springAt as Et, constantExpression as F, surfaceFill as Ft, elevationStyle as G, transparent as Gt, drawOnKeys as H, toPathData as Ht, contrastRatio as I, targetPoint as It, evaluateEase as J, windowExpression as Jt, ellipsePath as K, typingFrames as Kt, cover as L, targetSchema as Lt, boxPath as M, ai as Mn, staggerRanks as Mt, catmullRom as N, stepExpression as Nt, beats as O, sup as On, springSettleFrames as Ot, chain as P, supersede as Pt, frameSpan as Q, wobblePoints as Qt, defineComponent as R, textLayout as Rt, ascending as S, normalizeTextSpans as Sn, safeArea as St, bakeSamples as T, size as Tn, smoothRelease as Tt, ease as U, toSeconds as Ut, dist as V, toFrames as Vt, elevate as W, transformPathData as Wt, exitAnimation as X, withDefaults as Xt, evaluateGlyphExpression as Y, withAlpha as Yt, findRange as Z, within as Zt, after as _, bold as _n, resampleBands as _t, Media as a, PhysicsBody2D as an, last as at, arcPath as b, italic as bn, rng as bt, section as c, Transition as cn, lineShift as ct, analyzeAudio as d, ClipVision as dn, offsetCues as dt, Styles as en, hashRng as et, KeyBook as f, PersonTrack as fn, parseColor as ft, UNIT_INDEX as g, accent as gn, rendererChars as gt, Track as h, DEFAULT_CHART_COLORS as hn, rangeRects as ht, Light as i, Fracture3D as in, isLight as it, boundsOf as j, ValidationError as jn, staggerOffsets as jt, bind as k, ApiError as kn, springTrack as kt, bindComponent as l, Layer3D as ln, luminance as lt, SAFE_INSETS as m, retargetPose as mn, quantize as mt, Effect as n, PhysicsBody3D as nn, holdFirstKeys as nt, blurRegion as o, PhysicsWorld2D as on, lerp2 as ot, MOTION_PRESETS as p, RIG_PRESETS as pn, pulseKeys as pt, enterAnimation as q, valueAt as qt, Layer as r, PhysicsWorld3D as rn, inkOn as rt, editTrackedRegion as s, Lighting as sn, linePath as st, Composition as t, Physics as tn, hashString as tt, z$2 as u, Particles as un, mix as ut, analyzeChannels as v, code as vn, resolveMotion as vt, bakeFunction as w, rich as wn, scheduleExpression as wt, arrowPaths as x, mark as xn, round as xt, anchorPoint as y, color as yn, resolveTarget as yt, defineMeta as z, themeFrames as zt };
|
|
11286
|
+
//# sourceMappingURL=src-CoHAjviq.mjs.map
|