framefields 2.13.1 → 2.15.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 +5 -5
- package/dist/audio/index.mjs +10 -10
- package/dist/{audio-DIvi6hTD.mjs → audio-6TfPlfl4.mjs} +3 -3
- package/dist/{audio-DIvi6hTD.mjs.map → audio-6TfPlfl4.mjs.map} +1 -1
- package/dist/{audio-C4B9p_yq.d.mts → audio-7oqTUi4G.d.mts} +3 -3
- package/dist/{audio-C4B9p_yq.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.d.mts.map +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 +13 -13
- 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-CCrYOkcc.mjs → dist-COOpgG9G.mjs} +4 -3
- package/dist/{dist-CCrYOkcc.mjs.map → dist-COOpgG9G.mjs.map} +1 -1
- package/dist/{dist-DtPPPsZV.mjs → dist-XqlFM2a8.mjs} +14063 -5308
- 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 +5 -5
- package/dist/effects/index.mjs +35 -35
- package/dist/{effects-B-L3rLs6.mjs → effects-DlRMovU5.mjs} +2 -2
- package/dist/{effects-B-L3rLs6.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-k5ll8NTE.mjs → fonts-BWYcXjyK.mjs} +3 -3
- package/dist/fonts-BWYcXjyK.mjs.map +1 -0
- package/dist/{gpu-D2HT3KcE.mjs → gpu-CH1PdM4T.mjs} +2 -2
- package/dist/{gpu-D2HT3KcE.mjs.map → gpu-CH1PdM4T.mjs.map} +1 -1
- package/dist/{index-rtCXNxGO.d.mts → index-BHTycml5.d.mts} +2 -2
- package/dist/{index-rtCXNxGO.d.mts.map → index-BHTycml5.d.mts.map} +1 -1
- package/dist/{index-BFTtXosj.d.mts → index-BVd6nXd5.d.mts} +2 -2
- package/dist/{index-BFTtXosj.d.mts.map → index-BVd6nXd5.d.mts.map} +1 -1
- package/dist/{index-ByhlTwxh.d.mts → index-BcxxxwhV.d.mts} +5 -5
- package/dist/{index-ByhlTwxh.d.mts.map → index-BcxxxwhV.d.mts.map} +1 -1
- package/dist/{index-CnZhBlob.d.mts → index-BnB_Ou2y.d.mts} +2 -2
- package/dist/index-BnB_Ou2y.d.mts.map +1 -0
- package/dist/{index-a6JrbAK0.d.mts → index-C-V6CAhP.d.mts} +32 -2
- package/dist/index-C-V6CAhP.d.mts.map +1 -0
- package/dist/{index-DBh3WphX.d.mts → index-CMhkkc56.d.mts} +44 -12
- package/dist/index-CMhkkc56.d.mts.map +1 -0
- package/dist/{index-BGlaws7-.d.mts → index-CYVpYGM-.d.mts} +3 -3
- package/dist/{index-BGlaws7-.d.mts.map → index-CYVpYGM-.d.mts.map} +1 -1
- package/dist/{index-DQ1U3HC3.d.mts → index-DhL7ckvs.d.mts} +7 -7
- package/dist/index-DhL7ckvs.d.mts.map +1 -0
- package/dist/{index-CtKUQ2VG.d.mts → index-DkAjKnhW.d.mts} +1487 -533
- package/dist/index-DkAjKnhW.d.mts.map +1 -0
- package/dist/{index-B08eSpaI.d.mts → index-RILu3ULT.d.mts} +2 -2
- package/dist/{index-B08eSpaI.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-C2yaponf.d.mts → index-s2qQ8ifZ.d.mts} +911 -57
- package/dist/index-s2qQ8ifZ.d.mts.map +1 -0
- package/dist/index.d.mts +15 -15
- package/dist/index.mjs +52 -52
- package/dist/preview/index.d.mts +5 -5
- package/dist/preview/index.mjs +10 -10
- package/dist/preview-BeGF1Bb1.mjs +1002 -0
- package/dist/preview-BeGF1Bb1.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-BR56TQBP.mjs +5 -0
- 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-VM2ZBPLM.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 +2 -2
- 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 +327 -0
- package/dist/{program-BfiB9ttP.mjs → program-CMigyfso.mjs} +919 -58
- package/dist/program-CMigyfso.mjs.map +1 -0
- package/dist/renderer/index.d.mts +4 -4
- package/dist/renderer/index.mjs +2 -2
- package/dist/{renderer-CoC64eam.mjs → renderer-0GMEL_Zi.mjs} +3 -3
- package/dist/{renderer-CoC64eam.mjs.map → renderer-0GMEL_Zi.mjs.map} +1 -1
- package/dist/{renderer-CSu_vYPn.mjs → renderer-3Wv2ZBJG.mjs} +3 -3
- package/dist/{renderer-CSu_vYPn.mjs.map → renderer-3Wv2ZBJG.mjs.map} +1 -1
- package/dist/{renderer-Dv_iRIyx.mjs → renderer-4nXkaAWu.mjs} +1280 -285
- package/dist/renderer-4nXkaAWu.mjs.map +1 -0
- package/dist/{renderer-TfeohPxt.mjs → renderer-6SnfLXeg.mjs} +3 -3
- package/dist/{renderer-TfeohPxt.mjs.map → renderer-6SnfLXeg.mjs.map} +1 -1
- package/dist/{renderer-D0xM67cK.mjs → renderer-8gHw3O0P.mjs} +2 -2
- package/dist/{renderer-D0xM67cK.mjs.map → renderer-8gHw3O0P.mjs.map} +1 -1
- package/dist/{renderer-C64_B8It.mjs → renderer-AOBglZHC.mjs} +2 -2
- package/dist/{renderer-B10HDC13.mjs → renderer-B0bSARK3.mjs} +3 -3
- package/dist/{renderer-B10HDC13.mjs.map → renderer-B0bSARK3.mjs.map} +1 -1
- package/dist/{renderer-DWYmJSrl.mjs → renderer-B2_tuRfl.mjs} +2 -2
- package/dist/{renderer-DWYmJSrl.mjs.map → renderer-B2_tuRfl.mjs.map} +1 -1
- package/dist/{renderer-mDBoz0zT.mjs → renderer-B82FhkEr.mjs} +3 -3
- package/dist/{renderer-mDBoz0zT.mjs.map → renderer-B82FhkEr.mjs.map} +1 -1
- package/dist/{renderer-DYeNNc_G.mjs → renderer-B9lzA0PY.mjs} +3 -3
- package/dist/{renderer-DYeNNc_G.mjs.map → renderer-B9lzA0PY.mjs.map} +1 -1
- package/dist/{renderer-BGchUBW_.mjs → renderer-BBSIWSry.mjs} +2 -2
- package/dist/{renderer-BGchUBW_.mjs.map → renderer-BBSIWSry.mjs.map} +1 -1
- package/dist/{renderer-GIlQ9lZq.mjs → renderer-BEKDMxbi.mjs} +2 -2
- package/dist/{renderer-GIlQ9lZq.mjs.map → renderer-BEKDMxbi.mjs.map} +1 -1
- package/dist/renderer-BERGAxqA.mjs +5 -0
- package/dist/{renderer-Bw0O--gW.mjs → renderer-BF960HY8.mjs} +3 -3
- package/dist/{renderer-Bw0O--gW.mjs.map → renderer-BF960HY8.mjs.map} +1 -1
- package/dist/{renderer-BhcTYhaP.mjs → renderer-BFwyVxCu.mjs} +3 -3
- package/dist/{renderer-BhcTYhaP.mjs.map → renderer-BFwyVxCu.mjs.map} +1 -1
- package/dist/{renderer-DYlx7VHo.mjs → renderer-BNiwcI3-.mjs} +2 -2
- package/dist/{renderer-DYlx7VHo.mjs.map → renderer-BNiwcI3-.mjs.map} +1 -1
- package/dist/{renderer-B3_GddgJ.mjs → renderer-BPbVb2Q4.mjs} +2 -2
- package/dist/{renderer-B3_GddgJ.mjs.map → renderer-BPbVb2Q4.mjs.map} +1 -1
- package/dist/renderer-BQ_YkBMt.mjs +6 -0
- package/dist/{renderer-Y1kjtOto.mjs → renderer-BUWxlA8T.mjs} +3 -3
- package/dist/{renderer-Y1kjtOto.mjs.map → renderer-BUWxlA8T.mjs.map} +1 -1
- package/dist/renderer-BW0Tjsv9.mjs +5 -0
- package/dist/{renderer-DtFZbE1j.mjs → renderer-BX8liu-e.mjs} +2 -2
- package/dist/{renderer-BOlHW3Mi.mjs → renderer-BXIwDAr_.mjs} +2 -2
- package/dist/{renderer-BOlHW3Mi.mjs.map → renderer-BXIwDAr_.mjs.map} +1 -1
- package/dist/{renderer-DzON3wDZ.mjs → renderer-B_Hy1W-g.mjs} +3 -3
- package/dist/{renderer-DzON3wDZ.mjs.map → renderer-B_Hy1W-g.mjs.map} +1 -1
- package/dist/{renderer-BM19iK8v.mjs → renderer-Bb6cvSgh.mjs} +2 -2
- package/dist/{renderer-BM19iK8v.mjs.map → renderer-Bb6cvSgh.mjs.map} +1 -1
- package/dist/{renderer-D0h1hTOo.mjs → renderer-BdppwWC9.mjs} +2 -2
- package/dist/{renderer-D0h1hTOo.mjs.map → renderer-BdppwWC9.mjs.map} +1 -1
- package/dist/{renderer-BTwuM9u-.mjs → renderer-Bhc24HVe.mjs} +3 -3
- package/dist/{renderer-BTwuM9u-.mjs.map → renderer-Bhc24HVe.mjs.map} +1 -1
- package/dist/{renderer-BZX932Lj.mjs → renderer-BiNA2wF0.mjs} +2 -2
- package/dist/{renderer-BZX932Lj.mjs.map → renderer-BiNA2wF0.mjs.map} +1 -1
- package/dist/{renderer-CkTehyRX.mjs → renderer-BmoBgTp5.mjs} +3 -3
- package/dist/{renderer-CkTehyRX.mjs.map → renderer-BmoBgTp5.mjs.map} +1 -1
- package/dist/{renderer-B3un4Pdi.mjs → renderer-BmqFmCWS.mjs} +3 -3
- package/dist/{renderer-B3un4Pdi.mjs.map → renderer-BmqFmCWS.mjs.map} +1 -1
- package/dist/{renderer-CHCRcCKw.mjs → renderer-BnVwAObV.mjs} +2 -2
- package/dist/{renderer-CHCRcCKw.mjs.map → renderer-BnVwAObV.mjs.map} +1 -1
- package/dist/{renderer-Cv9CKKWG.mjs → renderer-BxttZHme.mjs} +2 -2
- package/dist/{renderer-Cv9CKKWG.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-B6bK9rXm.mjs → renderer-C8E4XsSg.mjs} +2 -2
- package/dist/{renderer-B6bK9rXm.mjs.map → renderer-C8E4XsSg.mjs.map} +1 -1
- package/dist/renderer-C8zY3pzk.mjs +5 -0
- package/dist/{renderer-4nsuReW2.mjs → renderer-C9U-LY50.mjs} +3 -3
- package/dist/{renderer-4nsuReW2.mjs.map → renderer-C9U-LY50.mjs.map} +1 -1
- package/dist/{renderer-BvBqTAtk.mjs → renderer-CB2JVu5x.mjs} +3 -3
- package/dist/{renderer-BvBqTAtk.mjs.map → renderer-CB2JVu5x.mjs.map} +1 -1
- package/dist/{renderer-CQ4h8n7p.mjs → renderer-CC4YBJ8Z.mjs} +3 -3
- package/dist/{renderer-CQ4h8n7p.mjs.map → renderer-CC4YBJ8Z.mjs.map} +1 -1
- package/dist/renderer-CEkSOyKu.mjs +5 -0
- package/dist/{renderer-zLi2qFGT.mjs → renderer-CIycc5O-.mjs} +2 -2
- package/dist/{renderer-zLi2qFGT.mjs.map → renderer-CIycc5O-.mjs.map} +1 -1
- package/dist/renderer-CJYtfa4x.mjs +5 -0
- package/dist/{renderer-yNWYqvvq.mjs → renderer-CJraQlV-.mjs} +2 -2
- package/dist/{renderer-yNWYqvvq.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-BrEeUw7T.mjs → renderer-COWGWtob.mjs} +2 -2
- package/dist/{renderer-BrEeUw7T.mjs.map → renderer-COWGWtob.mjs.map} +1 -1
- package/dist/{renderer-uER8kn7f.mjs → renderer-COxG2XGf.mjs} +2 -2
- package/dist/{renderer-uER8kn7f.mjs.map → renderer-COxG2XGf.mjs.map} +1 -1
- package/dist/{renderer-C4hd6Cqi.mjs → renderer-CQDCIsQm.mjs} +2 -2
- package/dist/{renderer-C4hd6Cqi.mjs.map → renderer-CQDCIsQm.mjs.map} +1 -1
- package/dist/{renderer-Cfx_FCSf.mjs → renderer-CRUeag8i.mjs} +3 -3
- package/dist/{renderer-Cfx_FCSf.mjs.map → renderer-CRUeag8i.mjs.map} +1 -1
- package/dist/{renderer-CXrnzihz.mjs → renderer-CWVput06.mjs} +3 -3
- package/dist/{renderer-CXrnzihz.mjs.map → renderer-CWVput06.mjs.map} +1 -1
- package/dist/renderer-CZlHjcxr.mjs +5 -0
- package/dist/{renderer-BmyFfvVA.mjs → renderer-CbbnBLOB.mjs} +3 -3
- package/dist/{renderer-BmyFfvVA.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-_J9JcCMR.mjs → renderer-CfLZein2.mjs} +3 -3
- package/dist/{renderer-_J9JcCMR.mjs.map → renderer-CfLZein2.mjs.map} +1 -1
- package/dist/{renderer-D-mX1EVA.mjs → renderer-Ch-q1O-q.mjs} +3 -3
- package/dist/{renderer-D-mX1EVA.mjs.map → renderer-Ch-q1O-q.mjs.map} +1 -1
- package/dist/{renderer-uzU6dsdR.mjs → renderer-Ch5JvJWl.mjs} +2 -2
- package/dist/{renderer-uzU6dsdR.mjs.map → renderer-Ch5JvJWl.mjs.map} +1 -1
- package/dist/{renderer-BZMh2io2.mjs → renderer-ChtEzq-R.mjs} +2 -2
- package/dist/{renderer-BZMh2io2.mjs.map → renderer-ChtEzq-R.mjs.map} +1 -1
- package/dist/{renderer-B2IUPjhw.mjs → renderer-Cj9nTC5l.mjs} +3 -3
- package/dist/{renderer-B2IUPjhw.mjs.map → renderer-Cj9nTC5l.mjs.map} +1 -1
- package/dist/{renderer-CdXBRdFf.mjs → renderer-CqT8HsSS.mjs} +2 -2
- package/dist/{renderer-CdXBRdFf.mjs.map → renderer-CqT8HsSS.mjs.map} +1 -1
- package/dist/{renderer-CldjJmRR.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-BsrKj6Td.mjs → renderer-Cz30EVws.mjs} +2 -2
- package/dist/{renderer-BsrKj6Td.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-CC22Djgi.mjs → renderer-DHoX-5U_.mjs} +3 -3
- package/dist/{renderer-CC22Djgi.mjs.map → renderer-DHoX-5U_.mjs.map} +1 -1
- package/dist/{renderer-HKv5cBdp.mjs → renderer-DOkm0Ycd.mjs} +2 -2
- package/dist/{renderer-HKv5cBdp.mjs.map → renderer-DOkm0Ycd.mjs.map} +1 -1
- package/dist/{renderer-fG8Jy8Rx.d.mts → renderer-DU3f6ZrS.d.mts} +2 -2
- package/dist/{renderer-fG8Jy8Rx.d.mts.map → renderer-DU3f6ZrS.d.mts.map} +1 -1
- package/dist/{renderer-C98XwEIr.mjs → renderer-DUzv-shq.mjs} +2 -2
- package/dist/{renderer-C98XwEIr.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-BEuXJY-C.mjs → renderer-DhnOWnEA.mjs} +3 -3
- package/dist/{renderer-BEuXJY-C.mjs.map → renderer-DhnOWnEA.mjs.map} +1 -1
- package/dist/{renderer-BIKkxw_Z.mjs → renderer-Dhy1XHzz.mjs} +3 -3
- package/dist/{renderer-BIKkxw_Z.mjs.map → renderer-Dhy1XHzz.mjs.map} +1 -1
- package/dist/renderer-DjCvpsV_.mjs +5 -0
- package/dist/{renderer-pn52dzZz.mjs → renderer-DjJshz9Y.mjs} +2 -2
- package/dist/{renderer-pn52dzZz.mjs.map → renderer-DjJshz9Y.mjs.map} +1 -1
- package/dist/{renderer-DhGZ41hQ.mjs → renderer-DmTUIdus.mjs} +3 -3
- package/dist/{renderer-DhGZ41hQ.mjs.map → renderer-DmTUIdus.mjs.map} +1 -1
- package/dist/{renderer-D_m6Qbsi.mjs → renderer-Dq7AioJa.mjs} +2 -2
- package/dist/{renderer-D_m6Qbsi.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-DCrKEVjb.mjs → renderer-Dtcs4idV.mjs} +3 -3
- package/dist/{renderer-DCrKEVjb.mjs.map → renderer-Dtcs4idV.mjs.map} +1 -1
- package/dist/renderer-Dxlv8LYm.mjs +5 -0
- package/dist/{renderer-CO9vE3sd.mjs → renderer-Gj8SrE2W.mjs} +2 -2
- package/dist/{renderer-CO9vE3sd.mjs.map → renderer-Gj8SrE2W.mjs.map} +1 -1
- package/dist/{renderer-DvHi_wXE.mjs → renderer-KfnXDJS0.mjs} +3 -3
- package/dist/{renderer-DvHi_wXE.mjs.map → renderer-KfnXDJS0.mjs.map} +1 -1
- package/dist/{renderer-7xQmXXMH.mjs → renderer-MXVlg4p5.mjs} +3 -3
- package/dist/{renderer-7xQmXXMH.mjs.map → renderer-MXVlg4p5.mjs.map} +1 -1
- package/dist/{renderer-YONlI6W-.mjs → renderer-N2b6QZ1E.mjs} +3 -3
- package/dist/{renderer-YONlI6W-.mjs.map → renderer-N2b6QZ1E.mjs.map} +1 -1
- package/dist/renderer-Pb43OO2t.mjs +5 -0
- package/dist/{renderer-DNynPM6X.mjs → renderer-Q7gDzm8c.mjs} +2 -2
- package/dist/{renderer-DNynPM6X.mjs.map → renderer-Q7gDzm8c.mjs.map} +1 -1
- package/dist/{renderer-BEhZiOT4.mjs → renderer-RCiANtRV.mjs} +2 -2
- package/dist/{renderer-BEhZiOT4.mjs.map → renderer-RCiANtRV.mjs.map} +1 -1
- package/dist/{renderer-Dm57W73p.mjs → renderer-Sig9nZcI.mjs} +2 -2
- package/dist/renderer-VQbm-cGr.mjs +5 -0
- package/dist/{renderer-DiZkZ0Pr.mjs → renderer-fabBgwQX.mjs} +3 -3
- package/dist/{renderer-DiZkZ0Pr.mjs.map → renderer-fabBgwQX.mjs.map} +1 -1
- package/dist/{renderer-Bw-_GZVw.mjs → renderer-g-0PCNoo.mjs} +3 -3
- package/dist/{renderer-Bw-_GZVw.mjs.map → renderer-g-0PCNoo.mjs.map} +1 -1
- package/dist/{renderer-QbSrnPZU.mjs → renderer-gmHKIbKI.mjs} +3 -3
- package/dist/{renderer-QbSrnPZU.mjs.map → renderer-gmHKIbKI.mjs.map} +1 -1
- package/dist/{renderer-CU6WT5jW.mjs → renderer-kVZwiRoK.mjs} +3 -3
- package/dist/{renderer-CU6WT5jW.mjs.map → renderer-kVZwiRoK.mjs.map} +1 -1
- package/dist/renderer-oPMypDM1.mjs +5 -0
- package/dist/{renderer-CRhEGqW4.mjs → renderer-p7tgxP-A.mjs} +3 -3
- package/dist/{renderer-CRhEGqW4.mjs.map → renderer-p7tgxP-A.mjs.map} +1 -1
- package/dist/{renderer-CO4NGvAh.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-BufiCyn7.mjs → renderers-CP8CFWDs-DLjtjrwx.mjs} +2 -2
- package/dist/{renderers-CP8CFWDs-BufiCyn7.mjs.map → renderers-CP8CFWDs-DLjtjrwx.mjs.map} +1 -1
- package/dist/sam/index.d.mts +3 -3
- package/dist/sam/index.mjs +1 -1
- package/dist/signals/index.d.mts +5 -5
- 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-DrP7fGJX.mjs → src-CoHAjviq.mjs} +1355 -178
- package/dist/src-CoHAjviq.mjs.map +1 -0
- package/dist/storage/index.mjs +1 -1
- package/package.json +63 -60
- package/dist/dist-CiTgmfUw.mjs.map +0 -1
- package/dist/dist-DtPPPsZV.mjs.map +0 -1
- package/dist/fonts-k5ll8NTE.mjs.map +0 -1
- package/dist/index-C2yaponf.d.mts.map +0 -1
- package/dist/index-C5sgRLlG.d.mts.map +0 -1
- package/dist/index-CnZhBlob.d.mts.map +0 -1
- package/dist/index-CtKUQ2VG.d.mts.map +0 -1
- package/dist/index-DBh3WphX.d.mts.map +0 -1
- package/dist/index-DQ1U3HC3.d.mts.map +0 -1
- package/dist/index-a6JrbAK0.d.mts.map +0 -1
- package/dist/preview-engine/chunk-5ZS46EFB.mjs +0 -5
- package/dist/preview-engine/chunk-N3XTDAL6.mjs +0 -2227
- package/dist/preview-engine/chunk-NCQHOGZK.mjs +0 -3
- package/dist/preview-engine/chunk-PH3UUX6A.mjs +0 -138
- package/dist/preview-engine/chunk-XCPRRMMW.mjs +0 -2462
- package/dist/preview-engine/renderers-ZMMQ7S2A.mjs +0 -228
- package/dist/preview-lHH8Tv4j.mjs +0 -2446
- package/dist/preview-lHH8Tv4j.mjs.map +0 -1
- package/dist/program-BfiB9ttP.mjs.map +0 -1
- package/dist/renderer-0rLmztAv.mjs +0 -5
- package/dist/renderer-B0pjOXFY.mjs +0 -5
- package/dist/renderer-B7J13reL.mjs +0 -5
- package/dist/renderer-BPGIKGgl.mjs +0 -5
- package/dist/renderer-Bv-Artj1.mjs +0 -5
- package/dist/renderer-BvLjbhcL.mjs +0 -5
- package/dist/renderer-By6awWaf.mjs +0 -5
- package/dist/renderer-C0rvsz7m.mjs +0 -5
- package/dist/renderer-CDgud_HB.mjs +0 -5
- package/dist/renderer-CDiRF3bG.mjs +0 -6
- package/dist/renderer-CIIEQd4B.mjs +0 -5
- package/dist/renderer-CJblwOA9.mjs +0 -5
- package/dist/renderer-CNMOXtXE.mjs +0 -5
- package/dist/renderer-CO4NGvAh.mjs.map +0 -1
- package/dist/renderer-COeSeNGg.mjs +0 -5
- package/dist/renderer-CUfElmtZ.mjs +0 -5
- package/dist/renderer-CYh2lFoJ.mjs +0 -5
- package/dist/renderer-CYtVZYMH.mjs +0 -5
- package/dist/renderer-CjxZlkjb.mjs +0 -5
- package/dist/renderer-Cpd6TvTC.mjs +0 -5
- package/dist/renderer-D3ziOPhX.mjs +0 -5
- package/dist/renderer-D5yp74NL.mjs +0 -3
- package/dist/renderer-DL-phtL5.mjs +0 -5
- package/dist/renderer-DSnmYnHg.mjs +0 -5
- package/dist/renderer-DUGfsT-E.mjs +0 -5
- package/dist/renderer-DW5af9x1.mjs +0 -5
- package/dist/renderer-DYMrol1t.mjs +0 -5
- package/dist/renderer-DekeUHaz.mjs +0 -5
- package/dist/renderer-Dt5uyJdZ.mjs +0 -5
- package/dist/renderer-Dv_iRIyx.mjs.map +0 -1
- package/dist/renderer-DwLQAnaK.mjs +0 -5
- package/dist/renderer-IXQP2CWM.mjs +0 -5
- package/dist/renderer-K-Pkw63O.mjs +0 -5
- package/dist/renderer-MPw2KH9P.mjs +0 -5
- package/dist/renderer-RPu8RMav.mjs +0 -5
- package/dist/renderer-dCqxd5N2.mjs +0 -5
- package/dist/renderer-lhjmE-Fp.mjs +0 -5
- package/dist/renderer-u9cmBuvM.mjs +0 -5
- package/dist/renderer-vH12jcpz.mjs +0 -5
- package/dist/src-BU6vm9sP-DdTHmCr4.mjs.map +0 -1
- package/dist/src-DrP7fGJX.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) {
|
|
@@ -3302,6 +3789,8 @@ function createSwarm3D(options) {
|
|
|
3302
3789
|
//#endregion
|
|
3303
3790
|
//#region src/shapes3d.ts
|
|
3304
3791
|
const MATERIAL_KEYS = [
|
|
3792
|
+
"toon",
|
|
3793
|
+
"outline",
|
|
3305
3794
|
"material",
|
|
3306
3795
|
"shininess",
|
|
3307
3796
|
"roughness",
|
|
@@ -3315,7 +3804,22 @@ const MATERIAL_KEYS = [
|
|
|
3315
3804
|
"envIntensity",
|
|
3316
3805
|
"emissive",
|
|
3317
3806
|
"emissiveIntensity",
|
|
3318
|
-
"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"
|
|
3319
3823
|
];
|
|
3320
3824
|
/** The material and surface options that were actually given. */
|
|
3321
3825
|
function materialProps(o) {
|
|
@@ -3332,6 +3836,7 @@ function normalizePathSpec(input) {
|
|
|
3332
3836
|
if (input instanceof Path3D) return input.getPoints(96);
|
|
3333
3837
|
return input;
|
|
3334
3838
|
}
|
|
3839
|
+
/** A Layer3D mesh node built from a procedural geometry spec. */
|
|
3335
3840
|
function primitiveNode(prefix, geometry, o) {
|
|
3336
3841
|
const spec$1 = Object.fromEntries(Object.entries({
|
|
3337
3842
|
...geometry,
|
|
@@ -3349,9 +3854,9 @@ function primitiveNode(prefix, geometry, o) {
|
|
|
3349
3854
|
x: o.x ?? 0,
|
|
3350
3855
|
y: o.y ?? 0,
|
|
3351
3856
|
z: o.z ?? 0,
|
|
3352
|
-
rotateX: o.rotateX ?? 0,
|
|
3353
|
-
rotateY: o.rotateY ?? 0,
|
|
3354
|
-
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,
|
|
3355
3860
|
scale: o.scale ?? 1,
|
|
3356
3861
|
scaleX: o.scaleX ?? 1,
|
|
3357
3862
|
scaleY: o.scaleY ?? 1,
|
|
@@ -3368,7 +3873,9 @@ function primitiveNode(prefix, geometry, o) {
|
|
|
3368
3873
|
twoSided: o.twoSided ?? false,
|
|
3369
3874
|
wireframe: o.wireframe,
|
|
3370
3875
|
startFrame: o.startFrame,
|
|
3371
|
-
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)) }
|
|
3372
3879
|
});
|
|
3373
3880
|
}
|
|
3374
3881
|
/**
|
|
@@ -3426,7 +3933,10 @@ const Layer3D = {
|
|
|
3426
3933
|
if (options.roughness !== void 0 && node.roughness === void 0) node.roughness = options.roughness;
|
|
3427
3934
|
if (options.metallic !== void 0 && node.metallic === void 0) node.metallic = options.metallic;
|
|
3428
3935
|
if (options.ambientIntensity !== void 0 && node.ambientIntensity === void 0) node.ambientIntensity = options.ambientIntensity;
|
|
3429
|
-
Object.assign(node,
|
|
3936
|
+
Object.assign(node, {
|
|
3937
|
+
...materialProps(options),
|
|
3938
|
+
...materialProps(node)
|
|
3939
|
+
}, faceProps);
|
|
3430
3940
|
return node;
|
|
3431
3941
|
}
|
|
3432
3942
|
const cfg = typeof input === "string" ? { background: input } : input ?? { background: defaultColor };
|
|
@@ -3519,9 +4029,9 @@ const Layer3D = {
|
|
|
3519
4029
|
height: h,
|
|
3520
4030
|
is3D: true,
|
|
3521
4031
|
transformStyle: "preserve-3d",
|
|
3522
|
-
rotateX: options.rotateX ?? 0,
|
|
3523
|
-
rotateY: options.rotateY ?? 0,
|
|
3524
|
-
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,
|
|
3525
4035
|
opacity: options.opacity ?? 1,
|
|
3526
4036
|
background: "transparent",
|
|
3527
4037
|
children: faces
|
|
@@ -3557,18 +4067,20 @@ const Layer3D = {
|
|
|
3557
4067
|
height: options.itemHeight ?? 200,
|
|
3558
4068
|
is3D: true,
|
|
3559
4069
|
transformStyle: "preserve-3d",
|
|
3560
|
-
rotateX: options.rotateX ?? 0,
|
|
3561
|
-
rotateY: options.rotateY ?? 0,
|
|
3562
|
-
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,
|
|
3563
4073
|
opacity: options.opacity ?? 1,
|
|
3564
4074
|
background: "transparent",
|
|
3565
4075
|
children: transformedItems
|
|
3566
4076
|
}), { items: transformedItems });
|
|
3567
4077
|
},
|
|
3568
|
-
prism(options) {
|
|
3569
|
-
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;
|
|
3570
4082
|
if (options.sideConfigs && options.sideConfigs.length > 0) {
|
|
3571
|
-
const {
|
|
4083
|
+
const { twoSided = true } = options;
|
|
3572
4084
|
const sideWidth = 2 * radius * Math.tan(Math.PI / n);
|
|
3573
4085
|
const angleStep = 360 / n;
|
|
3574
4086
|
const panels = [];
|
|
@@ -3630,20 +4142,23 @@ const Layer3D = {
|
|
|
3630
4142
|
height,
|
|
3631
4143
|
is3D: true,
|
|
3632
4144
|
transformStyle: "preserve-3d",
|
|
3633
|
-
rotateX: options.rotateX ?? 0,
|
|
3634
|
-
rotateY: options.rotateY ?? 0,
|
|
3635
|
-
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,
|
|
3636
4148
|
opacity: options.opacity ?? 1,
|
|
3637
4149
|
background: "transparent",
|
|
3638
4150
|
children: panels
|
|
3639
|
-
}), {
|
|
4151
|
+
}), {
|
|
4152
|
+
faces: panels,
|
|
4153
|
+
items: panels
|
|
4154
|
+
});
|
|
3640
4155
|
}
|
|
3641
4156
|
const modelNode = primitiveNode("prism", {
|
|
3642
4157
|
type: "cylinder",
|
|
3643
|
-
radius
|
|
3644
|
-
radiusTop: options.radiusTop ?? options.radius,
|
|
3645
|
-
radiusBottom: options.radiusBottom ?? options.radius,
|
|
3646
|
-
height
|
|
4158
|
+
radius,
|
|
4159
|
+
radiusTop: options.radiusTop ?? options.topRadius ?? radius,
|
|
4160
|
+
radiusBottom: options.radiusBottom ?? options.bottomRadius ?? radius,
|
|
4161
|
+
height,
|
|
3647
4162
|
segments: n,
|
|
3648
4163
|
openEnded: options.openEnded ?? false,
|
|
3649
4164
|
flatShaded: options.flatShaded ?? true
|
|
@@ -3657,14 +4172,14 @@ const Layer3D = {
|
|
|
3657
4172
|
items: [modelNode]
|
|
3658
4173
|
});
|
|
3659
4174
|
},
|
|
3660
|
-
pyramid(options) {
|
|
4175
|
+
pyramid(options = {}) {
|
|
3661
4176
|
const n = Math.max(3, Math.round(options.sides ?? 4));
|
|
3662
4177
|
return primitiveNode("pyramid", {
|
|
3663
4178
|
type: "cylinder",
|
|
3664
4179
|
radius: options.radius ?? 60,
|
|
3665
|
-
radiusTop: options.radiusTop ?? 0,
|
|
4180
|
+
radiusTop: options.radiusTop ?? options.topRadius ?? 0,
|
|
3666
4181
|
radiusBottom: options.radius ?? 60,
|
|
3667
|
-
height: options.height,
|
|
4182
|
+
height: options.height ?? 100,
|
|
3668
4183
|
segments: n,
|
|
3669
4184
|
openEnded: options.openEnded ?? false,
|
|
3670
4185
|
flatShaded: options.flatShaded ?? true
|
|
@@ -3685,9 +4200,9 @@ const Layer3D = {
|
|
|
3685
4200
|
z: options.z ?? 0,
|
|
3686
4201
|
is3D: true,
|
|
3687
4202
|
twoSided: options.twoSided ?? true,
|
|
3688
|
-
rotateX: options.rotateX ?? 0,
|
|
3689
|
-
rotateY: options.rotateY ?? 0,
|
|
3690
|
-
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,
|
|
3691
4206
|
background: options.background ?? "#3b82f6",
|
|
3692
4207
|
borderRadius: options.borderRadius ?? 0,
|
|
3693
4208
|
opacity: options.opacity ?? 1,
|
|
@@ -3741,9 +4256,9 @@ const Layer3D = {
|
|
|
3741
4256
|
z: options.z ?? 0,
|
|
3742
4257
|
is3D: true,
|
|
3743
4258
|
transformStyle: "preserve-3d",
|
|
3744
|
-
rotateX: options.rotateX ?? 90,
|
|
3745
|
-
rotateY: options.rotateY ?? 0,
|
|
3746
|
-
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,
|
|
3747
4262
|
background: "transparent",
|
|
3748
4263
|
opacity: options.opacity ?? 1,
|
|
3749
4264
|
children: lines
|
|
@@ -3762,9 +4277,9 @@ const Layer3D = {
|
|
|
3762
4277
|
z: options.z ?? 0,
|
|
3763
4278
|
is3D: true,
|
|
3764
4279
|
twoSided: options.twoSided ?? true,
|
|
3765
|
-
rotateX: options.rotateX ?? 0,
|
|
3766
|
-
rotateY: options.rotateY ?? 0,
|
|
3767
|
-
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,
|
|
3768
4283
|
fontSize: options.fontSize ?? 48,
|
|
3769
4284
|
fontFamily: options.fontFamily,
|
|
3770
4285
|
fontWeight: options.fontWeight ?? "bold",
|
|
@@ -3820,9 +4335,9 @@ const Layer3D = {
|
|
|
3820
4335
|
x: options.x ?? 0,
|
|
3821
4336
|
y: options.y ?? 0,
|
|
3822
4337
|
z: options.z ?? 0,
|
|
3823
|
-
rotateX: options.rotateX ?? 0,
|
|
3824
|
-
rotateY: options.rotateY ?? 0,
|
|
3825
|
-
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,
|
|
3826
4341
|
scale: options.scale ?? 1,
|
|
3827
4342
|
scaleX: options.scaleX ?? 1,
|
|
3828
4343
|
scaleY: options.scaleY ?? 1,
|
|
@@ -3852,7 +4367,7 @@ const Layer3D = {
|
|
|
3852
4367
|
width: options.width,
|
|
3853
4368
|
height: options.height,
|
|
3854
4369
|
depth: options.depth,
|
|
3855
|
-
radius: options.radius,
|
|
4370
|
+
radius: options.radius ?? options.cornerRadius ?? options.borderRadius,
|
|
3856
4371
|
segments: options.segments,
|
|
3857
4372
|
taper: options.taper
|
|
3858
4373
|
}, options);
|
|
@@ -3868,8 +4383,8 @@ const Layer3D = {
|
|
|
3868
4383
|
return primitiveNode("cylinder", {
|
|
3869
4384
|
type: "cylinder",
|
|
3870
4385
|
radius: options.radius,
|
|
3871
|
-
radiusTop: options.radiusTop,
|
|
3872
|
-
radiusBottom: options.radiusBottom,
|
|
4386
|
+
radiusTop: options.radiusTop ?? options.topRadius,
|
|
4387
|
+
radiusBottom: options.radiusBottom ?? options.bottomRadius,
|
|
3873
4388
|
height: options.height,
|
|
3874
4389
|
segments: options.segments,
|
|
3875
4390
|
openEnded: options.openEnded,
|
|
@@ -3882,8 +4397,8 @@ const Layer3D = {
|
|
|
3882
4397
|
torus(options = {}) {
|
|
3883
4398
|
return primitiveNode("torus", {
|
|
3884
4399
|
type: "torus",
|
|
3885
|
-
radius: options.radius,
|
|
3886
|
-
tube: options.tube,
|
|
4400
|
+
radius: options.radius ?? options.majorRadius,
|
|
4401
|
+
tube: options.tube ?? options.minorRadius ?? options.tubeRadius,
|
|
3887
4402
|
radialSegments: options.radialSegments,
|
|
3888
4403
|
tubularSegments: options.tubularSegments,
|
|
3889
4404
|
arc: options.arc
|
|
@@ -4025,6 +4540,15 @@ const Layer3D = {
|
|
|
4025
4540
|
irregularity: options.irregularity
|
|
4026
4541
|
}, options);
|
|
4027
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
|
+
},
|
|
4028
4552
|
instances(options) {
|
|
4029
4553
|
const primaryMesh = Array.isArray(options.mesh) ? options.mesh[0] : options.mesh;
|
|
4030
4554
|
const node = {
|
|
@@ -4033,9 +4557,9 @@ const Layer3D = {
|
|
|
4033
4557
|
x: options.x ?? 0,
|
|
4034
4558
|
y: options.y ?? 0,
|
|
4035
4559
|
z: options.z ?? 0,
|
|
4036
|
-
rotateX: options.rotateX ?? 0,
|
|
4037
|
-
rotateY: options.rotateY ?? 0,
|
|
4038
|
-
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,
|
|
4039
4563
|
scale: options.scale ?? 1,
|
|
4040
4564
|
color: options.color,
|
|
4041
4565
|
colorTint: options.colorTint,
|
|
@@ -4050,6 +4574,8 @@ const Layer3D = {
|
|
|
4050
4574
|
startFrame: options.startFrame,
|
|
4051
4575
|
durationFrames: options.durationFrames,
|
|
4052
4576
|
instances3d: { ...options },
|
|
4577
|
+
...options.wind && { wind: options.wind },
|
|
4578
|
+
...options.crowd && { crowd: options.crowd },
|
|
4053
4579
|
...materialProps(options)
|
|
4054
4580
|
};
|
|
4055
4581
|
if (primaryMesh) {
|
|
@@ -4486,6 +5012,9 @@ function rig(name, options) {
|
|
|
4486
5012
|
exposure: options.exposure,
|
|
4487
5013
|
toneMapping: options.toneMapping,
|
|
4488
5014
|
fog: options.fog,
|
|
5015
|
+
volumetricFog: options.volumetricFog,
|
|
5016
|
+
ssr: options.ssr,
|
|
5017
|
+
gi: options.gi,
|
|
4489
5018
|
bloom: options.bloom
|
|
4490
5019
|
}), Light.directional({
|
|
4491
5020
|
id: `${id}-key`,
|
|
@@ -4597,6 +5126,20 @@ var RapierWorld2D = class {
|
|
|
4597
5126
|
x,
|
|
4598
5127
|
y
|
|
4599
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
|
+
},
|
|
4600
5143
|
setKinematicTarget: ([x, y], angle) => {
|
|
4601
5144
|
body.setNextKinematicTranslation({
|
|
4602
5145
|
x,
|
|
@@ -4725,6 +5268,19 @@ var RapierWorld3D = class {
|
|
|
4725
5268
|
mass: () => body.mass(),
|
|
4726
5269
|
setEnabled: (on) => body.setEnabled(on),
|
|
4727
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
|
+
},
|
|
4728
5284
|
setKinematicTarget: (p, [x, y, z$3, w]) => {
|
|
4729
5285
|
body.setNextKinematicTranslation(vec3(p));
|
|
4730
5286
|
body.setNextKinematicRotation({
|
|
@@ -4832,6 +5388,7 @@ function shapeDesc3D(R, shape$1) {
|
|
|
4832
5388
|
if (!desc) throw new Error("Physics: could not build a convex hull for this shape.");
|
|
4833
5389
|
return desc;
|
|
4834
5390
|
}
|
|
5391
|
+
case "trimesh": return R.ColliderDesc.trimesh(new Float32Array(shape$1.vertices), new Uint32Array(shape$1.indices));
|
|
4835
5392
|
}
|
|
4836
5393
|
}
|
|
4837
5394
|
|
|
@@ -5025,6 +5582,8 @@ var PhysicsWorld2D = class extends WorldCore {
|
|
|
5025
5582
|
};
|
|
5026
5583
|
const simBody = this.sim.addBody(spec$1);
|
|
5027
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);
|
|
5028
5587
|
return this.addBody(body);
|
|
5029
5588
|
}
|
|
5030
5589
|
/** A fixed, very wide floor whose top edge sits at `y`. */
|
|
@@ -5219,7 +5778,7 @@ function effectiveMass(a, b) {
|
|
|
5219
5778
|
if (ma > 0 && mb > 0) return ma * mb / (ma + mb);
|
|
5220
5779
|
return Math.max(ma, mb, .001);
|
|
5221
5780
|
}
|
|
5222
|
-
function num$
|
|
5781
|
+
function num$4(v, fallback) {
|
|
5223
5782
|
return typeof v === "number" && Number.isFinite(v) ? v : fallback;
|
|
5224
5783
|
}
|
|
5225
5784
|
function layerGeometry(layer, options) {
|
|
@@ -5230,31 +5789,31 @@ function layerGeometry(layer, options) {
|
|
|
5230
5789
|
if ((width === void 0 || height === void 0) && layer.kind === "text") {
|
|
5231
5790
|
const m = FontManager.measure(String(layer.text ?? ""), {
|
|
5232
5791
|
fontFamily: String(layer.fontFamily ?? "Inter"),
|
|
5233
|
-
fontSize: num$
|
|
5792
|
+
fontSize: num$4(layer.fontSize, 48),
|
|
5234
5793
|
fontWeight: layer.fontWeight,
|
|
5235
|
-
letterSpacing: num$
|
|
5794
|
+
letterSpacing: num$4(layer.letterSpacing, 0),
|
|
5236
5795
|
lineHeight: typeof layer.lineHeight === "number" ? layer.lineHeight : void 0
|
|
5237
5796
|
});
|
|
5238
5797
|
width ??= m.width;
|
|
5239
5798
|
height ??= m.height;
|
|
5240
5799
|
}
|
|
5241
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.`);
|
|
5242
|
-
const scale = num$
|
|
5801
|
+
const scale = num$4(layer.scale, 1);
|
|
5243
5802
|
return {
|
|
5244
5803
|
x: layer.x,
|
|
5245
5804
|
y: layer.y,
|
|
5246
5805
|
width,
|
|
5247
5806
|
height,
|
|
5248
5807
|
scale,
|
|
5249
|
-
anchorX: num$
|
|
5250
|
-
anchorY: num$
|
|
5251
|
-
rotation: num$
|
|
5808
|
+
anchorX: num$4(layer.anchorX, .5),
|
|
5809
|
+
anchorY: num$4(layer.anchorY, .5),
|
|
5810
|
+
rotation: num$4(layer.rotation, 0),
|
|
5252
5811
|
shape: scaleShape$1(colliderShape(layer, width, height, options.shape ?? "auto"), scale)
|
|
5253
5812
|
};
|
|
5254
5813
|
}
|
|
5255
5814
|
function colliderShape(layer, w, h, mode) {
|
|
5256
5815
|
const shapeType = layer.kind === "shape" ? String(layer.shapeType ?? "rect") : "rect";
|
|
5257
|
-
const radius = num$
|
|
5816
|
+
const radius = num$4(layer.borderRadius, num$4(layer.cornerRadius, 0));
|
|
5258
5817
|
const box = {
|
|
5259
5818
|
kind: "box",
|
|
5260
5819
|
hx: w / 2,
|
|
@@ -5282,7 +5841,7 @@ function outlinePoints(layer, shapeType, w, h) {
|
|
|
5282
5841
|
shapeType,
|
|
5283
5842
|
width: w,
|
|
5284
5843
|
height: h,
|
|
5285
|
-
cornerRadius: num$
|
|
5844
|
+
cornerRadius: num$4(layer.cornerRadius, num$4(layer.borderRadius, 0)),
|
|
5286
5845
|
polygonSides: layer.polygonSides,
|
|
5287
5846
|
starPoints: layer.starPoints,
|
|
5288
5847
|
starInnerRadiusRatio: layer.starInnerRadiusRatio,
|
|
@@ -5331,6 +5890,275 @@ function centerToLayer(cx, cy, rotationDeg, f) {
|
|
|
5331
5890
|
return [cx - ox - f.anchorX * f.width, cy - oy - f.anchorY * f.height];
|
|
5332
5891
|
}
|
|
5333
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
|
+
|
|
5334
6162
|
//#endregion
|
|
5335
6163
|
//#region src/physics/world3d.ts
|
|
5336
6164
|
const DEG = Math.PI / 180;
|
|
@@ -5356,6 +6184,7 @@ function quatFromEuler(rx, ry, rz) {
|
|
|
5356
6184
|
Math.cos(half(rz))
|
|
5357
6185
|
], qy), qx);
|
|
5358
6186
|
}
|
|
6187
|
+
/** @internal */
|
|
5359
6188
|
function quatMul(a, b) {
|
|
5360
6189
|
const [ax, ay, az, aw] = a;
|
|
5361
6190
|
const [bx, by, bz, bw] = b;
|
|
@@ -5435,7 +6264,32 @@ var PhysicsBody3D = class {
|
|
|
5435
6264
|
this.recording = recording;
|
|
5436
6265
|
}
|
|
5437
6266
|
get startFrame() {
|
|
5438
|
-
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
|
+
]);
|
|
5439
6293
|
}
|
|
5440
6294
|
get gravityScale() {
|
|
5441
6295
|
return this.options.gravityScale ?? 1;
|
|
@@ -5489,17 +6343,17 @@ var PhysicsBody3D = class {
|
|
|
5489
6343
|
const follow = this.options.follow;
|
|
5490
6344
|
if (this.type !== "kinematic" || !follow) return void 0;
|
|
5491
6345
|
const fps = this.world.fps;
|
|
5492
|
-
const read$
|
|
6346
|
+
const read$2 = (d, fallback) => d === void 0 ? fallback : sampleDriver(d, frame, fps);
|
|
5493
6347
|
const p = this.start.position;
|
|
5494
6348
|
const r = this.start.rotation;
|
|
5495
6349
|
const ppm = this.world.pixelsPerMeter;
|
|
5496
6350
|
return {
|
|
5497
6351
|
position: [
|
|
5498
|
-
read$
|
|
5499
|
-
read$
|
|
5500
|
-
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
|
|
5501
6355
|
],
|
|
5502
|
-
rotation: quatFromEuler(read$
|
|
6356
|
+
rotation: quatFromEuler(read$2(follow.rotateX, r[0]), read$2(follow.rotateY, r[1]), read$2(follow.rotateZ, r[2]))
|
|
5503
6357
|
};
|
|
5504
6358
|
}
|
|
5505
6359
|
/** @internal */
|
|
@@ -5518,7 +6372,12 @@ var PhysicsBody3D = class {
|
|
|
5518
6372
|
ry[previous],
|
|
5519
6373
|
rz[previous]
|
|
5520
6374
|
];
|
|
5521
|
-
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);
|
|
5522
6381
|
rx[index] = e[0];
|
|
5523
6382
|
ry[index] = e[1];
|
|
5524
6383
|
rz[index] = e[2];
|
|
@@ -5571,6 +6430,7 @@ var PhysicsBody3D = class {
|
|
|
5571
6430
|
];
|
|
5572
6431
|
}
|
|
5573
6432
|
};
|
|
6433
|
+
/** @internal */
|
|
5574
6434
|
function rotateByQuat(v, q) {
|
|
5575
6435
|
const r = quatMul(quatMul(q, [
|
|
5576
6436
|
v[0],
|
|
@@ -5626,6 +6486,11 @@ var PhysicsWorld3D = class extends WorldCore {
|
|
|
5626
6486
|
num$2(options.rotateY ?? t.rotateY, 0),
|
|
5627
6487
|
num$2(options.rotateZ ?? t.rotateZ, 0)
|
|
5628
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();
|
|
5629
6494
|
const ppm = this.pixelsPerMeter;
|
|
5630
6495
|
const type = options.type ?? "dynamic";
|
|
5631
6496
|
const v = options.velocity ?? [
|
|
@@ -5671,15 +6536,37 @@ var PhysicsWorld3D = class extends WorldCore {
|
|
|
5671
6536
|
density: options.density ?? 1,
|
|
5672
6537
|
friction: options.friction ?? .6,
|
|
5673
6538
|
restitution: options.restitution ?? .3,
|
|
5674
|
-
shape: scaleShape(
|
|
6539
|
+
shape: scaleShape(shape$1, 1 / ppm)
|
|
5675
6540
|
};
|
|
5676
6541
|
const simBody = this.sim.addBody(spec$1);
|
|
5677
6542
|
const body = new PhysicsBody3D(this, simBody, type, layer, {
|
|
5678
6543
|
position,
|
|
5679
6544
|
rotation
|
|
5680
6545
|
}, options, this.newRecording());
|
|
6546
|
+
const start = body.kinematicTarget(this.startFrame);
|
|
6547
|
+
if (start) simBody.setPose(start.position, start.rotation);
|
|
5681
6548
|
return this.addBody(body);
|
|
5682
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
|
+
}
|
|
5683
6570
|
/** A fixed, very large floor whose top face sits at `y`. */
|
|
5684
6571
|
ground(options) {
|
|
5685
6572
|
const t = 2e3;
|
|
@@ -5828,11 +6715,11 @@ var PhysicsWorld3D = class extends WorldCore {
|
|
|
5828
6715
|
/** A steady push, px/s² (mass-independent). Drivers are read every frame. */
|
|
5829
6716
|
force(body, accel) {
|
|
5830
6717
|
const ppm = this.pixelsPerMeter;
|
|
5831
|
-
const read$
|
|
6718
|
+
const read$2 = (d, frame) => d === void 0 ? 0 : sampleDriver(d, frame, this.fps) / ppm;
|
|
5832
6719
|
this.addForce(body, (frame) => [
|
|
5833
|
-
read$
|
|
5834
|
-
read$
|
|
5835
|
-
read$
|
|
6720
|
+
read$2(accel.x, frame),
|
|
6721
|
+
read$2(accel.y, frame),
|
|
6722
|
+
read$2(accel.z, frame)
|
|
5836
6723
|
]);
|
|
5837
6724
|
return this;
|
|
5838
6725
|
}
|
|
@@ -5937,6 +6824,10 @@ function colliderShape3D(t, options) {
|
|
|
5937
6824
|
points: pts.map((v, i) => v * scale[i % 3])
|
|
5938
6825
|
};
|
|
5939
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
|
+
}
|
|
5940
6831
|
if (options.size || mode === "box") {
|
|
5941
6832
|
const [w, h$1, d] = options.size ?? boxSize(t, prim) ?? [
|
|
5942
6833
|
0,
|
|
@@ -6049,6 +6940,25 @@ function boxSize(t, prim) {
|
|
|
6049
6940
|
t.depth
|
|
6050
6941
|
];
|
|
6051
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
|
+
}
|
|
6052
6962
|
/** Every vertex of a model, flat xyz, at most ~4k points (the hull needs no more). */
|
|
6053
6963
|
function meshPoints(modelData) {
|
|
6054
6964
|
const meshes = modelData?.meshes;
|
|
@@ -6088,6 +6998,11 @@ function scaleShape(shape$1, s) {
|
|
|
6088
6998
|
kind: "hull",
|
|
6089
6999
|
points: shape$1.points.map((v) => v * s)
|
|
6090
7000
|
};
|
|
7001
|
+
case "trimesh": return {
|
|
7002
|
+
kind: "trimesh",
|
|
7003
|
+
vertices: shape$1.vertices.map((v) => v * s),
|
|
7004
|
+
indices: shape$1.indices
|
|
7005
|
+
};
|
|
6091
7006
|
}
|
|
6092
7007
|
}
|
|
6093
7008
|
|
|
@@ -8662,7 +9577,7 @@ var Media = class Media {
|
|
|
8662
9577
|
return this.virtualMedia;
|
|
8663
9578
|
}
|
|
8664
9579
|
/**
|
|
8665
|
-
* 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.
|
|
8666
9581
|
* Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).
|
|
8667
9582
|
*/
|
|
8668
9583
|
async renderFrame(options = {}) {
|
|
@@ -8775,7 +9690,11 @@ var Composition = class Composition {
|
|
|
8775
9690
|
vision(sourceOrLayer, options = {}) {
|
|
8776
9691
|
const source = typeof sourceOrLayer === "string" ? sourceOrLayer : sourceOrLayer.src ?? sourceOrLayer.inputHandleId;
|
|
8777
9692
|
if (typeof sourceOrLayer !== "string") {
|
|
8778
|
-
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
|
+
} };
|
|
8779
9698
|
if (!layer) throw new Error("Add the media layer to the composition before calling comp.vision(layer)");
|
|
8780
9699
|
options = {
|
|
8781
9700
|
startFrame: layer.operation.startFrame ?? sourceOrLayer.startFrame,
|
|
@@ -8818,9 +9737,12 @@ var Composition = class Composition {
|
|
|
8818
9737
|
if (!node || typeof node !== "object") return;
|
|
8819
9738
|
const n = node;
|
|
8820
9739
|
if (n.kind === "media" && n.dataType === "Video" && typeof n.inputHandleId === "string" && n.vision instanceof Vision && !(CLIP_SUBJECT in n.vision)) {
|
|
8821
|
-
layers ??= new Map(
|
|
8822
|
-
const op =
|
|
8823
|
-
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
|
+
}];
|
|
8824
9746
|
}));
|
|
8825
9747
|
const layer = layers.get(n.id);
|
|
8826
9748
|
const clip = this.clipForLayer(n.src ?? n.inputHandleId, n.vision, {
|
|
@@ -9373,10 +10295,11 @@ var Composition = class Composition {
|
|
|
9373
10295
|
return vm;
|
|
9374
10296
|
}
|
|
9375
10297
|
/**
|
|
9376
|
-
* Renders a single frame from the composition to
|
|
10298
|
+
* Renders a single frame from the composition to an image or raw RGBA Buffer.
|
|
9377
10299
|
* Can render either by timestamp in milliseconds (`atMs`) or by frame index (`frame`).
|
|
9378
10300
|
*/
|
|
9379
|
-
async renderFrame(
|
|
10301
|
+
async renderFrame(frameOrOptions = {}) {
|
|
10302
|
+
const options = typeof frameOrOptions === "number" ? { frame: frameOrOptions } : frameOrOptions;
|
|
9380
10303
|
const { frame } = resolveFrameRequest(options, this.fps);
|
|
9381
10304
|
if (options.fps !== void 0 && options.fps !== this.fps) throw new Error(`Composition fps is ${this.fps}; cannot render at fps ${options.fps}.`);
|
|
9382
10305
|
const vm = this.toVirtualMedia();
|
|
@@ -9394,7 +10317,9 @@ var Composition = class Composition {
|
|
|
9394
10317
|
}
|
|
9395
10318
|
return (options.renderer ?? new HeadlessMediaRenderer()).renderFrame(vm, {
|
|
9396
10319
|
fps: this.fps,
|
|
9397
|
-
frame
|
|
10320
|
+
frame,
|
|
10321
|
+
renderId: options.renderId,
|
|
10322
|
+
format: options.format
|
|
9398
10323
|
});
|
|
9399
10324
|
}
|
|
9400
10325
|
/**
|
|
@@ -9437,11 +10362,27 @@ var Composition = class Composition {
|
|
|
9437
10362
|
* never change. `renderVideo({ qa })` includes these automatically.
|
|
9438
10363
|
*/
|
|
9439
10364
|
lint() {
|
|
9440
|
-
return lintComposition(this.toSpec(), {
|
|
10365
|
+
return lintComposition(this.toSpec(), {
|
|
10366
|
+
emojiFont: FontManager.hasEmojiFont(),
|
|
10367
|
+
scatterCoverage
|
|
10368
|
+
});
|
|
9441
10369
|
}
|
|
9442
10370
|
};
|
|
9443
10371
|
function withAnimation(node) {
|
|
9444
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
|
+
}
|
|
9445
10386
|
if (target$1.animation instanceof LayerAnimation) target$1.animation = target$1.animation.toSpec();
|
|
9446
10387
|
Object.defineProperty(target$1, "animate", {
|
|
9447
10388
|
value: (...anims) => {
|
|
@@ -9628,8 +10569,89 @@ function withAnimation(node) {
|
|
|
9628
10569
|
writable: true,
|
|
9629
10570
|
configurable: true
|
|
9630
10571
|
});
|
|
10572
|
+
bindMaterialSignals(target$1);
|
|
9631
10573
|
return target$1;
|
|
9632
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
|
+
}
|
|
9633
10655
|
const Layer = {
|
|
9634
10656
|
video: (src, options = {}) => withAnimation({
|
|
9635
10657
|
id: options.id ?? autoId("video"),
|
|
@@ -9907,29 +10929,42 @@ const Layer = {
|
|
|
9907
10929
|
});
|
|
9908
10930
|
},
|
|
9909
10931
|
chart: (options, props = {}) => buildChart(options, props, FontManager.getAll()[0]?.family ?? "Inter"),
|
|
9910
|
-
camera: (options = {}) =>
|
|
9911
|
-
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
|
|
9918
|
-
|
|
9919
|
-
|
|
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({
|
|
9920
10955
|
id: options.id ?? autoId("light"),
|
|
9921
10956
|
kind: "light",
|
|
9922
10957
|
lightType: options.lightType ?? "point",
|
|
9923
10958
|
color: options.color ?? "#ffffff",
|
|
9924
|
-
intensity:
|
|
9925
|
-
|
|
9926
|
-
}),
|
|
10959
|
+
intensity: 1
|
|
10960
|
+
}, options),
|
|
9927
10961
|
ambientLight: (color$1 = "#ffffff", intensity = .5, options = {}) => Light.ambient(color$1, intensity, options),
|
|
9928
10962
|
sequence: (entries, options) => sequence(entries, options),
|
|
9929
10963
|
environment: (presetOrOptions = "studio", options = {}) => Light.environment(presetOrOptions, options),
|
|
9930
10964
|
directionalLight: (options = {}) => Light.directional(options),
|
|
9931
10965
|
pointLight: (options = {}) => Light.point(options),
|
|
9932
10966
|
spotLight: (options = {}) => Light.spot(options),
|
|
10967
|
+
rectLight: (options = {}) => Light.rect(options),
|
|
9933
10968
|
cube: (options) => Layer3D.cube(options),
|
|
9934
10969
|
carousel3d: (options) => Layer3D.carousel(options),
|
|
9935
10970
|
plane3d: (options) => Layer3D.plane(options),
|
|
@@ -9993,78 +11028,220 @@ const Layer = {
|
|
|
9993
11028
|
...options
|
|
9994
11029
|
})
|
|
9995
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
|
+
}
|
|
9996
11156
|
const Light = {
|
|
9997
11157
|
environment: (presetOrOptions = "studio", options = {}) => {
|
|
9998
|
-
const opts =
|
|
9999
|
-
preset: presetOrOptions,
|
|
10000
|
-
...options
|
|
10001
|
-
} : {
|
|
10002
|
-
...presetOrOptions,
|
|
11158
|
+
const opts = {
|
|
11159
|
+
...typeof presetOrOptions !== "string" ? presetOrOptions : isHdriPath(presetOrOptions) ? { hdri: presetOrOptions } : { preset: presetOrOptions },
|
|
10003
11160
|
...options
|
|
10004
11161
|
};
|
|
10005
|
-
return
|
|
11162
|
+
return buildLightNode({
|
|
11163
|
+
id: opts.id ?? autoId("environment"),
|
|
10006
11164
|
kind: "light",
|
|
10007
11165
|
lightType: "environment",
|
|
10008
11166
|
preset: "studio",
|
|
10009
|
-
intensity: 1
|
|
10010
|
-
|
|
10011
|
-
id: opts.id ?? autoId("environment")
|
|
10012
|
-
});
|
|
11167
|
+
intensity: 1
|
|
11168
|
+
}, opts);
|
|
10013
11169
|
},
|
|
10014
|
-
ambient: (color$1 = "#ffffff", intensity = .5, options = {}) =>
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
|
|
10018
|
-
|
|
10019
|
-
|
|
10020
|
-
|
|
10021
|
-
|
|
10022
|
-
|
|
10023
|
-
|
|
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({
|
|
10024
11186
|
id: options.id ?? autoId("light-directional"),
|
|
10025
11187
|
kind: "light",
|
|
10026
11188
|
lightType: "directional",
|
|
10027
11189
|
color: options.color ?? "#ffffff",
|
|
10028
|
-
intensity:
|
|
10029
|
-
x:
|
|
10030
|
-
y:
|
|
10031
|
-
z:
|
|
10032
|
-
targetX:
|
|
10033
|
-
targetY:
|
|
10034
|
-
targetZ:
|
|
10035
|
-
|
|
10036
|
-
})
|
|
10037
|
-
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({
|
|
10038
11199
|
id: options.id ?? autoId("light-point"),
|
|
10039
11200
|
kind: "light",
|
|
10040
11201
|
lightType: "point",
|
|
10041
11202
|
color: options.color ?? "#ffffff",
|
|
10042
|
-
intensity:
|
|
10043
|
-
x:
|
|
10044
|
-
y:
|
|
10045
|
-
z:
|
|
10046
|
-
radius:
|
|
10047
|
-
decay:
|
|
10048
|
-
|
|
10049
|
-
})
|
|
10050
|
-
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({
|
|
10051
11211
|
id: options.id ?? autoId("light-spot"),
|
|
10052
11212
|
kind: "light",
|
|
10053
11213
|
lightType: "spot",
|
|
10054
11214
|
color: options.color ?? "#ffffff",
|
|
10055
|
-
intensity:
|
|
10056
|
-
x:
|
|
10057
|
-
y:
|
|
10058
|
-
z:
|
|
10059
|
-
targetX:
|
|
10060
|
-
targetY:
|
|
10061
|
-
targetZ:
|
|
10062
|
-
angle:
|
|
10063
|
-
penumbra:
|
|
10064
|
-
radius:
|
|
10065
|
-
decay:
|
|
10066
|
-
|
|
10067
|
-
})
|
|
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)
|
|
10068
11245
|
};
|
|
10069
11246
|
function section(source, targetOrOptions = {}, options = {}) {
|
|
10070
11247
|
return Layer.section(source, targetOrOptions, options);
|
|
@@ -10105,5 +11282,5 @@ const Effect = Object.assign(Effect$1, effectFactories, {
|
|
|
10105
11282
|
});
|
|
10106
11283
|
|
|
10107
11284
|
//#endregion
|
|
10108
|
-
export { glyphAnimator as $, wordRanges as $t, boilKeys as A, squigglePath as At, defineTheme as B, themes as Bt, audioLevelsSchema as C,
|
|
10109
|
-
//# 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
|